You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENTS.md
+11-4Lines changed: 11 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -53,7 +53,7 @@ For environments that don't run `npm install` after fetching the plugin (Claude
53
53
-`opencode/bridge.js` — Spawns the binary with a fake HookEvent, parses the HookOutput response.
54
54
-`opencode/config.js` — Reads `open-plan-annotator.json` config for implementation handoff settings.
55
55
-`ui/` — React + Vite frontend, built to a single `build/index.html` embedded at compile time.
56
-
-`hooks/hooks.json` — Claude Code hook registration. `SessionStart` runs `scripts/install-runtime.mjs` (runtime fetch) and `scripts/session-context.mjs` (injects plan-routing instructions into Claude's session context). `PreToolUse:ExitPlanMode` launches the annotator binary.
56
+
-`hooks/hooks.json` — Claude Code hook registration. `SessionStart` runs `scripts/install-runtime.mjs` (runtime fetch) and `scripts/session-context.mjs` (injects plan-routing instructions into Claude's session context). `PreToolUse:ExitPlanMode` launches the annotator binary for Conductor-compatible denies; `PermissionRequest:ExitPlanMode` preserves native Claude Code approval behavior.
57
57
-`skills/plan-review-triggers/SKILL.md` — Auto-loaded Claude Code skill with the full trigger heuristics. This is the long-form reference; the SessionStart context injection is the always-on nudge that keeps Claude from rationalizing past it.
58
58
59
59
## Critical Rules
@@ -99,14 +99,21 @@ bun run format # Format
99
99
100
100
## Hook Protocol
101
101
102
-
Claude Code sends a `HookEvent` JSON on stdin with `tool_input.plan` containing the plan markdown. The binary responds on stdout with a `HookOutput` JSON:
102
+
Claude Code sends a `HookEvent` JSON on stdin with `tool_input.plan` containing the plan markdown. The binary responds on stdout with a `HookOutput` JSON matching the incoming hook event.
The deny `permissionDecisionReason` contains serialized annotations (deletions, replacements, insertions, comments) as markdown so Claude can revise the plan.
The deny feedback field (`permissionDecisionReason` or `decision.message`) contains serialized annotations (deletions, replacements, insertions, comments) as markdown so Claude can revise the plan.
108
115
109
-
The hook is registered on `PreToolUse`(not`PermissionRequest`) so it fires before the permission flow and regardless of `--permission-mode`. This makes Request Changes (`deny`) work across all hosts, including Conductor — which runs Claude Code with `--permission-prompt-tool stdio --permission-mode bypassPermissions` and never surfaces a `PermissionRequest` hook decision. (Note: in Conductor, exiting plan mode on approve is still owned by Conductor's own plan-approval UI, so an `allow` decision does not by itself leave plan mode there.)
116
+
The hook is registered on both `PreToolUse`and`PermissionRequest`. `PreToolUse`fires before the permission flow and regardless of `--permission-mode`, which makes Request Changes (`deny`) work in Conductor. Native Claude Code still needs `PermissionRequest` to apply final plan approval. When both fire for the same tool call, the `PreToolUse` decision is cached briefly and replayed to `PermissionRequest` so the browser UI opens only once.
110
117
111
118
The OpenCode bridge (`opencode/bridge.js`) constructs the same `HookEvent` format and parses the same `HookOutput` response, so the binary always goes through the same code path.
0 commit comments