@gempack/squad-mcp 0.3.1 → 0.6.0

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.
Files changed (111) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +4 -2
  3. package/CHANGELOG.md +395 -8
  4. package/INSTALL.md +554 -0
  5. package/README.md +311 -25
  6. package/agents/{Skill-Squad-Dev.md → _shared/Skill-Squad-Dev.md} +30 -3
  7. package/agents/{Skill-Squad-Review.md → _shared/Skill-Squad-Review.md} +70 -0
  8. package/agents/{PO.md → product-owner.md} +33 -1
  9. package/agents/{Senior-Architect.md → senior-architect.md} +33 -1
  10. package/agents/{Senior-DBA.md → senior-dba.md} +33 -1
  11. package/agents/senior-dev-reviewer.md +640 -0
  12. package/agents/{Senior-Dev-Security.md → senior-dev-security.md} +33 -1
  13. package/agents/{Senior-Developer.md → senior-developer.md} +33 -1
  14. package/agents/{Senior-QA.md → senior-qa.md} +33 -1
  15. package/agents/{TechLead-Consolidator.md → tech-lead-consolidator.md} +7 -1
  16. package/agents/{TechLead-Planner.md → tech-lead-planner.md} +7 -1
  17. package/commands/brainstorm.md +21 -0
  18. package/commands/commit-suggest.md +12 -0
  19. package/commands/squad-review.md +10 -58
  20. package/commands/squad.md +11 -70
  21. package/dist/config/ownership-matrix.d.ts +24 -2
  22. package/dist/config/ownership-matrix.js +466 -139
  23. package/dist/config/ownership-matrix.js.map +1 -1
  24. package/dist/config/squad-yaml.d.ts +242 -0
  25. package/dist/config/squad-yaml.js +403 -0
  26. package/dist/config/squad-yaml.js.map +1 -0
  27. package/dist/errors.d.ts +1 -1
  28. package/dist/errors.js +1 -1
  29. package/dist/errors.js.map +1 -1
  30. package/dist/format/pr-review.d.ts +61 -0
  31. package/dist/format/pr-review.js +146 -0
  32. package/dist/format/pr-review.js.map +1 -0
  33. package/dist/index.js +19 -13
  34. package/dist/index.js.map +1 -1
  35. package/dist/learning/format.d.ts +29 -0
  36. package/dist/learning/format.js +55 -0
  37. package/dist/learning/format.js.map +1 -0
  38. package/dist/learning/store.d.ts +102 -0
  39. package/dist/learning/store.js +169 -0
  40. package/dist/learning/store.js.map +1 -0
  41. package/dist/resources/agent-loader.d.ts +14 -2
  42. package/dist/resources/agent-loader.js +235 -53
  43. package/dist/resources/agent-loader.js.map +1 -1
  44. package/dist/tasks/select.d.ts +64 -0
  45. package/dist/tasks/select.js +84 -0
  46. package/dist/tasks/select.js.map +1 -0
  47. package/dist/tasks/store.d.ts +338 -0
  48. package/dist/tasks/store.js +321 -0
  49. package/dist/tasks/store.js.map +1 -0
  50. package/dist/tools/agents.js +4 -1
  51. package/dist/tools/agents.js.map +1 -1
  52. package/dist/tools/compose-advisory-bundle.d.ts +5 -5
  53. package/dist/tools/compose-advisory-bundle.js +24 -12
  54. package/dist/tools/compose-advisory-bundle.js.map +1 -1
  55. package/dist/tools/compose-prd-parse.d.ts +53 -0
  56. package/dist/tools/compose-prd-parse.js +167 -0
  57. package/dist/tools/compose-prd-parse.js.map +1 -0
  58. package/dist/tools/compose-squad-workflow.d.ts +28 -10
  59. package/dist/tools/compose-squad-workflow.js +0 -0
  60. package/dist/tools/compose-squad-workflow.js.map +1 -1
  61. package/dist/tools/consolidate.d.ts +55 -4
  62. package/dist/tools/consolidate.js +87 -15
  63. package/dist/tools/consolidate.js.map +1 -1
  64. package/dist/tools/expand-task.d.ts +51 -0
  65. package/dist/tools/expand-task.js +35 -0
  66. package/dist/tools/expand-task.js.map +1 -0
  67. package/dist/tools/list-tasks.d.ts +31 -0
  68. package/dist/tools/list-tasks.js +50 -0
  69. package/dist/tools/list-tasks.js.map +1 -0
  70. package/dist/tools/next-task.d.ts +37 -0
  71. package/dist/tools/next-task.js +60 -0
  72. package/dist/tools/next-task.js.map +1 -0
  73. package/dist/tools/read-learnings.d.ts +53 -0
  74. package/dist/tools/read-learnings.js +72 -0
  75. package/dist/tools/read-learnings.js.map +1 -0
  76. package/dist/tools/read-squad-config.d.ts +23 -0
  77. package/dist/tools/read-squad-config.js +34 -0
  78. package/dist/tools/read-squad-config.js.map +1 -0
  79. package/dist/tools/record-learning.d.ts +62 -0
  80. package/dist/tools/record-learning.js +80 -0
  81. package/dist/tools/record-learning.js.map +1 -0
  82. package/dist/tools/record-tasks.d.ts +71 -0
  83. package/dist/tools/record-tasks.js +45 -0
  84. package/dist/tools/record-tasks.js.map +1 -0
  85. package/dist/tools/registry.d.ts +1 -1
  86. package/dist/tools/registry.js +71 -39
  87. package/dist/tools/registry.js.map +1 -1
  88. package/dist/tools/score-rubric.d.ts +74 -0
  89. package/dist/tools/score-rubric.js +140 -0
  90. package/dist/tools/score-rubric.js.map +1 -0
  91. package/dist/tools/slice-files-for-task.d.ts +31 -0
  92. package/dist/tools/slice-files-for-task.js +52 -0
  93. package/dist/tools/slice-files-for-task.js.map +1 -0
  94. package/dist/tools/update-task-status.d.ts +29 -0
  95. package/dist/tools/update-task-status.js +35 -0
  96. package/dist/tools/update-task-status.js.map +1 -0
  97. package/dist/util/override-allowlist.d.ts +63 -0
  98. package/dist/util/override-allowlist.js +191 -0
  99. package/dist/util/override-allowlist.js.map +1 -0
  100. package/dist/util/path-internal.d.ts +6 -0
  101. package/dist/util/path-internal.js +27 -0
  102. package/dist/util/path-internal.js.map +1 -0
  103. package/dist/util/path-safety.js +0 -0
  104. package/dist/util/path-safety.js.map +1 -1
  105. package/package.json +5 -1
  106. package/skills/brainstorm/SKILL.md +284 -0
  107. package/skills/commit-suggest/SKILL.md +255 -0
  108. package/skills/squad/SKILL.md +454 -0
  109. package/tools/post-review.mjs +212 -0
  110. package/agents/Senior-Dev-Reviewer.md +0 -104
  111. /package/agents/{_Severity-and-Ownership.md → _shared/_Severity-and-Ownership.md} +0 -0
package/INSTALL.md ADDED
@@ -0,0 +1,554 @@
1
+ # Installation guide
2
+
3
+ This guide walks through installing `squad-mcp` in every supported host: Claude Code (as a plugin), and any other MCP-capable client (Claude Desktop, Cursor, Warp, Continue, etc.) via the npm package.
4
+
5
+ After install you get:
6
+
7
+ - 23 deterministic MCP tools (Claude Code exposes them as `mcp__squad__*`; other hosts may use a different prefix). Counts grow as new features land — the running server is authoritative; call `tools/list` to see the live count.
8
+ - 12 MCP resources (`agent://*`, `severity://*`)
9
+ - 3 MCP prompts (`squad_orchestration`, `agent_advisory`, `consolidator`)
10
+ - 4 slash commands — Claude Code only:
11
+ - `/squad <task>` — implementation workflow
12
+ - `/squad-review [target]` — advisory-only review of an existing diff/branch/PR
13
+ - `/brainstorm <topic>` — pre-implementation research
14
+ - `/commit-suggest` — Conventional Commits message suggester (read-only)
15
+ - Two on-disk stores under `.squad/` (versioned in git):
16
+ - `.squad/tasks.json` — atomic tasks decomposed from a PRD (see [`Tasks`](#path-d--using-the-tasks-store))
17
+ - `.squad/learnings.jsonl` — accept/reject decisions on past advisory findings (see [`Learnings`](#path-e--using-the-learnings-store))
18
+ - Optional repo configuration in [`.squad.yaml`](#repo-configuration--squadyaml) (weights, skip paths, disabled agents, learnings/tasks paths, PR-posting policy).
19
+
20
+ ## Prerequisites
21
+
22
+ - Node.js 20+ on `PATH`. Both the npm path and the Claude Code plugin path shell out to `node` (the plugin manifest runs `node ${CLAUDE_PLUGIN_ROOT}/dist/index.js`); CI tests on Node 20 and 22.
23
+ - A host that speaks MCP (Claude Code, Claude Desktop, Cursor, Warp, Continue, …)
24
+ - Git available on `PATH` (used by `detect_changed_files`)
25
+
26
+ Verify Node:
27
+
28
+ ```bash
29
+ node --version # v20+
30
+ ```
31
+
32
+ ## Path A — Claude Code plugin (recommended)
33
+
34
+ The plugin bundles the MCP server, the slash commands, and the agent definitions behind a single install. No JSON config to edit.
35
+
36
+ 1. **Add the marketplace.** In a Claude Code session, paste:
37
+
38
+ ```text
39
+ /plugin marketplace add ggemba/squad-mcp
40
+ ```
41
+
42
+ Wait for `marketplace added`.
43
+
44
+ 2. **Install the plugin.**
45
+
46
+ ```text
47
+ /plugin install squad@gempack
48
+ ```
49
+
50
+ Wait for `plugin installed`.
51
+
52
+ 3. **Restart Claude Code** (close and reopen). The slash-command registry is populated at startup, so the new `/squad` and `/squad-review` commands and the `squad` MCP server only become available after a restart.
53
+
54
+ 4. **Verify the install.** In a fresh prompt:
55
+ - Type `/squad ` (with the trailing space) — the autocomplete should suggest `/squad <task description>`.
56
+ - Type `/squad-review` — same check.
57
+ - Open Settings → MCP. You should see `squad` listed and connected.
58
+ - Ask Claude to call the `list_agents` tool from the `squad` MCP server. It should return 9 agents (`product-owner`, `tech-lead-planner`, `tech-lead-consolidator`, `senior-architect`, `senior-dba`, `senior-developer`, `senior-dev-reviewer`, `senior-dev-security`, `senior-qa`).
59
+
60
+ 5. **Use it.**
61
+
62
+ ```text
63
+ /squad add a /health endpoint that returns build SHA and uptime
64
+ /squad-review
65
+ /squad-review 1234 # PR number
66
+ /squad-review feature/x # branch
67
+ ```
68
+
69
+ `/squad` runs the full Phase 0–12 orchestration (classify → score risk → pick agents → plan → Gate 1 → advisory squad → Gate 2 → implement → consolidate). `/squad-review` is review-only — it never implements, commits, or pushes.
70
+
71
+ ### Updating the plugin
72
+
73
+ ```text
74
+ /plugin update squad@gempack
75
+ ```
76
+
77
+ Then restart Claude Code.
78
+
79
+ ### Uninstalling
80
+
81
+ ```text
82
+ /plugin uninstall squad@gempack
83
+ /plugin marketplace remove gempack
84
+ ```
85
+
86
+ ## Path B — npm package (any MCP client)
87
+
88
+ Use this path for hosts that don't have a plugin marketplace (Claude Desktop, Cursor, Warp, Continue, etc.) or when you want the MCP server only without the slash commands.
89
+
90
+ > **Path B vs Path A — what each path provides:** Path A (Claude Code plugin) registers agents, skills, slash commands, and the MCP server via the plugin manifest. Path B (npm package) ships **only the MCP server** (`dist/index.js`); slash commands and native subagents are Claude Code-specific concepts and don't apply to non-Claude-Code MCP clients. Those clients access the same agent definitions via MCP `agent://…` resources or the `get_agent_definition` tool exposed by the server.
91
+ >
92
+ > If you're running Claude Code, **always prefer Path A**. Path B exists for clients without a Claude-Code plugin layer (Claude Desktop, Cursor, Warp, Continue).
93
+
94
+ The package is published as [`@gempack/squad-mcp`](https://www.npmjs.com/package/@gempack/squad-mcp). You don't need to install it globally — `npx` will fetch and cache it on first run.
95
+
96
+ ### Version pinning and provenance
97
+
98
+ The default `npx -y @gempack/squad-mcp` resolves to the latest published version on every host launch. To pin a specific version, append `@<version>`:
99
+
100
+ ```bash
101
+ npx -y @gempack/squad-mcp@0.6.0
102
+ ```
103
+
104
+ Releases are published from CI with [npm provenance](https://docs.npmjs.com/generating-provenance-statements). Verify the published tarball before configuring a host:
105
+
106
+ ```bash
107
+ npm audit signatures @gempack/squad-mcp
108
+ ```
109
+
110
+ Pin in your host config the same way (e.g. `args: ["-y", "@gempack/squad-mcp@0.6.0"]`).
111
+
112
+ > **Note:** the per-host examples below use the unpinned default (`@gempack/squad-mcp`) for readability. For production setups, replace `@gempack/squad-mcp` with `@gempack/squad-mcp@<version>` in every host's `args` array.
113
+
114
+ ### Smoke test
115
+
116
+ Verify the binary downloads and runs:
117
+
118
+ ```bash
119
+ npx -y @gempack/squad-mcp
120
+ ```
121
+
122
+ The server starts on stdio and waits silently for JSON-RPC on stdin (Ctrl+C to exit). Any error during `npx` resolution prints to stderr.
123
+
124
+ ### Claude Desktop
125
+
126
+ Edit the config file:
127
+
128
+ - **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
129
+ - **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
130
+ - **Linux:** `~/.config/Claude/claude_desktop_config.json` (unofficial — not all Claude Desktop builds support Linux). Flatpak builds sandbox `~/.config/`; check `~/.var/app/com.anthropic.Claude/config/Claude/` if the standard path doesn't load. Snap builds use `~/snap/claude/current/.config/Claude/`.
131
+
132
+ Add (or merge) the `squad` entry:
133
+
134
+ ```json
135
+ {
136
+ "mcpServers": {
137
+ "squad": {
138
+ "command": "npx",
139
+ "args": ["-y", "@gempack/squad-mcp"]
140
+ }
141
+ }
142
+ }
143
+ ```
144
+
145
+ Restart Claude Desktop. In a chat, the MCP indicator (hammer icon) should show the `squad` server with its tools.
146
+
147
+ ### Cursor
148
+
149
+ Workspace-scoped: create `.cursor/mcp.json` in the repo root.
150
+ Global: open Cursor Settings → MCP and add the same JSON.
151
+
152
+ ```json
153
+ {
154
+ "mcpServers": {
155
+ "squad": {
156
+ "command": "npx",
157
+ "args": ["-y", "@gempack/squad-mcp"]
158
+ }
159
+ }
160
+ }
161
+ ```
162
+
163
+ Reload Cursor. The `squad` server appears under Settings → MCP. Tools become callable from chat.
164
+
165
+ ### Warp
166
+
167
+ Settings → MCP servers → Add server.
168
+
169
+ - **Name:** `squad`
170
+ - **Command:** `npx`
171
+ - **Args:** `["-y", "@gempack/squad-mcp"]`. If your Warp build's UI takes a single space-separated string instead, enter `-y @gempack/squad-mcp`.
172
+
173
+ Save. The server status should turn green.
174
+
175
+ ### Continue (VS Code / JetBrains)
176
+
177
+ In `~/.continue/config.json` (or the workspace equivalent):
178
+
179
+ ```json
180
+ {
181
+ "mcpServers": {
182
+ "squad": {
183
+ "command": "npx",
184
+ "args": ["-y", "@gempack/squad-mcp"]
185
+ }
186
+ }
187
+ }
188
+ ```
189
+
190
+ Reload the Continue extension.
191
+
192
+ > Older Continue releases (pre-1.x) used `experimental.modelContextProtocolServers` with a `transport` envelope. If your build does not pick up the `mcpServers` key, check the [Continue MCP docs](https://docs.continue.dev/customize/deep-dives/mcp) for the schema your version expects.
193
+
194
+ ### Any other MCP client
195
+
196
+ Same shape. The server is a stdio MCP server. Command + args:
197
+
198
+ ```text
199
+ command: npx
200
+ args: -y @gempack/squad-mcp
201
+ ```
202
+
203
+ Most hosts accept either a JSON config block or a UI form with these two fields.
204
+
205
+ ### Faster startup / offline / corporate-proxy setups
206
+
207
+ Install once globally and reference the binary by name (avoids the per-launch `npx` resolution):
208
+
209
+ ```bash
210
+ npm install -g @gempack/squad-mcp
211
+ ```
212
+
213
+ Then in any host config, replace `command: npx` + `args: ["-y", "@gempack/squad-mcp"]` with:
214
+
215
+ ```json
216
+ {
217
+ "command": "squad-mcp",
218
+ "args": []
219
+ }
220
+ ```
221
+
222
+ This also works behind a registry proxy that rejects on-the-fly `npx` lookups.
223
+
224
+ ## Path C — From source (development)
225
+
226
+ ```bash
227
+ git clone https://github.com/ggemba/squad-mcp.git
228
+ cd squad-mcp
229
+ npm install
230
+ npm run build
231
+ node dist/index.js # speaks MCP over stdio
232
+ ```
233
+
234
+ To point a host at your local build, replace `command: npx, args: -y @gempack/squad-mcp` with:
235
+
236
+ ```json
237
+ {
238
+ "command": "node",
239
+ "args": ["/absolute/path/to/squad-mcp/dist/index.js"]
240
+ }
241
+ ```
242
+
243
+ ## Repo configuration — `.squad.yaml`
244
+
245
+ Drop a `.squad.yaml` (or `.squad.yml`) at the workspace root to override defaults per-project. Versioned with the code. Picked up automatically by the composers (`compose_squad_workflow`, `compose_advisory_bundle`).
246
+
247
+ All keys optional; partial files merge with package defaults. Cached by mtime — long-running MCP servers pick up edits without restart.
248
+
249
+ ```yaml
250
+ # .squad.yaml — example for a regulated fintech backend
251
+
252
+ # Rubric weights (must sum to 100 across the agents you list).
253
+ weights:
254
+ senior-dev-security: 30
255
+ senior-dba: 22
256
+ senior-developer: 20
257
+ senior-architect: 15
258
+ senior-qa: 13
259
+
260
+ # Per-dimension flag threshold (default 75).
261
+ threshold: 80
262
+
263
+ # Quality floor: APPROVED with weighted score below this becomes CHANGES_REQUIRED.
264
+ min_score: 75
265
+
266
+ # Files excluded from advisory.
267
+ skip_paths:
268
+ - "docs/**"
269
+ - "**/*.md"
270
+ - "**/generated/**"
271
+
272
+ # Agents not relevant for this repo.
273
+ disable_agents:
274
+ - product-owner
275
+
276
+ # Tasks store (Path D below).
277
+ tasks:
278
+ path: .squad/tasks.json
279
+ enabled: true
280
+
281
+ # Learnings store (Path E below).
282
+ learnings:
283
+ path: .squad/learnings.jsonl
284
+ max_recent: 50
285
+ enabled: true
286
+
287
+ # PR posting (used by /squad-review with PR refs).
288
+ pr_posting:
289
+ auto_post: false
290
+ request_changes_below_score: 60
291
+ omit_attribution_footer: false
292
+ ```
293
+
294
+ Validation is strict: weights must sum to 100, unknown agent names rejected, threshold/min_score 0-100. `force_agents` in tool calls still wins over `disable_agents`.
295
+
296
+ ## Path D — Using the tasks store
297
+
298
+ The squad's biggest source of token bloat is re-analysing the whole repo on every prompt. The tasks store fixes that: a PRD is decomposed into atomic tasks up front; the squad runs against ONE task's narrowed scope at a time.
299
+
300
+ **Decompose a PRD (Claude Code):**
301
+
302
+ ```
303
+ /squad-tasks docs/my-prd.md
304
+ ```
305
+
306
+ The skill:
307
+
308
+ 1. Calls `compose_prd_parse` with the PRD text.
309
+ 2. Decomposes via the host LLM (no provider keys on the server).
310
+ 3. Shows you the parsed tasks; waits for your "record".
311
+ 4. Calls `record_tasks` only after confirmation.
312
+
313
+ **Work tasks:**
314
+
315
+ ```
316
+ /squad-next # picks the highest-priority ready task
317
+ /squad-task 5 # explicit pick by id
318
+ ```
319
+
320
+ For each task, `slice_files_for_task` narrows the changed-files list to the task's `scope` glob; `compose_squad_workflow` runs against that slice with `agent_hints` as `force_agents` so only the relevant specialists wake up. When done, the skill flips status via `update_task_status`.
321
+
322
+ **CLI for non-MCP environments:**
323
+
324
+ ```bash
325
+ echo '[{"title":"Add CSRF","scope":"src/api/**"}]' | node tools/record-tasks.mjs
326
+ node tools/list-tasks.mjs --status pending
327
+ node tools/next-task.mjs --json
328
+ node tools/update-task-status.mjs --task 5 --status done
329
+ ```
330
+
331
+ The tasks file (`.squad/tasks.json` by default) is intended to live in git so the team's decomposition ships with the repo.
332
+
333
+ ## Path E — Using the learnings store
334
+
335
+ Once `/squad-review` produces a verdict, you can record per-finding decisions (accept / reject + reason) into `.squad/learnings.jsonl`. Future advisory runs read the recent tail and inject it into agent + consolidator prompts so the squad stops re-raising findings the team has already considered.
336
+
337
+ **Record a decision (Claude Code):**
338
+
339
+ ```
340
+ record reject senior-dev-security "missing CSRF on POST /api/refund"
341
+ reason: CSRF terminated at API gateway
342
+ scope: src/api/**
343
+ ```
344
+
345
+ The skill restates the decision and waits for explicit confirmation before calling `record_learning`. Per-finding authorisation is required — silence or "thanks" is not authorisation.
346
+
347
+ **CLI helper:**
348
+
349
+ ```bash
350
+ node tools/record-learning.mjs --reject \
351
+ --agent senior-dev-security \
352
+ --finding "missing CSRF on POST /api/refund" \
353
+ --reason "CSRF terminated at API gateway" \
354
+ --scope "src/api/**" \
355
+ --pr 42
356
+ ```
357
+
358
+ The journal is append-only by design — corrections are appended, never amended.
359
+
360
+ ## Path F — Posting `/squad-review` to GitHub PRs
361
+
362
+ When `/squad-review #42` runs, the verdict + scorecard can be posted to the PR via `gh pr review`. Default behaviour: dry-run + confirmation.
363
+
364
+ ```bash
365
+ echo '<consolidation JSON>' | node tools/post-review.mjs --pr 42 --dry-run
366
+ # review the body, then:
367
+ echo '<consolidation JSON>' | node tools/post-review.mjs --pr 42
368
+ ```
369
+
370
+ The CLI maps verdict → `gh` action deterministically (APPROVED → `--approve`, CHANGES_REQUIRED → `--comment`, REJECTED → `--request-changes`). Set `pr_posting.auto_post: true` in `.squad.yaml` to skip the second confirmation, but the skill still always shows the body before posting.
371
+
372
+ Inviolable: never amend or delete a posted review through this skill (re-run for a fresh review); never post `--request-changes` on a PR you do not own without explicit user instruction.
373
+
374
+ ## Local override of agent definitions
375
+
376
+ The bundled agent markdowns can be overridden without forking. The loader picks ONE local override directory:
377
+
378
+ - If `SQUAD_AGENTS_DIR` is set, that path is used **exclusively** (the platform default is not consulted).
379
+ - Otherwise: `%APPDATA%\squad-mcp\agents` on Windows, `$XDG_CONFIG_HOME/squad-mcp/agents` on Unix (falls back to `~/.config/squad-mcp/agents` if `XDG_CONFIG_HOME` is unset).
380
+
381
+ Per-file resolution: if the agent's `*.md` exists in the chosen local directory, it wins. Otherwise, the embedded default bundled in the package is used.
382
+
383
+ **Security: override files are agent system prompts.** Files in the local override directory are loaded verbatim and rendered into the LLM's context with full agent authority. Treat the directory as code:
384
+
385
+ - It must be writable only by the running user.
386
+ - Never place it on a shared volume, network mount, or world-writable path.
387
+ - `SQUAD_AGENTS_DIR` must never be set from untrusted input (env files, CI variables sourced from PRs, etc.).
388
+
389
+ ### Allowlist (since v0.4.0)
390
+
391
+ The override directory is validated at load time. It must resolve (after symlink realpath) inside one of these user-controlled prefixes:
392
+
393
+ - `os.homedir()` — your home directory
394
+ - `APPDATA` and `LOCALAPPDATA` (Windows)
395
+ - `XDG_CONFIG_HOME` or `~/.config` (Unix)
396
+ - `process.cwd()` — the host's working directory at launch
397
+
398
+ UNC paths (`\\server\share\…`) and device-namespace paths (`\\?\…`, `\\.\…`) on Windows are rejected before any filesystem access. Per-file symlinks that escape the override directory silently fall back to the embedded default for that file.
399
+
400
+ If the validation fails, the MCP server throws `OVERRIDE_REJECTED` on the first tool call that resolves an agent. The host shows the structured error so the misconfiguration surfaces immediately rather than degrading silently.
401
+
402
+ ### Escape hatch: SQUAD_AGENTS_ALLOW_UNSAFE
403
+
404
+ For power users on unusual paths (NixOS, custom CI runners, `/opt/…`), set `SQUAD_AGENTS_ALLOW_UNSAFE=1` in the environment that launches the MCP host. This bypasses the allowlist while still rejecting malformed input (NUL bytes, ADS markers, tilde-prefixed paths). Every load logs a warn-level banner so the decision stays auditable.
405
+
406
+ ### Filesystem permissions (since v0.4.0)
407
+
408
+ `init_local_config` creates the override directory and copied agent files with restrictive permissions:
409
+
410
+ - **Unix:** directory is `chmod 0o700` (user-only rwx) and each agent file is `chmod 0o600` (user-only rw). The explicit `chmod` overrides any permissive `umask`.
411
+ - **Windows:** `%APPDATA%` typically inherits a user-only DACL on stand-alone profiles, and the loader does not verify Windows ACLs at runtime. On managed, domain-joined, or VDI machines the inherited DACL may be broader; verify with `icacls "$env:APPDATA\squad-mcp\agents"` if the host is multi-user. For custom `SQUAD_AGENTS_DIR` paths outside `APPDATA`, the directory inherits the parent's DACL — set the ACL explicitly before pointing the env var there.
412
+
413
+ `agent-loader` checks the resolved override directory at startup and emits a `warn`-level log once per process if it is world-writable (`mode & 0o002 !== 0` on Unix). To remediate:
414
+
415
+ ```bash
416
+ chmod 700 "$SQUAD_AGENTS_DIR"
417
+ chmod 600 "$SQUAD_AGENTS_DIR"/*.md
418
+ ```
419
+
420
+ The warning does not block the override — it is advisory. Override files are still loaded and used.
421
+
422
+ Seed the local directory with editable copies:
423
+
424
+ ```text
425
+ Call the `init_local_config` MCP tool from your host.
426
+ ```
427
+
428
+ Then edit any `*.md` in that directory. Restart the host (or reconnect the MCP server) to pick up changes.
429
+
430
+ ## Optional hardening — commit-suggest skill
431
+
432
+ The `commit-suggest` skill is read-only by spec and never adds AI co-author trailers, but the rule is enforced at the prompt layer only — a sufficiently adversarial prompt-injection or model regression could violate it. For repos where you want a structural guarantee, install the bundled `commit-msg` hook:
433
+
434
+ ```bash
435
+ # Per-repo install
436
+ cp tools/git-hooks/commit-msg .git/hooks/commit-msg
437
+ chmod +x .git/hooks/commit-msg
438
+
439
+ # Or repo-wide enforcement on every clone (preferred):
440
+ git config core.hooksPath tools/git-hooks
441
+ ```
442
+
443
+ The hook rejects any commit whose message contains `Co-Authored-By: Claude/Anthropic/GPT/OpenAI/Gemini/Copilot/AI`, `Generated with [Claude Code]`, `Made by AI`, or `<noreply@anthropic.com>` trailers. Comment lines (`#`-prefixed) are ignored so commit-message templates can still document the rule.
444
+
445
+ For host-level enforcement of read-only behavior during `/commit-suggest` invocations, add a `permissions.deny` block to your Claude Code project settings. Example `.claude/settings.json` snippet:
446
+
447
+ ```json
448
+ {
449
+ "permissions": {
450
+ "deny": [
451
+ "Bash(git commit*)",
452
+ "Bash(git add*)",
453
+ "Bash(git push*)",
454
+ "Bash(git reset*)",
455
+ "Bash(git rebase*)",
456
+ "Bash(git merge*)",
457
+ "Bash(git checkout*)",
458
+ "Bash(git switch*)",
459
+ "Bash(git stash*)",
460
+ "Bash(git tag*)",
461
+ "Bash(git branch*)",
462
+ "Bash(git apply*)",
463
+ "Bash(git cherry-pick*)",
464
+ "Bash(git revert*)",
465
+ "Bash(git rm*)",
466
+ "Bash(git mv*)",
467
+ "Bash(git restore*)",
468
+ "Bash(git clean*)",
469
+ "Bash(git update-ref*)"
470
+ ]
471
+ }
472
+ }
473
+ ```
474
+
475
+ Both layers compose: prompt rule, `permissions.deny`, and the `commit-msg` hook. A tampered skill or a prompt-injection attempt has to defeat all three.
476
+
477
+ ## Bundled skills
478
+
479
+ The plugin ships these skills under `skills/` (auto-registered when the plugin is enabled):
480
+
481
+ | Skill | Trigger | Purpose |
482
+ | ---------------- | ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
483
+ | `squad` | `/squad <task>`, `/squad-review [tgt]`, `/squad-tasks <prd>`, `/squad-next`, `/squad-task <id>` | Single skill, three modes. Implement runs the full orchestration. Review runs the advisory portion only on an existing diff/branch/PR. Tasks decomposes a PRD into atomic tasks and runs the squad on one task's scope at a time. |
484
+ | `commit-suggest` | `/commit-suggest` | Read-only Conventional Commits message suggester. No AI co-author trailers. |
485
+ | `brainstorm` | `/brainstorm <topic>` | Pre-implementation exploration. Web research + multi-agent perspectives + options matrix with cited sources. Produces no code. |
486
+
487
+ Workflow positioning:
488
+
489
+ ```
490
+ /brainstorm -> decide what to build (research + options)
491
+ v
492
+ /squad -> implement what was decided
493
+ v
494
+ /squad-review -> review what was implemented
495
+ v
496
+ /commit-suggest -> craft the commit message
497
+ ```
498
+
499
+ `/brainstorm` examples:
500
+
501
+ ```
502
+ /brainstorm choosing between SQLite and PostgreSQL for a desktop app
503
+ -> Default depth: medium (~6 web queries + 2-3 agents)
504
+
505
+ /brainstorm --depth deep how to design idempotent payment retries
506
+ -> 10+ queries + 4 agents + tech-lead consolidator
507
+
508
+ /brainstorm --no-web should we extract this module into a separate package
509
+ -> Agents-only (offline / repo-internal topic)
510
+
511
+ /brainstorm --focus security how to store API keys in a desktop app
512
+ -> Forces senior-dev-security as the primary specialist
513
+ ```
514
+
515
+ ## Verification checklist
516
+
517
+ After install, regardless of host:
518
+
519
+ - [ ] `squad` MCP server shows as connected in the host's MCP settings.
520
+ - [ ] `list_agents` tool returns 9 agents (names: `product-owner`, `tech-lead-planner`, `tech-lead-consolidator`, `senior-architect`, `senior-dba`, `senior-developer`, `senior-dev-reviewer`, `senior-dev-security`, `senior-qa`).
521
+ - [ ] `compose_squad_workflow` with arguments `{"workspace_root": "<absolute path to a git repo>", "user_prompt": "smoke"}` returns `work_type`, `risk`, `squad.agents`. Requires a git repo with at least one prior commit (the tool defaults `base_ref` to `HEAD~1` internally). **`workspace_root` must be an absolute path** — relative paths are rejected with `PATH_INVALID`.
522
+ - [ ] Resources `agent://senior-architect` and `severity://_severity-and-ownership` are readable.
523
+ - [ ] (Claude Code only) `/squad`, `/squad-review`, `/brainstorm`, and `/commit-suggest` autocomplete.
524
+
525
+ ## Troubleshooting
526
+
527
+ **`/plugin marketplace add` fails with "not found".**
528
+ Make sure you typed `ggemba/squad-mcp` exactly. The marketplace manifest lives at `.claude-plugin/marketplace.json` on the `main` branch of that repo.
529
+
530
+ **Plugin installed but `/squad` does not appear.**
531
+ Restart Claude Code. The slash command registry is populated at startup. If still missing, run `/plugin list` and confirm `squad@gempack` is listed and enabled.
532
+
533
+ **MCP server shows as failed / disconnected.**
534
+ Check the host's MCP log:
535
+
536
+ - Claude Code: Help → Show Logs → MCP.
537
+ - Claude Desktop: `%APPDATA%\Claude\logs\mcp-server-squad.log` (Windows), `~/Library/Logs/Claude/mcp-server-squad.log` (macOS), `~/.config/Claude/logs/mcp-server-squad.log` (Linux — note that Claude Desktop on Linux is unofficial; verify your build).
538
+
539
+ The log can include workspace file paths and `git diff` output. Review and redact before sharing for support.
540
+
541
+ Common causes: Node not on `PATH`, corporate proxy blocking npm, or `npx` cache permission errors. Run `npx -y @gempack/squad-mcp` in a terminal to surface the real error.
542
+
543
+ **`detect_changed_files` returns an error.**
544
+ The tool runs `git diff --name-status --no-renames` (renames are reported as add+delete pairs) and is hardened: 10s timeout, 1MB stdout cap, allowlisted subcommands only. Verify `git --version` works and the workspace is a git repo. Refs must satisfy: matches `^[a-zA-Z0-9_/][a-zA-Z0-9_./-]*$`, max 200 chars, no leading `-`, no trailing `.`, must not contain `..`, `@{`, or `.lock`.
545
+
546
+ **Tools work but the agents look wrong.**
547
+ You probably have a stale local override. If `SQUAD_AGENTS_DIR` is set, only that directory is consulted; otherwise check `%APPDATA%\squad-mcp\agents` (Windows) or `$XDG_CONFIG_HOME/squad-mcp/agents` / `~/.config/squad-mcp/agents` (Unix). Delete or edit the file — the loader prefers the local copy over the bundled defaults.
548
+
549
+ **Tools missing on Cursor / Warp after editing JSON.**
550
+ Both hosts cache the MCP server list. Fully quit and relaunch (not just reload window).
551
+
552
+ ## Where to file issues
553
+
554
+ <https://github.com/ggemba/squad-mcp/issues> — include host name + version, OS, Node version, and the relevant log excerpt.