Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -746,12 +746,21 @@ jobs:
SH
chmod +x "$fake_bin/curl"

# --skip-skills: this smoke installs a SYNTHETIC v9.9.9. The fake curl
# above serves the freshly built binary for any URL, but the skills and
# slash commands come from `git clone --branch v9.9.9` against real
# github.com, where that tag does not and cannot exist. The clone has
# always failed here; it only went unnoticed while a broken guard let
# the installer exit 0 anyway. This job checks the Codex hook config,
# not the skills, so opt out of the checkout rather than teach the test
# to ignore a real error. Both call sites below run through this
# function, so the flag applies to each of them.
run_installer() {
HOME="$tmp_home" \
PATH="$fake_bin:$PATH" \
SHELL=/bin/bash \
ARTIFACT="$artifact" \
bash scripts/install.sh --version v9.9.9 --skip-attestation
bash scripts/install.sh --version v9.9.9 --skip-attestation --skip-skills
}

run_installer
Expand Down
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ claude --plugin-dir ./apps/hook
| `PLANNOTATOR_SKIP_GEMINI_INSTALL` | **Read by the install scripts only.** Same opt-out shape for the Gemini CLI integration (`~/.gemini` policy file, settings hook, slash commands). Config key: `skipInstall.gemini`; flag: `--skip-gemini`. Off by default. |
| `PLANNOTATOR_SKIP_KIRO_INSTALL` | **Read by the install scripts only.** Same opt-out shape for the Kiro CLI integration (`~/.kiro` skills and agent, including the `~/.kiro` stale-skill sweep). Config key: `skipInstall.kiro`; flag: `--skip-kiro`. Off by default. |
| `PLANNOTATOR_SKIP_OPENCODE_INSTALL` | **Read by the install scripts only.** Do-not-write switch for the OpenCode integration (command stubs under `~/.config/opencode/commands`, the OpenCode plugin cache clear, and the stale command-stub sweep). OpenCode has no detection leg, so there is no detected/not-detected reporting, just a skip note. Config key: `skipInstall.opencode`; flag: `--skip-opencode`. Off by default. |
| `PLANNOTATOR_SKIP_SKILLS_INSTALL` | **Read by the install scripts only.** Set to `1` / `true` to skip the skills/slash-command sparse checkout entirely — no `git clone` of the release tag, so nothing is written to any skill or command scope (`~/.claude/skills`, `~/.agents/skills`, the OpenCode command stubs, the Gemini `.toml` commands, `~/.kiro`), the extras are not offered, and the skill-scope cleanup sweeps stay suspended (skip means do-not-write, never remove). The binary, sem sidecar, agent-terminal runtime, hooks, and per-agent config still install, and git stops being a hard requirement. The installer reports `Skills: skipped (...)` and the closing banner stops claiming the `/plannotator-*` commands are ready. Unlike the per-agent opt-outs this is not one agent's home — it covers every scope the checkout writes. Config key: `skipInstall.skills`; flags: `--skip-skills` (bash/cmd), `-SkipSkills` (PowerShell); precedence is flag > env var > config. Used by the `install-script-smoke` CI job, which installs a synthetic `v9.9.9` whose tag has no GitHub counterpart. Off by default. |
| `PLANNOTATOR_SKIP_AGENT_TERMINAL_INSTALL` | Set to `1` / `true` to skip installing the managed Node/WebTUI runtime used by compiled Bun builds for the annotate-mode agent terminal. Read by `plannotator install-runtime agent-terminal`, which the installers call automatically. |
| `PLANNOTATOR_MINIMAL` | **Read by the install scripts only**, not by the runtime binary. Set to `1` / `true` / `yes` to have `scripts/install.sh` / `install.ps1` / `install.cmd` install **only** the `plannotator` binary — skipping the sem sidecar, the agent-terminal runtime, and all per-agent skills, hooks, slash commands, and config. Equivalent to the `--minimal` (aliased `--binary-only`) flag; `--no-minimal` overrides it. Off by default. |
| `PLANNOTATOR_SKIP_SEM_INSTALL` | **Read by the install scripts only.** Set to `1` / `true` to skip installing the optional `sem` semantic-diff sidecar (used by code review). Off by default. |
Expand Down
19 changes: 19 additions & 0 deletions apps/marketing/src/content/docs/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,25 @@ Precedence: flag over environment variable over config file.

</details>

<details>
<summary><strong>Skipping the skills and slash commands</strong></summary>

The `/plannotator-*` skills and slash commands are fetched with a sparse `git clone` of the release tag. `--skip-skills` turns that fetch into a no-op: nothing is written to `~/.claude/skills`, `~/.agents/skills`, the OpenCode or Gemini command directories, or `~/.kiro`, the extras are not offered, and the skill-scope cleanup sweeps stay suspended. The binary, hooks, and per-agent config still install, and git stops being a hard requirement. Use it where the tag being installed cannot be fetched from GitHub, or where you manage the skills yourself.

```bash
curl -fsSL https://plannotator.ai/install.sh | bash -s -- --skip-skills
```

PowerShell: `-SkipSkills`. Windows CMD: `--skip-skills`. For unattended runs set `PLANNOTATOR_SKIP_SKILLS_INSTALL=1`, or persist it:

```json
{ "skipInstall": { "skills": true } }
```

Same precedence: flag over environment variable over config file. The installer reports `Skills: skipped (...)` and stops claiming the `/plannotator-*` commands are ready, so a skipped run is never mistaken for a complete one.

</details>

## Uninstall

`plannotator uninstall` removes recognized installed components while
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ When running your own paste service binary, these variables configure it:
| `PLANNOTATOR_SKIP_GEMINI_INSTALL` | off | Same opt-out for the Gemini CLI integration (`~/.gemini` policy, settings hook, commands). Config key `skipInstall.gemini`; flag `--skip-gemini`. Read by the install scripts only. |
| `PLANNOTATOR_SKIP_KIRO_INSTALL` | off | Same opt-out for the Kiro CLI integration (`~/.kiro` skills and agent). Config key `skipInstall.kiro`; flag `--skip-kiro`. Read by the install scripts only. |
| `PLANNOTATOR_SKIP_OPENCODE_INSTALL` | off | Do-not-write switch for the OpenCode integration (command stubs, plugin cache clear). Config key `skipInstall.opencode`; flag `--skip-opencode`. Read by the install scripts only. |
| `PLANNOTATOR_SKIP_SKILLS_INSTALL` | off | Set to `1` / `true` to skip the skills and slash-command checkout entirely: no `git clone` of the release tag, so nothing is written to `~/.claude/skills`, `~/.agents/skills`, the OpenCode or Gemini command directories, or `~/.kiro`, and the skill-scope cleanup sweeps stay suspended. The binary, hooks, and per-agent config still install, and git stops being a hard requirement. Unlike the per-agent opt-outs above, this covers every scope the checkout writes. Config key `skipInstall.skills`; flags `--skip-skills` (bash/cmd) and `-SkipSkills` (PowerShell). Read by the install scripts only. |
| `CLAUDE_CONFIG_DIR` | `~/.claude` | Custom Claude Code config directory. The install script places hooks here instead of the default location. |

## Remote mode behavior
Expand Down
105 changes: 89 additions & 16 deletions scripts/install.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ set "SKIP_CODEX_FLAG=0"
set "SKIP_GEMINI_FLAG=0"
set "SKIP_KIRO_FLAG=0"
set "SKIP_OPENCODE_FLAG=0"
REM Same shape, but scoped to the skills/slash-command sparse checkout rather
REM than one agent's home: --skip-skills turns the whole fetch into a no-op for
REM every scope it writes (Claude, .agents, OpenCode, Gemini, Kiro), including
REM the extras and the skill-scope cleanup sweeps.
set "SKIP_SKILLS_FLAG=0"

:parse_args
if "%~1"=="" goto args_done
Expand Down Expand Up @@ -151,6 +156,11 @@ if /i "%~1"=="--skip-opencode" (
shift
goto parse_args
)
if /i "%~1"=="--skip-skills" (
set "SKIP_SKILLS_FLAG=1"
shift
goto parse_args
)
REM Reject any other dash-prefixed token as an unknown option, so a typoed
REM flag like --verify-attesttion fails fast instead of being interpreted as
REM a version tag (which would 404 on releases/download/v--verify-attesttion/...).
Expand All @@ -165,7 +175,7 @@ REM unquoted arg containing `&` would re-trigger metacharacter interpretation.
set "CURRENT_ARG=%~1"
if "!CURRENT_ARG:~0,1!"=="-" (
echo Unknown option: "%~1" >&2
echo Usage: install.cmd [--version ^<tag^>] [--verify-attestation ^| --skip-attestation] [--extras ^| --no-extras] [--model-invocable ^<list^>] [--minimal ^| --no-minimal] [--skip-codex] [--skip-gemini] [--skip-kiro] [--skip-opencode] [--non-interactive] [--reconfigure] >&2
echo Usage: install.cmd [--version ^<tag^>] [--verify-attestation ^| --skip-attestation] [--extras ^| --no-extras] [--model-invocable ^<list^>] [--minimal ^| --no-minimal] [--skip-codex] [--skip-gemini] [--skip-kiro] [--skip-opencode] [--skip-skills] [--non-interactive] [--reconfigure] >&2
exit /b 1
)
REM Positional form: install.cmd vX.Y.Z (legacy interface).
Expand Down Expand Up @@ -455,9 +465,13 @@ set "SKIP_KIRO=0"
set "SKIP_KIRO_SOURCE="
set "SKIP_OPENCODE=0"
set "SKIP_OPENCODE_SOURCE="
REM skipInstall.skills is not an agent - it opts out of the skills/slash-command
REM checkout for every scope at once - but it shares the same three layers.
set "SKIP_SKILLS=0"
set "SKIP_SKILLS_SOURCE="
if exist "!_CONFIG_DIR!\config.json" (
set "PLN_CONFIG_JSON=!_CONFIG_DIR!\config.json"
for /f "usebackq delims=" %%K in (`powershell -NoProfile -Command "try { $c = Get-Content $env:PLN_CONFIG_JSON -Raw | ConvertFrom-Json } catch { exit 0 }; if (-not $c.skipInstall) { exit 0 }; foreach ($k in @('codex','gemini','kiro','opencode')) { $v = $c.skipInstall.$k; if ($v -is [bool] -and $v) { $k } }"`) do (
for /f "usebackq delims=" %%K in (`powershell -NoProfile -Command "try { $c = Get-Content $env:PLN_CONFIG_JSON -Raw | ConvertFrom-Json } catch { exit 0 }; if (-not $c.skipInstall) { exit 0 }; foreach ($k in @('codex','gemini','kiro','opencode','skills')) { $v = $c.skipInstall.$k; if ($v -is [bool] -and $v) { $k } }"`) do (
if /i "%%K"=="codex" (
set "SKIP_CODEX=1"
set "SKIP_CODEX_SOURCE=config skipInstall.codex"
Expand All @@ -474,6 +488,10 @@ if exist "!_CONFIG_DIR!\config.json" (
set "SKIP_OPENCODE=1"
set "SKIP_OPENCODE_SOURCE=config skipInstall.opencode"
)
if /i "%%K"=="skills" (
set "SKIP_SKILLS=1"
set "SKIP_SKILLS_SOURCE=config skipInstall.skills"
)
)
set "PLN_CONFIG_JSON="
)
Expand Down Expand Up @@ -509,6 +527,14 @@ for %%V in (0 false no) do if /i "!PLANNOTATOR_SKIP_OPENCODE_INSTALL!"=="%%V" (
set "SKIP_OPENCODE=0"
set "SKIP_OPENCODE_SOURCE="
)
for %%V in (1 true yes) do if /i "!PLANNOTATOR_SKIP_SKILLS_INSTALL!"=="%%V" (
set "SKIP_SKILLS=1"
set "SKIP_SKILLS_SOURCE=PLANNOTATOR_SKIP_SKILLS_INSTALL"
)
for %%V in (0 false no) do if /i "!PLANNOTATOR_SKIP_SKILLS_INSTALL!"=="%%V" (
set "SKIP_SKILLS=0"
set "SKIP_SKILLS_SOURCE="
)
if "!SKIP_CODEX_FLAG!"=="1" (
set "SKIP_CODEX=1"
set "SKIP_CODEX_SOURCE=--skip-codex"
Expand All @@ -525,6 +551,10 @@ if "!SKIP_OPENCODE_FLAG!"=="1" (
set "SKIP_OPENCODE=1"
set "SKIP_OPENCODE_SOURCE=--skip-opencode"
)
if "!SKIP_SKILLS_FLAG!"=="1" (
set "SKIP_SKILLS=1"
set "SKIP_SKILLS_SOURCE=--skip-skills"
)

REM Pre-flight: reject verification requests for tags older than the first
REM attested release BEFORE downloading. Critical security point: the version
Expand Down Expand Up @@ -1046,8 +1076,10 @@ if "!DO_PERSIST!"=="1" (

REM Extras install is delegated to the skills CLI (its UI picks the agents).
REM Interactive wizard runs only - silent runs and CI get the printed command.
REM Never runs when the extras already exist.
if "!EXTRAS_CHOICE!"=="yes" if "!EXTRAS_PRESENT!"=="0" (
REM Never runs when the extras already exist. The extras ARE skills, so
REM --skip-skills suppresses them too - a saved extras=yes preference must not
REM smuggle a skill install past the opt-out.
if "!SKIP_SKILLS!"=="0" if "!EXTRAS_CHOICE!"=="yes" if "!EXTRAS_PRESENT!"=="0" (
set "NPX_OK=0"
where npx >nul 2>&1
if !ERRORLEVEL! equ 0 if "!RUN_WIZARD!"=="1" set "NPX_OK=1"
Expand All @@ -1065,11 +1097,26 @@ REM git we cannot install the /plannotator-* skills, so fail loudly instead of
REM leaving a partial install. Hook/config writing above has already run; the
REM Pi update and Gemini config below are skipped on failure and complete when
REM the user re-runs the installer.
where git >nul 2>&1
if not !ERRORLEVEL! equ 0 (
echo Error: git is required to install Plannotator's skills and slash commands. 1>&2
echo Install git, then run this installer again. 1>&2
exit /b 1
REM
REM Skills/commands opt-out (--skip-skills / PLANNOTATOR_SKIP_SKILLS_INSTALL /
REM skipInstall.skills). HONEST reporting like the per-agent family: the skipped
REM state is announced, and skip means do-not-write - nothing already on disk in
REM any skill or command scope is fetched, replaced, or removed on this run.
REM Nothing is fetched, so git also stops being a requirement here.
if "!SKIP_SKILLS!"=="1" (
echo.
echo Skills: skipped ^(!SKIP_SKILLS_SOURCE!^).
echo No skills or slash commands were fetched, and none already installed
echo were changed or removed. The /plannotator-* commands are NOT installed
echo by this run - re-run without the opt-out to install them.
) else (
where git >nul 2>&1
if not !ERRORLEVEL! equ 0 (
echo Error: git is required to install Plannotator's skills and slash commands. 1>&2
echo Install git, then run this installer again. 1>&2
echo To install without them, re-run with --skip-skills. 1>&2
exit /b 1
)
)
set "CHECKOUT_FAILED=0"
set "KIRO_SKILLS_DIR=%USERPROFILE%\.kiro\skills"
Expand All @@ -1079,6 +1126,11 @@ set "GEMINI_COMMANDS_DIR=%USERPROFILE%\.gemini\commands"
set "SKILLS_TMP=%TEMP%\plannotator-skills-%RANDOM%"
mkdir "!SKILLS_TMP!" >nul 2>&1

REM Opt-out: jump past the clone so no network call is made and
REM CHECKOUT_FAILED stays 0 - an opt-out is not a fetch failure and must not
REM trip the guard below. Reported above, next to the git check.
if "!SKIP_SKILLS!"=="1" goto skills_checkout_done

git clone --depth 1 --filter=blob:none --sparse "https://github.com/!REPO!.git" --branch "!TAG!" "!SKILLS_TMP!\repo" >nul 2>&1
if !ERRORLEVEL! equ 0 (
pushd "!SKILLS_TMP!\repo"
Expand Down Expand Up @@ -1161,6 +1213,7 @@ if !ERRORLEVEL! equ 0 (
set "CHECKOUT_FAILED=1"
)

:skills_checkout_done
rmdir /s /q "!SKILLS_TMP!" >nul 2>&1

if "!CHECKOUT_FAILED!"=="1" (
Expand All @@ -1173,8 +1226,10 @@ 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.
REM A skills opt-out installed no replacement this run, so it removes nothing
REM either - skip means do-not-write, never remove.
for %%C in (plannotator-review plannotator-annotate plannotator-last) do (
if exist "!CLAUDE_SKILLS_DIR!\%%C" if exist "!CLAUDE_COMMANDS_DIR!\%%C.md" (
if "!SKIP_SKILLS!"=="0" 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^)
)
Expand All @@ -1184,7 +1239,9 @@ 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 (
REM A Kiro opt-out leaves ~/.kiro entirely untouched - including this sweep.
REM A skills opt-out leaves every skill scope untouched, sweep included.
set "SCOPE_OK=1"
if "!SKIP_SKILLS!"=="1" set "SCOPE_OK=0"
if /i "%%~D"=="!KIRO_SKILLS_DIR!" if "!SKIP_KIRO!"=="1" set "SCOPE_OK=0"
if "!SCOPE_OK!"=="1" if exist "%%~D\plannotator-archive" (
rmdir /s /q "%%~D\plannotator-archive" >nul 2>&1
Expand All @@ -1194,7 +1251,8 @@ for %%D in ("!CLAUDE_SKILLS_DIR!" "!AGENTS_SKILLS_DIR!" "!KIRO_SKILLS_DIR!") do

REM The /plannotator-archive OpenCode command was removed too - sweep the stub.
REM An OpenCode opt-out suspends the sweep: skip means do-not-write, never remove.
if "!SKIP_OPENCODE!"=="0" if exist "!OPENCODE_COMMANDS_DIR!\plannotator-archive.md" (
REM A skills opt-out suspends it for the same reason.
if "!SKIP_OPENCODE!"=="0" if "!SKIP_SKILLS!"=="0" if exist "!OPENCODE_COMMANDS_DIR!\plannotator-archive.md" (
del /q "!OPENCODE_COMMANDS_DIR!\plannotator-archive.md" >nul 2>&1
echo Removed stale plannotator-archive command from !OPENCODE_COMMANDS_DIR!
)
Expand All @@ -1204,8 +1262,9 @@ REM Core skills are removed only once their replacement exists; the stale
REM shared-agent extras were never Codex's and are removed unconditionally.
for %%S in (plannotator-review plannotator-annotate plannotator-last plannotator-compound plannotator-setup-goal) do (
REM A Codex opt-out leaves the Codex home entirely untouched - including
REM this stale-skill cleanup. Skip means do-not-write, never remove.
if "!SKIP_CODEX!"=="0" if exist "!STALE_CODEX_SKILLS_DIR!\%%S" (
REM this stale-skill cleanup. Skip means do-not-write, never remove. A
REM skills opt-out installed no replacement, so it suspends the sweep too.
if "!SKIP_CODEX!"=="0" if "!SKIP_SKILLS!"=="0" if exist "!STALE_CODEX_SKILLS_DIR!\%%S" (
set "OK_REMOVE=1"
if "%%S"=="plannotator-review" if not exist "!AGENTS_SKILLS_DIR!\%%S" set "OK_REMOVE=0"
if "%%S"=="plannotator-annotate" if not exist "!AGENTS_SKILLS_DIR!\%%S" set "OK_REMOVE=0"
Expand All @@ -1222,7 +1281,10 @@ REM arrive locked (disable-model-invocation: true in SKILL.md); for each
REM chosen skill we unlock the INSTALLED copy by removing that line, and flip
REM the Codex sidecar's allow_implicit_invocation to match. Re-applied on
REM every run because installs replace the skill folders wholesale.
if defined INVOCABLE_CHOICE if not "!INVOCABLE_CHOICE!"=="none" (
REM A skills opt-out installed no skill copies this run, so there is nothing to
REM unlock - and rewriting a PREVIOUS run's SKILL.md would be a write the
REM opt-out promised not to make.
if "!SKIP_SKILLS!"=="0" if defined INVOCABLE_CHOICE if not "!INVOCABLE_CHOICE!"=="none" (
for %%K in ("!INVOCABLE_CHOICE:,=" "!") do (
for %%D in ("!CLAUDE_SKILLS_DIR!" "!AGENTS_SKILLS_DIR!") do (
if exist "%%~D\%%~K\SKILL.md" (
Expand Down Expand Up @@ -1350,6 +1412,9 @@ if "!KIRO_AVAILABLE!"=="1" (
echo Kiro was detected, but the integration was skipped ^(!SKIP_KIRO_SOURCE!^).
echo No files under %USERPROFILE%\.kiro were written or removed. Re-run
echo without the opt-out to add Kiro skills.
) else if "!SKIP_SKILLS!"=="1" (
echo Kiro was detected, but skills were skipped ^(!SKIP_SKILLS_SOURCE!^), so no
echo Kiro skills or agent were installed. Re-run without the opt-out to add them.
) else (
echo Kiro skills are installed to %USERPROFILE%\.kiro\skills\
echo The Plannotator agent is installed to %USERPROFILE%\.kiro\agents\plannotator.json
Expand All @@ -1370,8 +1435,16 @@ 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, and /plannotator-last skills are ready to use!
if not "!EXTRAS_CHOICE!"=="yes" (
REM Never claim the /plannotator-* skills are ready when nothing was installed -
REM that false banner is exactly what the skills-checkout guard exists to prevent.
if "!SKIP_SKILLS!"=="1" (
echo Skills were skipped ^(!SKIP_SKILLS_SOURCE!^), so the /plannotator-review,
echo /plannotator-annotate, and /plannotator-last skills are NOT installed.
echo Re-run the installer without the opt-out to add them.
) else (
echo The /plannotator-review, /plannotator-annotate, and /plannotator-last skills are ready to use!
)
if "!SKIP_SKILLS!"=="0" if not "!EXTRAS_CHOICE!"=="yes" (
echo.
echo Optional skills ^(compound planning, setup-goal, visual explainer^):
echo npx skills add backnotprop/plannotator/apps/skills/extra --global
Expand Down
Loading