diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 986c2fc8..51149723 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -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." diff --git a/AGENTS.md b/AGENTS.md index e802e4bb..8d535c03 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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/ ↓ diff --git a/README.md b/README.md index 9ab6eeeb..51028ff4 100644 --- a/README.md +++ b/README.md @@ -279,7 +279,6 @@ This Droid plugin is commands-only. It adds: /plannotator-review /plannotator-annotate /plannotator-last -/plannotator-archive ``` It does not currently intercept Droid's planning flow. diff --git a/apps/droid-plugin/README.md b/apps/droid-plugin/README.md index d1c72850..d99895fb 100644 --- a/apps/droid-plugin/README.md +++ b/apps/droid-plugin/README.md @@ -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 ` - `/plannotator-last` -- `/plannotator-archive` It does not attempt plan-mode interception or host-level planning integration. diff --git a/apps/droid-plugin/commands/plannotator-archive.js b/apps/droid-plugin/commands/plannotator-archive.js deleted file mode 100755 index 04c5e90e..00000000 --- a/apps/droid-plugin/commands/plannotator-archive.js +++ /dev/null @@ -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"); diff --git a/apps/hook/README.md b/apps/hook/README.md index 2d385a3a..309c5cb0 100644 --- a/apps/hook/README.md +++ b/apps/hook/README.md @@ -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 ` | 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 diff --git a/apps/kiro-cli/README.md b/apps/kiro-cli/README.md index d1c6df4b..eace991f 100644 --- a/apps/kiro-cli/README.md +++ b/apps/kiro-cli/README.md @@ -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. @@ -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 diff --git a/apps/kiro-cli/agents/plannotator.json b/apps/kiro-cli/agents/plannotator.json index 968df86d..58aae47b 100644 --- a/apps/kiro-cli/agents/plannotator.json +++ b/apps/kiro-cli/agents/plannotator.json @@ -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" ], diff --git a/apps/kiro-cli/skills/plannotator-archive/SKILL.md b/apps/kiro-cli/skills/plannotator-archive/SKILL.md deleted file mode 100644 index a8c5a322..00000000 --- a/apps/kiro-cli/skills/plannotator-archive/SKILL.md +++ /dev/null @@ -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 -``` diff --git a/apps/marketing/src/components/landing/HeroSection.astro b/apps/marketing/src/components/landing/HeroSection.astro index 17c2b572..bef419b5 100644 --- a/apps/marketing/src/components/landing/HeroSection.astro +++ b/apps/marketing/src/components/landing/HeroSection.astro @@ -270,10 +270,9 @@ import AnnoReplace from './AnnoReplace.astro'; steps: [ 'kiro-cli chat --agent plannotator', 'plannotator-review', - 'plannotator-annotate ', - 'plannotator-archive' + 'plannotator-annotate ' ], - 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/' diff --git a/apps/marketing/src/content/docs/getting-started/installation.md b/apps/marketing/src/content/docs/getting-started/installation.md index 913844c5..f5d80624 100644 --- a/apps/marketing/src/content/docs/getting-started/installation.md +++ b/apps/marketing/src/content/docs/getting-started/installation.md @@ -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 /plannotator-last -/plannotator-archive ``` Those commands open the browser-based Plannotator review UI and send the result back into the Droid session. diff --git a/apps/marketing/src/content/docs/guides/claude-code.md b/apps/marketing/src/content/docs/guides/claude-code.md index e48257e2..0f7394df 100644 --- a/apps/marketing/src/content/docs/guides/claude-code.md +++ b/apps/marketing/src/content/docs/guides/claude-code.md @@ -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 diff --git a/apps/marketing/src/content/docs/guides/kiro-cli.md b/apps/marketing/src/content/docs/guides/kiro-cli.md index a58ea8ea..638e5815 100644 --- a/apps/marketing/src/content/docs/guides/kiro-cli.md +++ b/apps/marketing/src/content/docs/guides/kiro-cli.md @@ -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 | diff --git a/apps/marketing/src/content/docs/guides/opencode-migration-0-19-1.md b/apps/marketing/src/content/docs/guides/opencode-migration-0-19-1.md index 361da367..5b639503 100644 --- a/apps/marketing/src/content/docs/guides/opencode-migration-0-19-1.md +++ b/apps/marketing/src/content/docs/guides/opencode-migration-0-19-1.md @@ -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 diff --git a/apps/marketing/src/content/docs/guides/opencode.md b/apps/marketing/src/content/docs/guides/opencode.md index 83aeb38a..e2672d31 100644 --- a/apps/marketing/src/content/docs/guides/opencode.md +++ b/apps/marketing/src/content/docs/guides/opencode.md @@ -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`. diff --git a/apps/opencode-plugin/README.md b/apps/opencode-plugin/README.md index a4b7c288..7feeb566 100644 --- a/apps/opencode-plugin/README.md +++ b/apps/opencode-plugin/README.md @@ -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`. diff --git a/apps/opencode-plugin/cli-bridge.ts b/apps/opencode-plugin/cli-bridge.ts index 4877b9d3..6d4b0479 100644 --- a/apps/opencode-plugin/cli-bridge.ts +++ b/apps/opencode-plugin/cli-bridge.ts @@ -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)}`); } diff --git a/apps/opencode-plugin/commands.ts b/apps/opencode-plugin/commands.ts index b170528f..19706d0c 100644 --- a/apps/opencode-plugin/commands.ts +++ b/apps/opencode-plugin/commands.ts @@ -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(); -} diff --git a/apps/opencode-plugin/commands/plannotator-archive.md b/apps/opencode-plugin/commands/plannotator-archive.md deleted file mode 100644 index 2dfff75c..00000000 --- a/apps/opencode-plugin/commands/plannotator-archive.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -description: Browse saved plan decisions in the archive ---- diff --git a/apps/opencode-plugin/embedded.ts b/apps/opencode-plugin/embedded.ts index 23182493..78cc1eb0 100644 --- a/apps/opencode-plugin/embedded.ts +++ b/apps/opencode-plugin/embedded.ts @@ -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 {}; } diff --git a/apps/opencode-plugin/index.ts b/apps/opencode-plugin/index.ts index 90594587..5694ba5d 100644 --- a/apps/opencode-plugin/index.ts +++ b/apps/opencode-plugin/index.ts @@ -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; diff --git a/apps/pi-extension/README.md b/apps/pi-extension/README.md index df166d3c..cdc37486 100644 --- a/apps/pi-extension/README.md +++ b/apps/pi-extension/README.md @@ -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 ` | Open markdown file in annotation UI | | `/plannotator-last` | Annotate the last assistant message | diff --git a/apps/pi-extension/index.ts b/apps/pi-extension/index.ts index aa86c1b3..539aaa77 100644 --- a/apps/pi-extension/index.ts +++ b/apps/pi-extension/index.ts @@ -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) => { diff --git a/apps/skills/claude/plannotator-archive/SKILL.md b/apps/skills/claude/plannotator-archive/SKILL.md deleted file mode 100644 index d09ebe25..00000000 --- a/apps/skills/claude/plannotator-archive/SKILL.md +++ /dev/null @@ -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. diff --git a/apps/skills/core/plannotator-archive/SKILL.md b/apps/skills/core/plannotator-archive/SKILL.md deleted file mode 100644 index 4cc01b79..00000000 --- a/apps/skills/core/plannotator-archive/SKILL.md +++ /dev/null @@ -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. diff --git a/apps/skills/core/plannotator-archive/agents/openai.yaml b/apps/skills/core/plannotator-archive/agents/openai.yaml deleted file mode 100644 index 08f6ab89..00000000 --- a/apps/skills/core/plannotator-archive/agents/openai.yaml +++ /dev/null @@ -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 diff --git a/scripts/install.cmd b/scripts/install.cmd index 0c655953..8d3890f2 100644 --- a/scripts/install.cmd +++ b/scripts/install.cmd @@ -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 diff --git a/scripts/install.ps1 b/scripts/install.ps1 index f17a60e1..b3c862f9 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -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 "" diff --git a/scripts/install.sh b/scripts/install.sh index 4c3053d7..d7188b23 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -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 " 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 "" diff --git a/scripts/install.test.ts b/scripts/install.test.ts index 429a199b..60a17da7 100644 --- a/scripts/install.test.ts +++ b/scripts/install.test.ts @@ -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); }); });