@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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +4 -2
- package/CHANGELOG.md +395 -8
- package/INSTALL.md +554 -0
- package/README.md +311 -25
- package/agents/{Skill-Squad-Dev.md → _shared/Skill-Squad-Dev.md} +30 -3
- package/agents/{Skill-Squad-Review.md → _shared/Skill-Squad-Review.md} +70 -0
- package/agents/{PO.md → product-owner.md} +33 -1
- package/agents/{Senior-Architect.md → senior-architect.md} +33 -1
- package/agents/{Senior-DBA.md → senior-dba.md} +33 -1
- package/agents/senior-dev-reviewer.md +640 -0
- package/agents/{Senior-Dev-Security.md → senior-dev-security.md} +33 -1
- package/agents/{Senior-Developer.md → senior-developer.md} +33 -1
- package/agents/{Senior-QA.md → senior-qa.md} +33 -1
- package/agents/{TechLead-Consolidator.md → tech-lead-consolidator.md} +7 -1
- package/agents/{TechLead-Planner.md → tech-lead-planner.md} +7 -1
- package/commands/brainstorm.md +21 -0
- package/commands/commit-suggest.md +12 -0
- package/commands/squad-review.md +10 -58
- package/commands/squad.md +11 -70
- package/dist/config/ownership-matrix.d.ts +24 -2
- package/dist/config/ownership-matrix.js +466 -139
- package/dist/config/ownership-matrix.js.map +1 -1
- package/dist/config/squad-yaml.d.ts +242 -0
- package/dist/config/squad-yaml.js +403 -0
- package/dist/config/squad-yaml.js.map +1 -0
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/format/pr-review.d.ts +61 -0
- package/dist/format/pr-review.js +146 -0
- package/dist/format/pr-review.js.map +1 -0
- package/dist/index.js +19 -13
- package/dist/index.js.map +1 -1
- package/dist/learning/format.d.ts +29 -0
- package/dist/learning/format.js +55 -0
- package/dist/learning/format.js.map +1 -0
- package/dist/learning/store.d.ts +102 -0
- package/dist/learning/store.js +169 -0
- package/dist/learning/store.js.map +1 -0
- package/dist/resources/agent-loader.d.ts +14 -2
- package/dist/resources/agent-loader.js +235 -53
- package/dist/resources/agent-loader.js.map +1 -1
- package/dist/tasks/select.d.ts +64 -0
- package/dist/tasks/select.js +84 -0
- package/dist/tasks/select.js.map +1 -0
- package/dist/tasks/store.d.ts +338 -0
- package/dist/tasks/store.js +321 -0
- package/dist/tasks/store.js.map +1 -0
- package/dist/tools/agents.js +4 -1
- package/dist/tools/agents.js.map +1 -1
- package/dist/tools/compose-advisory-bundle.d.ts +5 -5
- package/dist/tools/compose-advisory-bundle.js +24 -12
- package/dist/tools/compose-advisory-bundle.js.map +1 -1
- package/dist/tools/compose-prd-parse.d.ts +53 -0
- package/dist/tools/compose-prd-parse.js +167 -0
- package/dist/tools/compose-prd-parse.js.map +1 -0
- package/dist/tools/compose-squad-workflow.d.ts +28 -10
- package/dist/tools/compose-squad-workflow.js +0 -0
- package/dist/tools/compose-squad-workflow.js.map +1 -1
- package/dist/tools/consolidate.d.ts +55 -4
- package/dist/tools/consolidate.js +87 -15
- package/dist/tools/consolidate.js.map +1 -1
- package/dist/tools/expand-task.d.ts +51 -0
- package/dist/tools/expand-task.js +35 -0
- package/dist/tools/expand-task.js.map +1 -0
- package/dist/tools/list-tasks.d.ts +31 -0
- package/dist/tools/list-tasks.js +50 -0
- package/dist/tools/list-tasks.js.map +1 -0
- package/dist/tools/next-task.d.ts +37 -0
- package/dist/tools/next-task.js +60 -0
- package/dist/tools/next-task.js.map +1 -0
- package/dist/tools/read-learnings.d.ts +53 -0
- package/dist/tools/read-learnings.js +72 -0
- package/dist/tools/read-learnings.js.map +1 -0
- package/dist/tools/read-squad-config.d.ts +23 -0
- package/dist/tools/read-squad-config.js +34 -0
- package/dist/tools/read-squad-config.js.map +1 -0
- package/dist/tools/record-learning.d.ts +62 -0
- package/dist/tools/record-learning.js +80 -0
- package/dist/tools/record-learning.js.map +1 -0
- package/dist/tools/record-tasks.d.ts +71 -0
- package/dist/tools/record-tasks.js +45 -0
- package/dist/tools/record-tasks.js.map +1 -0
- package/dist/tools/registry.d.ts +1 -1
- package/dist/tools/registry.js +71 -39
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/score-rubric.d.ts +74 -0
- package/dist/tools/score-rubric.js +140 -0
- package/dist/tools/score-rubric.js.map +1 -0
- package/dist/tools/slice-files-for-task.d.ts +31 -0
- package/dist/tools/slice-files-for-task.js +52 -0
- package/dist/tools/slice-files-for-task.js.map +1 -0
- package/dist/tools/update-task-status.d.ts +29 -0
- package/dist/tools/update-task-status.js +35 -0
- package/dist/tools/update-task-status.js.map +1 -0
- package/dist/util/override-allowlist.d.ts +63 -0
- package/dist/util/override-allowlist.js +191 -0
- package/dist/util/override-allowlist.js.map +1 -0
- package/dist/util/path-internal.d.ts +6 -0
- package/dist/util/path-internal.js +27 -0
- package/dist/util/path-internal.js.map +1 -0
- package/dist/util/path-safety.js +0 -0
- package/dist/util/path-safety.js.map +1 -1
- package/package.json +5 -1
- package/skills/brainstorm/SKILL.md +284 -0
- package/skills/commit-suggest/SKILL.md +255 -0
- package/skills/squad/SKILL.md +454 -0
- package/tools/post-review.mjs +212 -0
- package/agents/Senior-Dev-Reviewer.md +0 -104
- /package/agents/{_Severity-and-Ownership.md → _shared/_Severity-and-Ownership.md} +0 -0
package/dist/tools/agents.js
CHANGED
|
@@ -6,7 +6,10 @@ export const listAgentsTool = {
|
|
|
6
6
|
name: 'list_agents',
|
|
7
7
|
description: 'List all configured agents with their roles, ownership, and naming conventions.',
|
|
8
8
|
schema: listSchema,
|
|
9
|
-
handler: async () =>
|
|
9
|
+
handler: async () => {
|
|
10
|
+
const { rawDir, explicit } = getLocalDir();
|
|
11
|
+
return { agents: await listAvailableAgents(), local_dir: rawDir, local_dir_explicit: explicit };
|
|
12
|
+
},
|
|
10
13
|
};
|
|
11
14
|
const getSchema = z.object({
|
|
12
15
|
name: z.enum(Object.keys(AGENTS)),
|
package/dist/tools/agents.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/tools/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,MAAM,EAAkB,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEtH,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAEhC,MAAM,CAAC,MAAM,cAAc,GAA+B;IACxD,IAAI,EAAE,aAAa;IACnB,WAAW,EAAE,iFAAiF;IAC9F,MAAM,EAAE,UAAU;IAClB,OAAO,EAAE,KAAK,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/tools/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,MAAM,EAAkB,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEtH,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAEhC,MAAM,CAAC,MAAM,cAAc,GAA+B;IACxD,IAAI,EAAE,aAAa;IACnB,WAAW,EAAE,iFAAiF;IAC9F,MAAM,EAAE,UAAU;IAClB,OAAO,EAAE,KAAK,IAAI,EAAE;QAClB,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,WAAW,EAAE,CAAC;QAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,CAAC;IAClG,CAAC;CACF,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAgC,CAAC;CACjE,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAA8B;IAC/D,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EAAE,4GAA4G;IACzH,MAAM,EAAE,SAAS;IACjB,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5B,IAAI;QACJ,UAAU,EAAE,MAAM,mBAAmB,CAAC,IAAI,CAAC;KAC5C,CAAC;CACH,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;CAC7C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAA+B;IAC7D,IAAI,EAAE,mBAAmB;IACzB,WAAW,EACT,qKAAqK;IACvK,MAAM,EAAE,UAAU;IAClB,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC;CACrD,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { z } from
|
|
2
|
-
import type { ToolDef } from
|
|
3
|
-
import { type ComposeWorkflowOutput } from
|
|
4
|
-
import { type SliceOutput } from
|
|
5
|
-
import { type ValidatePlanOutput } from
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ToolDef } from "./registry.js";
|
|
3
|
+
import { type ComposeWorkflowOutput } from "./compose-squad-workflow.js";
|
|
4
|
+
import { type SliceOutput } from "./slice-files.js";
|
|
5
|
+
import { type ValidatePlanOutput } from "./validate-plan-text.js";
|
|
6
6
|
declare const schema: z.ZodObject<{
|
|
7
7
|
workspace_root: z.ZodEffects<z.ZodString, string, string>;
|
|
8
8
|
user_prompt: z.ZodEffects<z.ZodString, string, string>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { z } from
|
|
2
|
-
import { composeSquadWorkflow } from
|
|
3
|
-
import { sliceFilesForAgent } from
|
|
4
|
-
import { validatePlanText } from
|
|
5
|
-
import { AGENT_NAMES_TUPLE } from
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { composeSquadWorkflow, } from "./compose-squad-workflow.js";
|
|
3
|
+
import { sliceFilesForAgent } from "./slice-files.js";
|
|
4
|
+
import { validatePlanText, } from "./validate-plan-text.js";
|
|
5
|
+
import { AGENT_NAMES_TUPLE } from "../config/ownership-matrix.js";
|
|
6
6
|
const safeString = (max) => z
|
|
7
7
|
.string()
|
|
8
8
|
.max(max)
|
|
9
|
-
.refine((s) => s.indexOf(
|
|
9
|
+
.refine((s) => s.indexOf(" ") === -1, "must not contain NUL byte");
|
|
10
10
|
const schema = z.object({
|
|
11
11
|
workspace_root: safeString(4096),
|
|
12
12
|
user_prompt: safeString(8192),
|
|
@@ -15,7 +15,14 @@ const schema = z.object({
|
|
|
15
15
|
staged_only: z.boolean().optional().default(false),
|
|
16
16
|
read_content: z.boolean().optional().default(true),
|
|
17
17
|
force_work_type: z
|
|
18
|
-
.enum([
|
|
18
|
+
.enum([
|
|
19
|
+
"Feature",
|
|
20
|
+
"Bug Fix",
|
|
21
|
+
"Refactor",
|
|
22
|
+
"Performance",
|
|
23
|
+
"Security",
|
|
24
|
+
"Business Rule",
|
|
25
|
+
])
|
|
19
26
|
.optional(),
|
|
20
27
|
force_agents: z.array(z.enum(AGENT_NAMES_TUPLE)).optional().default([]),
|
|
21
28
|
risk_signals: z
|
|
@@ -43,7 +50,12 @@ export async function composeAdvisoryBundle(input) {
|
|
|
43
50
|
if (input.risk_signals !== undefined)
|
|
44
51
|
workflowInput.risk_signals = input.risk_signals;
|
|
45
52
|
const workflow = await composeSquadWorkflow(workflowInput);
|
|
46
|
-
|
|
53
|
+
// Use the FILTERED list (skip_paths already applied by composeSquadWorkflow).
|
|
54
|
+
// Slicing has to operate on the same set of files the squad was selected over,
|
|
55
|
+
// otherwise an agent would receive paths the composer just hid.
|
|
56
|
+
const allChanged = workflow.changed_files.files.map((f) => f.path);
|
|
57
|
+
const skippedSet = new Set(workflow.skipped_paths);
|
|
58
|
+
const filePaths = allChanged.filter((p) => !skippedSet.has(p));
|
|
47
59
|
const slices_by_agent = {};
|
|
48
60
|
for (const agent of workflow.squad.agents) {
|
|
49
61
|
const slice = await sliceFilesForAgent({
|
|
@@ -58,10 +70,10 @@ export async function composeAdvisoryBundle(input) {
|
|
|
58
70
|
return { workflow, slices_by_agent, plan_validation };
|
|
59
71
|
}
|
|
60
72
|
export const composeAdvisoryBundleTool = {
|
|
61
|
-
name:
|
|
62
|
-
description:
|
|
63
|
-
|
|
64
|
-
|
|
73
|
+
name: "compose_advisory_bundle",
|
|
74
|
+
description: "End-to-end advisory dispatch bundle. Runs compose_squad_workflow, then slice_files_for_agent for each " +
|
|
75
|
+
"selected agent, then validate_plan_text on the supplied plan. Returns the union output ready for the " +
|
|
76
|
+
"host to dispatch parallel advisory reviews.",
|
|
65
77
|
schema,
|
|
66
78
|
handler: composeAdvisoryBundle,
|
|
67
79
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose-advisory-bundle.js","sourceRoot":"","sources":["../../src/tools/compose-advisory-bundle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,
|
|
1
|
+
{"version":3,"file":"compose-advisory-bundle.js","sourceRoot":"","sources":["../../src/tools/compose-advisory-bundle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ToolDef } from "./registry.js";
|
|
3
|
+
declare const schema: z.ZodObject<{
|
|
4
|
+
workspace_root: z.ZodString;
|
|
5
|
+
/** PRD text. Free-form; the LLM is responsible for extracting structure. */
|
|
6
|
+
prd_text: z.ZodString;
|
|
7
|
+
/** Optional max number of tasks to extract (soft hint passed to the LLM). */
|
|
8
|
+
max_tasks: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
9
|
+
/**
|
|
10
|
+
* When true (default), include the existing tasks in the prompt so the LLM
|
|
11
|
+
* doesn't duplicate ids or re-decompose work already captured.
|
|
12
|
+
*/
|
|
13
|
+
include_existing: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
14
|
+
}, "strip", z.ZodTypeAny, {
|
|
15
|
+
workspace_root: string;
|
|
16
|
+
prd_text: string;
|
|
17
|
+
max_tasks: number;
|
|
18
|
+
include_existing: boolean;
|
|
19
|
+
}, {
|
|
20
|
+
workspace_root: string;
|
|
21
|
+
prd_text: string;
|
|
22
|
+
max_tasks?: number | undefined;
|
|
23
|
+
include_existing?: boolean | undefined;
|
|
24
|
+
}>;
|
|
25
|
+
type Input = z.infer<typeof schema>;
|
|
26
|
+
export interface ComposePrdParseOutput {
|
|
27
|
+
/** Markdown prompt to feed to the host LLM. */
|
|
28
|
+
prompt: string;
|
|
29
|
+
/** JSON schema the LLM is instructed to emit. Caller validates against this. */
|
|
30
|
+
output_schema: Record<string, unknown>;
|
|
31
|
+
/** Existing tasks, injected into the prompt and returned for caller convenience. */
|
|
32
|
+
existing: {
|
|
33
|
+
id: number;
|
|
34
|
+
title: string;
|
|
35
|
+
status: string;
|
|
36
|
+
}[];
|
|
37
|
+
/** Highest existing id, so caller can pre-allocate or warn the LLM. */
|
|
38
|
+
next_id_floor: number;
|
|
39
|
+
/** Recommended next step (string, for the host LLM): call record_tasks. */
|
|
40
|
+
next_action: "call_record_tasks_with_user_confirmation";
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Build the prompt + output schema for decomposing a PRD into squad-mcp tasks.
|
|
44
|
+
* Pure-MCP: this tool does NOT call any LLM. It returns the materials the host
|
|
45
|
+
* LLM (Claude Code, Cursor, etc.) needs to do the decomposition itself, and
|
|
46
|
+
* then call `record_tasks` with the result.
|
|
47
|
+
*
|
|
48
|
+
* Why pure-MCP: keeps squad-mcp deterministic and free of provider keys; the
|
|
49
|
+
* host already pays for inference and has the user's consent to do so.
|
|
50
|
+
*/
|
|
51
|
+
export declare function composePrdParseTool(input: Input): Promise<ComposePrdParseOutput>;
|
|
52
|
+
export declare const composePrdParseToolDef: ToolDef<typeof schema>;
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { readTasks } from "../tasks/store.js";
|
|
3
|
+
import { readSquadYaml } from "../config/squad-yaml.js";
|
|
4
|
+
import { resolveSafePath, createSafePathContext } from "../util/path-safety.js";
|
|
5
|
+
import { AGENT_NAMES_TUPLE } from "../config/ownership-matrix.js";
|
|
6
|
+
const schema = z.object({
|
|
7
|
+
workspace_root: z.string().min(1).max(4096),
|
|
8
|
+
/** PRD text. Free-form; the LLM is responsible for extracting structure. */
|
|
9
|
+
prd_text: z.string().min(1).max(200_000),
|
|
10
|
+
/** Optional max number of tasks to extract (soft hint passed to the LLM). */
|
|
11
|
+
max_tasks: z.number().int().positive().max(200).optional().default(40),
|
|
12
|
+
/**
|
|
13
|
+
* When true (default), include the existing tasks in the prompt so the LLM
|
|
14
|
+
* doesn't duplicate ids or re-decompose work already captured.
|
|
15
|
+
*/
|
|
16
|
+
include_existing: z.boolean().optional().default(true),
|
|
17
|
+
});
|
|
18
|
+
const TASK_INPUT_SCHEMA = {
|
|
19
|
+
type: "object",
|
|
20
|
+
properties: {
|
|
21
|
+
title: { type: "string", maxLength: 512 },
|
|
22
|
+
description: { type: "string", maxLength: 4096 },
|
|
23
|
+
dependencies: {
|
|
24
|
+
type: "array",
|
|
25
|
+
items: { type: "integer", minimum: 1 },
|
|
26
|
+
description: "Task IDs this task depends on. May reference existing tasks or other tasks in the same parsed batch (forward refs allowed — IDs assigned by record_tasks in array order starting from next_id_floor + 1).",
|
|
27
|
+
},
|
|
28
|
+
priority: { type: "string", enum: ["low", "medium", "high"] },
|
|
29
|
+
details: { type: "string", maxLength: 16384 },
|
|
30
|
+
test_strategy: { type: "string", maxLength: 4096 },
|
|
31
|
+
scope: {
|
|
32
|
+
type: "string",
|
|
33
|
+
maxLength: 512,
|
|
34
|
+
description: "Glob limiting which files this task touches (e.g. 'src/auth/**'). Optional. Used by slice_files_for_task and the advisory squad to narrow review.",
|
|
35
|
+
},
|
|
36
|
+
agent_hints: {
|
|
37
|
+
type: "array",
|
|
38
|
+
items: { type: "string", enum: AGENT_NAMES_TUPLE },
|
|
39
|
+
description: "Subset of squad agents most relevant for this task. Empty/absent means repo-wide.",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
required: ["title"],
|
|
43
|
+
};
|
|
44
|
+
const OUTPUT_SCHEMA = {
|
|
45
|
+
type: "object",
|
|
46
|
+
properties: {
|
|
47
|
+
tasks: {
|
|
48
|
+
type: "array",
|
|
49
|
+
items: TASK_INPUT_SCHEMA,
|
|
50
|
+
maxItems: 200,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
required: ["tasks"],
|
|
54
|
+
};
|
|
55
|
+
function renderExisting(existing) {
|
|
56
|
+
if (existing.length === 0) {
|
|
57
|
+
return "_(no existing tasks — this is a fresh decomposition)_";
|
|
58
|
+
}
|
|
59
|
+
const lines = existing.map((t) => `- ${t.id}. [${t.status}] ${t.title}`);
|
|
60
|
+
return lines.join("\n");
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Build the prompt + output schema for decomposing a PRD into squad-mcp tasks.
|
|
64
|
+
* Pure-MCP: this tool does NOT call any LLM. It returns the materials the host
|
|
65
|
+
* LLM (Claude Code, Cursor, etc.) needs to do the decomposition itself, and
|
|
66
|
+
* then call `record_tasks` with the result.
|
|
67
|
+
*
|
|
68
|
+
* Why pure-MCP: keeps squad-mcp deterministic and free of provider keys; the
|
|
69
|
+
* host already pays for inference and has the user's consent to do so.
|
|
70
|
+
*/
|
|
71
|
+
export async function composePrdParseTool(input) {
|
|
72
|
+
const ctx = createSafePathContext();
|
|
73
|
+
const safeRoot = await resolveSafePath(input.workspace_root, ".", ctx);
|
|
74
|
+
const config = await readSquadYaml(safeRoot);
|
|
75
|
+
const existingFile = input.include_existing
|
|
76
|
+
? await readTasks(safeRoot, { configuredPath: config.tasks.path })
|
|
77
|
+
: { tasks: [], version: 1 };
|
|
78
|
+
const nextIdFloor = existingFile.tasks.reduce((m, t) => Math.max(m, t.id), 0);
|
|
79
|
+
const existingSection = input.include_existing
|
|
80
|
+
? `## Existing tasks (do not duplicate)
|
|
81
|
+
|
|
82
|
+
The repo already has these tasks. Do NOT redecompose work they cover; reference
|
|
83
|
+
their IDs in \`dependencies\` if your new tasks depend on them.
|
|
84
|
+
|
|
85
|
+
${renderExisting(existingFile.tasks)}
|
|
86
|
+
|
|
87
|
+
The next available task ID will be ${nextIdFloor + 1}.`
|
|
88
|
+
: `## Existing tasks
|
|
89
|
+
_(skipped — caller passed \`include_existing: false\`)_`;
|
|
90
|
+
const agentList = AGENT_NAMES_TUPLE.filter((a) => a !== "tech-lead-planner" && a !== "tech-lead-consolidator").join(", ");
|
|
91
|
+
const prompt = `# Decompose the PRD below into atomic, ordered tasks.
|
|
92
|
+
|
|
93
|
+
You are decomposing a Product Requirements Document into a list of tasks for the
|
|
94
|
+
\`squad-mcp\` task store. The tasks will be reviewed by the user, then bulk-recorded
|
|
95
|
+
via the \`record_tasks\` MCP tool, then executed one-at-a-time by the squad.
|
|
96
|
+
|
|
97
|
+
## Output contract
|
|
98
|
+
|
|
99
|
+
Emit ONE JSON object matching the schema below. No prose before or after — your
|
|
100
|
+
entire response is parsed as JSON.
|
|
101
|
+
|
|
102
|
+
\`\`\`json
|
|
103
|
+
${JSON.stringify(OUTPUT_SCHEMA, null, 2)}
|
|
104
|
+
\`\`\`
|
|
105
|
+
|
|
106
|
+
## Decomposition rules
|
|
107
|
+
|
|
108
|
+
1. **Atomic** — each task should be small enough that a developer can complete
|
|
109
|
+
it in a single sitting (one PR, one commit). If a task feels like "the whole
|
|
110
|
+
feature", break it down further.
|
|
111
|
+
2. **Ordered via dependencies** — if task B can't start until task A is done,
|
|
112
|
+
set \`B.dependencies = [A's id]\`. IDs are assigned in array order starting
|
|
113
|
+
from ${nextIdFloor + 1}.
|
|
114
|
+
3. **Cap at ${input.max_tasks} tasks** — if the PRD is huge, prefer fewer
|
|
115
|
+
higher-level tasks; the squad can \`expand_task\` later as needed.
|
|
116
|
+
4. **Scope when sensible** — if a task touches a clearly-bounded directory
|
|
117
|
+
tree (e.g. just \`src/auth/\`), set \`scope\` to a glob (\`src/auth/**\`).
|
|
118
|
+
Skip \`scope\` for repo-wide tasks (config, docs, refactors).
|
|
119
|
+
5. **Agent hints when obvious** — \`agent_hints\` narrows which squad agents
|
|
120
|
+
review the task. Available: ${agentList}. Pick 1-3 agents whose ownership
|
|
121
|
+
genuinely covers the task. Skip when the task spans multiple domains.
|
|
122
|
+
6. **Test strategy** — for code tasks, write 1-3 sentences on how to verify.
|
|
123
|
+
Skip for non-code tasks (docs, config, deps).
|
|
124
|
+
7. **Priority** — use \`high\` for blockers / security / critical path,
|
|
125
|
+
\`medium\` for normal work, \`low\` for nice-to-haves. Default \`medium\`.
|
|
126
|
+
8. **No AI fluff** — \`title\` and \`description\` are read by humans.
|
|
127
|
+
Lead with the action verb. Example: "Add CSRF token to checkout flow",
|
|
128
|
+
not "Implementation of CSRF protection mechanism for the checkout module".
|
|
129
|
+
|
|
130
|
+
## What NOT to do
|
|
131
|
+
|
|
132
|
+
- Don't generate "setup", "init", or "scaffolding" tasks unless the PRD
|
|
133
|
+
explicitly requires them. Bias toward what the PRD actually asks for.
|
|
134
|
+
- Don't invent tasks. If the PRD doesn't mention testing, don't add a
|
|
135
|
+
generic "write tests" task. The host can ask separately.
|
|
136
|
+
- Don't reference task IDs that don't exist in either the existing list
|
|
137
|
+
or your own batch.
|
|
138
|
+
- Don't emit a self-dependency (a task depending on itself).
|
|
139
|
+
|
|
140
|
+
${existingSection}
|
|
141
|
+
|
|
142
|
+
## PRD
|
|
143
|
+
|
|
144
|
+
${input.prd_text}
|
|
145
|
+
|
|
146
|
+
## Now emit the JSON
|
|
147
|
+
|
|
148
|
+
Remember: ONE JSON object, schema above, no prose before or after.`;
|
|
149
|
+
return {
|
|
150
|
+
prompt,
|
|
151
|
+
output_schema: OUTPUT_SCHEMA,
|
|
152
|
+
existing: existingFile.tasks.map((t) => ({
|
|
153
|
+
id: t.id,
|
|
154
|
+
title: t.title,
|
|
155
|
+
status: t.status,
|
|
156
|
+
})),
|
|
157
|
+
next_id_floor: nextIdFloor,
|
|
158
|
+
next_action: "call_record_tasks_with_user_confirmation",
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
export const composePrdParseToolDef = {
|
|
162
|
+
name: "compose_prd_parse",
|
|
163
|
+
description: "Build a prompt + JSON schema for the host LLM to decompose a PRD into atomic tasks. Pure-MCP: does NOT call any LLM. Caller (skill/host) feeds the prompt to its LLM, receives JSON, then calls record_tasks with user confirmation. Includes existing tasks in the prompt to prevent duplication.",
|
|
164
|
+
schema,
|
|
165
|
+
handler: composePrdParseTool,
|
|
166
|
+
};
|
|
167
|
+
//# sourceMappingURL=compose-prd-parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compose-prd-parse.js","sourceRoot":"","sources":["../../src/tools/compose-prd-parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { z } from
|
|
2
|
-
import type { ToolDef } from
|
|
3
|
-
import { type DetectChangedFilesOutput } from
|
|
4
|
-
import { type ClassifyOutput } from
|
|
5
|
-
import { type RiskOutput } from
|
|
6
|
-
import { type SelectSquadOutput } from
|
|
7
|
-
import { type WorkType } from
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ToolDef } from "./registry.js";
|
|
3
|
+
import { type DetectChangedFilesOutput } from "./detect-changed-files.js";
|
|
4
|
+
import { type ClassifyOutput } from "./classify-work-type.js";
|
|
5
|
+
import { type RiskOutput } from "./score-risk.js";
|
|
6
|
+
import { type SelectSquadOutput } from "./select-squad.js";
|
|
7
|
+
import { type AgentName, type WorkType } from "../config/ownership-matrix.js";
|
|
8
|
+
import { type ResolvedSquadConfig } from "../config/squad-yaml.js";
|
|
8
9
|
declare const schema: z.ZodObject<{
|
|
9
10
|
workspace_root: z.ZodEffects<z.ZodString, string, string>;
|
|
10
11
|
user_prompt: z.ZodEffects<z.ZodString, string, string>;
|
|
@@ -12,7 +13,7 @@ declare const schema: z.ZodObject<{
|
|
|
12
13
|
staged_only: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
13
14
|
read_content: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
14
15
|
force_work_type: z.ZodOptional<z.ZodEnum<["Feature", "Bug Fix", "Refactor", "Performance", "Security", "Business Rule"]>>;
|
|
15
|
-
force_agents: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodEnum<[
|
|
16
|
+
force_agents: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodEnum<[AgentName, ...AgentName[]]>, "many">>>;
|
|
16
17
|
risk_signals: z.ZodOptional<z.ZodObject<{
|
|
17
18
|
touches_auth: z.ZodOptional<z.ZodBoolean>;
|
|
18
19
|
touches_money: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -34,7 +35,7 @@ declare const schema: z.ZodObject<{
|
|
|
34
35
|
}>>;
|
|
35
36
|
}, "strip", z.ZodTypeAny, {
|
|
36
37
|
read_content: boolean;
|
|
37
|
-
force_agents:
|
|
38
|
+
force_agents: AgentName[];
|
|
38
39
|
workspace_root: string;
|
|
39
40
|
user_prompt: string;
|
|
40
41
|
staged_only: boolean;
|
|
@@ -51,7 +52,7 @@ declare const schema: z.ZodObject<{
|
|
|
51
52
|
workspace_root: string;
|
|
52
53
|
user_prompt: string;
|
|
53
54
|
read_content?: boolean | undefined;
|
|
54
|
-
force_agents?:
|
|
55
|
+
force_agents?: AgentName[] | undefined;
|
|
55
56
|
base_ref?: string | undefined;
|
|
56
57
|
staged_only?: boolean | undefined;
|
|
57
58
|
force_work_type?: "Feature" | "Bug Fix" | "Refactor" | "Performance" | "Security" | "Business Rule" | undefined;
|
|
@@ -78,6 +79,23 @@ export interface ComposeWorkflowOutput {
|
|
|
78
79
|
new_module: boolean;
|
|
79
80
|
api_contract_change: boolean;
|
|
80
81
|
};
|
|
82
|
+
/**
|
|
83
|
+
* Resolved `.squad.yaml` config (defaults filled in). `source` is null if no
|
|
84
|
+
* config file existed in workspace_root. Downstream callers (compose_advisory_bundle,
|
|
85
|
+
* apply_consolidation_rules) can lift weights/threshold/min_score from here.
|
|
86
|
+
*/
|
|
87
|
+
config: ResolvedSquadConfig;
|
|
88
|
+
/**
|
|
89
|
+
* Files removed from advisory by `config.skip_paths`. Surfaced so callers can
|
|
90
|
+
* see *why* the slice list got narrower.
|
|
91
|
+
*/
|
|
92
|
+
skipped_paths: string[];
|
|
93
|
+
/**
|
|
94
|
+
* Agents removed from the selected squad by `config.disable_agents`. Empty
|
|
95
|
+
* unless config disabled at least one of the agents the matrix would have
|
|
96
|
+
* picked.
|
|
97
|
+
*/
|
|
98
|
+
disabled_agents: AgentName[];
|
|
81
99
|
}
|
|
82
100
|
export declare function composeSquadWorkflow(input: Input): Promise<ComposeWorkflowOutput>;
|
|
83
101
|
export declare const composeSquadWorkflowTool: ToolDef<typeof schema>;
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compose-squad-workflow.js","sourceRoot":"","sources":["../../src/tools/compose-squad-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,
|
|
1
|
+
{"version":3,"file":"compose-squad-workflow.js","sourceRoot":"","sources":["../../src/tools/compose-squad-workflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { z } from
|
|
2
|
-
import type { ToolDef } from
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ToolDef } from "./registry.js";
|
|
3
|
+
import { type RubricOutput } from "./score-rubric.js";
|
|
3
4
|
declare const schema: z.ZodObject<{
|
|
4
5
|
reports: z.ZodArray<z.ZodObject<{
|
|
5
6
|
agent: z.ZodEnum<[import("../config/ownership-matrix.js").AgentName, ...import("../config/ownership-matrix.js").AgentName[]]>;
|
|
@@ -23,6 +24,14 @@ declare const schema: z.ZodObject<{
|
|
|
23
24
|
justified?: boolean | undefined;
|
|
24
25
|
}>, "many">;
|
|
25
26
|
not_evaluated: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
27
|
+
/**
|
|
28
|
+
* Optional dimension score 0-100 produced by the agent. When at least one
|
|
29
|
+
* report carries a score, the consolidator emits a rubric scorecard and the
|
|
30
|
+
* verdict can be downgraded if `min_score` is supplied. Backward compatible:
|
|
31
|
+
* pre-rubric clients omit this field and behave exactly as before.
|
|
32
|
+
*/
|
|
33
|
+
score: z.ZodOptional<z.ZodNumber>;
|
|
34
|
+
score_rationale: z.ZodOptional<z.ZodString>;
|
|
26
35
|
}, "strip", z.ZodTypeAny, {
|
|
27
36
|
agent: import("../config/ownership-matrix.js").AgentName;
|
|
28
37
|
findings: {
|
|
@@ -33,6 +42,8 @@ declare const schema: z.ZodObject<{
|
|
|
33
42
|
forwarded_to?: import("../config/ownership-matrix.js").AgentName | undefined;
|
|
34
43
|
}[];
|
|
35
44
|
not_evaluated: boolean;
|
|
45
|
+
score?: number | undefined;
|
|
46
|
+
score_rationale?: string | undefined;
|
|
36
47
|
}, {
|
|
37
48
|
agent: import("../config/ownership-matrix.js").AgentName;
|
|
38
49
|
findings: {
|
|
@@ -42,9 +53,28 @@ declare const schema: z.ZodObject<{
|
|
|
42
53
|
forwarded_to?: import("../config/ownership-matrix.js").AgentName | undefined;
|
|
43
54
|
justified?: boolean | undefined;
|
|
44
55
|
}[];
|
|
56
|
+
score?: number | undefined;
|
|
45
57
|
not_evaluated?: boolean | undefined;
|
|
58
|
+
score_rationale?: string | undefined;
|
|
46
59
|
}>, "many">;
|
|
60
|
+
/**
|
|
61
|
+
* Optional weight overrides for the rubric (sum must be 100). Forwarded to
|
|
62
|
+
* `score_rubric`. Ignored when no report carries a score.
|
|
63
|
+
*/
|
|
64
|
+
weights: z.ZodOptional<z.ZodRecord<z.ZodEnum<[import("../config/ownership-matrix.js").AgentName, ...import("../config/ownership-matrix.js").AgentName[]]>, z.ZodNumber>>;
|
|
65
|
+
/**
|
|
66
|
+
* Per-dimension threshold for flagging individual scores. Defaults to 75.
|
|
67
|
+
*/
|
|
68
|
+
threshold: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
69
|
+
/**
|
|
70
|
+
* If supplied AND the weighted score is below this floor AND severity rules
|
|
71
|
+
* would otherwise return APPROVED, downgrade to CHANGES_REQUIRED. Lets a
|
|
72
|
+
* project enforce a "minimum quality bar" beyond just absence of Blockers.
|
|
73
|
+
* Independent of `threshold` (which flags individual dimensions).
|
|
74
|
+
*/
|
|
75
|
+
min_score: z.ZodOptional<z.ZodNumber>;
|
|
47
76
|
}, "strip", z.ZodTypeAny, {
|
|
77
|
+
threshold: number;
|
|
48
78
|
reports: {
|
|
49
79
|
agent: import("../config/ownership-matrix.js").AgentName;
|
|
50
80
|
findings: {
|
|
@@ -55,7 +85,11 @@ declare const schema: z.ZodObject<{
|
|
|
55
85
|
forwarded_to?: import("../config/ownership-matrix.js").AgentName | undefined;
|
|
56
86
|
}[];
|
|
57
87
|
not_evaluated: boolean;
|
|
88
|
+
score?: number | undefined;
|
|
89
|
+
score_rationale?: string | undefined;
|
|
58
90
|
}[];
|
|
91
|
+
weights?: Partial<Record<import("../config/ownership-matrix.js").AgentName, number>> | undefined;
|
|
92
|
+
min_score?: number | undefined;
|
|
59
93
|
}, {
|
|
60
94
|
reports: {
|
|
61
95
|
agent: import("../config/ownership-matrix.js").AgentName;
|
|
@@ -66,12 +100,17 @@ declare const schema: z.ZodObject<{
|
|
|
66
100
|
forwarded_to?: import("../config/ownership-matrix.js").AgentName | undefined;
|
|
67
101
|
justified?: boolean | undefined;
|
|
68
102
|
}[];
|
|
103
|
+
score?: number | undefined;
|
|
69
104
|
not_evaluated?: boolean | undefined;
|
|
105
|
+
score_rationale?: string | undefined;
|
|
70
106
|
}[];
|
|
107
|
+
weights?: Partial<Record<import("../config/ownership-matrix.js").AgentName, number>> | undefined;
|
|
108
|
+
threshold?: number | undefined;
|
|
109
|
+
min_score?: number | undefined;
|
|
71
110
|
}>;
|
|
72
111
|
type Input = z.infer<typeof schema>;
|
|
73
|
-
export type Verdict =
|
|
74
|
-
export type Severity =
|
|
112
|
+
export type Verdict = "APPROVED" | "CHANGES_REQUIRED" | "REJECTED";
|
|
113
|
+
export type Severity = "Blocker" | "Major" | "Minor" | "Suggestion";
|
|
75
114
|
export interface ConsolidationOutput {
|
|
76
115
|
verdict: Verdict;
|
|
77
116
|
blockers: {
|
|
@@ -91,6 +130,18 @@ export interface ConsolidationOutput {
|
|
|
91
130
|
severity_counts: Record<Severity, number>;
|
|
92
131
|
agents_involved: string[];
|
|
93
132
|
summary: string;
|
|
133
|
+
/**
|
|
134
|
+
* Weighted-rubric scorecard if any report carried a score, else null.
|
|
135
|
+
* Independent of verdict — verdict logic preserves the legacy severity rules,
|
|
136
|
+
* extended only by the optional `min_score` floor.
|
|
137
|
+
*/
|
|
138
|
+
rubric: RubricOutput | null;
|
|
139
|
+
/**
|
|
140
|
+
* True iff the verdict was downgraded from APPROVED to CHANGES_REQUIRED
|
|
141
|
+
* because the weighted score fell below `min_score`. Helps callers explain
|
|
142
|
+
* the downgrade in their output.
|
|
143
|
+
*/
|
|
144
|
+
downgraded_by_score: boolean;
|
|
94
145
|
}
|
|
95
146
|
export declare function applyConsolidationRules(input: Input): ConsolidationOutput;
|
|
96
147
|
export declare const applyConsolidationRulesTool: ToolDef<typeof schema>;
|