open-plan-annotator 1.5.3 → 1.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/CLAUDE.md +63 -16
- package/README.md +32 -38
- package/commands/{open-plan-annotator.md → annotate-plan.md} +9 -3
- package/opencode/index.js +40 -12
- package/package.json +6 -5
- package/shared/piExtension.mjs +2 -2
- package/skills/plan-review-triggers/SKILL.md +94 -0
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
},
|
|
6
6
|
"metadata": {
|
|
7
7
|
"description": "Interactive plan annotation plugin for Claude Code",
|
|
8
|
-
"version": "1.5.
|
|
8
|
+
"version": "1.5.5"
|
|
9
9
|
},
|
|
10
10
|
"plugins": [
|
|
11
11
|
{
|
|
12
12
|
"name": "open-plan-annotator",
|
|
13
13
|
"source": "./",
|
|
14
14
|
"description": "Interactive plan annotation UI: review, strikethrough, and comment on Claude's plans before approving. Fully local, no external services.",
|
|
15
|
-
"version": "1.5.
|
|
15
|
+
"version": "1.5.5",
|
|
16
16
|
"author": {
|
|
17
17
|
"name": "ndom91"
|
|
18
18
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "open-plan-annotator",
|
|
3
3
|
"description": "Interactive plan annotation UI: review, strikethrough, and comment on Claude's plans before approving. Fully local, no external services.",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.5",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "ndom91"
|
|
7
7
|
},
|
package/CLAUDE.md
CHANGED
|
@@ -1,42 +1,86 @@
|
|
|
1
1
|
# open-plan-annotator: Plan Review Instructions
|
|
2
2
|
|
|
3
|
+
<!--
|
|
4
|
+
Maintainer note: this file's content is mirrored in
|
|
5
|
+
`skills/plan-review-triggers/SKILL.md` because Claude Code plugin installs do
|
|
6
|
+
not load repo-root markdown — only skills/, commands/, hooks/. Keep both files
|
|
7
|
+
in sync when editing trigger rules. Sections that diverge intentionally
|
|
8
|
+
(audience, framing) are still close enough that a side-by-side diff catches
|
|
9
|
+
drift quickly.
|
|
10
|
+
-->
|
|
11
|
+
|
|
3
12
|
## Why This Plugin Exists
|
|
4
13
|
|
|
5
14
|
Markdown plans rendered in chat are read-only for the user. To give feedback they have to retype sections inline, which is awkward in a terminal. open-plan-annotator opens a browser UI where the user can mark up your plan directly — delete lines, replace text, insert steps, leave comments. Their annotations come back to you as structured feedback.
|
|
6
15
|
|
|
7
|
-
**
|
|
16
|
+
**This is the user's required review surface for any multi-section proposal.** Inline plans bypass the tool the user installed and silently lose their preferred feedback workflow.
|
|
8
17
|
|
|
9
18
|
This is distinct from `plannotator-review` (post-implementation code review). open-plan-annotator runs *before* code is written.
|
|
10
19
|
|
|
11
|
-
##
|
|
20
|
+
## Hard Rule: Annotator Required When Triggers Match
|
|
21
|
+
|
|
22
|
+
When any trigger below fires, you MUST route through the annotator. "Prefer" / "consider" do not apply. Inline plans are a bug.
|
|
23
|
+
|
|
24
|
+
- Assistant-initiated (you decided a plan is needed): call `EnterPlanMode`, draft, then `ExitPlanMode` — this fires the annotator hook.
|
|
25
|
+
- User-initiated ("draft a plan", "/plan", etc.): invoke the `/annotate-plan <task>` slash command. It runs the same plan-mode flow.
|
|
26
|
+
|
|
27
|
+
## Trigger: Mechanical Heuristic
|
|
28
|
+
|
|
29
|
+
Annotator REQUIRED when the response would contain ANY of:
|
|
30
|
+
|
|
31
|
+
- 3 or more file paths to be created or modified
|
|
32
|
+
- 2 or more option/tradeoff comparisons the user is asked to choose between
|
|
33
|
+
- A `Plan:`, `Steps:`, `Concrete changes:`, `Implementation:`, `Approach:`, or similar section header
|
|
34
|
+
- A numbered or bulleted list of action items the user is expected to react to
|
|
35
|
+
- A multi-section proposal with decision points
|
|
36
|
+
|
|
37
|
+
This is a hard gate. Count file paths. Count options. If the count crosses the line, you do not get to write the inline response.
|
|
12
38
|
|
|
13
|
-
|
|
39
|
+
## Trigger: Task Shape
|
|
40
|
+
|
|
41
|
+
Enter plan mode (or invoke the slash command) before any of:
|
|
14
42
|
|
|
15
43
|
- Creating or modifying more than 2 files
|
|
16
44
|
- Architectural or structural changes
|
|
17
|
-
- Anything the user hasn't explicitly described step-by-step
|
|
18
45
|
- Refactoring, migration, or feature additions
|
|
19
46
|
- Bug fixes that require investigation
|
|
47
|
+
- Anything the user has not explicitly described step-by-step
|
|
48
|
+
|
|
49
|
+
## Trigger: Phrase Match
|
|
50
|
+
|
|
51
|
+
Treat these as plan triggers regardless of length:
|
|
52
|
+
|
|
53
|
+
- User says "draft a plan", "let's plan X", "what's the approach", "give me options", "how should we tackle this", "what would it look like"
|
|
54
|
+
- Your response would contain "recommended approach", "implementation plan", "proposed fix", "rollout plan", "here's what I'd do", or "concrete file changes"
|
|
55
|
+
- Any moment you would otherwise ask "want me to proceed?" / "shall I draft this?" / "OK to proceed?" / "sound good?"
|
|
56
|
+
|
|
57
|
+
## Mixed Signals: Still Trigger
|
|
58
|
+
|
|
59
|
+
When a user message combines directives ("let's add X", "can we Y") with an exploratory question ("what do you think?"), the annotator still applies. Do NOT collapse into a 2-3 sentence inline response just because one clause was exploratory.
|
|
60
|
+
|
|
61
|
+
The annotator IS the discussion surface. Tradeoffs, options, and open questions belong inside the plan body where the user can comment on each one — not in flat chat where they would have to retype your bullets to push back. Treat exploratory clauses as "include alternatives in the plan", not "skip the plan".
|
|
20
62
|
|
|
21
|
-
##
|
|
63
|
+
## Self-Check Before Sending
|
|
22
64
|
|
|
23
|
-
|
|
65
|
+
Before emitting any response, scan it for these strings:
|
|
24
66
|
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
67
|
+
- "Concrete file changes", "Concrete changes", "Plan:", "Steps:", "Implementation:", "Approach:"
|
|
68
|
+
- "OK to proceed?", "Want me to proceed?", "Shall I…?", "Sound good?", "Confirm…?"
|
|
69
|
+
- 3+ lines that look like file paths (`foo/bar.tsx`, `path/to/file.ts`)
|
|
70
|
+
- Numbered list of more than 2 items each describing a code change
|
|
71
|
+
- "**N.**" / "**Fix N —**" headers introducing proposed changes
|
|
29
72
|
|
|
30
|
-
|
|
73
|
+
If ANY match: stop, discard the inline response, route through the annotator instead.
|
|
31
74
|
|
|
32
75
|
## Do NOT Trigger For
|
|
33
76
|
|
|
34
77
|
- Single-line fixes, typos, renames
|
|
35
78
|
- Direct factual answers
|
|
36
79
|
- Status updates or progress reports
|
|
37
|
-
- Plans the user has already approved (
|
|
80
|
+
- Plans the user has already approved (do not re-prompt)
|
|
38
81
|
- Pure research or exploration with no proposed actions
|
|
39
82
|
- Trivial questions where a plan would be overhead
|
|
83
|
+
- Replies to the user's questions ABOUT an already-submitted plan (answer the question, do not re-submit)
|
|
40
84
|
|
|
41
85
|
## Plan Quality Standards
|
|
42
86
|
|
|
@@ -44,15 +88,18 @@ When writing a plan, include:
|
|
|
44
88
|
|
|
45
89
|
- Brief summary of what you understood the task to require
|
|
46
90
|
- Specific files you intend to create or modify and why
|
|
47
|
-
- Any assumptions you
|
|
91
|
+
- Any assumptions you are making
|
|
48
92
|
- Explicit question if anything is ambiguous
|
|
93
|
+
- Tradeoffs / option comparisons inline in the plan (since mixed-signal user messages route here)
|
|
49
94
|
|
|
50
95
|
## Workflow
|
|
51
96
|
|
|
52
|
-
**
|
|
97
|
+
**Assistant-initiated (you decided a plan is needed):**
|
|
98
|
+
draft mentally → call `EnterPlanMode` → draft plan → call `ExitPlanMode` → annotator opens → user annotates → revise based on feedback → re-exit when aligned.
|
|
53
99
|
|
|
54
|
-
**
|
|
100
|
+
**User-initiated (user asked for a plan):**
|
|
101
|
+
invoke `/annotate-plan <task>`. The command enters plan mode, drafts a plan, and exits to fire the annotator. Do not paste a multi-section plan inline and ask "sound good?" — that bypasses the annotator.
|
|
55
102
|
|
|
56
103
|
## Slash Command
|
|
57
104
|
|
|
58
|
-
`/
|
|
105
|
+
`/annotate-plan <task>` is the canonical user-invoked entry point. When the user invokes it, follow the command body exactly. When you (the assistant) decide a plan is needed without the user invoking the command, prefer `EnterPlanMode` directly — the slash command is for user invocation, the tool is for assistant initiation. Both paths fire the same annotator hook.
|
package/README.md
CHANGED
|
@@ -23,25 +23,28 @@ Everything runs locally. Nothing leaves your machine.
|
|
|
23
23
|
|
|
24
24
|
## Install
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
> `open-plan-annotator` now ships as one package-managed install. The npm package
|
|
28
|
-
> contains the plugin glue and resolves a platform runtime package locally. There
|
|
29
|
-
> is no first-run binary download and no in-app self-update path.
|
|
26
|
+
`open-plan-annotator` is package-managed: the plugin package installs the local platform runtime it needs. There is no first-run binary download and no in-app updater.
|
|
30
27
|
|
|
31
28
|
### Claude Code
|
|
32
29
|
|
|
33
|
-
|
|
30
|
+
Install from inside Claude Code:
|
|
34
31
|
|
|
35
32
|
```
|
|
36
33
|
/plugin marketplace add ndom91/open-plan-annotator
|
|
37
34
|
/plugin install open-plan-annotator@ndom91-open-plan-annotator
|
|
38
35
|
```
|
|
39
36
|
|
|
40
|
-
|
|
37
|
+
What you get:
|
|
38
|
+
|
|
39
|
+
- `ExitPlanMode` hook: opens the annotation UI whenever Claude submits a plan
|
|
40
|
+
- `/annotate-plan [task description]`: asks Claude to draft a plan and send it to the UI
|
|
41
|
+
- `open-plan-annotator`: runtime command invoked by the hook
|
|
42
|
+
|
|
43
|
+
Third-party marketplace auto-update is disabled by default in Claude Code. Enable auto-update for the `ndom91-open-plan-annotator` marketplace in the Marketplace UI if you want updates automatically.
|
|
41
44
|
|
|
42
45
|
### OpenCode
|
|
43
46
|
|
|
44
|
-
Add
|
|
47
|
+
Add the plugin to your OpenCode config (`opencode.json` or `.opencode/config.json`):
|
|
45
48
|
|
|
46
49
|
```json
|
|
47
50
|
{
|
|
@@ -49,66 +52,57 @@ Add `open-plan-annotator` to the `plugin` array in your OpenCode config (`openco
|
|
|
49
52
|
}
|
|
50
53
|
```
|
|
51
54
|
|
|
52
|
-
|
|
53
|
-
- Injects plan-mode instructions into the agent's system prompt
|
|
54
|
-
- Registers a `submit_plan` tool that the agent calls after creating a plan
|
|
55
|
-
- Spawns the annotation UI in your browser for review
|
|
56
|
-
- Returns structured feedback to the agent on approval or rejection
|
|
57
|
-
- Optionally hands off to an implementation agent after approval
|
|
55
|
+
What you get:
|
|
58
56
|
|
|
59
|
-
|
|
57
|
+
- `annotate_plan`: tool the agent calls after drafting a markdown plan
|
|
58
|
+
- `open-plan-annotator`: runtime command spawned by the plugin
|
|
59
|
+
- optional implementation-agent handoff after approval
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
> The update mechanism changed significantly in `1.0.20+`: OpenCode now loads the npm package plus a platform runtime package instead of using the old in-place binary updater. If OpenCode appears to be stuck on an older plugin build, clear the cached `open-plan-annotator` entries under `~/.cache/opencode/node_modules/` and restart OpenCode.
|
|
61
|
+
Restart OpenCode after installing or updating so it reloads the package-managed runtime.
|
|
63
62
|
|
|
64
63
|
### Pi
|
|
65
64
|
|
|
66
|
-
Install the
|
|
65
|
+
Install the Pi extension:
|
|
67
66
|
|
|
68
67
|
```sh
|
|
69
68
|
pi install npm:@open-plan-annotator/pi-extension
|
|
70
69
|
```
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
- a `submit_plan` tool, exposed to the model with prompt guidance to call it after drafting a concrete markdown plan and before implementation
|
|
75
|
-
- an `/annotate-plan` command for manual review of the latest assistant message or supplied plan text
|
|
76
|
-
|
|
77
|
-
Typical flow:
|
|
71
|
+
What you get:
|
|
78
72
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
4. Approval returns “Plan approved. Continue with implementation.”; requested changes return the serialized annotations as feedback.
|
|
73
|
+
- `annotate_plan`: tool the agent calls after drafting a markdown plan
|
|
74
|
+
- `/annotate-plan [plan markdown]`: command for manually reviewing supplied text or the latest assistant message
|
|
75
|
+
- `open-plan-annotator`: runtime command used by the extension
|
|
83
76
|
|
|
84
|
-
|
|
77
|
+
Manual review examples:
|
|
85
78
|
|
|
86
79
|
```sh
|
|
87
80
|
/annotate-plan
|
|
88
81
|
/annotate-plan # Plan\n\n1. Do the thing
|
|
89
82
|
```
|
|
90
83
|
|
|
91
|
-
### Manual
|
|
84
|
+
### Manual / CLI
|
|
92
85
|
|
|
93
|
-
|
|
86
|
+
Install globally if you want to run the CLI directly:
|
|
94
87
|
|
|
95
88
|
```sh
|
|
96
|
-
|
|
89
|
+
bun add -g open-plan-annotator
|
|
97
90
|
npm install -g open-plan-annotator
|
|
98
91
|
```
|
|
99
92
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
- OpenCode: update the installed npm plugin through OpenCode, then restart OpenCode.
|
|
103
|
-
- Claude Code: update the marketplace/plugin install, then restart Claude Code.
|
|
104
|
-
- Standalone/global install: update the npm package (`npm`, `pnpm`, or `bun`), then rerun `open-plan-annotator`.
|
|
105
|
-
|
|
106
|
-
The built-in `doctor` command reports the resolved runtime package and runtime path:
|
|
93
|
+
This adds the `open-plan-annotator` command. To verify the resolved runtime:
|
|
107
94
|
|
|
108
95
|
```sh
|
|
109
96
|
open-plan-annotator doctor
|
|
110
97
|
```
|
|
111
98
|
|
|
99
|
+
## Updates
|
|
100
|
+
|
|
101
|
+
- Claude Code: update the marketplace/plugin install, then restart Claude Code.
|
|
102
|
+
- OpenCode: update the installed npm plugin through OpenCode, then restart OpenCode.
|
|
103
|
+
- Pi: update the Pi extension, then restart Pi.
|
|
104
|
+
- Manual/global install: update the npm package, then rerun `open-plan-annotator`.
|
|
105
|
+
|
|
112
106
|
## Keyboard Shortcuts
|
|
113
107
|
|
|
114
108
|
| Action | Shortcut | Description |
|
|
@@ -3,7 +3,7 @@ description: Draft a plan and open it in the annotator UI for user review
|
|
|
3
3
|
argument-hint: [task description]
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
The user wants a plan drafted and reviewed via the open-plan-annotator UI before any implementation.
|
|
6
|
+
The user wants a plan drafted and reviewed via the open-plan-annotator UI before any implementation. This is required, not optional.
|
|
7
7
|
|
|
8
8
|
**Task to plan:** $ARGUMENTS
|
|
9
9
|
|
|
@@ -13,11 +13,17 @@ Steps:
|
|
|
13
13
|
2. Investigate the codebase as needed to draft a concrete plan. Include:
|
|
14
14
|
- Brief summary of what you understood the task to require
|
|
15
15
|
- Specific files you intend to create or modify and why
|
|
16
|
-
- Any assumptions you
|
|
16
|
+
- Any assumptions you are making
|
|
17
|
+
- Tradeoffs and option comparisons inline (do NOT pull these into chat — they belong in the plan body where the user can comment on each one)
|
|
17
18
|
- Explicit questions if anything is ambiguous
|
|
18
19
|
3. Call `ExitPlanMode` with the plan. This triggers the open-plan-annotator browser UI.
|
|
19
20
|
4. The user will annotate the plan (deletions, replacements, insertions, comments) in the browser.
|
|
20
21
|
5. If the user denies with annotations, revise the plan based on their feedback and re-exit plan mode.
|
|
21
22
|
6. Only begin implementation after the user approves.
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
Hard rules:
|
|
25
|
+
|
|
26
|
+
- Do not skip plan mode.
|
|
27
|
+
- Do not paste a plan inline and ask "sound good?" — that bypasses the annotator UI the user installed this plugin for.
|
|
28
|
+
- Do not collapse into a 2-3 sentence inline response just because the user message contains an exploratory clause like "what do you think?" alongside directive items. Mixed signals still route through the annotator.
|
|
29
|
+
- Self-check the response before sending: if it contains a "Plan:" / "Steps:" / "Concrete changes:" header, 3+ file paths, or ends with "OK to proceed?" — discard and route through the annotator instead.
|
package/opencode/index.js
CHANGED
|
@@ -2,7 +2,35 @@ import { tool } from "@opencode-ai/plugin";
|
|
|
2
2
|
import { runPlanReview } from "./bridge.js";
|
|
3
3
|
import { resolveImplementationHandoff } from "./config.js";
|
|
4
4
|
|
|
5
|
-
const PLAN_REVIEW_INSTRUCTIONS = `## Plan Review
|
|
5
|
+
const PLAN_REVIEW_INSTRUCTIONS = `## Plan Review Tool
|
|
6
|
+
|
|
7
|
+
The "open-plan-annotator plan annotation tool" refers to the \`annotate_plan\` tool.
|
|
8
|
+
|
|
9
|
+
When the user asks for a plan, proposal, implementation strategy, migration path, rollout plan, or asks "what would it look like," you MUST use the \`annotate_plan\` tool instead of replying with a normal Markdown plan.
|
|
10
|
+
|
|
11
|
+
Use \`annotate_plan\` when:
|
|
12
|
+
- The user explicitly says "make a plan", "write a plan", "give me a plan", "proposal", or "implementation plan".
|
|
13
|
+
- The user asks to evaluate an approach before code changes.
|
|
14
|
+
- The response contains ordered implementation steps.
|
|
15
|
+
- The plan would benefit from user approval before execution.
|
|
16
|
+
|
|
17
|
+
Do not use \`annotate_plan\` for:
|
|
18
|
+
- Tiny one-step tasks.
|
|
19
|
+
- Pure explanations with no proposed action.
|
|
20
|
+
- Final summaries after work is complete.
|
|
21
|
+
|
|
22
|
+
If there is any ambiguity about whether a response is a plan, prefer using \`annotate_plan\`.
|
|
23
|
+
|
|
24
|
+
The \`annotate_plan\` call should include:
|
|
25
|
+
- \`summary\`: one sentence describing the plan.
|
|
26
|
+
- \`plan\`: the full Markdown plan.
|
|
27
|
+
|
|
28
|
+
After calling \`annotate_plan\`, follow the returned instruction exactly:
|
|
29
|
+
- If approved, proceed.
|
|
30
|
+
- If revisions are requested, revise the plan and call \`annotate_plan\` again.
|
|
31
|
+
- If the user asks questions, answer them before proceeding.
|
|
32
|
+
|
|
33
|
+
## Plan Review Workflow
|
|
6
34
|
|
|
7
35
|
Track planning/execution using this state enum:
|
|
8
36
|
- \`DISCOVERY\`, \`PLAN_DRAFT\`, \`AWAITING_PLAN_DECISION\`, \`EXECUTION\`, \`DONE\`
|
|
@@ -10,7 +38,7 @@ Track planning/execution using this state enum:
|
|
|
10
38
|
State transitions:
|
|
11
39
|
- Start in \`DISCOVERY\`.
|
|
12
40
|
- Move to \`PLAN_DRAFT\` only when a plan is required.
|
|
13
|
-
- From \`PLAN_DRAFT\`, call \`
|
|
41
|
+
- From \`PLAN_DRAFT\`, call \`annotate_plan\` exactly once, then move to \`AWAITING_PLAN_DECISION\`.
|
|
14
42
|
- If user approves plan, set \`plan_status=approved\` and move to \`EXECUTION\`.
|
|
15
43
|
- If user rejects or requests plan changes, set \`plan_status=rejected\` and return to \`PLAN_DRAFT\`.
|
|
16
44
|
- When work is complete, move to \`DONE\`.
|
|
@@ -21,16 +49,16 @@ Required flags:
|
|
|
21
49
|
- Set \`explicit_replan=true\` only when user clearly asks to replan (for example: revise/change/new/update plan).
|
|
22
50
|
|
|
23
51
|
Hard rules:
|
|
24
|
-
1) \`
|
|
25
|
-
2) If \`plan_status=approved\`, \`
|
|
26
|
-
3) Call \`
|
|
52
|
+
1) \`annotate_plan\` is allowed only in \`PLAN_DRAFT\`.
|
|
53
|
+
2) If \`plan_status=approved\`, \`annotate_plan\` is forbidden unless \`explicit_replan=true\`.
|
|
54
|
+
3) Call \`annotate_plan\` at most once per plan draft/version. If rejected, revise and submit once for the new draft.
|
|
27
55
|
4) After approval, treat follow-up user messages as execution refinements by default, not planning triggers.
|
|
28
56
|
5) On conflict, prioritize the approved plan and execute immediately.
|
|
29
57
|
6) Do not ask permission to proceed after approval; execute and report progress/results.
|
|
30
58
|
7) When delegating to subagents, always pass current \`plan_status\` and \`explicit_replan\` values.
|
|
31
|
-
8) If \`plan_status=approved\` and \`explicit_replan=false\`, subagents must execute and must not call \`
|
|
59
|
+
8) If \`plan_status=approved\` and \`explicit_replan=false\`, subagents must execute and must not call \`annotate_plan\`.
|
|
32
60
|
|
|
33
|
-
Tool guard before calling \`
|
|
61
|
+
Tool guard before calling \`annotate_plan\`:
|
|
34
62
|
- assert \`state == PLAN_DRAFT\`
|
|
35
63
|
- assert \`plan_status != approved || explicit_replan == true\`
|
|
36
64
|
- if an assertion fails, continue execution without submitting a new plan.`;
|
|
@@ -40,7 +68,7 @@ const IMPLEMENTATION_PROMPT = [
|
|
|
40
68
|
"State transition: next_state=EXECUTION.",
|
|
41
69
|
"Replan intent: explicit_replan=false unless the user explicitly asks to revise the plan.",
|
|
42
70
|
"Execute the approved plan directly now — write code, create files, and make changes.",
|
|
43
|
-
"Do not call `
|
|
71
|
+
"Do not call `annotate_plan` again unless the user explicitly requests re-planning.",
|
|
44
72
|
].join(" ");
|
|
45
73
|
|
|
46
74
|
function getErrorMessage(error) {
|
|
@@ -151,7 +179,7 @@ export const OpenPlanAnnotatorPlugin = async (ctx) => {
|
|
|
151
179
|
return;
|
|
152
180
|
}
|
|
153
181
|
|
|
154
|
-
if (!currentSystem.includes("
|
|
182
|
+
if (!currentSystem.includes("annotate_plan")) {
|
|
155
183
|
const shouldInject = await shouldInjectPlanReviewInstructions(input?.sessionID);
|
|
156
184
|
if (shouldInject) {
|
|
157
185
|
output.system.push(PLAN_REVIEW_INSTRUCTIONS);
|
|
@@ -160,7 +188,7 @@ export const OpenPlanAnnotatorPlugin = async (ctx) => {
|
|
|
160
188
|
},
|
|
161
189
|
|
|
162
190
|
tool: {
|
|
163
|
-
|
|
191
|
+
annotate_plan: tool({
|
|
164
192
|
description:
|
|
165
193
|
"Submit a markdown plan for interactive user review. Returns plain-text execution or revision instructions for the agent.",
|
|
166
194
|
|
|
@@ -196,7 +224,7 @@ export const OpenPlanAnnotatorPlugin = async (ctx) => {
|
|
|
196
224
|
|
|
197
225
|
lines.push("Replan intent: explicit_replan=false unless the user explicitly asks to revise the plan.");
|
|
198
226
|
lines.push("Execute the approved plan directly now — write code, create files, and make changes.");
|
|
199
|
-
lines.push("Do not call `
|
|
227
|
+
lines.push("Do not call `annotate_plan` again unless the user explicitly requests re-planning.");
|
|
200
228
|
|
|
201
229
|
return lines.join("\n\n");
|
|
202
230
|
}
|
|
@@ -209,7 +237,7 @@ export const OpenPlanAnnotatorPlugin = async (ctx) => {
|
|
|
209
237
|
"",
|
|
210
238
|
feedback,
|
|
211
239
|
"",
|
|
212
|
-
"Revise the plan using this feedback, then submit the revised draft once via `
|
|
240
|
+
"Revise the plan using this feedback, then submit the revised draft once via `annotate_plan`.",
|
|
213
241
|
].join("\n");
|
|
214
242
|
},
|
|
215
243
|
}),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "open-plan-annotator",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Fully local plugin for interactive plan annotation from your Agentic assistants",
|
|
6
6
|
"author": "ndom91",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"opencode/index.js",
|
|
43
43
|
"hooks/",
|
|
44
44
|
"commands/",
|
|
45
|
+
"skills/",
|
|
45
46
|
"CLAUDE.md",
|
|
46
47
|
"README.md"
|
|
47
48
|
],
|
|
@@ -82,10 +83,10 @@
|
|
|
82
83
|
}
|
|
83
84
|
},
|
|
84
85
|
"optionalDependencies": {
|
|
85
|
-
"@open-plan-annotator/runtime-darwin-arm64": "1.5.
|
|
86
|
-
"@open-plan-annotator/runtime-darwin-x64": "1.5.
|
|
87
|
-
"@open-plan-annotator/runtime-linux-arm64": "1.5.
|
|
88
|
-
"@open-plan-annotator/runtime-linux-x64": "1.5.
|
|
86
|
+
"@open-plan-annotator/runtime-darwin-arm64": "1.5.5",
|
|
87
|
+
"@open-plan-annotator/runtime-darwin-x64": "1.5.5",
|
|
88
|
+
"@open-plan-annotator/runtime-linux-arm64": "1.5.5",
|
|
89
|
+
"@open-plan-annotator/runtime-linux-x64": "1.5.5"
|
|
89
90
|
},
|
|
90
91
|
"overrides": {
|
|
91
92
|
"uuid": "^14.0.0"
|
package/shared/piExtension.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { detectPackageManager } from "./packageManager.mjs";
|
|
|
4
4
|
import { runPlanReviewBinary } from "./planReview.mjs";
|
|
5
5
|
import { resolveRuntimeBinary } from "./runtimeResolver.mjs";
|
|
6
6
|
|
|
7
|
-
const TOOL_NAME = "
|
|
7
|
+
const TOOL_NAME = "annotate_plan";
|
|
8
8
|
|
|
9
9
|
function getSessionId(ctx) {
|
|
10
10
|
try {
|
|
@@ -65,7 +65,7 @@ export function registerPiExtension(pi) {
|
|
|
65
65
|
description: "Open the browser-based plan annotation UI and return approval or revision feedback.",
|
|
66
66
|
promptSnippet: "Use this tool after drafting a plan that needs human review before implementation.",
|
|
67
67
|
promptGuidelines: [
|
|
68
|
-
"Call
|
|
68
|
+
"Call annotate_plan when you have a concrete plan in markdown form.",
|
|
69
69
|
"Include the full plan text, including numbered steps if available.",
|
|
70
70
|
"Wait for the review result before proceeding with implementation.",
|
|
71
71
|
],
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plan-review-triggers
|
|
3
|
+
description: Required reading whenever drafting any multi-step proposal, implementation plan, refactor approach, or response containing file paths and decision points. Use BEFORE writing any response that lists 3+ file paths, 2+ option-tradeoffs, a "Plan:"/"Steps:"/"Concrete changes:" section, or ends with "OK to proceed?" / "sound good?" / "shall I…?". Use whenever the user says "draft a plan", "let's plan X", "what's the approach", "give me options", "how should we tackle this", "what would it look like", or asks for a "recommended approach" / "implementation plan" / "proposed fix" / "rollout plan". Also use when modifying more than 2 files, doing architectural/structural changes, refactoring, migration, feature additions, or investigation-based bug fixes. Routes the response through the open-plan-annotator browser UI instead of pasting plans inline.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Plan Review Triggers
|
|
7
|
+
|
|
8
|
+
<!--
|
|
9
|
+
Maintainer note: trigger rules below are mirrored in `CLAUDE.plugin.md` at the
|
|
10
|
+
repo root. Skills are how the rules reach users who installed the Claude Code
|
|
11
|
+
plugin via the marketplace (repo-root markdown does not load through that
|
|
12
|
+
path). Keep both files in sync when editing trigger rules.
|
|
13
|
+
-->
|
|
14
|
+
|
|
15
|
+
This plugin (open-plan-annotator) installs a hook on `ExitPlanMode` that opens a browser UI where the user marks up plans directly — deletions, replacements, insertions, comments — and returns structured feedback. Inline markdown plans bypass that workflow.
|
|
16
|
+
|
|
17
|
+
## Hard Rule: Annotator Required When Triggers Match
|
|
18
|
+
|
|
19
|
+
Inline plans are a bug. When any trigger below fires, route through the annotator:
|
|
20
|
+
|
|
21
|
+
- Assistant-initiated (you decided a plan is needed): call `EnterPlanMode`, draft, then `ExitPlanMode` — fires the annotator hook.
|
|
22
|
+
- User-initiated ("draft a plan", "/plan", etc.): invoke `/annotate-plan <task>`.
|
|
23
|
+
|
|
24
|
+
## Mechanical Heuristic
|
|
25
|
+
|
|
26
|
+
Annotator REQUIRED when the response would contain ANY of:
|
|
27
|
+
|
|
28
|
+
- 3 or more file paths to create or modify
|
|
29
|
+
- 2 or more option/tradeoff comparisons for the user to choose between
|
|
30
|
+
- A `Plan:`, `Steps:`, `Concrete changes:`, `Implementation:`, `Approach:` section header
|
|
31
|
+
- A numbered/bulleted list of action items the user is expected to react to
|
|
32
|
+
- A multi-section proposal with decision points
|
|
33
|
+
|
|
34
|
+
Hard gate. Count file paths. Count options. If the count crosses the line, the inline response is not allowed.
|
|
35
|
+
|
|
36
|
+
## Task Shape Triggers
|
|
37
|
+
|
|
38
|
+
- Creating or modifying more than 2 files
|
|
39
|
+
- Architectural or structural changes
|
|
40
|
+
- Refactoring, migration, or feature additions
|
|
41
|
+
- Bug fixes that require investigation
|
|
42
|
+
- Anything the user has not explicitly described step-by-step
|
|
43
|
+
|
|
44
|
+
## Phrase Triggers
|
|
45
|
+
|
|
46
|
+
- User says "draft a plan", "let's plan X", "what's the approach", "give me options", "how should we tackle this", "what would it look like"
|
|
47
|
+
- Response would contain "recommended approach", "implementation plan", "proposed fix", "rollout plan", "here's what I'd do", "concrete file changes"
|
|
48
|
+
- Any moment you'd ask "want me to proceed?" / "shall I draft this?" / "OK to proceed?" / "sound good?"
|
|
49
|
+
|
|
50
|
+
## Mixed Signals Still Trigger
|
|
51
|
+
|
|
52
|
+
User messages combining directives ("let's add X", "can we Y") with an exploratory clause ("what do you think?") still trigger the annotator. Do NOT collapse into a short inline response because one clause was exploratory.
|
|
53
|
+
|
|
54
|
+
The annotator IS the discussion surface. Tradeoffs, options, and open questions belong inside the plan body where the user can comment on each one — not in flat chat. Treat exploratory clauses as "include alternatives in the plan", not "skip the plan".
|
|
55
|
+
|
|
56
|
+
## Self-Check Before Sending
|
|
57
|
+
|
|
58
|
+
Scan the drafted response for:
|
|
59
|
+
|
|
60
|
+
- "Concrete file changes", "Concrete changes", "Plan:", "Steps:", "Implementation:", "Approach:"
|
|
61
|
+
- "OK to proceed?", "Want me to proceed?", "Shall I…?", "Sound good?", "Confirm…?"
|
|
62
|
+
- 3+ lines that look like file paths (`foo/bar.tsx`, `path/to/file.ts`)
|
|
63
|
+
- Numbered list of more than 2 items each describing a code change
|
|
64
|
+
- "**N.**" / "**Fix N —**" headers introducing proposed changes
|
|
65
|
+
|
|
66
|
+
ANY match → discard inline response, route through annotator.
|
|
67
|
+
|
|
68
|
+
## Do NOT Trigger For
|
|
69
|
+
|
|
70
|
+
- Single-line fixes, typos, renames
|
|
71
|
+
- Direct factual answers
|
|
72
|
+
- Status updates or progress reports
|
|
73
|
+
- Already-approved plans (do not re-prompt)
|
|
74
|
+
- Pure research / exploration with no proposed actions
|
|
75
|
+
- Trivial questions where a plan is overhead
|
|
76
|
+
- Answering questions ABOUT an already-submitted plan (answer the question, do not re-submit)
|
|
77
|
+
|
|
78
|
+
## Plan Quality Standards
|
|
79
|
+
|
|
80
|
+
Include in every plan:
|
|
81
|
+
|
|
82
|
+
- Brief summary of the task as you understood it
|
|
83
|
+
- Specific files to create or modify and why
|
|
84
|
+
- Assumptions you are making
|
|
85
|
+
- Explicit questions if anything is ambiguous
|
|
86
|
+
- Tradeoffs / option comparisons inline (since mixed-signal user messages route here)
|
|
87
|
+
|
|
88
|
+
## Workflow
|
|
89
|
+
|
|
90
|
+
**Assistant-initiated:** `EnterPlanMode` → draft → `ExitPlanMode` → user annotates → revise on feedback → re-exit when aligned.
|
|
91
|
+
|
|
92
|
+
**User-initiated:** invoke `/annotate-plan <task>`. Same flow under the hood.
|
|
93
|
+
|
|
94
|
+
The slash command is for user invocation. When you decide a plan is needed without the user invoking it, prefer `EnterPlanMode` directly. Both paths fire the same annotator hook.
|