squad-kit 1.3.12 → 1.3.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,366 @@
1
+ ---
2
+ title: Config, credentials, and safe deletes
3
+ description: .squad config, secrets, squad config, rm, doctor, and upgrades.
4
+ ---
5
+
6
+ squad-kit intentionally gives you two places to customise: **`.squad/config.yaml`** (and **`.squad/secrets.yaml`** for credentials) and the **story and plan content** you own under `.squad/stories/**` and `.squad/plans/**`. Everything else — default prompts, meta-prompt assembly, and planner defaults that ship with the package — is updated by **upgrading the `squad-kit` npm install**, not by editing files beside the workspace.
7
+
8
+ If you only remember one command after reading this page, make it **`squad config show`** — it is the safest way to see how the CLI will interpret your workspace before you run **`squad new-plan --api`** or **`squad doctor`**.
9
+
10
+ ## What you own vs. what squad-kit owns
11
+
12
+ | Path | Who owns it | How to change |
13
+ | --- | --- | --- |
14
+ | `.squad/config.yaml` | You (commit this) | Prefer **`squad config set …`**; hand-editing is possible but easy to get wrong. |
15
+ | `.squad/secrets.yaml` | You (git-ignored, `0600` on POSIX) | **`squad config set planner` / `set tracker`**, **`squad auth login` / `logout`** for the Claude OAuth token, or **`squad config remove-credential …`**. |
16
+ | `.squad/stories/**`, `.squad/plans/**` | You | Normal file operations; use **`squad rm`** to delete in sync with overviews. |
17
+ | `templates/prompts/*.md` (inside the installed package) | squad-kit | Fork, patch, then `pnpm link` (or publish a fork). No runtime override. |
18
+ | Agent slash files (`.claude/`, `.cursor/`, `.github/prompts/`, `.gemini/`) | You (committed) | Regenerate with **`squad init --force --agents …`** (overwrites only those files). |
19
+
20
+ ## Managing configuration (`squad config`)
21
+
22
+ Secrets never belong in **`.squad/config.yaml`**: the loader rejects secret-shaped key names, by design. Anything sensitive goes to **`.squad/secrets.yaml`** (or the provider env vars squad-kit already documents). For tracker keys and for **API-key** planner credentials, **resolution order** in normal operation is: **env var** → **`.squad/secrets.yaml`** → **prompt** in a TTY → **fail with a recovery hint**.
23
+
24
+ Since **0.12.0** the Anthropic planner can authenticate with your **Claude subscription** instead, which has its own resolution chain — see [Anthropic authentication](#anthropic-authentication-plannerauthanthropic) below and the full guide in [auth.md](auth.md).
25
+
26
+ The rejected key names are matched against the **exact lowercased key name**, not as a substring: `apikey`, `api_key`, `token`, `oauthtoken`, `anthropicoauthtoken`, `secret`, `credential`, `credentials`. Exact matching is deliberate — a substring rule would reject the legitimate `planner.maxOutputTokens` and break every existing workspace. A new credential-shaped key has to be added to that list by name.
27
+
28
+ **`squad config show`** — prints the current config and a **masked** view of secrets (values are **never** echoed in full). Use **`--json`** for machine-readable output (secrets still masked).
29
+
30
+ **`squad config set planner`** — interactive flow to enable or change the direct planner: provider (Anthropic / OpenAI / Google), the Anthropic **authentication mode** (subscription / API key / automatic), optional `modelOverride`, and where to put the API key (`.squad/secrets.yaml` or remind you to use a provider env var). Updates `.squad/config.yaml` and, when you choose in-file storage, `.squad/secrets.yaml`. Logging in and out lives on **`squad auth`**, not here.
31
+
32
+ **`squad config set tracker`** — set tracker type (`none`, `github`, `jira`, `azure`), workspace / org / project fields, and tracker credentials for APIs that need them. Secrets go to `.squad/secrets.yaml` only.
33
+
34
+ **`squad config unset planner`** — removes the `planner` block from `config.yaml` (disables the direct planner). **By default, planner keys in `secrets.yaml` are left in place** so you can re-enable without re-entering. Pass **`--remove-credentials`** to delete planner keys from `secrets.yaml` as well. Use **`-y`** in scripts.
35
+
36
+ **`squad config unset tracker`** — sets the tracker to **`none`** in config. **By default, existing tracker entries in `secrets.yaml` are preserved**. Pass **`--remove-credentials`** to drop `tracker` secrets. Use **`-y`** when you need non-interactive confirmation.
37
+
38
+ **`squad config remove-credential <planner|tracker>`** — removes only the matching credential subtree from **`.squad/secrets.yaml`**, without touching non-secret fields in `config.yaml`. Handy for rotation when you do not want to re-run a full `set` flow.
39
+
40
+ **`squad auth <login|status|logout>`** — the Claude subscription surface. `login` runs the browser flow (or takes `--token <v>` on a headless machine, or `--print-only` to produce a token without storing it), `status` reports the resolved mode and account (`--json`, `--offline`), `logout` removes only the token squad-kit stored. See [auth.md](auth.md).
41
+
42
+ ### If you must hand-edit `config.yaml`
43
+
44
+ Some teams check in a **template** and expand secrets in CI. For local work, prefer **`squad config set …`** so you never write `apiKey:` into the wrong file. If you do edit YAML by hand, keep `planner.budget` limits positive, avoid secret keys in the committed file, and run **`squad doctor`** after edits.
45
+
46
+ ## Anthropic authentication (`planner.auth.anthropic`)
47
+
48
+ **New in 0.12.0.** The Anthropic planner can run on your **Claude subscription** instead of an API key. `planner.auth` is a per-provider map; 0.12.0 populates `anthropic` alone, and OpenAI / Google stay API-key only.
49
+
50
+ | Value | Behaviour |
51
+ | --- | --- |
52
+ | **`subscription`** | Always use the Claude login (`squad auth login`, or `claude` → `/login`). Never reads an API key. |
53
+ | **`api-key`** | Always use an API key. Identical to 0.11.0 behaviour. |
54
+ | **`auto`** | **Merged default.** Prefer a detected Claude login; fall back to a resolvable API key; otherwise fail naming both recovery paths. |
55
+
56
+ ```yaml
57
+ planner:
58
+ enabled: true
59
+ provider: anthropic
60
+ auth:
61
+ anthropic: subscription # subscription | api-key | auto (default: auto)
62
+ runtime:
63
+ anthropic: agent-sdk # required for subscription auth — see below
64
+ modelOverride:
65
+ anthropic: claude-opus-4-7
66
+ ```
67
+
68
+ An omitted `planner.auth` block merges to `{ anthropic: 'auto' }`, so an untouched 0.11.0 workspace keeps loading. An invalid value is a load-time error naming the three legal ones. `squad init` writes `subscription` explicitly for new workspaces.
69
+
70
+ > **Under `auto`, a Claude login beats a stored API key.** On a machine that has both, an upgraded 0.11.0 workspace switches to subscription billing. Nothing errors, and `squad doctor`'s `planner auth mode` row says so explicitly — it names the API key it is ignoring. Pin `api-key` if you want the old behaviour.
71
+
72
+ ### `planner.anthropicOauthToken` is a **secrets-only** key
73
+
74
+ The OAuth token from `claude setup-token` is a credential. It lives at `planner.anthropicOauthToken` in **`.squad/secrets.yaml`** (git-ignored, `0600` on POSIX) and nowhere else:
75
+
76
+ ```yaml
77
+ # .squad/secrets.yaml — never .squad/config.yaml
78
+ planner:
79
+ anthropicOauthToken: sk-ant-oat01-…
80
+ ```
81
+
82
+ `config.yaml` **rejects** it by name. Putting it there fails the load with:
83
+
84
+ > Refusing to load …/config.yaml: key "planner.anthropicOauthToken" looks like a secret.
85
+
86
+ Write it with `squad auth login` (or `squad auth login --token <v>`); remove it with `squad auth logout`.
87
+
88
+ ### `auth: subscription` requires the Agent SDK runtime
89
+
90
+ `@ai-sdk/anthropic` — the `vercel` runtime — authenticates with an `x-api-key` header against `api.anthropic.com`. An OAuth subscription credential is not an API key, so that combination cannot work. squad-kit makes it a **hard, early failure** rather than a silent downgrade to API-key billing:
91
+
92
+ - `planner.auth.anthropic: subscription` + `planner.runtime.anthropic: vercel` → throws before any network call, with the fix hint.
93
+ - `planner.auth.anthropic: subscription` + `planner.provider: openai` / `google` → same failure; those providers are API-key only.
94
+
95
+ `squad doctor`'s **`planner auth vs. runtime`** check catches both before you attempt a run, and the console's Config page disables Save on the conflict.
96
+
97
+ ### Environment variables the CLI respects
98
+
99
+ | Variable | How squad-kit uses it |
100
+ | --- | --- |
101
+ | `ANTHROPIC_API_KEY` | **API-key mode:** first source in the Anthropic key chain. **Subscription mode: deleted from the planner subprocess environment.** |
102
+ | `ANTHROPIC_AUTH_TOKEN` | Never read by squad-kit. **Subscription mode: deleted from the planner subprocess environment.** |
103
+ | `CLAUDE_CODE_OAUTH_TOKEN` | **Subscription mode:** highest-priority login source, above the token stored in `.squad/secrets.yaml`. |
104
+ | `CLAUDE_CONFIG_DIR` | Relocates the `.claude` directory when squad-kit probes for a login (relative paths resolve against the cwd). |
105
+ | `OPENAI_API_KEY`, `GOOGLE_API_KEY` | Provider key for those providers. Unchanged. |
106
+ | `SQUAD_PLANNER_API_KEY` | Cross-provider API-key fall-back. **Never cleared** — it is squad-kit's own variable and the Agent SDK does not read it. |
107
+
108
+ **Why the two Anthropic variables are cleared.** Inside Claude Code's credential precedence, `ANTHROPIC_AUTH_TOKEN` and `ANTHROPIC_API_KEY` rank **above** the `/login` subscription credential. If squad-kit passed an inherited one through, a user who thought they were planning on their Claude plan would be silently billed against API credits instead. So in subscription mode both are removed from the child environment before the Agent SDK subprocess starts — **case-insensitively**, because a `{...process.env}` copy is a plain object and would otherwise miss `Anthropic_Api_Key` on Windows.
109
+
110
+ Your shell is not modified; only the planner subprocess sees the stripped environment. **If you have `ANTHROPIC_API_KEY` exported and it is being ignored, this is why** — set `planner.auth.anthropic: api-key` to use it.
111
+
112
+ Jira and Azure have host/org/project in **`config.yaml`** and tokens in **`secrets.yaml`** (or the env var names the tracker clients document). `squad status`, `squad auth status`, and `squad config show` are the best way to see what your current workspace *resolves* without printing raw secrets.
113
+
114
+ Tracker-specific env names are the ones implemented in the squad-kit version you have installed; when in doubt, prefer **`squad config set tracker`** so the right keys are written to **`secrets.yaml`** in the shape the clients expect.
115
+
116
+ Full walkthrough of both login paths, per-platform credential storage, CI, usage limits, and troubleshooting: [Anthropic authentication](auth.md).
117
+
118
+ ## Model override
119
+
120
+ You can pin a different **plan-phase** model id per provider with **`planner.modelOverride`**, without editing squad-kit source. Example:
121
+
122
+ ```yaml
123
+ planner:
124
+ enabled: true
125
+ provider: anthropic
126
+ modelOverride:
127
+ anthropic: claude-opus-5-0
128
+ ```
129
+
130
+ Use this when you need to **ride ahead** of a squad-kit release (provider ships a new id) or **pin** a specific snapshot. **`squad status`** appends **`(override)`** to the planner line when an override is active for the current provider. **`squad doctor`** checks the resolved id against the provider’s **model list** API (a cheap HTTP call — **not** a paid chat completion) and reports if the id is missing.
131
+
132
+ ## Planner runtimes (Anthropic: Agent SDK vs Vercel)
133
+
134
+ For **Anthropic**, the planner uses **`@anthropic-ai/claude-agent-sdk`** by default so the **default plan model** (`claude-opus-4-7`) can use **adaptive thinking** and **effort** on the wire shapes Anthropic expects. **OpenAI** and **Google** stay on the **Vercel AI SDK** path (`streamText` / `generateObject`); there is no Agent SDK option for those providers.
135
+
136
+ - **Switch runtime:** `planner.runtime.anthropic: 'agent-sdk' | 'vercel'` (default **`agent-sdk`**) or per-run **`--anthropic-runtime agent-sdk|vercel`**. Legacy **`vercel`** may not work with Opus 4.7+; **`squad doctor`** warns when the combo is unsafe unless you override the model to a pre–4.7 id (e.g. Sonnet 4.5).
137
+ - **Thinking and effort** (Agent SDK only; stored under `planner.providerOptions.anthropic`):
138
+ - `thinking: 'adaptive' | 'enabled' | 'disabled' | 'off'` (default **`adaptive`**). With **`enabled`**, use **`thinkingBudget`** for the token budget.
139
+ - `effort: 'minimal' | 'medium' | 'high'` (default **`medium`**).
140
+ - `effortByPhase: { scout?, draft? }` — e.g. **`minimal`** for scout and **`high`** for draft.
141
+ - **CLI overrides:** `--effort`, `--scout-effort`, `--no-thinking` (maps to thinking off for that run).
142
+
143
+ **Known limitations of the Agent SDK path** (see **`CHANGELOG.md`**): cache creation/read **counts** are not exposed (CLI shows **`(agent-sdk: not exposed)`**; caching behaviour still applies). **Per-turn** token usage is not available (live UI is **aggregate-only** until the run ends). **Cancellation** stops the client iterator; the upstream request may still run to completion.
144
+
145
+ ## Copy-paste vs direct API for plans
146
+
147
+ - **Copy-paste** (`squad new-plan` without a working key, or with **`--copy`**) — composes the **generate-plan** prompt with your intake, prints to **stdout**, and **copies to the clipboard** unless **`--no-clipboard`**. You paste into any agent. No provider bill from squad-kit for the compose step; your agent session may still charge.
148
+ - **Direct API** (`squad new-plan --api` or default when the planner is enabled and the key resolves) — squad-kit calls the provider, runs the **bounded** tool loop, and **writes the plan file** and **updates `00-overview.md`** the same way the writer always has.
149
+
150
+ `--api` and **`--copy`** are mutually exclusive; **`--feature`** and **`--all`** work with both modes. See [getting-started.md](getting-started.md) (section **3. Generate a plan**).
151
+
152
+ ## Planner budget (direct API)
153
+
154
+ When the planner is enabled, **`planner.budget`** caps the **`squad new-plan --api`** loop. Defaults (if omitted) are **25** file reads, **50 000** bytes of read context, and **180** seconds wall-clock, per `0.2.0`’s `mergePlanner` logic.
155
+
156
+ ```yaml
157
+ planner:
158
+ enabled: true
159
+ provider: anthropic
160
+ budget:
161
+ maxFileReads: 25
162
+ maxContextBytes: 50000
163
+ maxDurationSeconds: 180
164
+ ```
165
+
166
+ If the planner hits a cap mid-run, the CLI still writes partial output and warns. Raise limits carefully — the point of squad-kit is to **bound** work, not map the whole monorepo. For hand-edits, run **`squad doctor`** after changing numbers (it validates **> 0**).
167
+
168
+ ### Multi-stage planner (`squad new-plan --api`)
169
+
170
+ When the direct API planner runs, squad-kit uses a **pipeline** by default:
171
+
172
+ 1. **Scout** — a **cheap-tier** model reads the intake and repo tree, then returns a ranked list of files to preload for the drafter.
173
+ 2. **Draft** — your configured **plan** model writes the plan with the tool loop (`list_dir`, `grep`, `read_file` including ranged reads).
174
+ 3. **Validation** — an LLM-free pass flags likely problems: missing paths, line ranges past EOF, and simple symbol checks. Treat findings as **warnings** to investigate; the rules are heuristic.
175
+
176
+ **Cost:** the scout uses the small model id for your provider; **`planner.modelOverride` applies to the draft only**. Override the scout with **`--scout-model`** or **`planner.stages.scout.modelOverride`**.
177
+
178
+ **Disable or tighten:**
179
+
180
+ - **`--no-scout`** / **`planner.stages.scout.enabled: false`** — skip scout (draft-only, closer to older behaviour).
181
+ - **`--no-validation`** / **`planner.validation.enabled: false`** — skip validation.
182
+ - **`--strict-validation`** / **`planner.validation.strict: true`** — write **`*.partial.md`** when validation reports issues.
183
+ - **`planner.tools`** — toggle `grep`, `listDir`, `rangedRead` individually.
184
+
185
+ **Eval without API cost:** in a dev checkout, `pnpm eval:offline` re-validates existing plans under `.squad/plans/` (see `test/eval/run-eval-offline.ts`).
186
+
187
+ ## Prompt caching
188
+
189
+ Starting in 0.3.0, squad-kit uses provider prompt caching on every planning run. Cached tokens
190
+ bill at ~10% (Anthropic), ~25% (Google), and ~50% (OpenAI) of the normal input rate — and on
191
+ Anthropic they **don't count against your per-minute rate limit the same way**, which is the
192
+ difference between "Tier 1 Opus works" and "Tier 1 Opus hits 429 after five tool reads."
193
+
194
+ ### How it works per provider
195
+
196
+ - **Anthropic** — explicit `cache_control: { type: 'ephemeral' }` on the system prompt (stable)
197
+ and the most recent tool-result block (rolling forward each turn). 5-minute TTL.
198
+ - **OpenAI** — automatic prefix caching on prompts ≥1024 tokens. No code or config needed; just
199
+ a stable prefix, which 0.3.0 guarantees.
200
+ - **Google** (Gemini 2.0+ / 2.5) — implicit caching enabled by default. Same prefix-stability
201
+ guarantee makes it work.
202
+
203
+ ### Reading the telemetry
204
+
205
+ Every `squad new-plan --api` run prints a cache line:
206
+
207
+ cache hit 68% (22.4k read / 32.9k total · 1.2k written)
208
+
209
+ - `68%` — fraction of input tokens served from cache (higher is cheaper).
210
+ - `22.4k read` — tokens this run served from cache.
211
+ - `32.9k total` — total input tokens this run.
212
+ - `1.2k written` — tokens newly written into the cache (first turn of a session only).
213
+
214
+ A fresh run against a new repo shows low hit % on turn 1 and rising through turn 3-4 as the
215
+ cache warms up. By turn 5 you should see 60–80% hits on Anthropic.
216
+
217
+ ### Turning it off
218
+
219
+ squad config set planner
220
+
221
+ …and answer `No` to the caching prompt. You'll see `cache disabled` in the run summary.
222
+ `squad doctor` will warn that caching is off (noisy for a reason — you're paying 3-10× more).
223
+
224
+ ### Troubleshooting
225
+
226
+ Run `squad doctor`. The `planner cache effectiveness` check has four outcomes:
227
+
228
+ - **skip** — no runs yet, or planner disabled. Run `squad new-plan --api` once.
229
+ - **ok** — caching is working. You'll see the last run's hit rate.
230
+ - **warn** — hit rate < 30% after 3+ turns. Something is busting the prefix. Check your
231
+ `.squad/config.yaml` for anything that changes per-run. Run with
232
+ `NODE_ENV=development squad new-plan --api` to surface prefix-mismatch warnings.
233
+ - **fail** — 0% hits across multiple turns. Same causes as warn, more severe.
234
+
235
+ ## Naming convention
236
+
237
+ `.squad/config.yaml`:
238
+
239
+ ```yaml
240
+ naming:
241
+ includeTrackerId: false # NN-story-<slug>.md
242
+ # or
243
+ includeTrackerId: true # NN-story-<slug>-<id>.md
244
+ globalSequence: false # reset NN per feature folder
245
+ ```
246
+
247
+ **`squad rm`** accepts plans and stories by either filename shape; interactive pickers show the same entries you see in `squad list`.
248
+
249
+ ## NN collisions on branches
250
+
251
+ `NN` is computed globally when `naming.globalSequence: true`. Two branches cut from the same commit can each allocate the same `NN` for a new plan. On merge:
252
+
253
+ 1. Find the conflicting files under `.squad/plans/`.
254
+ 2. Renumber one of them. `git mv` is fine.
255
+ 3. Update the feature’s `00-overview.md` row and any cross-references.
256
+
257
+ If this is painful, switch to `globalSequence: false` and accept per-feature numbering.
258
+
259
+ After a messy rebase, **`squad rm plan`** (or trash + restore) **plus `squad new-plan --api`** is a clean way to regenerate with a fresh global `NN` if you are willing to drop the local plan file only.
260
+
261
+ ## Removing things safely (`squad rm`)
262
+
263
+ | Command | What it does |
264
+ | --- | --- |
265
+ | `squad rm story` | Interactive picker; removes the **intake folder**, the **matching plan file**, and the **overview row**. |
266
+ | `squad rm story <path or id>` | Same, but targets one story. |
267
+ | `squad rm plan` | Interactive picker; removes the **plan file only** (intake stays; use `squad new-plan` to regenerate). |
268
+ | `squad rm feature` | Removes **every** story, plan, and overview content under a feature. |
269
+ | `… --dry-run` | Print what would be deleted. |
270
+ | `… --trash` | Move into **`.squad/.trash/<timestamp>/`** instead of deleting. |
271
+ | `… -y` / `… --yes` | Skip confirmation (for scripts and CI). |
272
+
273
+ **Recovery:** the trash folder is under `.squad/` and is **git-ignored**. Inspect `.squad/.trash/<timestamp>/` and move files back if you trashed something by mistake.
274
+
275
+ The trash directory is for recovery only — it is not a long-term backup strategy.
276
+
277
+ ## Common workflows (quick reference)
278
+
279
+ - **Plan on your Claude subscription instead of an API key** — `squad auth login`, then `squad new-plan --api`. Or `claude` → `/login` and set `planner.auth.anthropic: subscription`. See [auth.md](auth.md).
280
+ - **Move back to an API key** — set `planner.auth.anthropic: api-key` (via `squad config set planner`), and make sure a key resolves. Optionally `squad auth logout` to drop the stored token.
281
+ - **First-time planner key after a `skip-secrets` init** — `squad config set planner`, choose provider, paste or defer to env.
282
+ - **Rotate a leaked Jira token** — `squad config remove-credential tracker`, then `squad config set tracker` to write a new PAT, or edit `secrets.yaml` with `squad doctor` to verify.
283
+ - **Temporarily drop the tracker API** — `squad config unset tracker` (keeps `secrets.yaml` unless you add `--remove-credentials`); re-enable with `squad config set tracker`.
284
+ - **Regenerate one plan, keep the intake** — `squad rm plan` (or target the plan path), then `squad new-plan --api` or `squad new-plan --copy`.
285
+ - **Nuke a feature safely** — `squad rm feature --dry-run`, then re-run with `--trash` if you want a safety net, or without if you are sure.
286
+ - **CI / scripts** — pass **`-y`** on mutating `config` and `rm` subcommands when stdin is not a TTY; pair with explicit paths instead of pickers.
287
+ - **Inspect machine-readable state** — `squad config show --json` and `squad doctor --json` for scripts (secrets remain masked in `config show`).
288
+
289
+ ## Project structure hints
290
+
291
+ - **`project.projectRoots`** — list repo roots the planner and meta-prompts should know about (see [getting-started.md](getting-started.md#multi-repo-workspaces)).
292
+ - **`naming.includeTrackerId` + tracker type** — when both are set, new stories may require a work-item id unless you pass **`--no-tracker`**.
293
+ - **`.squad/plans/00-index.md`** — global index; feature work lives under **`.squad/plans/<feature>/`**, with **`00-overview.md`** per feature updated when plans are created or removed via the supported commands.
294
+
295
+ ## Health checks (`squad doctor`)
296
+
297
+ **`squad doctor`** runs this checklist (and exits non-zero on failures), in order:
298
+
299
+ 1. `.squad/` directory structure
300
+ 2. `.squad/config.yaml` readable
301
+ 3. `.gitignore` managed block (e.g. secrets patterns)
302
+ 4. `.gitignore` includes `.squad/.trash/`
303
+ 5. `.squad/secrets.yaml` permissions (POSIX; skipped on Windows)
304
+ 6. `.squad/secrets.yaml` parseable
305
+ 7. **Legacy prompts directory** (0.1.x; same check name in the CLI: legacy `.squad/prompts/` when present — **removed in 0.2.0** for new installs)
306
+ 8. planner configuration (shape, budget, `modelOverride` when set)
307
+ 9. **planner auth mode** — the resolved mode, why, and the credential behind it (0.12.0)
308
+ 10. planner credential resolves — a live Agent SDK login check on subscription auth
309
+ 11. planner model resolves at provider (models list API — not a chat completion); **skips on subscription auth**
310
+ 12. planner tier vs. model; **skips on subscription auth**
311
+ 13. planner cache effectiveness
312
+ 14. planner runtime (resolved)
313
+ 15. **planner auth vs. runtime** — subscription auth needs the Agent SDK runtime (0.12.0)
314
+ 16. Anthropic Opus 4.7+ vs Vercel runtime
315
+ 17. Anthropic Agent SDK install
316
+ 18. tracker configuration (required fields for Jira / Azure, etc.)
317
+ 19. tracker credential resolves
318
+ 20. tracker connectivity (Jira, Azure, or GitHub when applicable)
319
+
320
+ The two subscription **skips** are deliberate, not gaps: the model-list probe needs an API key and there is none, and a Claude plan has no API rate tier to warn about.
321
+
322
+ **`squad doctor --fix`** applies **non-destructive** fixes only (directories, `gitignore`, `chmod` on `secrets.yaml`). It does **not** remove legacy `prompts/` or rewrite config the way **`squad migrate`** does.
323
+
324
+ It also deliberately **does not pin an implicit `auto` to `api-key`**. When `auto` falls back to a key, `planner auth mode` reports `ok` with an explanatory hint and writes nothing: `auto` exists precisely so a Claude login takes over once one appears, and pinning would silently prevent that forever. Use `squad config set planner` if you want the mode fixed.
325
+
326
+ **`squad doctor --json`** prints `{ root, checks }` for scripts.
327
+
328
+ squad-kit **never** runs a **paid** planner completion during `squad doctor`; “model resolves” is a **models-API** probe with your key, and the subscription login check is an `accountInfo()` handshake that runs no model round.
329
+
330
+ ## Upgrading the CLI
331
+
332
+ ```bash
333
+ squad upgrade # preferred — detects pnpm / npm / yarn / bun
334
+ squad upgrade --check # report only
335
+ squad upgrade --yes # skip confirmation
336
+ ```
337
+
338
+ **`squad upgrade`** fetches the **latest** release from npm and refuses **dev** installs and **major** version jumps (it prints a manual guide instead) so you do not jump across breaking changes by accident. Patch and minor updates within the same major are the sweet spot.
339
+
340
+ **The Update button.** The app looks for a new version on start and once a day (Settings › About, "Check for updates every day"; turn it off on a network without internet). When one is out, Home and every project page show "squad-kit 1.0.2 is ready" with what is new from the GitHub release. **Update now** waits until no agent is in the middle of a step (or press **Update now anyway**), installs with the package manager that installed squad-kit, and restarts the app on the same link: every ticket carries on where it was. If the install needs permission, the app shows the one command to run in a terminal, then **Restart**. A source checkout and a new major version only get the command. API: `GET /api/v1/app/update`, `POST /api/v1/app/update` (`{ "now": true }` skips the wait), `POST /api/v1/app/update/check`.
341
+
342
+ After installing a new **version** of the package, run **`squad migrate` once per repo** the first time the CLI reports structural drift, or when upgrading from **0.1.x** → **0.2.x**, so `.squad/` matches what the new CLI expects. The full 0.1.x → 0.2.x walkthrough (including what gets deleted) is on the site: [migration guide](https://squad-kit.com/docs/migrating-from-0.1) (a repo-local `docs/migrating-from-0.1.md` is maintained alongside the project).
343
+
344
+ `npm install -g squad-kit@x` or `pnpm add -g squad-kit@x` is still valid if you pin versions in automation; **`squad upgrade`** is the interactive default.
345
+
346
+ ### `squad list` and `squad status`
347
+
348
+ These read-only commands complement config work:
349
+
350
+ - **`squad list`** — table of intakes, plan filenames, and whether a plan was last produced by **API** or **copy-paste** (per `squad` metadata).
351
+ - **`squad status`** — global **next `NN`**, story/plan counts, **planner** row (provider, model, `(override)` when `modelOverride` applies), a **planner auth** row (resolved mode, credential hint, and why it resolved that way), and **tracker** row (type, workspace, credential source: `env` / `secrets.yaml` / `missing`).
352
+ - **`squad auth status`** — the auth row on its own, plus the live Claude account when one resolves. `--offline` skips the live check; `--json` is stable and never contains a credential.
353
+
354
+ Use them after any `squad config` change to confirm the workspace is coherent before running `squad new-plan --api`.
355
+
356
+ ## Adding agents post-init
357
+
358
+ ```bash
359
+ squad init --force --agents claude-code,cursor,copilot,gemini
360
+ ```
361
+
362
+ `--force` overwrites the generated slash-command files in the repo root. Your `config.yaml`, stories, and plans are not wiped.
363
+
364
+ ## Forking to change prompts
365
+
366
+ The plan meta-prompts (`generate-plan.md`, `intake.md`, `story-skeleton.md`) are **not** user-editable at runtime. They ship inside the npm package at `templates/prompts/`. To change them, **fork** `squad-kit`, edit those files, and **`pnpm link`** your fork (or publish a package under a different name). There is **no** `.squad/prompts/` override; it was **removed in 0.2.0** so user copies and CLI behaviour could not drift silently.
@@ -0,0 +1,35 @@
1
+ # User-facing error audit (no-stuck / dead-end pass)
2
+
3
+ Working notes for Story 04. `docs/` is not published in the npm `files` list (see `package.json`).
4
+
5
+ ## Convention
6
+
7
+ User-visible errors use one of:
8
+
9
+ - **Simple:** `<What failed>. Run \`<command>\` to <action>.`
10
+ - **Contextual:** short cause, then `Run \`...\`` (and optionally `, or \`...\``).
11
+
12
+ ## Inventory (representative callsites)
13
+
14
+ | File:line (area) | Status | Notes |
15
+ |------------------|--------|--------|
16
+ | `commands/new-story.ts` | REWRITE → OK | Missing slug, tracker id, invalid id, folder name, duplicate intake |
17
+ | `commands/tracker-link.ts` | REWRITE → OK | Non-interactive usage, invalid id, missing intake |
18
+ | `commands/new-plan.ts` | REWRITE → OK | Mode conflict, paths, API/config/copy, empty plan |
19
+ | `commands/init.ts` | REWRITE → OK | Existing config (non-interactive), bad `--planner` |
20
+ | `commands/config/*.ts` | REWRITE → OK | set planner/tracker, remove-credential |
21
+ | `commands/rm/*.ts` | REWRITE → OK | Usage, confirmation, resolve errors, shared pickers |
22
+ | `commands/upgrade.ts` | REWRITE → OK | Dev install, registry, major bump, non-interactive, spawn failure |
23
+ | `commands/migrate.ts` | REWRITE → OK | Non-interactive confirm, suspicious path |
24
+ | `core/config.ts` | REWRITE → OK | Secrets in YAML, YAML/parse, validation, budgets |
25
+ | `core/secrets.ts` | REWRITE → OK | Read/parse/structure |
26
+ | `core/paths.ts` | OK | Already had `Run \`squad init\`` |
27
+ | `planner/provider-errors.ts` | REWRITE → OK | `modelNotFoundMessage` recovery list |
28
+ | `planner/loop.ts` | REWRITE → OK | Provider stopReason error |
29
+ | `tracker/index.ts` | REWRITE → OK | `ClientResolutionError.detail` for jira/azure/unsupported |
30
+
31
+ Internal or non-CLI errors (registry fetch, package root resolution, etc.) were reviewed; only user-reachable paths were expanded with `Run \`...\`` hints.
32
+
33
+ ## Maintenance
34
+
35
+ When adding a new `throw new Error` or `ui.failure` on a command path, keep the same shape and update this table if the command is user-facing.