open-plan-annotator 1.0.15 → 1.0.17

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.
@@ -5,14 +5,14 @@
5
5
  },
6
6
  "metadata": {
7
7
  "description": "Interactive plan annotation plugin for Claude Code",
8
- "version": "1.0.15"
8
+ "version": "1.0.17"
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.0.15",
15
+ "version": "1.0.17",
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.0.15",
4
+ "version": "1.0.17",
5
5
  "author": {
6
6
  "name": "ndom91"
7
7
  },
package/README.md CHANGED
@@ -22,6 +22,13 @@ Everything runs locally. Nothing leaves your machine.
22
22
 
23
23
  ## Install
24
24
 
25
+ > [!NOTE]
26
+ > The first run might take up to 30s to pop open the UI. If your agentic coding
27
+ > tool installed it via pnpm, they block post-install scripts by default so
28
+ > Claude / OpenCode will trigger the download of the correct binary for your
29
+ > platform upon first use, i.e. when first transitioning out of plan mode.
30
+ > All subsequent runs will be instant.
31
+
25
32
  ### Claude Code
26
33
 
27
34
  From within Claude Code, add the marketplace and install the plugin:
@@ -73,10 +80,6 @@ If you want to run the binary standalone or build from source:
73
80
  npm install -g open-plan-annotator
74
81
  ```
75
82
 
76
- > [!NOTE]
77
- > The first run might take a few seconds if you use pnpm, as it blocks postinstall scripts.
78
- > Claude / OpenCode will trigger the download upon first use then.
79
-
80
83
  #### From Source
81
84
 
82
85
  ```sh
package/opencode/index.js CHANGED
@@ -162,7 +162,7 @@ export const OpenPlanAnnotatorPlugin = async (ctx) => {
162
162
  tool: {
163
163
  submit_plan: tool({
164
164
  description:
165
- "Submit a markdown plan for interactive user review. Returns a structured result with plan_status, next_state, approved, and feedback fields.",
165
+ "Submit a markdown plan for interactive user review. Returns a structured result with plan_status, next_state, feedback, and guidance fields.",
166
166
 
167
167
  args: {
168
168
  plan: tool.schema.string().describe("The complete implementation plan in markdown format"),
@@ -176,11 +176,12 @@ export const OpenPlanAnnotatorPlugin = async (ctx) => {
176
176
  cwd: ctx.directory,
177
177
  });
178
178
 
179
+ const feedback = result.approved ? "" : (result.feedback ?? "Plan changes requested.");
180
+
179
181
  const basePayload = {
180
182
  plan_status: result.approved ? "approved" : "rejected",
181
183
  next_state: result.approved ? "EXECUTION" : "PLAN_DRAFT",
182
- approved: result.approved,
183
- feedback: result.approved ? null : (result.feedback ?? "Plan changes requested."),
184
+ feedback,
184
185
  };
185
186
 
186
187
  if (result.approved) {
@@ -216,7 +217,7 @@ export const OpenPlanAnnotatorPlugin = async (ctx) => {
216
217
  "",
217
218
  "## User feedback",
218
219
  "",
219
- basePayload.feedback,
220
+ feedback,
220
221
  "",
221
222
  "Revise the plan using this feedback, then submit the revised draft once via `submit_plan`.",
222
223
  ].join("\n"),
@@ -32,8 +32,8 @@ describe("submit_plan return schema contract", () => {
32
32
 
33
33
  expect(result.plan_status).toBe("approved");
34
34
  expect(result.next_state).toBe("EXECUTION");
35
- expect(result.approved).toBe(true);
36
- expect(result.feedback).toBeNull();
35
+ expect(result.feedback).toBe("");
36
+ expect(result.guidance).toContain("Plan approved by the user.");
37
37
  });
38
38
 
39
39
  test("rejected decision maps to plan redraft payload with bridge feedback", async () => {
@@ -50,7 +50,27 @@ describe("submit_plan return schema contract", () => {
50
50
 
51
51
  expect(result.plan_status).toBe("rejected");
52
52
  expect(result.next_state).toBe("PLAN_DRAFT");
53
- expect(result.approved).toBe(false);
54
53
  expect(result.feedback).toBe(bridgeFeedback);
54
+ expect(result.guidance).toContain("## User feedback");
55
+ });
56
+
57
+ test("all top-level submit_plan fields are strings for display safety", async () => {
58
+ mock.module("./bridge.js", () => ({
59
+ runPlanReview: async () => ({ approved: true }),
60
+ }));
61
+
62
+ const { OpenPlanAnnotatorPlugin } = await import(`./index.js?display-safe-${Date.now()}`);
63
+ const plugin = await OpenPlanAnnotatorPlugin(createPluginContext());
64
+
65
+ const result = await plugin.tool.submit_plan.execute(
66
+ { plan: "# Plan", summary: "Short summary" },
67
+ { sessionID: "session-3" },
68
+ );
69
+
70
+ for (const value of Object.values(result)) {
71
+ expect(typeof value).toBe("string");
72
+ }
73
+
74
+ expect(result).not.toHaveProperty("approved");
55
75
  });
56
76
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-plan-annotator",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "type": "module",
5
5
  "description": "Fully local plugin for interactive plan annotation from your Agentic assistants",
6
6
  "author": "ndom91",