@gempack/squad-mcp 0.5.0 → 0.6.1

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 (102) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +3 -2
  3. package/CHANGELOG.md +271 -17
  4. package/INSTALL.md +156 -24
  5. package/README.md +278 -27
  6. package/agents/{PO.md → product-owner.md} +33 -1
  7. package/agents/{Senior-Architect.md → senior-architect.md} +33 -1
  8. package/agents/{Senior-DBA.md → senior-dba.md} +33 -1
  9. package/agents/{Senior-Dev-Reviewer.md → senior-dev-reviewer.md} +33 -1
  10. package/agents/{Senior-Dev-Security.md → senior-dev-security.md} +33 -1
  11. package/agents/{Senior-Developer.md → senior-developer.md} +33 -1
  12. package/agents/{Senior-QA.md → senior-qa.md} +33 -1
  13. package/agents/{TechLead-Consolidator.md → tech-lead-consolidator.md} +7 -1
  14. package/agents/{TechLead-Planner.md → tech-lead-planner.md} +7 -1
  15. package/commands/squad-review.md +10 -58
  16. package/commands/squad.md +11 -70
  17. package/dist/config/ownership-matrix.d.ts +24 -2
  18. package/dist/config/ownership-matrix.js +466 -139
  19. package/dist/config/ownership-matrix.js.map +1 -1
  20. package/dist/config/squad-yaml.d.ts +242 -0
  21. package/dist/config/squad-yaml.js +403 -0
  22. package/dist/config/squad-yaml.js.map +1 -0
  23. package/dist/errors.d.ts +1 -1
  24. package/dist/errors.js +1 -1
  25. package/dist/errors.js.map +1 -1
  26. package/dist/format/pr-review.d.ts +61 -0
  27. package/dist/format/pr-review.js +146 -0
  28. package/dist/format/pr-review.js.map +1 -0
  29. package/dist/index.js +19 -13
  30. package/dist/index.js.map +1 -1
  31. package/dist/learning/format.d.ts +29 -0
  32. package/dist/learning/format.js +55 -0
  33. package/dist/learning/format.js.map +1 -0
  34. package/dist/learning/store.d.ts +102 -0
  35. package/dist/learning/store.js +169 -0
  36. package/dist/learning/store.js.map +1 -0
  37. package/dist/resources/agent-loader.d.ts +8 -1
  38. package/dist/resources/agent-loader.js +83 -48
  39. package/dist/resources/agent-loader.js.map +1 -1
  40. package/dist/tasks/select.d.ts +64 -0
  41. package/dist/tasks/select.js +84 -0
  42. package/dist/tasks/select.js.map +1 -0
  43. package/dist/tasks/store.d.ts +338 -0
  44. package/dist/tasks/store.js +321 -0
  45. package/dist/tasks/store.js.map +1 -0
  46. package/dist/tools/compose-advisory-bundle.d.ts +5 -5
  47. package/dist/tools/compose-advisory-bundle.js +24 -12
  48. package/dist/tools/compose-advisory-bundle.js.map +1 -1
  49. package/dist/tools/compose-prd-parse.d.ts +53 -0
  50. package/dist/tools/compose-prd-parse.js +167 -0
  51. package/dist/tools/compose-prd-parse.js.map +1 -0
  52. package/dist/tools/compose-squad-workflow.d.ts +28 -10
  53. package/dist/tools/compose-squad-workflow.js +0 -0
  54. package/dist/tools/compose-squad-workflow.js.map +1 -1
  55. package/dist/tools/consolidate.d.ts +55 -4
  56. package/dist/tools/consolidate.js +87 -15
  57. package/dist/tools/consolidate.js.map +1 -1
  58. package/dist/tools/expand-task.d.ts +51 -0
  59. package/dist/tools/expand-task.js +35 -0
  60. package/dist/tools/expand-task.js.map +1 -0
  61. package/dist/tools/list-tasks.d.ts +31 -0
  62. package/dist/tools/list-tasks.js +50 -0
  63. package/dist/tools/list-tasks.js.map +1 -0
  64. package/dist/tools/next-task.d.ts +37 -0
  65. package/dist/tools/next-task.js +60 -0
  66. package/dist/tools/next-task.js.map +1 -0
  67. package/dist/tools/read-learnings.d.ts +53 -0
  68. package/dist/tools/read-learnings.js +72 -0
  69. package/dist/tools/read-learnings.js.map +1 -0
  70. package/dist/tools/read-squad-config.d.ts +23 -0
  71. package/dist/tools/read-squad-config.js +34 -0
  72. package/dist/tools/read-squad-config.js.map +1 -0
  73. package/dist/tools/record-learning.d.ts +62 -0
  74. package/dist/tools/record-learning.js +80 -0
  75. package/dist/tools/record-learning.js.map +1 -0
  76. package/dist/tools/record-tasks.d.ts +71 -0
  77. package/dist/tools/record-tasks.js +45 -0
  78. package/dist/tools/record-tasks.js.map +1 -0
  79. package/dist/tools/registry.d.ts +1 -1
  80. package/dist/tools/registry.js +71 -39
  81. package/dist/tools/registry.js.map +1 -1
  82. package/dist/tools/score-rubric.d.ts +74 -0
  83. package/dist/tools/score-rubric.js +140 -0
  84. package/dist/tools/score-rubric.js.map +1 -0
  85. package/dist/tools/slice-files-for-task.d.ts +31 -0
  86. package/dist/tools/slice-files-for-task.js +52 -0
  87. package/dist/tools/slice-files-for-task.js.map +1 -0
  88. package/dist/tools/update-task-status.d.ts +29 -0
  89. package/dist/tools/update-task-status.js +35 -0
  90. package/dist/tools/update-task-status.js.map +1 -0
  91. package/package.json +11 -1
  92. package/skills/squad/SKILL.md +454 -0
  93. package/tools/_tasks-io.mjs +69 -0
  94. package/tools/list-tasks.mjs +110 -0
  95. package/tools/next-task.mjs +131 -0
  96. package/tools/post-review.mjs +212 -0
  97. package/tools/record-learning.mjs +145 -0
  98. package/tools/record-tasks.mjs +186 -0
  99. package/tools/update-task-status.mjs +114 -0
  100. /package/{agents → shared}/Skill-Squad-Dev.md +0 -0
  101. /package/{agents → shared}/Skill-Squad-Review.md +0 -0
  102. /package/{agents → shared}/_Severity-and-Ownership.md +0 -0
@@ -0,0 +1,403 @@
1
+ import { promises as fs } from "node:fs";
2
+ import path from "node:path";
3
+ import yaml from "js-yaml";
4
+ import { z } from "zod";
5
+ import { AGENT_NAMES_TUPLE, DEFAULT_RUBRIC_WEIGHTS, } from "./ownership-matrix.js";
6
+ import { SquadError } from "../errors.js";
7
+ import { logger } from "../observability/logger.js";
8
+ /**
9
+ * `.squad.yaml` schema. All fields optional; absent keys fall back to package defaults.
10
+ *
11
+ * Repo-versioned config. Lives at workspace_root. Loaded by composers
12
+ * (compose_squad_workflow, compose_advisory_bundle) automatically when they
13
+ * receive a workspace_root. Pure tools (apply_consolidation_rules, score_rubric,
14
+ * select_squad) do NOT read it directly — that would make them stateful and
15
+ * couple their inputs to the filesystem. Composers do the read; pure tools
16
+ * receive the resolved values via parameters.
17
+ */
18
+ const squadYamlSchema = z.object({
19
+ /**
20
+ * Override default rubric weights. Keys are agent names; values 0-100. The set
21
+ * of supplied keys MUST sum to 100 across the agents you list. Agents not
22
+ * listed fall back to the package default. Use weight 0 to ignore a dimension.
23
+ */
24
+ weights: z
25
+ .record(z.enum(AGENT_NAMES_TUPLE), z.number().min(0).max(100))
26
+ .optional(),
27
+ /**
28
+ * Per-dimension threshold (0-100). Below this, the dimension is flagged in the
29
+ * scorecard. Default 75 (in code, not duplicated here).
30
+ */
31
+ threshold: z.number().min(0).max(100).optional(),
32
+ /**
33
+ * Quality floor. If supplied AND the weighted score is below it AND verdict
34
+ * would otherwise be APPROVED, the consolidator downgrades to CHANGES_REQUIRED.
35
+ */
36
+ min_score: z.number().min(0).max(100).optional(),
37
+ /**
38
+ * Glob patterns (relative to workspace_root) of files to exclude from advisory.
39
+ * Matched against `changed_files` BEFORE squad selection. Use to silence
40
+ * docs-only changes, generated code, etc.
41
+ */
42
+ skip_paths: z.array(z.string().min(1).max(512)).max(200).optional(),
43
+ /**
44
+ * Agents to disable for this repo. Removed from the selected squad in
45
+ * compose_squad_workflow. Useful for repos that don't have, say, a database
46
+ * (disable senior-dba) or aren't user-facing (disable product-owner).
47
+ */
48
+ disable_agents: z.array(z.enum(AGENT_NAMES_TUPLE)).max(20).optional(),
49
+ /**
50
+ * Optional GitHub PR posting policy used by `tools/post-review.mjs` and the
51
+ * `/squad-review` skill. Default behaviour without this section: dry-run.
52
+ * The skill prepares the post and shows the user — never posts unsolicited.
53
+ *
54
+ * - `auto_post`: when true, the skill posts without asking for confirmation
55
+ * each time. The user opted in by editing this YAML — no AI action without
56
+ * prior authorisation.
57
+ * - `request_changes_below_score`: when set, an APPROVED verdict with
58
+ * weighted score below this floor is posted as `--request-changes` instead
59
+ * of `--approve`. Independent of `min_score` (which downgrades the verdict
60
+ * itself).
61
+ * - `omit_attribution_footer`: omits the trailing "Generated by squad-mcp"
62
+ * line from the PR body. Useful for orgs that prefer a leaner PR.
63
+ */
64
+ pr_posting: z
65
+ .object({
66
+ auto_post: z.boolean().optional(),
67
+ request_changes_below_score: z.number().min(0).max(100).optional(),
68
+ omit_attribution_footer: z.boolean().optional(),
69
+ })
70
+ .optional(),
71
+ /**
72
+ * Optional `.squad/learnings.jsonl` configuration. The store records
73
+ * accept/reject decisions on findings; future advisory runs read the
74
+ * recent tail and inject it into agent / consolidator prompts so the
75
+ * squad stops re-suggesting things the team has already declined.
76
+ *
77
+ * - `path`: relative location of the JSONL file (default
78
+ * `.squad/learnings.jsonl`). Override only if the repo already uses
79
+ * `.squad/` for something else.
80
+ * - `max_recent`: how many entries to inject per advisory run (default 50,
81
+ * hard cap 200). Larger = more context but more prompt cost.
82
+ * - `enabled`: master switch. Default true. Set false to disable the
83
+ * read/inject side without deleting the file.
84
+ */
85
+ learnings: z
86
+ .object({
87
+ path: z.string().min(1).max(512).optional(),
88
+ max_recent: z.number().int().positive().max(200).optional(),
89
+ enabled: z.boolean().optional(),
90
+ })
91
+ .optional(),
92
+ /**
93
+ * Optional `.squad/tasks.json` configuration. The store holds the task list
94
+ * decomposed from a PRD (or seeded manually); the squad workflow runs one
95
+ * task at a time with scope-narrowed context to avoid prompt bloat.
96
+ *
97
+ * - `path`: relative location of the JSON file (default `.squad/tasks.json`).
98
+ * Override only if the repo already uses `.squad/` for something else.
99
+ * - `enabled`: master switch. Default true. Set false to silence task tools
100
+ * without deleting the file.
101
+ */
102
+ tasks: z
103
+ .object({
104
+ path: z.string().min(1).max(512).optional(),
105
+ enabled: z.boolean().optional(),
106
+ })
107
+ .optional(),
108
+ });
109
+ const CANDIDATE_FILENAMES = [".squad.yaml", ".squad.yml"];
110
+ const cache = new Map();
111
+ /**
112
+ * Test-only: clear the cache. Production code MUST NOT call this.
113
+ */
114
+ export function __resetSquadYamlCacheForTests() {
115
+ cache.clear();
116
+ }
117
+ async function locate(workspaceRoot) {
118
+ for (const name of CANDIDATE_FILENAMES) {
119
+ const candidate = path.join(workspaceRoot, name);
120
+ try {
121
+ const s = await fs.stat(candidate);
122
+ if (s.isFile()) {
123
+ return { filePath: candidate, mtimeMs: s.mtimeMs };
124
+ }
125
+ }
126
+ catch {
127
+ // ENOENT or stat failure — try next.
128
+ }
129
+ }
130
+ return null;
131
+ }
132
+ function applyDefaults(parsed, source) {
133
+ // Merge weights: parsed override sums to 100 across its keys (validated below);
134
+ // missing keys take the default. Returning a fully-populated map keeps the
135
+ // downstream score_rubric simple (no fallback chain in math).
136
+ const weights = { ...DEFAULT_RUBRIC_WEIGHTS };
137
+ if (parsed.weights) {
138
+ const supplied = Object.entries(parsed.weights);
139
+ const sum = supplied.reduce((acc, [, v]) => acc + v, 0);
140
+ if (Math.abs(sum - 100) > 0.01) {
141
+ throw new SquadError("INVALID_INPUT", `.squad.yaml weights must sum to 100 across the agents listed; got ${sum}`, { source: source ?? "<inline>", supplied: parsed.weights });
142
+ }
143
+ for (const [name, w] of supplied) {
144
+ weights[name] = w;
145
+ }
146
+ // Zero-out the agents NOT supplied — the YAML user explicitly chose a
147
+ // partial set of weights, so anything missing is "this dimension does not
148
+ // count for this repo". Keeping defaults would let ungated dimensions sneak
149
+ // back into the rollup.
150
+ const overridden = new Set(supplied.map(([name]) => name));
151
+ for (const name of AGENT_NAMES_TUPLE) {
152
+ if (!overridden.has(name))
153
+ weights[name] = 0;
154
+ }
155
+ }
156
+ const pr_posting = {
157
+ auto_post: parsed.pr_posting?.auto_post ?? false,
158
+ request_changes_below_score: parsed.pr_posting?.request_changes_below_score,
159
+ omit_attribution_footer: parsed.pr_posting?.omit_attribution_footer ?? false,
160
+ };
161
+ const learnings = {
162
+ path: parsed.learnings?.path ?? ".squad/learnings.jsonl",
163
+ max_recent: parsed.learnings?.max_recent ?? 50,
164
+ enabled: parsed.learnings?.enabled ?? true,
165
+ };
166
+ const tasks = {
167
+ path: parsed.tasks?.path ?? ".squad/tasks.json",
168
+ enabled: parsed.tasks?.enabled ?? true,
169
+ };
170
+ return {
171
+ weights,
172
+ threshold: parsed.threshold ?? 75,
173
+ min_score: parsed.min_score,
174
+ skip_paths: parsed.skip_paths ?? [],
175
+ disable_agents: parsed.disable_agents ?? [],
176
+ pr_posting,
177
+ learnings,
178
+ tasks,
179
+ source,
180
+ };
181
+ }
182
+ /**
183
+ * Read `.squad.yaml` (or `.squad.yml`) from workspace_root. Returns the resolved
184
+ * config with defaults filled in. If no file is present, returns defaults.
185
+ * Caches by absolute path + mtimeMs.
186
+ *
187
+ * Throws `SquadError(INVALID_INPUT)` only on malformed YAML or schema violations
188
+ * (e.g. weights not summing to 100). Missing-file and partial config are NOT
189
+ * errors — they fall back gracefully.
190
+ */
191
+ export async function readSquadYaml(workspaceRoot) {
192
+ const absRoot = path.resolve(workspaceRoot);
193
+ const located = await locate(absRoot);
194
+ if (!located) {
195
+ // No file. Cache the "no file" sentinel keyed by mtimeMs=0.
196
+ const cached = cache.get(absRoot);
197
+ if (cached && cached.filePath === null && cached.mtimeMs === 0) {
198
+ return cached.resolved;
199
+ }
200
+ const resolved = applyDefaults({}, null);
201
+ cache.set(absRoot, { mtimeMs: 0, resolved, filePath: null });
202
+ return resolved;
203
+ }
204
+ const cached = cache.get(absRoot);
205
+ if (cached &&
206
+ cached.filePath === located.filePath &&
207
+ cached.mtimeMs === located.mtimeMs) {
208
+ return cached.resolved;
209
+ }
210
+ let raw;
211
+ try {
212
+ raw = await fs.readFile(located.filePath, "utf8");
213
+ }
214
+ catch (err) {
215
+ throw new SquadError("CONFIG_READ_FAILED", `failed to read ${located.filePath}: ${err.message}`, {
216
+ source: located.filePath,
217
+ });
218
+ }
219
+ let doc;
220
+ try {
221
+ doc = yaml.load(raw, {
222
+ filename: located.filePath,
223
+ schema: yaml.FAILSAFE_SCHEMA,
224
+ });
225
+ }
226
+ catch (err) {
227
+ throw new SquadError("INVALID_INPUT", `invalid YAML in ${located.filePath}: ${err.message}`, {
228
+ source: located.filePath,
229
+ });
230
+ }
231
+ // FAILSAFE_SCHEMA returns strings for everything; coerce numbers in known fields.
232
+ // Doing this here keeps the zod schema strict (numbers stay numbers) while
233
+ // tolerating YAML's "1" vs 1 ambiguity.
234
+ if (typeof doc === "object" && doc !== null) {
235
+ const o = doc;
236
+ if (o.threshold !== undefined)
237
+ o.threshold = coerceNumber(o.threshold, "threshold", located.filePath);
238
+ if (o.min_score !== undefined)
239
+ o.min_score = coerceNumber(o.min_score, "min_score", located.filePath);
240
+ if (o.weights && typeof o.weights === "object") {
241
+ const w = o.weights;
242
+ for (const [k, v] of Object.entries(w)) {
243
+ w[k] = coerceNumber(v, `weights.${k}`, located.filePath);
244
+ }
245
+ }
246
+ if (o.pr_posting && typeof o.pr_posting === "object") {
247
+ const p = o.pr_posting;
248
+ if (p.request_changes_below_score !== undefined) {
249
+ p.request_changes_below_score = coerceNumber(p.request_changes_below_score, "pr_posting.request_changes_below_score", located.filePath);
250
+ }
251
+ // FAILSAFE_SCHEMA returns booleans as the strings "true"/"false". Coerce.
252
+ if (typeof p.auto_post === "string") {
253
+ p.auto_post = p.auto_post === "true";
254
+ }
255
+ if (typeof p.omit_attribution_footer === "string") {
256
+ p.omit_attribution_footer = p.omit_attribution_footer === "true";
257
+ }
258
+ }
259
+ if (o.learnings && typeof o.learnings === "object") {
260
+ const l = o.learnings;
261
+ if (l.max_recent !== undefined) {
262
+ l.max_recent = coerceNumber(l.max_recent, "learnings.max_recent", located.filePath);
263
+ }
264
+ if (typeof l.enabled === "string") {
265
+ l.enabled = l.enabled === "true";
266
+ }
267
+ }
268
+ }
269
+ else if (doc === null || doc === undefined) {
270
+ // Empty YAML file — treat as empty object.
271
+ doc = {};
272
+ }
273
+ const parsed = squadYamlSchema.safeParse(doc);
274
+ if (!parsed.success) {
275
+ throw new SquadError("INVALID_INPUT", `${located.filePath}: ${parsed.error.message}`, {
276
+ source: located.filePath,
277
+ issues: parsed.error.issues.length,
278
+ });
279
+ }
280
+ const resolved = applyDefaults(parsed.data, located.filePath);
281
+ cache.set(absRoot, {
282
+ mtimeMs: located.mtimeMs,
283
+ resolved,
284
+ filePath: located.filePath,
285
+ });
286
+ logger.info("squad-yaml loaded", {
287
+ details: {
288
+ source: located.filePath,
289
+ has_weights: Boolean(parsed.data.weights),
290
+ threshold: resolved.threshold,
291
+ skip_paths_count: resolved.skip_paths.length,
292
+ disabled_agents_count: resolved.disable_agents.length,
293
+ },
294
+ });
295
+ return resolved;
296
+ }
297
+ function coerceNumber(value, field, source) {
298
+ if (typeof value === "number")
299
+ return value;
300
+ if (typeof value === "string") {
301
+ const n = Number(value);
302
+ if (!Number.isFinite(n)) {
303
+ throw new SquadError("INVALID_INPUT", `${source}: ${field} must be a number, got "${value}"`, { source });
304
+ }
305
+ return n;
306
+ }
307
+ throw new SquadError("INVALID_INPUT", `${source}: ${field} must be a number`, { source });
308
+ }
309
+ /**
310
+ * Glob-ish path matching used for skip_paths. Supports:
311
+ * - double-star matches any number of segments (zero or more)
312
+ * - single star matches anything within a single segment
313
+ * - `?` matches one character within a segment
314
+ * - exact strings
315
+ *
316
+ * Patterns and paths are matched after normalising path separators to `/`.
317
+ * NOT a full minimatch — kept tiny on purpose to avoid pulling minimatch as a
318
+ * dep. Sufficient for the canonical use cases (docs/double-star, double-star
319
+ * slash *.md, double-star slash generated slash *.ts, vendor/double-star).
320
+ */
321
+ export function matchesGlob(pattern, p) {
322
+ const normPattern = pattern.replace(/\\/g, "/");
323
+ const normPath = p.replace(/\\/g, "/");
324
+ const re = globToRegExp(normPattern);
325
+ return re.test(normPath);
326
+ }
327
+ function globToRegExp(pattern) {
328
+ let i = 0;
329
+ let out = "^";
330
+ while (i < pattern.length) {
331
+ const c = pattern[i];
332
+ if (c === "*" && pattern[i + 1] === "*") {
333
+ // `**` — zero or more segments
334
+ // Handle `**/`, `/**`, `/**/`, or bare `**`.
335
+ if (pattern[i + 2] === "/") {
336
+ // `**/` — zero or more segments followed by /
337
+ out += "(?:.*/)?";
338
+ i += 3;
339
+ continue;
340
+ }
341
+ out += ".*";
342
+ i += 2;
343
+ continue;
344
+ }
345
+ if (c === "*") {
346
+ // single segment
347
+ out += "[^/]*";
348
+ i += 1;
349
+ continue;
350
+ }
351
+ if (c === "?") {
352
+ out += "[^/]";
353
+ i += 1;
354
+ continue;
355
+ }
356
+ if (".+^${}()|[]\\".includes(c)) {
357
+ out += "\\" + c;
358
+ i += 1;
359
+ continue;
360
+ }
361
+ out += c;
362
+ i += 1;
363
+ }
364
+ out += "$";
365
+ return new RegExp(out);
366
+ }
367
+ /**
368
+ * Apply `skip_paths` filter to a list of files. Returns { kept, skipped }.
369
+ * Skipped files are excluded from advisory; they still appear in the diff but
370
+ * agents don't see them.
371
+ */
372
+ export function applySkipPaths(files, skipPaths) {
373
+ if (skipPaths.length === 0)
374
+ return { kept: files, skipped: [] };
375
+ const kept = [];
376
+ const skipped = [];
377
+ for (const f of files) {
378
+ if (skipPaths.some((p) => matchesGlob(p, f))) {
379
+ skipped.push(f);
380
+ }
381
+ else {
382
+ kept.push(f);
383
+ }
384
+ }
385
+ return { kept, skipped };
386
+ }
387
+ /**
388
+ * Filter a selected squad against `disable_agents`. Returns the agents that
389
+ * remain. Logs a warning if every agent was disabled (likely a misconfig).
390
+ */
391
+ export function applyDisableAgents(squad, disableAgents) {
392
+ if (disableAgents.length === 0)
393
+ return squad;
394
+ const disabled = new Set(disableAgents);
395
+ const remaining = squad.filter((a) => !disabled.has(a));
396
+ if (remaining.length === 0 && squad.length > 0) {
397
+ logger.warn("squad-yaml disable_agents removed every selected agent", {
398
+ details: { selected: squad, disabled: disableAgents },
399
+ });
400
+ }
401
+ return remaining;
402
+ }
403
+ //# sourceMappingURL=squad-yaml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"squad-yaml.js","sourceRoot":"","sources":["../../src/config/squad-yaml.ts"],"names":[],"mappings":"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"}
package/dist/errors.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type SquadErrorCode = 'PATH_TRAVERSAL_DENIED' | 'PATH_REQUIRES_WORKSPACE' | 'PATH_INVALID' | 'AGENT_DIR_MISSING' | 'UNKNOWN_AGENT' | 'OVERRIDE_REJECTED' | 'INVALID_INPUT' | 'INTERNAL_ERROR' | 'GIT_EXEC_DENIED' | 'GIT_EXEC_TIMEOUT' | 'GIT_NOT_FOUND' | 'GIT_OUTPUT_TOO_LARGE' | 'GIT_NOT_A_REPO';
1
+ export type SquadErrorCode = "PATH_TRAVERSAL_DENIED" | "PATH_REQUIRES_WORKSPACE" | "PATH_INVALID" | "AGENT_DIR_MISSING" | "UNKNOWN_AGENT" | "OVERRIDE_REJECTED" | "INVALID_INPUT" | "INTERNAL_ERROR" | "GIT_EXEC_DENIED" | "GIT_EXEC_TIMEOUT" | "GIT_NOT_FOUND" | "GIT_OUTPUT_TOO_LARGE" | "GIT_NOT_A_REPO" | "CONFIG_READ_FAILED";
2
2
  export declare class SquadError extends Error {
3
3
  readonly code: SquadErrorCode;
4
4
  readonly details?: Record<string, unknown>;
package/dist/errors.js CHANGED
@@ -3,7 +3,7 @@ export class SquadError extends Error {
3
3
  details;
4
4
  constructor(code, message, details) {
5
5
  super(message);
6
- this.name = 'SquadError';
6
+ this.name = "SquadError";
7
7
  this.code = code;
8
8
  this.details = details;
9
9
  }
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAeA,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,IAAI,CAAiB;IACrB,OAAO,CAA2B;IAE3C,YAAY,IAAoB,EAAE,OAAe,EAAE,OAAiC;QAClF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,OAAO,GAAG,YAAY,UAAU,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAgBA,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,IAAI,CAAiB;IACrB,OAAO,CAA2B;IAE3C,YACE,IAAoB,EACpB,OAAe,EACf,OAAiC;QAEjC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,OAAO,GAAG,YAAY,UAAU,CAAC;AACnC,CAAC"}
@@ -0,0 +1,61 @@
1
+ import type { ConsolidationOutput } from "../tools/consolidate.js";
2
+ /**
3
+ * Verdict → `gh pr review` action mapping. The CLI passes the chosen action as
4
+ * a flag; we compute it deterministically from verdict + score so the formatter
5
+ * stays pure (no env reads, no auth).
6
+ *
7
+ * REJECTED -> request-changes (blocks merge)
8
+ * CHANGES_REQUIRED -> comment (advisory, doesn't block)
9
+ * APPROVED + downgraded_by_score=true -> comment (downgraded, treat like CR)
10
+ * APPROVED + score < request_changes_below -> request-changes (project-policy gate)
11
+ * APPROVED otherwise -> approve
12
+ *
13
+ * `request_changes_below_score` is opt-in via .squad.yaml.pr_posting; without
14
+ * it, APPROVED always maps to approve.
15
+ */
16
+ export type GhReviewAction = "approve" | "comment" | "request-changes";
17
+ export interface FormatPrReviewOptions {
18
+ /**
19
+ * Below this weighted score, force `request-changes` even when verdict is
20
+ * APPROVED. Lets a repo enforce a hard quality bar at PR review time.
21
+ * Default: undefined (no override — APPROVED stays APPROVED).
22
+ */
23
+ requestChangesBelowScore?: number;
24
+ /**
25
+ * Optional repo identifier shown in the review header (e.g. "ggemba/squad-mcp").
26
+ * Cosmetic — surface where the review came from when the PR aggregates many
27
+ * sources.
28
+ */
29
+ repoLabel?: string;
30
+ }
31
+ export interface PrReviewPayload {
32
+ /** Markdown body to pass to `gh pr review --body-file -`. */
33
+ body: string;
34
+ /** Which `gh pr review --<action>` flag to invoke. */
35
+ action: GhReviewAction;
36
+ /** Short one-line summary suitable for `gh pr review --body` if you want a fallback. */
37
+ summary: string;
38
+ }
39
+ /**
40
+ * Compute the `gh pr review` action for the given consolidation output and
41
+ * options. Pure function; deterministic.
42
+ *
43
+ * Promotion never happens — a low-severity verdict cannot become approval.
44
+ * Demotion (score-driven) only applies to APPROVED.
45
+ */
46
+ export declare function chooseGhAction(consolidation: ConsolidationOutput, options: FormatPrReviewOptions): GhReviewAction;
47
+ /**
48
+ * Build the PR review payload from a consolidation output. Pure, deterministic.
49
+ *
50
+ * Output shape mirrors the squad's terminal report, repurposed as a markdown PR
51
+ * review body:
52
+ * 1. Header with verdict + weighted score
53
+ * 2. Rubric scorecard (fenced code block — keeps the bars monospace)
54
+ * 3. Findings grouped by agent (Blockers + unjustified Majors expanded;
55
+ * Minor/Suggestion totals only)
56
+ * 4. Footer with attribution + override hint
57
+ *
58
+ * The action is chosen via `chooseGhAction` — caller passes it to
59
+ * `gh pr review --<action>`.
60
+ */
61
+ export declare function formatPrReview(consolidation: ConsolidationOutput, options?: FormatPrReviewOptions): PrReviewPayload;
@@ -0,0 +1,146 @@
1
+ const SEVERITY_ORDER = ["Blocker", "Major", "Minor", "Suggestion"];
2
+ /**
3
+ * Compute the `gh pr review` action for the given consolidation output and
4
+ * options. Pure function; deterministic.
5
+ *
6
+ * Promotion never happens — a low-severity verdict cannot become approval.
7
+ * Demotion (score-driven) only applies to APPROVED.
8
+ */
9
+ export function chooseGhAction(consolidation, options) {
10
+ if (consolidation.verdict === "REJECTED")
11
+ return "request-changes";
12
+ if (consolidation.verdict === "CHANGES_REQUIRED")
13
+ return "comment";
14
+ // APPROVED. Check downgrade signals.
15
+ if (consolidation.downgraded_by_score)
16
+ return "comment";
17
+ if (consolidation.rubric &&
18
+ typeof options.requestChangesBelowScore === "number" &&
19
+ consolidation.rubric.weighted_score < options.requestChangesBelowScore) {
20
+ return "request-changes";
21
+ }
22
+ return "approve";
23
+ }
24
+ function verdictHeader(consolidation) {
25
+ const r = consolidation.rubric;
26
+ const v = consolidation.verdict;
27
+ if (r) {
28
+ const score = r.weighted_score.toFixed(1);
29
+ if (v === "APPROVED" &&
30
+ r.passes_threshold &&
31
+ !consolidation.downgraded_by_score) {
32
+ return `Squad Advisory: APPROVED (${score} / 100)`;
33
+ }
34
+ if (v === "APPROVED") {
35
+ return `Squad Advisory: APPROVED with attention (${score} / 100)`;
36
+ }
37
+ return `Squad Advisory: ${v} (${score} / 100)`;
38
+ }
39
+ return `Squad Advisory: ${v}`;
40
+ }
41
+ function groupFindingsByAgent(consolidation) {
42
+ // Consolidator output retains blocker/major lists with agent attribution; we
43
+ // need the full set including Minor/Suggestion. The current ConsolidationOutput
44
+ // shape only exposes blockers + majors_unjustified explicitly; severity_counts
45
+ // is aggregate. To produce a per-agent listing of all findings, we'd need the
46
+ // raw reports. The skill is responsible for passing that input — but post-review
47
+ // CLI receives the consolidator output. We work with what's exposed here, which
48
+ // is enough for the v1 PR comment: blockers + unjustified majors are the actionable
49
+ // items. Minor/Suggestion counts go in the summary.
50
+ const grouped = new Map();
51
+ for (const b of consolidation.blockers) {
52
+ const list = grouped.get(b.agent) ?? [];
53
+ list.push({ severity: "Blocker", title: b.title });
54
+ grouped.set(b.agent, list);
55
+ }
56
+ for (const m of consolidation.majors_unjustified) {
57
+ const list = grouped.get(m.agent) ?? [];
58
+ list.push({ severity: "Major", title: m.title });
59
+ grouped.set(m.agent, list);
60
+ }
61
+ return grouped;
62
+ }
63
+ function formatFindingsSection(consolidation) {
64
+ const grouped = groupFindingsByAgent(consolidation);
65
+ const c = consolidation.severity_counts;
66
+ const totalFindings = c.Blocker + c.Major + c.Minor + c.Suggestion;
67
+ // Clean review with zero of every severity — skip the section entirely.
68
+ if (totalFindings === 0)
69
+ return "";
70
+ const totals = `**Severity totals:** ${c.Blocker} blocker / ${c.Major} major / ${c.Minor} minor / ${c.Suggestion} suggestion`;
71
+ // No actionable findings (no Blockers, no unjustified Majors) but Minor/Suggestion
72
+ // counts exist. Emit just the totals — no per-agent expansion needed.
73
+ if (grouped.size === 0) {
74
+ return ["### Findings", "", totals].join("\n");
75
+ }
76
+ const sections = [];
77
+ // Sort agents alphabetically for stable output (snapshot-friendly).
78
+ const agentNames = Array.from(grouped.keys()).sort();
79
+ for (const agent of agentNames) {
80
+ const findings = grouped.get(agent) ?? [];
81
+ findings.sort((a, b) => SEVERITY_ORDER.indexOf(a.severity) - SEVERITY_ORDER.indexOf(b.severity));
82
+ const lines = [`#### ${agent}`];
83
+ for (const f of findings) {
84
+ lines.push(`- **${f.severity}** — ${f.title}`);
85
+ }
86
+ sections.push(lines.join("\n"));
87
+ }
88
+ return ["### Findings", "", sections.join("\n\n"), "", totals].join("\n");
89
+ }
90
+ function formatRubricBlock(rubric) {
91
+ if (!rubric)
92
+ return "";
93
+ // Wrap the existing scorecard_text in a fenced block so the bars and ⚠ flags
94
+ // render as monospace in the GitHub PR review body.
95
+ return ["```", rubric.scorecard_text, "```"].join("\n");
96
+ }
97
+ function formatFooter(consolidation, action, options) {
98
+ const lines = [];
99
+ lines.push("---");
100
+ if (consolidation.downgraded_by_score) {
101
+ lines.push(`_Verdict downgraded from APPROVED to CHANGES_REQUIRED because the weighted score is below the configured floor._`);
102
+ }
103
+ if (action === "request-changes" && consolidation.verdict === "APPROVED") {
104
+ lines.push(`_Posting as request-changes because score is below \`request_changes_below_score\` (${options.requestChangesBelowScore})._`);
105
+ }
106
+ const suffix = options.repoLabel ? ` (\`${options.repoLabel}\`)` : "";
107
+ lines.push(`_Generated by [@gempack/squad-mcp](https://github.com/ggemba/squad-mcp)${suffix}. Each agent reviewed only its sliced jurisdiction; the rubric is the weighted rollup. Tune \`.squad.yaml\` to override weights, threshold, or skip paths._`);
108
+ return lines.join("\n\n");
109
+ }
110
+ /**
111
+ * Build the PR review payload from a consolidation output. Pure, deterministic.
112
+ *
113
+ * Output shape mirrors the squad's terminal report, repurposed as a markdown PR
114
+ * review body:
115
+ * 1. Header with verdict + weighted score
116
+ * 2. Rubric scorecard (fenced code block — keeps the bars monospace)
117
+ * 3. Findings grouped by agent (Blockers + unjustified Majors expanded;
118
+ * Minor/Suggestion totals only)
119
+ * 4. Footer with attribution + override hint
120
+ *
121
+ * The action is chosen via `chooseGhAction` — caller passes it to
122
+ * `gh pr review --<action>`.
123
+ */
124
+ export function formatPrReview(consolidation, options = {}) {
125
+ const action = chooseGhAction(consolidation, options);
126
+ const sections = [];
127
+ sections.push(`## ${verdictHeader(consolidation)}`);
128
+ const rubricBlock = formatRubricBlock(consolidation.rubric);
129
+ if (rubricBlock)
130
+ sections.push(rubricBlock);
131
+ const findings = formatFindingsSection(consolidation);
132
+ if (findings)
133
+ sections.push(findings);
134
+ sections.push(formatFooter(consolidation, action, options));
135
+ const body = sections.join("\n\n") + "\n";
136
+ // Single-line summary for fallbacks. Capped at ~200 chars — gh accepts more,
137
+ // but PR review bodies that go in `--body` instead of `--body-file` get
138
+ // shell-quoted and long lines invite escaping bugs.
139
+ const c = consolidation.severity_counts;
140
+ const scoreSegment = consolidation.rubric
141
+ ? ` | score ${consolidation.rubric.weighted_score.toFixed(1)}/100`
142
+ : "";
143
+ const summary = `Squad: ${consolidation.verdict}${scoreSegment} | ${c.Blocker}B/${c.Major}M/${c.Minor}m/${c.Suggestion}s`;
144
+ return { body, action, summary };
145
+ }
146
+ //# sourceMappingURL=pr-review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr-review.js","sourceRoot":"","sources":["../../src/format/pr-review.ts"],"names":[],"mappings":"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"}