diff --git a/apps/hook/server/plannotator-skill-reference.test.ts b/apps/hook/server/plannotator-skill-reference.test.ts index ac63c61bc..c85823474 100644 --- a/apps/hook/server/plannotator-skill-reference.test.ts +++ b/apps/hook/server/plannotator-skill-reference.test.ts @@ -44,6 +44,16 @@ const SKILL_MD_PATH = join( "SKILL.md", ); +const ANNOTATE_SKILL_MD_PATH = join( + import.meta.dir, + "..", + "..", + "skills", + "core", + "plannotator-annotate", + "SKILL.md", +); + // CLI sources that parse flags. index.ts strips flags via // args.indexOf/includes; the shared parsers use case/=== comparisons. const PARSER_SOURCES = [ @@ -112,6 +122,7 @@ for (const m of indexSource.matchAll(/args\[0\] === "([a-z][a-z0-9-]*)"/g)) { // --- The skill's documented surface --- const skillDoc = readFileSync(SKILL_MD_PATH, "utf-8"); +const annotateSkillDoc = readFileSync(ANNOTATE_SKILL_MD_PATH, "utf-8"); const documentedSubcommands = new Set(); for (const fence of skillDoc.matchAll(/```[a-z]*\n([\s\S]*?)```/g)) { @@ -126,6 +137,16 @@ for (const m of skillDoc.matchAll(/(? { + test("file approval guidance enables the annotate gate", () => { + expect(skillDoc).toContain("plannotator annotate --gate --json"); + expect(annotateSkillDoc).toContain( + "plannotator annotate --gate --json", + ); + expect(annotateSkillDoc).toContain( + "`--json` only changes the output format and does not enable approval by itself", + ); + }); + test("extractors actually extracted (a parsing regression must not pass vacuously)", () => { // If the fence or flag regexes stop matching, the forward assertions // below would pass on empty sets. Pin known-present anchors instead of diff --git a/apps/skills/core/plannotator-annotate/SKILL.md b/apps/skills/core/plannotator-annotate/SKILL.md index 904f467e5..0a1a15a98 100644 --- a/apps/skills/core/plannotator-annotate/SKILL.md +++ b/apps/skills/core/plannotator-annotate/SKILL.md @@ -8,19 +8,27 @@ disable-model-invocation: true Use this skill when the user wants to annotate a document in Plannotator instead of reviewing it inline in chat. -Run: +Run for ordinary annotation/feedback: ```bash plannotator annotate ``` +Run when the user asks to review, approve, accept, or gate a generated plan/spec/document: + +```bash +plannotator annotate --gate --json +``` + +Plain `annotate` has no **Approve** button; it only supports feedback or closing the session. Never promise an approval action unless `--gate` is present. `--json` only changes the output format and does not enable approval by itself. + Behavior: 1. Launch the command with Bash. 2. Wait for the browser review to finish. 3. If annotations are returned, address them directly. 4. If the session closes without feedback, say so briefly and continue. -5. An approval may still carry notes — a `"decision": "approved"` result with a +5. In a `--gate --json` session, an approval may still carry notes — a `"decision": "approved"` result with a `"feedback"` field. Read those notes and carry them into subsequent work, but do not revise the document over them: they are guidance, not a change request. 6. If the command reports that the arguments could not be resolved to a file, diff --git a/apps/skills/core/plannotator/SKILL.md b/apps/skills/core/plannotator/SKILL.md index a505cf54c..e2f4e2fd9 100644 --- a/apps/skills/core/plannotator/SKILL.md +++ b/apps/skills/core/plannotator/SKILL.md @@ -14,6 +14,7 @@ This skill is the knowledge layer. The `plannotator-review`, `plannotator-annota | The user wants | Run | | --- | --- | | Review a plan you produced | Nothing. Plan review opens automatically on plan exit via hooks. Never run bare `plannotator` yourself. | +| Review and explicitly approve a plan/spec saved as a file | `plannotator annotate --gate --json` | | Review current code changes | `plannotator review` | | Review a GitHub PR or GitLab MR | `plannotator review ` | | Annotate a markdown, text, config, or HTML file | `plannotator annotate ` | @@ -58,6 +59,8 @@ plannotator annotate [--markdown] [--no-jina] [--app | --static] [--ren Opens one document, page, or app in the annotation UI and returns the human's annotations on stdout. +Plain `annotate` is feedback-only: it shows **Close** but no **Approve** button. When the user asks to review, approve, accept, or gate a generated plan/spec/document saved as a file, always add `--gate --json`. Do not tell the user they can approve a plain `annotate` session. If the plan is being handed off through the host agent's native plan flow, do not launch `annotate`; let the plan-exit hook open the approval UI automatically. + Targets: - Markdown and text files: `.md`, `.mdx`, `.txt`.