chore: remove the redundant /plannotator-status and /plannotator-archive commands (#873)

Two agent command-surface cleanups. Both remove only the command entry points; all underlying infrastructure stays.

1. /plannotator-status (Pi): removed — it echoed phase/plan-file/progress on
   demand, but that state is already shown ambiently (status bar + live
   checklist widget). The phase/checklist state machine is untouched.

2. /plannotator-archive (all agents): removed the command/skill entry points
   across every surface — Claude/Codex/Kiro skills, Pi, OpenCode (handler +
   dispatch + cli-bridge + embedded + stub), Droid, the Kiro agent prompt, all
   three installers, docs, marketing, and the CI deprecated-command guard. The
   installers also gained a stale-skill cleanup so upgraders drop a previously
   installed plannotator-archive skill.

Kept (infrastructure) — archive browsing stays available in-review via the
sidebar: the `plannotator archive` CLI subcommand (apps/hook/server), the
mode:"archive" server path + /api/archive endpoints, ArchiveBrowser/useArchive,
the sidebar Archive tab, sessions.ts "archive" mode, and ~/.plannotator/plans
storage.

Verified: bun test scripts/install.test.ts → 72 pass; pi-extension typecheck +
build:opencode pass; repo-wide residual scan clean; KEEP-set integrity
confirmed; one orphaned import (opencode commands.ts) caught in self-review and
removed.
This commit is contained in:
Michael Ramos
2026-06-08 11:08:11 -07:00
committed by GitHub
parent aac5aacbe8
commit b19505efd3
30 changed files with 93 additions and 236 deletions
+1 -1
View File
@@ -260,7 +260,7 @@ jobs:
# NEW contract: a fresh install must not create plannotator command
# files.
$cmdDir = "$env:USERPROFILE\.claude\commands"
foreach ($file in @("plannotator-review.md", "plannotator-annotate.md", "plannotator-last.md", "plannotator-archive.md")) {
foreach ($file in @("plannotator-review.md", "plannotator-annotate.md", "plannotator-last.md")) {
$path = Join-Path $cmdDir $file
if (Test-Path $path) {
throw "Installer wrote a deprecated Claude command file: $path. Commands were replaced by skills; the installer must not generate them."
+4 -5
View File
@@ -13,7 +13,7 @@ plannotator/
│ │ ├── server/index.ts # Entry point (plan + review + annotate + archive subcommands)
│ │ └── dist/ # Built single-file apps (index.html, review.html)
│ ├── opencode-plugin/ # OpenCode plugin
│ │ ├── commands/ # Slash command stubs (review, annotate, last, archive — plugin intercepts execution)
│ │ ├── commands/ # Slash command stubs (review, annotate, last — plugin intercepts execution)
│ │ ├── index.ts # Plugin entry with submit_plan tool + review/annotate event handlers
│ │ ├── plannotator.html # Built plan review app
│ │ └── review-editor.html # Built code review app
@@ -28,7 +28,7 @@ plannotator/
│ │ └── astro.config.mjs # Astro 5 static site with content collections
│ ├── kiro-cli/ # Kiro CLI integration source (consumed by scripts/install.sh; auto-detected via ~/.kiro)
│ │ ├── agents/plannotator.json # Example Kiro custom agent
│ │ └── skills/ # Kiro-specific skill packages (review, annotate, archive); setup-goal + visual-explainer install from apps/skills/extra
│ │ └── skills/ # Kiro-specific skill packages (review, annotate); setup-goal + visual-explainer install from apps/skills/extra
│ ├── paste-service/ # Paste service for short URL sharing
│ │ ├── core/ # Platform-agnostic logic (handler, storage interface, cors)
│ │ ├── stores/ # Storage backends (fs, kv, s3)
@@ -45,8 +45,7 @@ plannotator/
│ ├── core/ # CORE skills (single-sourced) — installed to ~/.claude/skills and ~/.agents/skills (Codex)
│ │ ├── plannotator-review/ # Lightweight: opens review UI
│ │ ├── plannotator-annotate/ # Lightweight: opens annotate UI
│ │ ├── plannotator-last/ # Lightweight: annotates last message
│ │ └── plannotator-archive/ # Lightweight: opens read-only archive UI
│ │ └── plannotator-last/ # Lightweight: annotates last message
│ └── extra/ # EXTRA skills — NOT default-installed (except Kiro); add via `npx skills add backnotprop/plannotator/apps/skills/extra`
│ ├── plannotator-compound/ # Research analysis agent (map-reduce over denied plans)
│ ├── plannotator-setup-goal/ # Goal package scaffolder for /goal workflows
@@ -232,7 +231,7 @@ Send Annotations → feedback sent to agent session
## Archive Flow
```
User runs plannotator archive (CLI) or /plannotator-archive (Pi)
User runs plannotator archive (CLI)
↓
Server starts in mode:"archive", reads ~/.plannotator/plans/
↓
-1
View File
@@ -279,7 +279,6 @@ This Droid plugin is commands-only. It adds:
/plannotator-review
/plannotator-annotate <file|folder|url>
/plannotator-last
/plannotator-archive
```
It does not currently intercept Droid's planning flow.
-1
View File
@@ -5,7 +5,6 @@ Plannotator's Droid plugin ships the manual slash-command workflow only:
- `/plannotator-review [PR_URL]` (no args reviews local changes)
- `/plannotator-annotate <file|folder|url>`
- `/plannotator-last`
- `/plannotator-archive`
It does not attempt plan-mode interception or host-level planning integration.
@@ -1,11 +0,0 @@
#!/usr/bin/env node
const { exitWithFailure, runPlannotator } = require("../lib/run-plannotator");
const result = runPlannotator(["archive", ...process.argv.slice(2)]);
if (result.error || result.status !== 0) {
exitWithFailure(result, "plannotator archive");
}
process.stdout.write("Archive browsing finished.\n");
-1
View File
@@ -113,7 +113,6 @@ Plannotator's slash commands are installed as Claude Code skills in `~/.claude/s
| `/plannotator-review [--git]` | Open code review UI for current changes or a GitHub PR; `--git` forces Git in JJ workspaces |
| `/plannotator-annotate <file.md>` | Annotate any markdown file |
| `/plannotator-last` | Annotate the agent's last message |
| `/plannotator-archive` | Browse saved plan decisions in the read-only archive UI |
## Obsidian Integration
+5 -5
View File
@@ -6,8 +6,8 @@ one-liner as everyone else.
## Contents
- `skills/` — Kiro-specific skill packages (`plannotator-review`, `plannotator-annotate`,
`plannotator-archive`), each baking `PLANNOTATOR_ORIGIN=kiro-cli` into its command.
- `skills/` — Kiro-specific skill packages (`plannotator-review`, `plannotator-annotate`),
each baking `PLANNOTATOR_ORIGIN=kiro-cli` into its command.
<!-- NOTE: The canonical, single-sourced core skills live in `apps/skills/core/`. These Kiro
copies are intentionally independent (they hardcode PLANNOTATOR_ORIGIN=kiro-cli) and are
exempt from single-sourcing — do not replace them with the core copies. -->
@@ -20,7 +20,7 @@ one-liner as everyone else.
`scripts/install.sh` auto-detects Kiro (if `~/.kiro` exists or `kiro-cli` is on PATH — the same
convention used for Codex and Gemini) and installs:
- the 3 Kiro-specific skills above → `~/.kiro/skills`
- the 2 Kiro-specific skills above → `~/.kiro/skills`
- the 2 shared skills `plannotator-setup-goal` and `plannotator-visual-explainer` (pulled from
`apps/skills/extra/`, not duplicated here) → `~/.kiro/skills`
- the example agent `agents/plannotator.json` → `~/.kiro/agents/plannotator.json` (an existing file
@@ -32,8 +32,8 @@ curl -fsSL https://plannotator.ai/install.sh | bash
## Use the Plannotator agent
The installed agent wires all five skills via `skill://` resources and, in its prompt, documents
which skill to use for which task (review, annotate, archive, setup-goal, visual-explainer). Launch
The installed agent wires all four skills via `skill://` resources and, in its prompt, documents
which skill to use for which task (review, annotate, setup-goal, visual-explainer). Launch
it:
```bash
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "plannotator",
"description": "Kiro custom agent wiring for Plannotator review and annotation workflows.",
"prompt": "You run Plannotator, which opens a browser UI for human review and annotation. Choose the skill that matches the task:\n- plannotator-review: review the current code changes (git/jj diff) or a pull request before continuing; optionally pass a PR URL.\n- plannotator-annotate: annotate a markdown or HTML file, a folder of docs, or a URL, then act on the returned annotations.\n- plannotator-archive: browse previously approved/denied plan decisions (read-only).\n- plannotator-setup-goal: turn an idea into a structured goal package by interviewing the user, building a fact sheet, then a plan.\n- plannotator-visual-explainer: generate a polished, self-contained HTML visual (implementation plan, PR walkthrough, or diagram) and open it for review.\nEach skill runs a `plannotator` shell command. plannotator-review, plannotator-annotate, and plannotator-archive set PLANNOTATOR_ORIGIN=kiro-cli.",
"prompt": "You run Plannotator, which opens a browser UI for human review and annotation. Choose the skill that matches the task:\n- plannotator-review: review the current code changes (git/jj diff) or a pull request before continuing; optionally pass a PR URL.\n- plannotator-annotate: annotate a markdown or HTML file, a folder of docs, or a URL, then act on the returned annotations.\n- plannotator-setup-goal: turn an idea into a structured goal package by interviewing the user, building a fact sheet, then a plan.\n- plannotator-visual-explainer: generate a polished, self-contained HTML visual (implementation plan, PR walkthrough, or diagram) and open it for review.\nEach skill runs a `plannotator` shell command. plannotator-review and plannotator-annotate set PLANNOTATOR_ORIGIN=kiro-cli.",
"tools": [
"shell"
],
@@ -1,13 +0,0 @@
---
name: plannotator-archive
disable-model-invocation: true
description: Open the read-only Plannotator archive browser for prior plan decisions.
---
# Plannotator Archive (Kiro)
Run:
```bash
PLANNOTATOR_ORIGIN=kiro-cli plannotator archive
```
@@ -270,10 +270,9 @@ import AnnoReplace from './AnnoReplace.astro';
steps: [
'kiro-cli chat --agent plannotator',
'plannotator-review',
'plannotator-annotate <file|folder|url>',
'plannotator-archive'
'plannotator-annotate <file|folder|url>'
],
detail: 'Skills-based integration. Installs review, annotation, and archive skills in Kiro:',
detail: 'Skills-based integration. Installs review and annotation skills in Kiro:',
link: {
text: 'Read the Kiro install docs',
url: '/docs/guides/kiro-cli/'
@@ -111,7 +111,7 @@ claude --plugin-dir ./apps/hook
### Slash commands
Plannotator's slash commands (`/plannotator-review`, `/plannotator-annotate`, `/plannotator-last`, `/plannotator-archive`) are installed as Claude Code skills in `~/.claude/skills` by the install script — Claude Code skills are user-invocable by directory name, so the command names are unchanged. There is no separate `~/.claude/commands` step.
Plannotator's slash commands (`/plannotator-review`, `/plannotator-annotate`, `/plannotator-last`) are installed as Claude Code skills in `~/.claude/skills` by the install script — Claude Code skills are user-invocable by directory name, so the command names are unchanged. There is no separate `~/.claude/commands` step.
Upgrading from an older version? The installer removes the legacy `~/.claude/commands/plannotator-*.md` files automatically, but the marketplace plugin's old namespaced `plannotator:*` command entries are managed by Claude Code — run `/plugin marketplace update` once so they disappear from the `/` menu.
@@ -220,7 +220,7 @@ Notes:
- Codex hooks are currently experimental.
- The current official Codex hooks docs say hooks are disabled on Windows, so this flow is currently macOS/Linux/WSL only.
The installer also copies Plannotator's core skills (`plannotator-review`, `plannotator-annotate`, `plannotator-last`, `plannotator-archive`) into `~/.agents/skills` — the official OpenAI agent skills path. Optional extra skills (compound planning, setup-goal, visual explainer) are not installed by default; add them with:
The installer also copies Plannotator's core skills (`plannotator-review`, `plannotator-annotate`, `plannotator-last`) into `~/.agents/skills` — the official OpenAI agent skills path. Optional extra skills (compound planning, setup-goal, visual explainer) are not installed by default; add them with:
```bash
npx skills add backnotprop/plannotator/apps/skills/extra
@@ -310,7 +310,6 @@ This adds the following slash commands:
/plannotator-review
/plannotator-annotate <file|folder|url>
/plannotator-last
/plannotator-archive
```
Those commands open the browser-based Plannotator review UI and send the result back into the Droid session.
@@ -89,10 +89,6 @@ Opens any markdown file in the annotation UI. See the [annotate docs](/docs/comm
Annotates the agent's most recent message. See the [annotate last docs](/docs/commands/annotate-last/) for details.
### `/plannotator-archive`
Opens the read-only archive UI to browse your saved approved/denied plan decisions.
Optional extra skills (compound planning, setup-goal, visual explainer) are not installed by default. Add them with:
```bash
@@ -44,7 +44,6 @@ Kiro-specific skills (run with `PLANNOTATOR_ORIGIN=kiro-cli`):
- `plannotator-review`
- `plannotator-annotate`
- `plannotator-archive`
Shared extra skills (installed from Plannotator's canonical `apps/skills/extra/` set, not duplicated):
@@ -64,7 +63,6 @@ commands, and its prompt spells out which skill to use for which task:
|-------|-----------|
| `plannotator-review` | Review the current code changes or a pull request |
| `plannotator-annotate` | Annotate a markdown/HTML file, folder, or URL |
| `plannotator-archive` | Browse prior approved/denied plan decisions |
| `plannotator-setup-goal` | Turn an idea into a structured goal package |
| `plannotator-visual-explainer` | Generate a polished visual HTML explainer |
@@ -20,7 +20,7 @@ If you already use `@plannotator/opencode` and upgrade to `0.19.1` without addin
- any agents you list in `planningAgents` are added alongside `plan`
- `build` and other non-planning primary agents stop seeing or calling `submit_plan` by default
- the broad reminder that nudged non-plan primary agents toward `submit_plan` goes away
- `/plannotator-last`, `/plannotator-annotate`, `/plannotator-review`, and `/plannotator-archive` still work
- `/plannotator-last`, `/plannotator-annotate`, and `/plannotator-review` still work
This is the new omitted-config default:
@@ -89,7 +89,6 @@ In `manual` mode:
- `/plannotator-last`
- `/plannotator-annotate`
- `/plannotator-review`
- `/plannotator-archive`
## Recommended upgrade path
@@ -25,7 +25,7 @@ The OpenCode plugin (`@plannotator/opencode`) hooks into OpenCode's plugin syste
OpenCode support has four explicit modes:
- **`plan-agent`** (default): `submit_plan` is available to OpenCode's built-in `plan` agent plus any extra agents listed in `planningAgents`.
- **`manual`**: `submit_plan` is not registered. Use `/plannotator-last`, `/plannotator-annotate`, `/plannotator-review`, and `/plannotator-archive` when you want Plannotator.
- **`manual`**: `submit_plan` is not registered. Use `/plannotator-last`, `/plannotator-annotate`, and `/plannotator-review` when you want Plannotator.
- **`user-managed`**: `submit_plan` is registered but no prompts or agent permissions are modified. You configure which agents can call `submit_plan` via OpenCode's agent configuration.
- **`all-agents`**: legacy broad behavior. Primary agents can see and call `submit_plan`.
+1 -1
View File
@@ -41,7 +41,7 @@ Restart OpenCode. By default, the `submit_plan` tool is available to OpenCode's
Plannotator supports four OpenCode workflows:
- **`plan-agent`** (default): `submit_plan` is available to OpenCode's built-in `plan` agent plus any extra agents listed in `planningAgents`. This keeps Plannotator integrated with OpenCode plan mode without nudging `build` to call it.
- **`manual`**: `submit_plan` is not registered. Use `/plannotator-last`, `/plannotator-annotate`, `/plannotator-review`, and `/plannotator-archive` when you want Plannotator.
- **`manual`**: `submit_plan` is not registered. Use `/plannotator-last`, `/plannotator-annotate`, and `/plannotator-review` when you want Plannotator.
- **`user-managed`**: `submit_plan` is registered but no prompts or agent permissions are modified. You manage which agents can call `submit_plan` via OpenCode's native agent configuration.
- **`all-agents`**: legacy broad behavior. Primary agents can see and call `submit_plan`.
-14
View File
@@ -566,20 +566,6 @@ export async function handleCliCommand(input: {
return;
}
if (input.command === "plannotator-archive") {
const result = await runPlannotatorCli({
client: input.client,
args: ["archive"],
cwd: input.cwd,
readyLabel: "archive",
bridge: input.bridge,
});
if (result.exitCode !== 0) {
log(input.client, "error", result.stderr.trim() || `Plannotator CLI exited with code ${result.exitCode}`);
} else {
logCliWarnings(input.client, result.stderr);
}
}
} catch (error) {
log(input.client, "error", `[Plannotator] ${error instanceof Error ? error.message : String(error)}`);
}
+2 -36
View File
@@ -1,15 +1,10 @@
/**
* Command Handlers for OpenCode Plugin
*
* Handles /plannotator-review, /plannotator-annotate, /plannotator-last,
* and /plannotator-archive slash commands. Extracted from the event hook
* for modularity.
* Handles /plannotator-review, /plannotator-annotate, and /plannotator-last
* slash commands. Extracted from the event hook for modularity.
*/
import {
startPlannotatorServer,
handleServerReady,
} from "@plannotator/server";
import {
startReviewServer,
handleReviewServerReady,
@@ -446,32 +441,3 @@ export async function handleAnnotateLastCommand(
return result.feedback || null;
}
export async function handleArchiveCommand(
event: any,
deps: CommandDeps
) {
const { client, htmlContent, getSharingEnabled, getShareBaseUrl, getPasteApiUrl } = deps;
client.app.log({ level: "info", message: "Opening plan archive..." });
const server = await startPlannotatorServer({
plan: "",
origin: "opencode",
mode: "archive",
sharingEnabled: await getSharingEnabled(),
shareBaseUrl: getShareBaseUrl(),
pasteApiUrl: getPasteApiUrl(),
htmlContent,
onReady: (url, isRemote, port) => {
handleServerReady(url, isRemote, port);
client.app.log({ level: "info", message: `[Plannotator] Open archive: ${url}` });
},
});
if (server.waitForDone) {
await server.waitForDone();
}
await Bun.sleep(1500);
server.stop();
}
@@ -1,3 +0,0 @@
---
description: Browse saved plan decisions in the archive
---
-6
View File
@@ -87,7 +87,6 @@ export async function handleEmbeddedCommand(
handleReviewCommand,
handleAnnotateCommand,
handleAnnotateLastCommand,
handleArchiveCommand,
} = await loadCommandHandlers();
if (command === "plannotator-last") {
@@ -104,10 +103,5 @@ export async function handleEmbeddedCommand(
return {};
}
if (command === "plannotator-archive") {
await handleArchiveCommand(event, deps);
return {};
}
return {};
}
+1 -2
View File
@@ -496,8 +496,7 @@ Do NOT proceed with implementation until your plan is approved.`);
if (
cmd !== "plannotator-last" &&
cmd !== "plannotator-annotate" &&
cmd !== "plannotator-review" &&
cmd !== "plannotator-archive"
cmd !== "plannotator-review"
) return;
output.parts.length = 0;
-1
View File
@@ -191,7 +191,6 @@ During execution, the agent marks completed steps with `[DONE:n]` markers. Progr
| Command | Description |
|---------|-------------|
| `/plannotator` | Toggle plan mode. The agent writes a markdown plan file anywhere in the working directory and submits its path |
| `/plannotator-status` | Show current phase, plan file, and progress |
| `/plannotator-review` | Open code review UI for current changes |
| `/plannotator-annotate <file>` | Open markdown file in annotation UI |
| `/plannotator-last` | Annotate the last assistant message |
-41
View File
@@ -57,7 +57,6 @@ import {
hasPlanBrowserHtml,
hasReviewBrowserHtml,
getStartupErrorMessage,
openArchiveBrowserAction,
startCodeReviewBrowserSession,
startLastMessageAnnotationSession,
startMarkdownAnnotationSession,
@@ -393,21 +392,6 @@ export default function plannotator(pi: ExtensionAPI): void {
},
});
pi.registerCommand("plannotator-status", {
description: "Show plannotator status",
handler: async (_args, ctx) => {
const parts = [`Phase: ${phase}`];
if (lastSubmittedPath) {
parts.push(`Plan file: ${lastSubmittedPath}`);
}
if (checklistItems.length > 0) {
const done = checklistItems.filter((t) => t.completed).length;
parts.push(`Progress: ${done}/${checklistItems.length}`);
}
ctx.ui.notify(parts.join("\n"), "info");
},
});
pi.registerCommand("plannotator-review", {
description: "Open interactive code review for current changes or a PR URL; pass --git to force Git in JJ workspaces",
handler: async (args, ctx) => {
@@ -728,31 +712,6 @@ export default function plannotator(pi: ExtensionAPI): void {
},
});
pi.registerCommand("plannotator-archive", {
description: "Browse saved plan decisions",
handler: async (_args, ctx) => {
if (!hasPlanBrowserHtml()) {
ctx.ui.notify(
"Archive UI not available. Run 'bun run build' in the pi-extension directory.",
"error",
);
return;
}
ctx.ui.notify("Opening plan archive...", "info");
try {
await openArchiveBrowserAction(ctx);
ctx.ui.notify("Archive browser closed.", "info");
} catch (err) {
ctx.ui.notify(
`Failed to start archive: ${getStartupErrorMessage(err)}`,
"error",
);
}
},
});
pi.registerShortcut(Key.ctrlAlt("p"), {
description: "Toggle plannotator",
handler: async (ctx) => {
@@ -1,16 +0,0 @@
---
name: plannotator-archive
description: Browse saved plan decisions in Plannotator's read-only archive UI in the browser.
allowed-tools: Bash(plannotator:*)
disable-model-invocation: true
---
# Plannotator Archive
## Plan archive
!`plannotator archive`
## Your task
The user has finished browsing the plan archive. Acknowledge and continue.
@@ -1,23 +0,0 @@
---
name: plannotator-archive
description: Browse saved plan decisions in Plannotator's read-only archive UI in the browser.
disable-model-invocation: true
---
# Plannotator Archive
Use this skill when the user wants to browse their saved plan decisions in Plannotator's read-only archive UI.
Run:
```bash
plannotator archive
```
Behavior:
1. Launch the command with Bash.
2. Wait for the browser archive session to finish (the archive is read-only, so no feedback is returned).
3. When the session closes, acknowledge that the user finished browsing the archive and continue.
Run the command yourself rather than telling the user to invoke shell syntax manually.
@@ -1,5 +0,0 @@
interface:
display_name: "Plannotator Archive"
short_description: "Browse saved plan decisions in Plannotator's read-only archive."
policy:
allow_implicit_invocation: false
+19 -11
View File
@@ -722,7 +722,7 @@ if !ERRORLEVEL! equ 0 (
REM so the two are sourced separately. Replace rather than merge on each run.
if exist "apps\skills\claude" (
if not exist "!CLAUDE_SKILLS_DIR!" mkdir "!CLAUDE_SKILLS_DIR!"
for %%S in (plannotator-review plannotator-annotate plannotator-last plannotator-archive) do (
for %%S in (plannotator-review plannotator-annotate plannotator-last) do (
if exist "apps\skills\claude\%%S" (
if exist "!CLAUDE_SKILLS_DIR!\%%S" rmdir /s /q "!CLAUDE_SKILLS_DIR!\%%S" >nul 2>&1
xcopy /s /i /y /q "apps\skills\claude\%%S" "!CLAUDE_SKILLS_DIR!\%%S\" >nul 2>&1
@@ -732,7 +732,7 @@ if !ERRORLEVEL! equ 0 (
)
if exist "apps\skills\core" (
if not exist "!AGENTS_SKILLS_DIR!" mkdir "!AGENTS_SKILLS_DIR!"
for %%S in (plannotator-review plannotator-annotate plannotator-last plannotator-archive) do (
for %%S in (plannotator-review plannotator-annotate plannotator-last) do (
if exist "apps\skills\core\%%S" (
REM Replace rather than merge so files removed upstream don't linger.
if exist "!AGENTS_SKILLS_DIR!\%%S" rmdir /s /q "!AGENTS_SKILLS_DIR!\%%S" >nul 2>&1
@@ -762,7 +762,7 @@ if !ERRORLEVEL! equ 0 (
if "!KIRO_AVAILABLE!"=="1" if exist "apps\kiro-cli\skills" (
if not exist "!KIRO_SKILLS_DIR!" mkdir "!KIRO_SKILLS_DIR!"
REM Kiro-specific skills with origin baked in come from apps\kiro-cli\skills.
for %%S in (plannotator-review plannotator-annotate plannotator-archive) do (
for %%S in (plannotator-review plannotator-annotate) do (
if exist "apps\kiro-cli\skills\%%S" (
if exist "!KIRO_SKILLS_DIR!\%%S" rmdir /s /q "!KIRO_SKILLS_DIR!\%%S" >nul 2>&1
xcopy /s /i /y /q "apps\kiro-cli\skills\%%S" "!KIRO_SKILLS_DIR!\%%S\" >nul 2>&1
@@ -802,13 +802,22 @@ REM Claude Code commands are deprecated in favor of skills. Remove a legacy
REM command file only once its replacement skill is actually on disk — running
REM AFTER the install above guarantees a failed or skipped skill install never
REM leaves users with neither the command nor the skill.
for %%C in (plannotator-review plannotator-annotate plannotator-last plannotator-archive) do (
for %%C in (plannotator-review plannotator-annotate plannotator-last) do (
if exist "!CLAUDE_SKILLS_DIR!\%%C" if exist "!CLAUDE_COMMANDS_DIR!\%%C.md" (
del /q "!CLAUDE_COMMANDS_DIR!\%%C.md" >nul 2>&1
echo Removed deprecated Claude command !CLAUDE_COMMANDS_DIR!\%%C.md ^(replaced by the %%C skill^)
)
)
REM plannotator-archive no longer ships as a skill. Remove any stale installed
REM copy from every skill scope so upgraders don't keep a dead skill around.
for %%D in ("!CLAUDE_SKILLS_DIR!" "!AGENTS_SKILLS_DIR!" "!KIRO_SKILLS_DIR!") do (
if exist "%%~D\plannotator-archive" (
rmdir /s /q "%%~D\plannotator-archive" >nul 2>&1
echo Removed stale plannotator-archive skill from %%~D\plannotator-archive
)
)
REM Codex no longer hosts core skills (they live in %%USERPROFILE%%\.agents\skills).
REM Core skills are removed only once their replacement exists; the stale
REM shared-agent extras were never Codex's and are removed unconditionally.
@@ -955,7 +964,7 @@ echo.
echo Upgrading from an older version? Also run /plugin marketplace update
echo so the plugin drops its old plannotator:* command entries.
echo.
echo The /plannotator-review, /plannotator-annotate, /plannotator-last, and /plannotator-archive skills are ready to use!
echo The /plannotator-review, /plannotator-annotate, and /plannotator-last skills are ready to use!
if not "!EXTRAS_CHOICE!"=="yes" (
echo.
echo Optional skills ^(compound planning, setup-goal, visual explainer^):
@@ -1028,16 +1037,15 @@ if "!WANT_INVOCABLE!"=="no" (
set "INVOCABLE_CHOICE=none"
goto :glimpse_question
)
set "SKILL_COUNT=4"
set "SKILL_COUNT=3"
set "SKILL_1=plannotator-review"
set "SKILL_2=plannotator-annotate"
set "SKILL_3=plannotator-last"
set "SKILL_4=plannotator-archive"
if "!EXTRAS_CHOICE!"=="yes" (
set "SKILL_COUNT=7"
set "SKILL_5=plannotator-compound"
set "SKILL_6=plannotator-setup-goal"
set "SKILL_7=plannotator-visual-explainer"
set "SKILL_COUNT=6"
set "SKILL_4=plannotator-compound"
set "SKILL_5=plannotator-setup-goal"
set "SKILL_6=plannotator-visual-explainer"
)
REM Preselect previously chosen skills. NOTE: no pipes here — each side of a
REM cmd pipe runs in a child without delayed expansion, so !vars! would pass
+16 -7
View File
@@ -409,7 +409,7 @@ if (-not (Test-Path $extrasMigration)) {
# re-runs. -Reconfigure re-opens the wizard; -NonInteractive forces silence;
# redirected/CI runs never prompt. Flags win over everything.
$prefsFile = Join-Path $configDir "install-prefs"
$coreSkillNames = @("plannotator-review", "plannotator-annotate", "plannotator-last", "plannotator-archive")
$coreSkillNames = @("plannotator-review", "plannotator-annotate", "plannotator-last")
$extraSkillNames = @("plannotator-compound", "plannotator-setup-goal", "plannotator-visual-explainer")
$savedExtras = ""
@@ -655,7 +655,7 @@ try {
# existing target dir) so re-runs replace rather than nest.
if ((Test-Path "apps\skills\claude") -and (Get-ChildItem "apps\skills\claude" -ErrorAction SilentlyContinue)) {
New-Item -ItemType Directory -Force -Path $claudeSkillsDir | Out-Null
foreach ($skill in @("plannotator-review", "plannotator-annotate", "plannotator-last", "plannotator-archive")) {
foreach ($skill in @("plannotator-review", "plannotator-annotate", "plannotator-last")) {
Copy-SkillIfPresent "apps\skills\claude\$skill" $claudeSkillsDir
}
Write-Host "Installed Claude Code skills to $claudeSkillsDir\"
@@ -664,7 +664,7 @@ try {
}
if ((Test-Path "apps\skills\core") -and (Get-ChildItem "apps\skills\core" -ErrorAction SilentlyContinue)) {
New-Item -ItemType Directory -Force -Path $agentsSkillsDir | Out-Null
foreach ($skill in @("plannotator-review", "plannotator-annotate", "plannotator-last", "plannotator-archive")) {
foreach ($skill in @("plannotator-review", "plannotator-annotate", "plannotator-last")) {
Copy-SkillIfPresent "apps\skills\core\$skill" $agentsSkillsDir
}
Write-Host "Installed shared agent skills to $agentsSkillsDir\"
@@ -679,7 +679,6 @@ try {
# Kiro-specific skills (origin baked in) come from apps/kiro-cli/skills.
Copy-SkillIfPresent "apps\kiro-cli\skills\plannotator-review" $kiroSkillsDir
Copy-SkillIfPresent "apps\kiro-cli\skills\plannotator-annotate" $kiroSkillsDir
Copy-SkillIfPresent "apps\kiro-cli\skills\plannotator-archive" $kiroSkillsDir
# Two extras come from apps/skills/extra (not duplicated into apps/kiro-cli/skills).
Copy-SkillIfPresent "apps\skills\extra\plannotator-setup-goal" $kiroSkillsDir
Copy-SkillIfPresent "apps\skills\extra\plannotator-visual-explainer" $kiroSkillsDir
@@ -739,7 +738,7 @@ if ($checkoutFailed) {
# command file only once its replacement skill is actually on disk — running
# AFTER the install above guarantees a failed or skipped skill install never
# leaves users with neither the command nor the skill.
foreach ($cmd in @("plannotator-review", "plannotator-annotate", "plannotator-last", "plannotator-archive")) {
foreach ($cmd in @("plannotator-review", "plannotator-annotate", "plannotator-last")) {
$cmdPath = Join-Path $claudeCommandsDir "$cmd.md"
$skillPath = Join-Path $claudeSkillsDir $cmd
if ((Test-Path $skillPath) -and (Test-Path $cmdPath)) {
@@ -748,6 +747,16 @@ foreach ($cmd in @("plannotator-review", "plannotator-annotate", "plannotator-la
}
}
# plannotator-archive no longer ships as a skill. Remove any stale installed
# copy from every skill scope so upgraders don't keep a dead skill around.
foreach ($scope in @($claudeSkillsDir, $agentsSkillsDir, "$env:USERPROFILE\.kiro\skills")) {
$staleArchivePath = Join-Path $scope "plannotator-archive"
if (Test-Path $staleArchivePath) {
Write-Host "Removing stale plannotator-archive skill $staleArchivePath"
Remove-Item -Recurse -Force $staleArchivePath -ErrorAction SilentlyContinue
}
}
# Codex no longer hosts core skills (they now live in ~/.agents/skills).
# Core skills are removed only once their replacement exists; the stale
# shared-agent extras were never Codex's and are removed unconditionally.
@@ -876,7 +885,7 @@ Write-Host "Add the plugin to your opencode.json:"
Write-Host ""
Write-Host ' "plugin": ["@plannotator/opencode@latest"]'
Write-Host ""
Write-Host "Then restart OpenCode. The /plannotator-review, /plannotator-annotate, /plannotator-last, and /plannotator-archive commands are ready!"
Write-Host "Then restart OpenCode. The /plannotator-review, /plannotator-annotate, and /plannotator-last commands are ready!"
Write-Host ""
Write-Host "=========================================="
Write-Host " PI USERS"
@@ -909,7 +918,7 @@ Write-Host ""
Write-Host "Upgrading from an older version? Also run /plugin marketplace update"
Write-Host "so the plugin drops its old plannotator:* command entries."
Write-Host ""
Write-Host "The /plannotator-review, /plannotator-annotate, /plannotator-last, and /plannotator-archive commands are ready to use after you restart Claude Code!"
Write-Host "The /plannotator-review, /plannotator-annotate, and /plannotator-last commands are ready to use after you restart Claude Code!"
if ($extrasChoice -ne "yes") {
Write-Host ""
+13 -8
View File
@@ -699,7 +699,7 @@ fi
# --reconfigure re-opens the wizard; --non-interactive forces silence; piped
# CI runs without a terminal never prompt. CLI flags win over everything.
PREFS_FILE="$_config_dir/install-prefs"
CORE_SKILL_NAMES="plannotator-review plannotator-annotate plannotator-last plannotator-archive"
CORE_SKILL_NAMES="plannotator-review plannotator-annotate plannotator-last"
EXTRA_SKILL_NAMES="plannotator-compound plannotator-setup-goal plannotator-visual-explainer"
saved_extras=""
@@ -1024,7 +1024,6 @@ checkout_failed=0
copy_skill_if_present apps/skills/claude/plannotator-review "$CLAUDE_SKILLS_DIR"
copy_skill_if_present apps/skills/claude/plannotator-annotate "$CLAUDE_SKILLS_DIR"
copy_skill_if_present apps/skills/claude/plannotator-last "$CLAUDE_SKILLS_DIR"
copy_skill_if_present apps/skills/claude/plannotator-archive "$CLAUDE_SKILLS_DIR"
echo "Installed Claude Code skills to ${CLAUDE_SKILLS_DIR}/"
else
echo "Tag ${latest_tag} predates the per-agent skill layout — skipping Claude Code skill install"
@@ -1034,7 +1033,6 @@ checkout_failed=0
copy_skill_if_present apps/skills/core/plannotator-review "$AGENTS_SKILLS_DIR"
copy_skill_if_present apps/skills/core/plannotator-annotate "$AGENTS_SKILLS_DIR"
copy_skill_if_present apps/skills/core/plannotator-last "$AGENTS_SKILLS_DIR"
copy_skill_if_present apps/skills/core/plannotator-archive "$AGENTS_SKILLS_DIR"
echo "Installed shared agent skills to ${AGENTS_SKILLS_DIR}/"
else
echo "Tag ${latest_tag} predates the core/extra skill layout — skipping shared agent skill install"
@@ -1060,7 +1058,6 @@ checkout_failed=0
# Kiro-specific skills (origin baked in) come from apps/kiro-cli/skills.
copy_skill_if_present apps/kiro-cli/skills/plannotator-review "$KIRO_SKILLS_DIR"
copy_skill_if_present apps/kiro-cli/skills/plannotator-annotate "$KIRO_SKILLS_DIR"
copy_skill_if_present apps/kiro-cli/skills/plannotator-archive "$KIRO_SKILLS_DIR"
# Extras come from apps/skills/extra (not duplicated into apps/kiro-cli/skills).
copy_skill_if_present apps/skills/extra/plannotator-setup-goal "$KIRO_SKILLS_DIR"
copy_skill_if_present apps/skills/extra/plannotator-visual-explainer "$KIRO_SKILLS_DIR"
@@ -1086,13 +1083,22 @@ fi
# AFTER the install above guarantees a failed or skipped skill install never
# leaves users with neither the command nor the skill.
CLAUDE_COMMANDS_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/commands"
for cmd in plannotator-review plannotator-annotate plannotator-last plannotator-archive; do
for cmd in plannotator-review plannotator-annotate plannotator-last; do
if [ -d "$CLAUDE_SKILLS_DIR/$cmd" ] && [ -f "$CLAUDE_COMMANDS_DIR/$cmd.md" ]; then
rm -f "$CLAUDE_COMMANDS_DIR/$cmd.md"
echo "Removed legacy Claude command ${CLAUDE_COMMANDS_DIR}/$cmd.md (replaced by the $cmd skill)"
fi
done
# plannotator-archive no longer ships as a skill. Remove any stale installed
# copy from every skill scope so upgraders don't keep a dead skill around.
for scope in "$CLAUDE_SKILLS_DIR" "$AGENTS_SKILLS_DIR" "$KIRO_SKILLS_DIR"; do
if [ -d "$scope/plannotator-archive" ]; then
rm -rf "$scope/plannotator-archive"
echo "Removed stale plannotator-archive skill from ${scope}/plannotator-archive"
fi
done
# Codex no longer hosts core skills (they now live in ~/.agents/skills).
# Core skills are removed only once their replacement exists; the stale
# shared-agent extras were never Codex's and are removed unconditionally.
@@ -1216,7 +1222,7 @@ echo "Add the plugin to your opencode.json:"
echo ""
echo ' "plugin": ["@plannotator/opencode@latest"]'
echo ""
echo "Then restart OpenCode. The /plannotator-review, /plannotator-annotate, /plannotator-last, and /plannotator-archive commands are ready!"
echo "Then restart OpenCode. The /plannotator-review, /plannotator-annotate, and /plannotator-last commands are ready!"
echo ""
echo "=========================================="
echo " PI USERS"
@@ -1251,7 +1257,6 @@ if [ "$codex_available" -eq 1 ]; then
echo " \$plannotator-review"
echo " \$plannotator-annotate <file|url|folder>"
echo " \$plannotator-last"
echo " \$plannotator-archive"
else
echo "Codex was not detected. After installing Codex, rerun this installer to add"
echo "the Stop hook."
@@ -1280,7 +1285,7 @@ echo ""
echo "Upgrading from an older version? Also run /plugin marketplace update"
echo "so the plugin drops its old plannotator:* command entries."
echo ""
echo "The /plannotator-review, /plannotator-annotate, /plannotator-last, and /plannotator-archive commands are ready to use after you restart Claude Code!"
echo "The /plannotator-review, /plannotator-annotate, and /plannotator-last commands are ready to use after you restart Claude Code!"
if [ "$extras_choice" != "yes" ]; then
echo ""
+24 -8
View File
@@ -13,13 +13,12 @@ import { join } from "node:path";
const scriptsDir = import.meta.dir;
// The four always-installed core skills (apps/skills/core/*). Single list so
// The three always-installed core skills (apps/skills/core/*). Single list so
// the copy assertions, sidecar checks, and frontmatter checks can't drift.
const CORE_SKILLS = [
"plannotator-review",
"plannotator-annotate",
"plannotator-last",
"plannotator-archive",
];
describe("install.sh", () => {
@@ -171,7 +170,6 @@ describe("install.sh", () => {
// Kiro-specific skills (origin baked in) come from apps/kiro-cli/skills.
expect(script).toContain('copy_skill_if_present apps/kiro-cli/skills/plannotator-review "$KIRO_SKILLS_DIR"');
expect(script).toContain('copy_skill_if_present apps/kiro-cli/skills/plannotator-annotate "$KIRO_SKILLS_DIR"');
expect(script).toContain('copy_skill_if_present apps/kiro-cli/skills/plannotator-archive "$KIRO_SKILLS_DIR"');
// The two extras Kiro keeps receiving come from apps/skills/extra.
expect(script).toContain('copy_skill_if_present apps/skills/extra/plannotator-setup-goal "$KIRO_SKILLS_DIR"');
expect(script).toContain('copy_skill_if_present apps/skills/extra/plannotator-visual-explainer "$KIRO_SKILLS_DIR"');
@@ -188,7 +186,7 @@ describe("install.sh", () => {
// Claude Code commands are deprecated in favor of skills — remove the files.
expect(script).toContain("CLAUDE_COMMANDS_DIR");
expect(script).toContain(
"for cmd in plannotator-review plannotator-annotate plannotator-last plannotator-archive; do",
"for cmd in plannotator-review plannotator-annotate plannotator-last; do",
);
// The legacy ~/.agents cleanup block (review/annotate/last) is GONE —
// core skills now intentionally live in ~/.agents/skills.
@@ -201,6 +199,12 @@ describe("install.sh", () => {
);
// Extras stop being managed in the Claude and shared-agent scopes.
expect(script).toContain("plannotator-compound plannotator-setup-goal plannotator-visual-explainer");
// plannotator-archive no longer ships as a skill — a stale installed copy
// is removed unconditionally from every skill scope.
expect(script).toContain(
'for scope in "$CLAUDE_SKILLS_DIR" "$AGENTS_SKILLS_DIR" "$KIRO_SKILLS_DIR"; do',
);
expect(script).toContain('rm -rf "$scope/plannotator-archive"');
});
test("suggests installing extras via npx skills add", () => {
@@ -352,7 +356,7 @@ describe("install.ps1", () => {
// (PowerShell's Copy-Item -Recurse into an existing dir nests).
expect(script).toContain('Copy-SkillIfPresent "apps\\skills\\claude\\$skill" $claudeSkillsDir');
expect(script).toContain('Copy-SkillIfPresent "apps\\skills\\core\\$skill" $agentsSkillsDir');
expect(script).toContain('"plannotator-review", "plannotator-annotate", "plannotator-last", "plannotator-archive"');
expect(script).toContain('"plannotator-review", "plannotator-annotate", "plannotator-last"');
// Copy-SkillIfPresent pre-removes the destination to avoid nesting on upgrade.
expect(script).toContain("if (Test-Path $dest) { Remove-Item -Recurse -Force $dest }");
// No Codex skills install.
@@ -384,6 +388,12 @@ describe("install.ps1", () => {
expect(script).toContain('"plannotator-compound", "plannotator-setup-goal", "plannotator-visual-explainer"');
expect(script).toContain("2026-06-extras-default-install-removed");
expect(script).toContain("if (-not (Test-Path $extrasMigration))");
// plannotator-archive no longer ships as a skill — a stale installed copy
// is removed unconditionally from every skill scope.
expect(script).toContain(
'foreach ($scope in @($claudeSkillsDir, $agentsSkillsDir, "$env:USERPROFILE\\.kiro\\skills"))',
);
expect(script).toContain('Join-Path $scope "plannotator-archive"');
});
test("does not treat a skills-only Codex home as configured", () => {
@@ -475,7 +485,7 @@ describe("install.cmd", () => {
// agent (Codex) scope reads the prose skills (apps\skills\core).
expect(script).toContain('xcopy /s /i /y /q "apps\\skills\\claude\\%%S" "!CLAUDE_SKILLS_DIR!\\%%S\\"');
expect(script).toContain('xcopy /s /i /y /q "apps\\skills\\core\\%%S" "!AGENTS_SKILLS_DIR!\\%%S\\"');
expect(script).toContain("for %%S in (plannotator-review plannotator-annotate plannotator-last plannotator-archive) do");
expect(script).toContain("for %%S in (plannotator-review plannotator-annotate plannotator-last) do");
// No Codex skills install — only the cleanup loop references CODEX skills.
expect(script).not.toContain('xcopy /s /i /y /q "apps\\skills\\core\\%%S" "!CODEX_SKILLS_DIR!\\%%S\\"');
// Missing git is a hard failure with an actionable message (parity with sh/ps1).
@@ -503,6 +513,12 @@ describe("install.cmd", () => {
expect(script).toContain("for %%S in (plannotator-compound plannotator-setup-goal plannotator-visual-explainer) do");
expect(script).toContain("2026-06-extras-default-install-removed");
expect(script).toContain('if not exist "!EXTRAS_MIGRATION!"');
// plannotator-archive no longer ships as a skill — a stale installed copy
// is removed unconditionally from every skill scope.
expect(script).toContain(
'for %%D in ("!CLAUDE_SKILLS_DIR!" "!AGENTS_SKILLS_DIR!" "!KIRO_SKILLS_DIR!") do',
);
expect(script).toContain('rmdir /s /q "%%~D\\plannotator-archive"');
});
test("does not treat a skills-only Codex home as configured", () => {
@@ -598,8 +614,8 @@ describe("Core Plannotator skills", () => {
checked++;
}
}
// 4 core + 3 extra + 3 kiro — bump when adding skills, never below.
expect(checked).toBeGreaterThanOrEqual(10);
// 3 core + 3 extra + 2 kiro — bump when adding skills, never below.
expect(checked).toBeGreaterThanOrEqual(8);
});
});