@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
@@ -11,8 +11,8 @@
11
11
  "source": "github",
12
12
  "repo": "ggemba/squad-mcp"
13
13
  },
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",
14
+ "description": "Squad-dev workflow: deterministic classification, risk scoring, agent selection, advisory orchestration over MCP, native subagents, plus /squad and /squad-review slash commands.",
15
+ "version": "0.6.0",
16
16
  "license": "Apache-2.0",
17
17
  "homepage": "https://github.com/ggemba/squad-mcp"
18
18
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "squad",
3
- "version": "0.3.1",
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.",
3
+ "version": "0.6.0",
4
+ "description": "Squad-dev workflow as a Claude Code plugin: classification, risk scoring, agent selection, advisory orchestration. Bundles an MCP server, native subagents, and the /squad and /squad-review slash commands.",
5
5
  "license": "Apache-2.0",
6
6
  "author": {
7
7
  "name": "Gustavo",
@@ -10,7 +10,9 @@
10
10
  "homepage": "https://github.com/ggemba/squad-mcp#readme",
11
11
  "repository": "https://github.com/ggemba/squad-mcp",
12
12
  "keywords": ["mcp", "squad-dev", "code-review", "advisory", "agent"],
13
+ "agents": "./agents/",
13
14
  "commands": "./commands/",
15
+ "skills": "./skills/",
14
16
  "mcpServers": {
15
17
  "squad": {
16
18
  "command": "node",
package/CHANGELOG.md CHANGED
@@ -7,13 +7,398 @@ 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
+ ### Added — Tasks: PRD-decomposed atomic work units (anti-bloat for the squad)
11
+
12
+ Borrows the core idea from claude-task-master and adapts it to squad-mcp's primitives. A PRD is decomposed by the host LLM into atomic tasks; each task carries optional `scope` (glob) and `agent_hints`; the squad runs against ONE task's scope at a time. Less context per pass, fewer tokens, less drift.
13
+
14
+ - `src/tasks/store.ts` — mutable JSON store with mtime-keyed cache, atomic write (tmp + rename), stable id-sorted serialisation. Schema (zod): `{ id, title, description, status, dependencies, priority, details, test_strategy, scope?, agent_hints?, subtasks[], created_at, updated_at }`. Status: pending / in-progress / review / done / blocked / cancelled. Schema-versioned (`version: 1`) so future breaking changes can ship cleanly.
15
+ - `src/tasks/select.ts` — pure helpers. `listTasks` filters by status / agent / scope. `nextTask` does topo-aware selection: candidate status (default pending), all deps in done_statuses, optional agent + changed_files filter; tiebreak priority then id; returns a structured result with `reason: no_candidates | all_blocked | ok` + the blocked list (so callers can show "X is next when Y completes").
16
+ - 7 new MCP tools:
17
+ - `list_tasks`, `next_task`, `record_tasks`, `update_task_status`, `expand_task`, `slice_files_for_task` — the data-plane operations.
18
+ - `compose_prd_parse` — pure-MCP composer that builds a prompt + JSON schema for the host LLM to decompose a PRD. Server does NO LLM calls; the host already has provider keys and user consent. Includes existing tasks in the prompt so the LLM doesn't duplicate.
19
+ - New `.squad.yaml` section `tasks`:
20
+ - `path` (default `.squad/tasks.json`)
21
+ - `enabled` (default true — turn off to silence reads without deleting the file; writes stay open, matching the learnings policy)
22
+ - `tools/{list-tasks,next-task,record-tasks,update-task-status}.mjs` — non-MCP CLI helpers sharing a tiny `tools/_tasks-io.mjs` module. Run anywhere with node 18+.
23
+ - `skills/squad/SKILL.md` adds:
24
+ - **Phase 0.5 — Decompose PRD into tasks** (task-mode only). Build prompt → run LLM → preview → user-confirm → `record_tasks`. Inviolable: never bulk-record without per-list confirmation, never invent dependencies, never alter ids the user reviewed.
25
+ - **Phase 0.6 — Pick a task** via `/squad-next` or `/squad-task <id>`. Slice files via `slice_files_for_task`, narrow squad via the task's `agent_hints`, run normal advisory. When done, flip status via `update_task_status`.
26
+ - 38 new tests cover store (read / record / update / expand / cache invalidation / on-disk format) and select (filter / topo / priority tiebreak / blocked surfacing). Smoke test now verifies 23 tools (was 16).
27
+
28
+ ### Added — Learning JSONL: persistent accept/reject memory
29
+
30
+ Closes the squad's biggest UX gap: re-running review on the same repo no
31
+ longer re-raises findings the team already considered and rejected (with
32
+ reason). Every accept/reject decision becomes one append-only line in
33
+ `.squad/learnings.jsonl`, versioned in git, surfaced as a markdown block
34
+ injected into the next run's agent and consolidator prompts.
35
+
36
+ - `src/learning/store.ts` — JSONL store with mtime-keyed cache.
37
+ `readLearnings`, `appendLearning`, and `tailRecent` (filterable by agent
38
+ / decision). Schema: `{ ts, pr?, branch?, agent, severity?, finding,
39
+ decision, reason?, scope? }`. Schema violations on read are loud
40
+ rejections — silent corruption is worse.
41
+ - `src/learning/format.ts` — pure formatter rendering a most-recent-first
42
+ numbered list under a `## Past team decisions` heading. Filters scoped
43
+ entries by glob match against `changedFiles`; entries without a scope
44
+ are repo-wide and always pass. Returns `''` when no entries qualify
45
+ (callers check before injecting — no empty headers in prompts).
46
+ - New tool `read_learnings` — load, filter (agent / decision / scope),
47
+ return both raw entries and the rendered markdown block. Honors the
48
+ master switch `learnings.enabled` from `.squad.yaml`.
49
+ - New tool `record_learning` — append a decision. Side-effecting; the
50
+ skill (or CLI) is responsible for user confirmation per finding.
51
+ - New `.squad.yaml` section `learnings`:
52
+ - `path` (default `.squad/learnings.jsonl`)
53
+ - `max_recent` (default 50, hard cap 200)
54
+ - `enabled` (default true — turn off to disable injection without
55
+ deleting the journal)
56
+ - `tools/record-learning.mjs` — CLI helper for non-MCP clients. Direct
57
+ JSONL append, no MCP round-trip. Same flags as the MCP tool plus
58
+ `--workspace` / `--file`.
59
+ - `skills/squad/SKILL.md` adds **Phase 14 — Post-PR record decision**
60
+ (opt-in, per-finding authorisation required) and injects
61
+ `read_learnings` output into Phase 5 (per-agent advisory) and Phase 10
62
+ (consolidator). Inviolable rules: never record without explicit
63
+ per-finding authorisation, never invent a `reason`, never amend or
64
+ delete past entries through the skill.
65
+
66
+ 38 new tests cover the store (read / append / cache invalidation /
67
+ schema violations) and the formatter (limits, scope filtering,
68
+ rendering variants). Smoke test now verifies 16 tools (was 14).
69
+
70
+ ### Added — Post `/squad-review` results as a GitHub PR review
71
+
72
+ Closes the loop from "advisory in your terminal" to "advisory on the PR
73
+ where the team works". The verdict + scorecard go up as a `gh pr review`
74
+ with the appropriate action (`--approve` / `--comment` / `--request-changes`)
75
+ chosen deterministically from verdict + score.
76
+
77
+ - `src/format/pr-review.ts` — pure formatter taking `ConsolidationOutput`
78
+ plus options, returning markdown body, chosen `gh` action, and summary
79
+ line. Header, fenced rubric scorecard, per-agent finding sections
80
+ (sorted), severity totals, footer. Verdict-to-action mapping in
81
+ `chooseGhAction` (exported separately for testability).
82
+ - `tools/post-review.mjs` — CLI helper that lives outside the MCP server
83
+ (alongside the commit-msg hook). Reads consolidation JSON from stdin,
84
+ formats, invokes `gh pr review --<action> --body-file -`. Supports
85
+ `--dry-run`, `--repo owner/name`, `--request-changes-below N`,
86
+ `--no-footer`, `--pr <n>` (required). Exit codes:
87
+ `2` invalid input, `3` gh missing/unauthenticated, `4` gh failed.
88
+ - New `.squad.yaml` section `pr_posting`:
89
+ - `auto_post: bool` (default false — skill always confirms)
90
+ - `request_changes_below_score: number` (opt-in floor)
91
+ - `omit_attribution_footer: bool` (default false)
92
+ - `skills/squad/SKILL.md` adds **Phase 13 — Post to PR** (review mode,
93
+ opt-in). Inviolable rules: never post without showing the body first,
94
+ never post `--request-changes` on someone else's PR without explicit
95
+ user instruction, never amend or delete a posted review.
96
+
97
+ 23 new tests cover the formatter (header variants, rubric block, findings
98
+ section, footer, summary, action mapping). The action mapping never
99
+ promotes a verdict (low-severity can't become approve) and only demotes
100
+ APPROVED — never downgrades CHANGES_REQUIRED further.
101
+
102
+ ### Added — `.squad.yaml` repo configuration
103
+
104
+ Per-repo configuration file (versioned with the code) lets each project tune
105
+ the rubric, thresholds, and scope without editing call sites.
106
+
107
+ - `src/config/squad-yaml.ts` — reader with zod schema, mtime-keyed cache, and
108
+ the `applySkipPaths` / `applyDisableAgents` helpers. YAML-to-zod path uses
109
+ `js-yaml` (FAILSAFE_SCHEMA + numeric coercion for known fields). Looks up
110
+ `.squad.yaml` then `.squad.yml` at workspace_root; absent file falls back to
111
+ package defaults silently.
112
+ - New tool `read_squad_config` — MCP wrapper for direct introspection by
113
+ non-Claude-Code clients or callers that build their own bundle.
114
+ - `compose_squad_workflow` now reads `.squad.yaml` and: applies `skip_paths`
115
+ to changed_files BEFORE classification (skipped paths still count toward
116
+ risk signals — disabling a file from advisory does not make the change
117
+ less risky), then applies `disable_agents` to the selected squad. Returns
118
+ the resolved `config`, `skipped_paths`, and `disabled_agents` so callers
119
+ see why the slice list got narrower.
120
+ - `compose_advisory_bundle` propagates `skip_paths` filtering through to
121
+ per-agent slices, so an agent never receives a path the composer hid.
122
+ - New `CONFIG_READ_FAILED` error code.
123
+ - New dep: `js-yaml` (^4.1) + `@types/js-yaml`. Battle-tested, MIT, ~70KB.
124
+ - `force_agents` in tool calls still wins over `config.disable_agents` —
125
+ config is a default policy, not a veto over explicit caller intent.
126
+
127
+ Validation: weights that don't sum to 100 across the listed agents → reject.
128
+ Unknown agent names in `weights` or `disable_agents` → reject. Threshold or
129
+ min_score outside 0-100 → reject. Errors carry `source` (file path) for
130
+ diagnosability.
131
+
132
+ Example `.squad.yaml`:
133
+
134
+ ```yaml
135
+ weights:
136
+ senior-dev-security: 30 # PCI compliance
137
+ senior-dba: 22
138
+ senior-developer: 20
139
+ senior-architect: 15
140
+ senior-qa: 13
141
+ threshold: 80
142
+ min_score: 75
143
+ skip_paths:
144
+ - "docs/**"
145
+ - "**/*.md"
146
+ - "**/generated/**"
147
+ disable_agents:
148
+ - product-owner # internal tool, no PO involved
149
+ ```
150
+
151
+ 22 new tests cover reader (file presence, weights override, skip_paths,
152
+ disable_agents, caching, mtime invalidation, glob matching). Backward
153
+ compatible: callers that don't pass `workspace_root` to non-composer tools
154
+ get the legacy behaviour (no config read).
155
+
156
+ ### Added — weighted rubric scorecard
157
+
158
+ Each advisory agent now represents a dimension of a multi-dimensional rubric
159
+ with a default weight. The consolidator emits a pre-formatted ASCII scorecard
160
+ alongside the legacy verdict.
161
+
162
+ - New tool `score_rubric` (`src/tools/score-rubric.ts`): pure function over
163
+ per-agent scores (0-100) and optional weight overrides; returns
164
+ `weighted_score`, per-dimension breakdown with bars, `passes_threshold`,
165
+ `ignored_agents`, and a pre-formatted `scorecard_text`.
166
+ - `AgentDef` extended with `weight: number` and `dimension: string`. Default
167
+ weights sum to 100 across the seven advisory agents (Architecture 18%,
168
+ Security 18%, Application Code 18%, Data Layer 14%, Testing & QA 14%, Code
169
+ Quality 10%, Business & UX 8%). Meta-agents (tech-lead-planner,
170
+ tech-lead-consolidator) carry weight 0 — they don't score a dimension.
171
+ - `apply_consolidation_rules` accepts optional per-agent `score`/`score_rationale`,
172
+ optional `weights` override, optional `threshold` (default 75), and optional
173
+ `min_score`. Returns `rubric: RubricOutput | null` and `downgraded_by_score`.
174
+ When `min_score` is set, an APPROVED verdict with weighted score below the
175
+ floor is downgraded to CHANGES_REQUIRED. Backward compatible: callers that
176
+ omit scores get the legacy output shape and verdict logic.
177
+ - Each advisory agent file (`agents/*.md`) now ships a `## Score` section with
178
+ a calibration table (90-100 / 70-89 / 50-69 / 30-49 / 0-29 bands) specific
179
+ to that dimension, plus the protocol for emitting `Score: NN/100`.
180
+ - Skill `skills/squad/SKILL.md` updated to capture per-agent scores into the
181
+ reports array and surface `rubric.scorecard_text` verbatim in the final
182
+ output. Tech-lead-planner/consolidator excluded (weight 0).
183
+ - Weight renormalisation: when only a subset of agents scores (partial pass),
184
+ the rubric renormalises across the agents that actually scored. A 4-of-9
185
+ advisory still produces a meaningful weighted score over those 4.
186
+ - `tests/score-rubric.test.ts` and `tests/consolidate-rubric.test.ts` cover
187
+ the math (renormalisation, weight overrides, sum=100 validation, threshold
188
+ edge cases), backward compatibility, and the `min_score` downgrade rule.
189
+
190
+ Planned for a future minor:
191
+
192
+ - Per-PR memory of accept/reject decisions feeding back into agent prompts.
193
+ - Inline line-by-line annotations on the diff (one `gh` review comment per finding with file:line links).
194
+ - GitHub Action wrapper for PR posting in CI.
195
+ - Streaming SHA-256 over `fs.createReadStream` for any large bundled asset
196
+ reads (avoids `readFileSync` doubling memory).
197
+ - Property-based tests for severity/consolidation rules via `fast-check`.
198
+
199
+ ## [0.6.0] - 2026-05-10
200
+
201
+ ### Architectural cleanup — separation of concerns
202
+
203
+ This release rationalizes the role of each layer of the project. The MCP server
204
+ owns deterministic primitives + agent definitions. The Claude Code plugin owns
205
+ packaging (skill, commands, native subagents, MCP wiring). One skill (`squad`)
206
+ hosts both `implement` and `review` modes — no client bifurcation, no skill
207
+ fragmentation. Agent markdowns live in **one** place per install: the plugin's
208
+ `agents/` directory at install time, exposed both as native Claude Code
209
+ subagents and as MCP `agent://…` resources for non-Claude-Code clients.
210
+
211
+ ### Changed (BREAKING)
212
+
213
+ - **Agent markdown filenames renamed to kebab-case** with YAML frontmatter so
214
+ Claude Code registers them as native subagents. Old (PascalCase) filenames
215
+ no longer exist:
216
+ - `agents/PO.md` → `agents/product-owner.md`
217
+ - `agents/Senior-Architect.md` → `agents/senior-architect.md`
218
+ - `agents/Senior-DBA.md` → `agents/senior-dba.md`
219
+ - `agents/Senior-Developer.md` → `agents/senior-developer.md`
220
+ - `agents/Senior-Dev-Reviewer.md` → `agents/senior-dev-reviewer.md`
221
+ - `agents/Senior-Dev-Security.md` → `agents/senior-dev-security.md`
222
+ - `agents/Senior-QA.md` → `agents/senior-qa.md`
223
+ - `agents/TechLead-Planner.md` → `agents/tech-lead-planner.md`
224
+ - `agents/TechLead-Consolidator.md` → `agents/tech-lead-consolidator.md`
225
+ - **Shared docs moved to `agents/_shared/`**: `_Severity-and-Ownership.md`,
226
+ `Skill-Squad-Dev.md`, `Skill-Squad-Review.md`. They are not registered as
227
+ subagents; they're reference material. Cross-references inside agent files
228
+ updated accordingly.
229
+ - **AgentName `'po'` renamed to `'product-owner'`** across the type, AGENTS
230
+ registry, AGENT_FILE_MAP, ownership matrix entries, MCP resource URI, and
231
+ tests — full consistency with the file/frontmatter name. MCP resource URI
232
+ changes from `agent://po` to `agent://product-owner`.
233
+ - **Plugin manifest declares `agents/`**: `.claude-plugin/plugin.json` now
234
+ includes `"agents": "./agents/"`, registering the nine subagents natively
235
+ in Claude Code.
236
+ - **Single `squad` skill replaces the two command-only entries.** Both
237
+ `/squad` and `/squad-review` invoke `skills/squad/SKILL.md`; the entry
238
+ command selects mode (`implement` vs `review`). Phases 2/4/8/9/11 only run
239
+ in implement mode.
240
+
241
+ ### Removed (BREAKING)
242
+
243
+ - **`tools/sync-agents.mjs` deleted.** The plugin install path is the canonical
244
+ Claude Code distribution; non-Claude-Code MCP clients consume agent
245
+ definitions over MCP. Users on the previous "npm install + sync to
246
+ `~/.claude/`" flow should migrate to the plugin install (Path A in
247
+ INSTALL.md).
248
+ - **`tests/sync-agents.test.ts` deleted** alongside the script.
249
+
250
+ ### Migration
251
+
252
+ If you had `%APPDATA%\squad-mcp\agents` (Windows) or
253
+ `$XDG_CONFIG_HOME/squad-mcp/agents` (Unix) overrides for the old PascalCase
254
+ filenames, rename them to the new kebab-case names. The override allowlist and
255
+ loader semantics are unchanged. Shared-doc overrides moved into a `_shared/`
256
+ subdirectory under the same override root.
257
+
258
+ If you depended on `~/.claude/agents/` being populated by the sync script,
259
+ install the plugin (`/plugin install squad@gempack`) — Claude Code now
260
+ registers the agents directly from the plugin's bundled `agents/` directory.
11
261
 
12
- - Promote bundled agent markdowns to Claude Code native plugin agents (rename to
13
- kebab-case + add YAML frontmatter), with a migration path for existing
14
- `%APPDATA%\squad-mcp\agents` overrides.
15
- - Retire the legacy `/squad` and `/squad-review` skills now that the plugin
16
- ships them as slash commands.
262
+ ### Added
263
+
264
+ - `initLocalConfig` ensures the `_shared/` subdirectory exists before copying
265
+ shared docs (previously a latent bug on first init when the override root
266
+ did not yet contain a subdirectory).
267
+
268
+ ## [0.5.0] - 2026-05-04
269
+
270
+ ### Added
271
+
272
+ - **`Senior-Dev-Reviewer` weighted scorecard.** Reviewer agent now produces a
273
+ numeric scorecard (0–10 per dimension, weighted average overall) across Code
274
+ Quality 20%, Security 20%, Maintainability 20%, Performance 20%,
275
+ Async/Concurrency 8%, Error Handling 7%, Architecture Fit 5%. Includes
276
+ per-stack idiomatic checklists for the top 5 backend (C#/.NET, Python, Java,
277
+ Go, Node.js) and top 5 frontend (TypeScript, React, Vue, Angular, Svelte)
278
+ stacks with auto-detection. Severity table drives the scorecard penalty.
279
+ Dimensions lacking diff evidence are reported as `N/A` rather than zero.
280
+ - **`brainstorm` skill.** Collaborative pre-implementation exploration. Takes a
281
+ problem, decision, or implementation idea; runs deep web research in parallel
282
+ (market patterns, best practices, pitfalls, examples); spawns specialist
283
+ agents for multi-domain perspectives; synthesizes findings into a sourced
284
+ options matrix with a recommendation. Exploratory only — produces no code or
285
+ file changes. Position in the workflow: `/brainstorm` decides _what_ to
286
+ build; `/squad` implements; `/squad-review` reviews. Triggered via
287
+ `/brainstorm` or natural-language asks ("brainstorm", "research approaches",
288
+ "explore options", "what does the industry use"). Supports `--depth
289
+ quick|medium|deep`, `--no-web`, `--focus <domain>`, and `--sources <N>`.
290
+ - **`commit-suggest` skill.** Read-only Conventional Commits message suggester.
291
+ Runs only an allowlist of git commands (`status`, `diff`, `log`, `rev-parse`,
292
+ `config --get`, `ls-files`, `show <ref>:<path>`); never executes any
293
+ state-mutating git command; never adds AI co-author trailers. Output is text
294
+ only — the user runs the commit themselves. Triggered via `/commit-suggest`
295
+ or natural-language asks ("suggest a commit", "commit message").
296
+ - **Plugin manifest exports `skills/`**. The `commit-suggest` skill (and any
297
+ future skill bundled under `skills/`) is auto-registered when the plugin is
298
+ enabled in Claude Code.
299
+ - **`tools/git-hooks/commit-msg`**. Optional opt-in hook that rejects commits
300
+ whose messages contain AI-attribution trailers (`Co-Authored-By: Claude /
301
+ Anthropic / GPT / OpenAI / Gemini / Copilot / AI`, `Generated with [Claude
302
+ Code]`, `Made by AI`, `<noreply@anthropic.com>`). Install via `cp` to
303
+ `.git/hooks/` or repo-wide via `git config core.hooksPath tools/git-hooks`.
304
+ - **`tools/sync-agents.mjs` skills sync.** Mirrors bundled skills to
305
+ `~/.claude/skills/` for non-plugin clients (Claude Desktop, Cursor, Warp).
306
+ Recursive walker; baseline-hash store at `~/.claude/skills/.bundle-hashes.json`
307
+ with versioned envelope (`{version: 1, baselines: {...}}`); tri-state policy
308
+ (identical / stale-baseline / user-modified) preserves user edits with a
309
+ `skip-with-warning` log; symlink refusal at source, destination, leaf, and
310
+ baseline-file layers; containment assert against escape-via-skill-name;
311
+ `COPYFILE_EXCL` race guard with EEXIST recurse fallback; mode `0o600` on
312
+ baseline file (Unix); atomic temp+rename writes; non-zero exit on
313
+ `skillsFailed > 0`.
314
+ - **`tools/sync-agents.mjs` agents sync hardening.** Symmetric symlink-at-
315
+ destination defense for the agents path: refuses to write through a symlinked
316
+ `~/.claude/agents/<file>.md` (matches the existing skills behavior).
317
+ - **8 integration tests** for the skills sync (`tests/sync-agents.test.ts`):
318
+ cold sync + baseline persistence, bundle update overwrites stale dst, user
319
+ edits preserved, symlink-dst refused (Unix-only), corrupt baseline graceful
320
+ fallback, idempotent rerun, HOME/USERPROFILE guard.
321
+
322
+ ### Changed
323
+
324
+ - **Global `~/.claude/CLAUDE.md` rule** (user-side, not shipped): commits
325
+ produced or suggested by Claude must never carry AI-attribution trailers.
326
+
327
+ ### Documentation
328
+
329
+ - **`INSTALL.md` Path B note**: documents that npm-package users must run
330
+ `node tools/sync-agents.mjs` to mirror agents and skills to `~/.claude/`,
331
+ and that the manual sync is idempotent.
332
+ - **`INSTALL.md` Optional hardening section**: documents how to install the
333
+ `commit-msg` hook and a recommended `permissions.deny` block in
334
+ `.claude/settings.json` for structural enforcement of the read-only invariant.
335
+ - **`INSTALL.md` baseline file note**: documents that
336
+ `~/.claude/skills/.bundle-hashes.json` is installer state and should not be
337
+ edited or deleted manually.
338
+
339
+ ## [0.4.0] - 2026-05-02
340
+
341
+ ### Security
342
+
343
+ - **BREAKING:** `SQUAD_AGENTS_DIR` is now validated against an allowlist of
344
+ user-controlled prefixes (`HOME`, `APPDATA`, `LOCALAPPDATA`, `XDG_CONFIG_HOME`,
345
+ `process.cwd()`). Override directories outside the allowlist are rejected with
346
+ a new structured `OVERRIDE_REJECTED` error. UNC and device-namespace paths on
347
+ Windows (`\\?\…`, `\\.\…`, `\\server\share\…`) are rejected before any
348
+ filesystem access. Migration: move the directory under one of the allowed
349
+ prefixes, or set `SQUAD_AGENTS_ALLOW_UNSAFE=1` to bypass the allowlist (logs a
350
+ warn-level banner once per process).
351
+ - **BREAKING:** Per-file resolution now realpath-checks each agent file. If a
352
+ file inside the override directory is a symlink whose target escapes the
353
+ directory, that file silently falls back to the embedded default — preserving
354
+ the operator's per-file customizations while blocking the symlink-out
355
+ primitive.
356
+ - Lexical AND realpath checks are both required for an override directory to
357
+ match the allowlist (closes the lexical-allowed-but-symlinked-out bypass).
358
+ - `init_local_config` now creates the override directory with mode `0o700` and
359
+ copied agent files with mode `0o600` on Unix (`fs.chmod` after `mkdir` /
360
+ `copyFile` to override the umask). Windows relies on `%APPDATA%`'s default
361
+ user-only DACL; custom paths outside `APPDATA` on Windows fall back to the
362
+ parent directory's DACL — document and use with care.
363
+ - `agent-loader` warns once per process if the resolved override directory is
364
+ world-writable (`mode & 0o002 !== 0`). Group-writable does not trigger the
365
+ warning (single-user-host convention). Skipped on Windows since `fs.stat`
366
+ does not surface DACL semantics.
367
+
368
+ ### Added
369
+
370
+ - `src/util/override-allowlist.ts` — new module exposing `validateOverrideDir`
371
+ and `validateOverrideFile`.
372
+ - `src/util/path-internal.ts` — extracted shared helpers (`rejectIfMalformed`,
373
+ `realpathOrSelf`) reused by `path-safety` and `override-allowlist`.
374
+ - `OVERRIDE_REJECTED` added to `SquadErrorCode`.
375
+ - `SQUAD_AGENTS_ALLOW_UNSAFE=1` opt-in escape hatch for power users / CI on
376
+ unusual paths.
377
+ - `tests/agent-loader.test.ts` and `tests/override-allowlist.test.ts` covering
378
+ the accept/reject matrix, escape hatch, agent-name traversal guard, symlink
379
+ escape, and Unix filesystem permissions (`0o700` dir, `0o600` files,
380
+ world-writable warn-once).
381
+
382
+ ### Changed
383
+
384
+ - `agent-loader` now logs a structured `agent override active` line on first
385
+ resolution with `resolved_path`, `allowlist_match`, `has_unsafe_override`,
386
+ `source` (`env` vs `platform_default`). Escape-hatch resolutions log at
387
+ `warn` instead of `info`.
388
+ - `getLocalDir()` now returns `{ rawDir, explicit }` — the `list_agents` tool
389
+ output exposes both `local_dir` (the raw path) and `local_dir_explicit`.
390
+
391
+ ### Migration
392
+
393
+ - If you set `SQUAD_AGENTS_DIR` to a path under your home / APPDATA / XDG dir,
394
+ no action is needed.
395
+ - If you set it to `/opt/...`, `/srv/...`, a CI runner path, or any other
396
+ location outside those prefixes, you have two options:
397
+ 1. Move the directory under `~/`, `~/AppData/Local/`, `~/.config/`, or your
398
+ project's working directory.
399
+ 2. Set `SQUAD_AGENTS_ALLOW_UNSAFE=1` in the environment that launches the MCP
400
+ host. This bypasses the allowlist and logs a warning on every process
401
+ start so the choice stays auditable.
17
402
 
18
403
  ## [0.3.1] - 2026-05-02
19
404
 
@@ -149,7 +534,7 @@ content signals). No `0.2.0` git tag was created; that scope ships as part of
149
534
  - **CWD validation**: must be absolute, must exist, must be a directory,
150
535
  must contain a `.git` entry. Resolved via `realpath`.
151
536
  - **Hardening prefix**: every invocation prepends `-c core.fsmonitor=false
152
- -c diff.external= -c core.hooksPath=NUL` (or `/dev/null`).
537
+ -c diff.external= -c core.hooksPath=NUL` (or `/dev/null`).
153
538
  - **Environment scrub**: drops user env, sets `GIT_TERMINAL_PROMPT=0`,
154
539
  `GIT_OPTIONAL_LOCKS=0`, `GIT_CONFIG_NOSYSTEM=1`,
155
540
  `GIT_CEILING_DIRECTORIES=<parent of cwd>`.
@@ -276,7 +661,9 @@ update at commit `052c2ad`.
276
661
  - Smoke test (`tests/smoke.mjs`) plus initial unit tests for `score_risk`,
277
662
  `select_squad`, `consolidate`.
278
663
 
279
- [Unreleased]: https://github.com/ggemba/squad-mcp/compare/v0.3.1...HEAD
664
+ [Unreleased]: https://github.com/ggemba/squad-mcp/compare/v0.5.0...HEAD
665
+ [0.5.0]: https://github.com/ggemba/squad-mcp/releases/tag/v0.5.0
666
+ [0.4.0]: https://github.com/ggemba/squad-mcp/releases/tag/v0.4.0
280
667
  [0.3.1]: https://github.com/ggemba/squad-mcp/releases/tag/v0.3.1
281
668
  [0.3.0]: https://github.com/ggemba/squad-mcp/releases/tag/v0.3.0
282
669
  [0.1.0]: https://github.com/ggemba/squad-mcp/commit/548adc2