@gempack/squad-mcp 0.3.1 → 0.5.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.
@@ -12,7 +12,7 @@
12
12
  "repo": "ggemba/squad-mcp"
13
13
  },
14
14
  "description": "Squad-dev workflow: deterministic classification, risk scoring, agent selection, advisory orchestration over MCP, plus /squad and /squad-review slash commands.",
15
- "version": "0.3.1",
15
+ "version": "0.4.0",
16
16
  "license": "Apache-2.0",
17
17
  "homepage": "https://github.com/ggemba/squad-mcp"
18
18
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "squad",
3
- "version": "0.3.1",
3
+ "version": "0.5.0",
4
4
  "description": "Squad-dev workflow as a Claude Code plugin: classification, risk scoring, agent selection, advisory orchestration. Bundles an MCP server and the /squad and /squad-review slash commands.",
5
5
  "license": "Apache-2.0",
6
6
  "author": {
@@ -11,6 +11,7 @@
11
11
  "repository": "https://github.com/ggemba/squad-mcp",
12
12
  "keywords": ["mcp", "squad-dev", "code-review", "advisory", "agent"],
13
13
  "commands": "./commands/",
14
+ "skills": "./skills/",
14
15
  "mcpServers": {
15
16
  "squad": {
16
17
  "command": "node",
package/CHANGELOG.md CHANGED
@@ -7,13 +7,155 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- Planned for `0.4.0`:
10
+ Planned for a future minor:
11
11
 
12
12
  - Promote bundled agent markdowns to Claude Code native plugin agents (rename to
13
13
  kebab-case + add YAML frontmatter), with a migration path for existing
14
14
  `%APPDATA%\squad-mcp\agents` overrides.
15
15
  - Retire the legacy `/squad` and `/squad-review` skills now that the plugin
16
16
  ships them as slash commands.
17
+ - Extract `tools/sync-agents.mjs` helpers into a `tools/sync/` module
18
+ (`baseline-store.mjs`, `safe-copy.mjs`, `agents.mjs`, `skills.mjs`) once a
19
+ third sync target lands.
20
+ - Streaming SHA-256 over `fs.createReadStream` for skill files larger than a
21
+ threshold (avoids `readFileSync` doubling memory on large bundled assets).
22
+ - Property-based tests for `hasPathSeparator` and the tri-state baseline
23
+ policy state machine via `fast-check`.
24
+
25
+ ## [0.5.0] - 2026-05-04
26
+
27
+ ### Added
28
+
29
+ - **`Senior-Dev-Reviewer` weighted scorecard.** Reviewer agent now produces a
30
+ numeric scorecard (0–10 per dimension, weighted average overall) across Code
31
+ Quality 20%, Security 20%, Maintainability 20%, Performance 20%,
32
+ Async/Concurrency 8%, Error Handling 7%, Architecture Fit 5%. Includes
33
+ per-stack idiomatic checklists for the top 5 backend (C#/.NET, Python, Java,
34
+ Go, Node.js) and top 5 frontend (TypeScript, React, Vue, Angular, Svelte)
35
+ stacks with auto-detection. Severity table drives the scorecard penalty.
36
+ Dimensions lacking diff evidence are reported as `N/A` rather than zero.
37
+ - **`brainstorm` skill.** Collaborative pre-implementation exploration. Takes a
38
+ problem, decision, or implementation idea; runs deep web research in parallel
39
+ (market patterns, best practices, pitfalls, examples); spawns specialist
40
+ agents for multi-domain perspectives; synthesizes findings into a sourced
41
+ options matrix with a recommendation. Exploratory only — produces no code or
42
+ file changes. Position in the workflow: `/brainstorm` decides *what* to
43
+ build; `/squad` implements; `/squad-review` reviews. Triggered via
44
+ `/brainstorm` or natural-language asks ("brainstorm", "research approaches",
45
+ "explore options", "what does the industry use"). Supports `--depth
46
+ quick|medium|deep`, `--no-web`, `--focus <domain>`, and `--sources <N>`.
47
+ - **`commit-suggest` skill.** Read-only Conventional Commits message suggester.
48
+ Runs only an allowlist of git commands (`status`, `diff`, `log`, `rev-parse`,
49
+ `config --get`, `ls-files`, `show <ref>:<path>`); never executes any
50
+ state-mutating git command; never adds AI co-author trailers. Output is text
51
+ only — the user runs the commit themselves. Triggered via `/commit-suggest`
52
+ or natural-language asks ("suggest a commit", "commit message").
53
+ - **Plugin manifest exports `skills/`**. The `commit-suggest` skill (and any
54
+ future skill bundled under `skills/`) is auto-registered when the plugin is
55
+ enabled in Claude Code.
56
+ - **`tools/git-hooks/commit-msg`**. Optional opt-in hook that rejects commits
57
+ whose messages contain AI-attribution trailers (`Co-Authored-By: Claude /
58
+ Anthropic / GPT / OpenAI / Gemini / Copilot / AI`, `Generated with [Claude
59
+ Code]`, `Made by AI`, `<noreply@anthropic.com>`). Install via `cp` to
60
+ `.git/hooks/` or repo-wide via `git config core.hooksPath tools/git-hooks`.
61
+ - **`tools/sync-agents.mjs` skills sync.** Mirrors bundled skills to
62
+ `~/.claude/skills/` for non-plugin clients (Claude Desktop, Cursor, Warp).
63
+ Recursive walker; baseline-hash store at `~/.claude/skills/.bundle-hashes.json`
64
+ with versioned envelope (`{version: 1, baselines: {...}}`); tri-state policy
65
+ (identical / stale-baseline / user-modified) preserves user edits with a
66
+ `skip-with-warning` log; symlink refusal at source, destination, leaf, and
67
+ baseline-file layers; containment assert against escape-via-skill-name;
68
+ `COPYFILE_EXCL` race guard with EEXIST recurse fallback; mode `0o600` on
69
+ baseline file (Unix); atomic temp+rename writes; non-zero exit on
70
+ `skillsFailed > 0`.
71
+ - **`tools/sync-agents.mjs` agents sync hardening.** Symmetric symlink-at-
72
+ destination defense for the agents path: refuses to write through a symlinked
73
+ `~/.claude/agents/<file>.md` (matches the existing skills behavior).
74
+ - **8 integration tests** for the skills sync (`tests/sync-agents.test.ts`):
75
+ cold sync + baseline persistence, bundle update overwrites stale dst, user
76
+ edits preserved, symlink-dst refused (Unix-only), corrupt baseline graceful
77
+ fallback, idempotent rerun, HOME/USERPROFILE guard.
78
+
79
+ ### Changed
80
+
81
+ - **Global `~/.claude/CLAUDE.md` rule** (user-side, not shipped): commits
82
+ produced or suggested by Claude must never carry AI-attribution trailers.
83
+
84
+ ### Documentation
85
+
86
+ - **`INSTALL.md` Path B note**: documents that npm-package users must run
87
+ `node tools/sync-agents.mjs` to mirror agents and skills to `~/.claude/`,
88
+ and that the manual sync is idempotent.
89
+ - **`INSTALL.md` Optional hardening section**: documents how to install the
90
+ `commit-msg` hook and a recommended `permissions.deny` block in
91
+ `.claude/settings.json` for structural enforcement of the read-only invariant.
92
+ - **`INSTALL.md` baseline file note**: documents that
93
+ `~/.claude/skills/.bundle-hashes.json` is installer state and should not be
94
+ edited or deleted manually.
95
+
96
+ ## [0.4.0] - 2026-05-02
97
+
98
+ ### Security
99
+
100
+ - **BREAKING:** `SQUAD_AGENTS_DIR` is now validated against an allowlist of
101
+ user-controlled prefixes (`HOME`, `APPDATA`, `LOCALAPPDATA`, `XDG_CONFIG_HOME`,
102
+ `process.cwd()`). Override directories outside the allowlist are rejected with
103
+ a new structured `OVERRIDE_REJECTED` error. UNC and device-namespace paths on
104
+ Windows (`\\?\…`, `\\.\…`, `\\server\share\…`) are rejected before any
105
+ filesystem access. Migration: move the directory under one of the allowed
106
+ prefixes, or set `SQUAD_AGENTS_ALLOW_UNSAFE=1` to bypass the allowlist (logs a
107
+ warn-level banner once per process).
108
+ - **BREAKING:** Per-file resolution now realpath-checks each agent file. If a
109
+ file inside the override directory is a symlink whose target escapes the
110
+ directory, that file silently falls back to the embedded default — preserving
111
+ the operator's per-file customizations while blocking the symlink-out
112
+ primitive.
113
+ - Lexical AND realpath checks are both required for an override directory to
114
+ match the allowlist (closes the lexical-allowed-but-symlinked-out bypass).
115
+ - `init_local_config` now creates the override directory with mode `0o700` and
116
+ copied agent files with mode `0o600` on Unix (`fs.chmod` after `mkdir` /
117
+ `copyFile` to override the umask). Windows relies on `%APPDATA%`'s default
118
+ user-only DACL; custom paths outside `APPDATA` on Windows fall back to the
119
+ parent directory's DACL — document and use with care.
120
+ - `agent-loader` warns once per process if the resolved override directory is
121
+ world-writable (`mode & 0o002 !== 0`). Group-writable does not trigger the
122
+ warning (single-user-host convention). Skipped on Windows since `fs.stat`
123
+ does not surface DACL semantics.
124
+
125
+ ### Added
126
+
127
+ - `src/util/override-allowlist.ts` — new module exposing `validateOverrideDir`
128
+ and `validateOverrideFile`.
129
+ - `src/util/path-internal.ts` — extracted shared helpers (`rejectIfMalformed`,
130
+ `realpathOrSelf`) reused by `path-safety` and `override-allowlist`.
131
+ - `OVERRIDE_REJECTED` added to `SquadErrorCode`.
132
+ - `SQUAD_AGENTS_ALLOW_UNSAFE=1` opt-in escape hatch for power users / CI on
133
+ unusual paths.
134
+ - `tests/agent-loader.test.ts` and `tests/override-allowlist.test.ts` covering
135
+ the accept/reject matrix, escape hatch, agent-name traversal guard, symlink
136
+ escape, and Unix filesystem permissions (`0o700` dir, `0o600` files,
137
+ world-writable warn-once).
138
+
139
+ ### Changed
140
+
141
+ - `agent-loader` now logs a structured `agent override active` line on first
142
+ resolution with `resolved_path`, `allowlist_match`, `has_unsafe_override`,
143
+ `source` (`env` vs `platform_default`). Escape-hatch resolutions log at
144
+ `warn` instead of `info`.
145
+ - `getLocalDir()` now returns `{ rawDir, explicit }` — the `list_agents` tool
146
+ output exposes both `local_dir` (the raw path) and `local_dir_explicit`.
147
+
148
+ ### Migration
149
+
150
+ - If you set `SQUAD_AGENTS_DIR` to a path under your home / APPDATA / XDG dir,
151
+ no action is needed.
152
+ - If you set it to `/opt/...`, `/srv/...`, a CI runner path, or any other
153
+ location outside those prefixes, you have two options:
154
+ 1. Move the directory under `~/`, `~/AppData/Local/`, `~/.config/`, or your
155
+ project's working directory.
156
+ 2. Set `SQUAD_AGENTS_ALLOW_UNSAFE=1` in the environment that launches the MCP
157
+ host. This bypasses the allowlist and logs a warning on every process
158
+ start so the choice stays auditable.
17
159
 
18
160
  ## [0.3.1] - 2026-05-02
19
161
 
@@ -276,7 +418,9 @@ update at commit `052c2ad`.
276
418
  - Smoke test (`tests/smoke.mjs`) plus initial unit tests for `score_risk`,
277
419
  `select_squad`, `consolidate`.
278
420
 
279
- [Unreleased]: https://github.com/ggemba/squad-mcp/compare/v0.3.1...HEAD
421
+ [Unreleased]: https://github.com/ggemba/squad-mcp/compare/v0.5.0...HEAD
422
+ [0.5.0]: https://github.com/ggemba/squad-mcp/releases/tag/v0.5.0
423
+ [0.4.0]: https://github.com/ggemba/squad-mcp/releases/tag/v0.4.0
280
424
  [0.3.1]: https://github.com/ggemba/squad-mcp/releases/tag/v0.3.1
281
425
  [0.3.0]: https://github.com/ggemba/squad-mcp/releases/tag/v0.3.0
282
426
  [0.1.0]: https://github.com/ggemba/squad-mcp/commit/548adc2
package/INSTALL.md ADDED
@@ -0,0 +1,422 @@
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
+ - 12 deterministic MCP tools (Claude Code exposes them as `mcp__squad__*`; other hosts may use a different prefix)
8
+ - 12 MCP resources (`agent://*`, `severity://*`)
9
+ - 3 MCP prompts (`squad_orchestration`, `agent_advisory`, `consolidator`)
10
+ - 2 slash commands (`/squad`, `/squad-review`) — Claude Code only
11
+
12
+ ## Prerequisites
13
+
14
+ - 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.
15
+ - A host that speaks MCP (Claude Code, Claude Desktop, Cursor, Warp, Continue, …)
16
+ - Git available on `PATH` (used by `detect_changed_files`)
17
+
18
+ Verify Node:
19
+
20
+ ```bash
21
+ node --version # v20+
22
+ ```
23
+
24
+ ## Path A — Claude Code plugin (recommended)
25
+
26
+ The plugin bundles the MCP server, the slash commands, and the agent definitions behind a single install. No JSON config to edit.
27
+
28
+ 1. **Add the marketplace.** In a Claude Code session, paste:
29
+
30
+ ```text
31
+ /plugin marketplace add ggemba/squad-mcp
32
+ ```
33
+
34
+ Wait for `marketplace added`.
35
+
36
+ 2. **Install the plugin.**
37
+
38
+ ```text
39
+ /plugin install squad@gempack
40
+ ```
41
+
42
+ Wait for `plugin installed`.
43
+
44
+ 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.
45
+
46
+ 4. **Verify the install.** In a fresh prompt:
47
+
48
+ - Type `/squad ` (with the trailing space) — the autocomplete should suggest `/squad <task description>`.
49
+ - Type `/squad-review` — same check.
50
+ - Open Settings → MCP. You should see `squad` listed and connected.
51
+ - Ask Claude to call the `list_agents` tool from the `squad` MCP server. It should return 9 agents (`po`, `tech-lead-planner`, `tech-lead-consolidator`, `senior-architect`, `senior-dba`, `senior-developer`, `senior-dev-reviewer`, `senior-dev-security`, `senior-qa`).
52
+
53
+ 5. **Use it.**
54
+
55
+ ```text
56
+ /squad add a /health endpoint that returns build SHA and uptime
57
+ /squad-review
58
+ /squad-review 1234 # PR number
59
+ /squad-review feature/x # branch
60
+ ```
61
+
62
+ `/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.
63
+
64
+ ### Updating the plugin
65
+
66
+ ```text
67
+ /plugin update squad@gempack
68
+ ```
69
+
70
+ Then restart Claude Code.
71
+
72
+ ### Uninstalling
73
+
74
+ ```text
75
+ /plugin uninstall squad@gempack
76
+ /plugin marketplace remove gempack
77
+ ```
78
+
79
+ ## Path B — npm package (any MCP client)
80
+
81
+ 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.
82
+
83
+ > **Path B vs Path A — what gets installed:** the npm package ships **only the MCP server** (`dist/index.js`). The bundled agents (`agents/*.md`), shared docs (`agents/_squad-shared/`), and skills (`skills/*/SKILL.md`) are **not** auto-mirrored to `~/.claude/` by `npx`. Path A (Claude Code plugin) registers them via the manifest; Path B users who want the slash commands and skills materialized in `~/.claude/agents/` and `~/.claude/skills/` must run the bundled sync script after installing:
84
+ >
85
+ > ```bash
86
+ > # From a checkout of https://github.com/ggemba/squad-mcp at the matching tag:
87
+ > node tools/sync-agents.mjs
88
+ > ```
89
+ >
90
+ > The sync is idempotent. Re-running it preserves any skill files you have edited locally (skip-with-warning policy). Delete a skill file under `~/.claude/skills/<name>/` (losing your edits) to receive the next bundled update.
91
+ >
92
+ > The script maintains a `~/.claude/skills/.bundle-hashes.json` baseline file that records the hash of the last bundled version of each skill file. It distinguishes "unmodified prior bundle" (overwrite on update) from "user-modified" (preserve with warning). Do **not** edit or delete this file manually — deleting it forces all existing skills to be classified as user-modified until they happen to match a future bundle.
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.4.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.4.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)
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
+ ## Local override of agent definitions
244
+
245
+ The bundled agent markdowns can be overridden without forking. The loader picks ONE local override directory:
246
+
247
+ - If `SQUAD_AGENTS_DIR` is set, that path is used **exclusively** (the platform default is not consulted).
248
+ - 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).
249
+
250
+ 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.
251
+
252
+ **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:
253
+
254
+ - It must be writable only by the running user.
255
+ - Never place it on a shared volume, network mount, or world-writable path.
256
+ - `SQUAD_AGENTS_DIR` must never be set from untrusted input (env files, CI variables sourced from PRs, etc.).
257
+
258
+ ### Allowlist (since v0.4.0)
259
+
260
+ The override directory is validated at load time. It must resolve (after symlink realpath) inside one of these user-controlled prefixes:
261
+
262
+ - `os.homedir()` — your home directory
263
+ - `APPDATA` and `LOCALAPPDATA` (Windows)
264
+ - `XDG_CONFIG_HOME` or `~/.config` (Unix)
265
+ - `process.cwd()` — the host's working directory at launch
266
+
267
+ 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.
268
+
269
+ 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.
270
+
271
+ ### Escape hatch: SQUAD_AGENTS_ALLOW_UNSAFE
272
+
273
+ 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.
274
+
275
+ ### Filesystem permissions (since v0.4.0)
276
+
277
+ `init_local_config` creates the override directory and copied agent files with restrictive permissions:
278
+
279
+ - **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`.
280
+ - **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.
281
+
282
+ `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:
283
+
284
+ ```bash
285
+ chmod 700 "$SQUAD_AGENTS_DIR"
286
+ chmod 600 "$SQUAD_AGENTS_DIR"/*.md
287
+ ```
288
+
289
+ The warning does not block the override — it is advisory. Override files are still loaded and used.
290
+
291
+ Seed the local directory with editable copies:
292
+
293
+ ```text
294
+ Call the `init_local_config` MCP tool from your host.
295
+ ```
296
+
297
+ Then edit any `*.md` in that directory. Restart the host (or reconnect the MCP server) to pick up changes.
298
+
299
+ ## Optional hardening — commit-suggest skill
300
+
301
+ 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:
302
+
303
+ ```bash
304
+ # Per-repo install
305
+ cp tools/git-hooks/commit-msg .git/hooks/commit-msg
306
+ chmod +x .git/hooks/commit-msg
307
+
308
+ # Or repo-wide enforcement on every clone (preferred):
309
+ git config core.hooksPath tools/git-hooks
310
+ ```
311
+
312
+ 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.
313
+
314
+ 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:
315
+
316
+ ```json
317
+ {
318
+ "permissions": {
319
+ "deny": [
320
+ "Bash(git commit*)",
321
+ "Bash(git add*)",
322
+ "Bash(git push*)",
323
+ "Bash(git reset*)",
324
+ "Bash(git rebase*)",
325
+ "Bash(git merge*)",
326
+ "Bash(git checkout*)",
327
+ "Bash(git switch*)",
328
+ "Bash(git stash*)",
329
+ "Bash(git tag*)",
330
+ "Bash(git branch*)",
331
+ "Bash(git apply*)",
332
+ "Bash(git cherry-pick*)",
333
+ "Bash(git revert*)",
334
+ "Bash(git rm*)",
335
+ "Bash(git mv*)",
336
+ "Bash(git restore*)",
337
+ "Bash(git clean*)",
338
+ "Bash(git update-ref*)"
339
+ ]
340
+ }
341
+ }
342
+ ```
343
+
344
+ 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.
345
+
346
+ ## Bundled skills
347
+
348
+ The plugin ships these skills under `skills/` (auto-registered when the plugin is enabled, or mirrored to `~/.claude/skills/` via `node tools/sync-agents.mjs` for non-plugin clients):
349
+
350
+ | Skill | Trigger | Purpose |
351
+ |-------|---------|---------|
352
+ | `commit-suggest` | `/commit-suggest` | Read-only Conventional Commits message suggester. No AI co-author trailers. |
353
+ | `brainstorm` | `/brainstorm <topic>` | Pre-implementation exploration. Web research + multi-agent perspectives + options matrix with cited sources. Produces no code. |
354
+
355
+ Workflow positioning:
356
+
357
+ ```
358
+ /brainstorm -> decide what to build (research + options)
359
+ v
360
+ /squad -> implement what was decided
361
+ v
362
+ /squad-review -> review what was implemented
363
+ v
364
+ /commit-suggest -> craft the commit message
365
+ ```
366
+
367
+ `/brainstorm` examples:
368
+
369
+ ```
370
+ /brainstorm choosing between SQLite and PostgreSQL for a desktop app
371
+ -> Default depth: medium (~6 web queries + 2-3 agents)
372
+
373
+ /brainstorm --depth deep how to design idempotent payment retries
374
+ -> 10+ queries + 4 agents + tech-lead consolidator
375
+
376
+ /brainstorm --no-web should we extract this module into a separate package
377
+ -> Agents-only (offline / repo-internal topic)
378
+
379
+ /brainstorm --focus security how to store API keys in a desktop app
380
+ -> Forces senior-dev-security as the primary specialist
381
+ ```
382
+
383
+ ## Verification checklist
384
+
385
+ After install, regardless of host:
386
+
387
+ - [ ] `squad` MCP server shows as connected in the host's MCP settings.
388
+ - [ ] `list_agents` tool returns 9 agents.
389
+ - [ ] `compose_squad_workflow` with arguments `{"workspace_root": ".", "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).
390
+ - [ ] Resources `agent://senior-architect` and `severity://_severity-and-ownership` are readable.
391
+ - [ ] (Claude Code only) `/squad` and `/squad-review` autocomplete.
392
+
393
+ ## Troubleshooting
394
+
395
+ **`/plugin marketplace add` fails with "not found".**
396
+ Make sure you typed `ggemba/squad-mcp` exactly. The marketplace manifest lives at `.claude-plugin/marketplace.json` on the `main` branch of that repo.
397
+
398
+ **Plugin installed but `/squad` does not appear.**
399
+ 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.
400
+
401
+ **MCP server shows as failed / disconnected.**
402
+ Check the host's MCP log:
403
+
404
+ - Claude Code: Help → Show Logs → MCP.
405
+ - 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).
406
+
407
+ The log can include workspace file paths and `git diff` output. Review and redact before sharing for support.
408
+
409
+ 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.
410
+
411
+ **`detect_changed_files` returns an error.**
412
+ 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`.
413
+
414
+ **Tools work but the agents look wrong.**
415
+ 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.
416
+
417
+ **Tools missing on Cursor / Warp after editing JSON.**
418
+ Both hosts cache the MCP server list. Fully quit and relaunch (not just reload window).
419
+
420
+ ## Where to file issues
421
+
422
+ <https://github.com/ggemba/squad-mcp/issues> — include host name + version, OS, Node version, and the relevant log excerpt.