Implementation Plan

Add PostToolUse Hook to Auto-Rebuild the Plans Index

todo
2026-05-30 agentics feature

Wire a PostToolUse hook into kit/plugins/plan-agent so that whenever a .html file (excluding index.html) is written to docs/plans/, the plans gallery index regenerates automatically — keeping the library current without user intervention.

File add-hook-to-rebuild-plans-index.html
Path docs/plans/add-hook-to-rebuild-plans-index.html
Acceptance criteria 0 / 5 done

Context

The plan-agent plugin's /plan-agent:planning skill writes HTML plan files to docs/plans/. The gallery at docs/plans/index.html is only updated when a user explicitly runs /plan-agent:plans-library. This creates stale-index state: a newly written plan doesn't appear in the gallery until the user manually triggers a rebuild.

A PostToolUse hook that fires on every Write to docs/plans/*.html and calls bash docs/plans/build-index.sh eliminates the manual step. The hook is an observation hook (always exits 0) so index-rebuild failures never block plan writes.

Note on hook registration: The objective referenced plugin.json, but the existing validate-plan-filename hook for this plugin is registered in kit/plugins/plan-agent/hooks.json — a separate file that Claude Code reads alongside plugin.json. This plan follows the established pattern and adds to hooks.json.

Steps

1
todo Create docs/plans/build-index.sh
The hook needs a stable, self-contained shell entry point that regenerates the gallery without Claude. The script searches ~/.claude/plugins for plan-agent/*/templates/plans-gallery.html (same strategy as the plans-library skill). If the template is not found, the script falls back to a minimal embedded styled list (plan title, date, status badge, direct link) so the hook always succeeds regardless of plugin installation state.
Verify
Run bash docs/plans/build-index.sh from the project root and confirm docs/plans/index.html is rewritten with a fresh GENERATED_AT timestamp and at least one plan card in the gallery HTML. The script must exit 0.
2
todo Create kit/plugins/plan-agent/hooks/rebuild-plans-index.py
Keeping the filter logic in Python (mirroring validate-plan-filename.py) enables reuse of the plansDirectory settings-resolution function and keeps both hooks consistent. Always exiting 0 ensures plan writes are never blocked by an index-rebuild failure. The subprocess call uses cwd=os.getcwd() (the project root where Claude Code operates) so the relative path docs/plans/build-index.sh resolves correctly.
Verify
Run both cases from the project root:
echo '{"tool_input":{"file_path":"docs/plans/add-sample.html"}}' | python3 kit/plugins/plan-agent/hooks/rebuild-plans-index.py — should exit 0 and update index.html.
echo '{"tool_input":{"file_path":"docs/plans/index.html"}}' | python3 kit/plugins/plan-agent/hooks/rebuild-plans-index.py — should exit 0 without running build-index.sh.
3
todo Register the hook in kit/plugins/plan-agent/hooks.json
hooks.json is the canonical hook-registration file for this plugin (the existing validate-plan-filename hook uses this same file, not plugin.json). Using a Write|Edit|MultiEdit matcher covers new plan creation, in-place status edits (e.g. updating a plan's <meta name="plan-status"> tag from todo to completed), and batched multi-edit operations. Timeout of 30 s accommodates scanning up to ~50 HTML files.
Verify
Open kit/plugins/plan-agent/hooks.json and confirm two PostToolUse entries are present: the existing Write|Edit matcher for validate-plan-filename.py and a new Write|Edit|MultiEdit matcher for rebuild-plans-index.py with timeout: 30.
4
todo Bump plan-agent to v0.14.0 in marketplace.json and update CHANGELOG.md
Adding a new hook is a MINOR feature addition per the project's versioning conventions in .claude/rules/marketplace.md. The CHANGELOG entry documents the change for users upgrading the plugin.
Verify
grep -A3 '"plan-agent"' .claude-plugin/marketplace.json shows "version": "0.14.0". head -15 kit/plugins/plan-agent/CHANGELOG.md shows a new entry describing the rebuild-plans-index hook.
5
todo End-to-end test: write a minimal plan file and confirm the gallery auto-updates
Manual invocation of the hook scripts proves unit-level correctness, but only a live Write in a Claude Code session proves the hook fires through the harness PostToolUse pipeline.
Verify
Write any valid docs/plans/add-hook-rebuild-test.html file during the session, then read docs/plans/index.html and confirm the GENERATED_AT timestamp matches the current session time and a card linking to add-hook-rebuild-test.html is present in the gallery HTML.

Acceptance Criteria

Verification

Run the full sequence end-to-end:

  1. bash docs/plans/build-index.sh from the project root — confirm index.html is rewritten with a fresh timestamp and valid gallery cards.
  2. Pipe a matching plan path through rebuild-plans-index.py via stdin — confirm exit 0 and index.html updates.
  3. Pipe docs/plans/index.html through rebuild-plans-index.py — confirm exit 0 with no build-index.sh invocation.
  4. Write a test plan file in a live session — confirm the gallery refreshes automatically and the new card is visible in index.html.

Next Steps

Wish List
Embed build-index logic directly in the hook (no shell script intermediary) Wish List

Speculative / blue-sky idea — not on the critical path. Paste into Claude when ready to explore:

Refactor rebuild-plans-index.py to perform the full index-rebuild logic inline (Python only, no subprocess call to build-index.sh). The hook would locate the plans-gallery.html template using the same search strategy as the plans-library skill, parse plan HTML files, and write index.html directly. This removes the dependency on a standalone shell script and makes the hook fully self-contained. The tradeoff: build-index.sh is no longer independently runnable from the CLI without loading the hook script. Evaluate whether standalone CLI usability of build-index.sh is worth maintaining before proceeding.