@gempack/squad-mcp 0.5.0 → 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 (96) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +3 -2
  3. package/CHANGELOG.md +260 -17
  4. package/INSTALL.md +156 -24
  5. package/README.md +279 -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 +1 -1
  38. package/dist/resources/agent-loader.js +53 -40
  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 +4 -1
  92. package/skills/squad/SKILL.md +454 -0
  93. package/tools/post-review.mjs +212 -0
  94. /package/agents/{Skill-Squad-Dev.md → _shared/Skill-Squad-Dev.md} +0 -0
  95. /package/agents/{Skill-Squad-Review.md → _shared/Skill-Squad-Review.md} +0 -0
  96. /package/agents/{_Severity-and-Ownership.md → _shared/_Severity-and-Ownership.md} +0 -0
@@ -0,0 +1,321 @@
1
+ import { promises as fs } from "node:fs";
2
+ import path from "node:path";
3
+ import { z } from "zod";
4
+ import { AGENT_NAMES_TUPLE } from "../config/ownership-matrix.js";
5
+ import { SquadError } from "../errors.js";
6
+ import { logger } from "../observability/logger.js";
7
+ /**
8
+ * Mutable JSON store for tasks. Lives at `.squad/tasks.json` (path overridable
9
+ * via `.squad.yaml.tasks.path`). Distinct from learnings/ which is JSONL +
10
+ * append-only — tasks mutate (status flips, subtasks expand) so JSON with
11
+ * atomic write (tmp + rename) is the right primitive.
12
+ *
13
+ * Schema is small on purpose. Inspired by claude-task-master but adapted to
14
+ * squad-mcp primitives:
15
+ * - `scope`: glob limiting which files this task touches (reuses matchesGlob)
16
+ * - `agent_hints`: which advisory agents are relevant for this task
17
+ *
18
+ * No `tags` system in V1 — single linear list. Add later if multi-feature
19
+ * parallel work in the same repo becomes a real need.
20
+ */
21
+ const taskStatusSchema = z.enum([
22
+ "pending",
23
+ "in-progress",
24
+ "review",
25
+ "done",
26
+ "blocked",
27
+ "cancelled",
28
+ ]);
29
+ const taskPrioritySchema = z.enum(["low", "medium", "high"]);
30
+ const subtaskSchema = z.object({
31
+ id: z.number().int().positive(),
32
+ title: z.string().min(1).max(512),
33
+ description: z.string().max(4096).optional(),
34
+ status: taskStatusSchema,
35
+ dependencies: z.array(z.number().int().positive()).max(50).default([]),
36
+ details: z.string().max(8192).optional(),
37
+ });
38
+ const taskSchema = z.object({
39
+ id: z.number().int().positive(),
40
+ title: z.string().min(1).max(512),
41
+ description: z.string().max(4096).optional(),
42
+ status: taskStatusSchema,
43
+ dependencies: z.array(z.number().int().positive()).max(50).default([]),
44
+ priority: taskPrioritySchema.default("medium"),
45
+ details: z.string().max(16384).optional(),
46
+ test_strategy: z.string().max(4096).optional(),
47
+ /**
48
+ * Glob limiting which files belong to this task (e.g. "src/auth/**"). Used
49
+ * by slice_files_for_task. Optional — without scope, the task is repo-wide.
50
+ */
51
+ scope: z.string().min(1).max(512).optional(),
52
+ /**
53
+ * Subset of squad agents most relevant for this task. Used by /squad-task
54
+ * to narrow the advisory squad. Optional — without hints, the task uses
55
+ * the standard select_squad heuristic.
56
+ */
57
+ agent_hints: z
58
+ .array(z.enum(AGENT_NAMES_TUPLE))
59
+ .max(AGENT_NAMES_TUPLE.length)
60
+ .optional(),
61
+ subtasks: z.array(subtaskSchema).max(50).default([]),
62
+ /** ISO timestamp set on first record. */
63
+ created_at: z.string().min(1).max(40),
64
+ /** ISO timestamp updated on every mutation (status change, subtask add, etc). */
65
+ updated_at: z.string().min(1).max(40),
66
+ });
67
+ const tasksFileSchema = z.object({
68
+ /** Schema version — bump when breaking changes ship. Readers reject newer versions. */
69
+ version: z.literal(1).default(1),
70
+ tasks: z.array(taskSchema).max(2000),
71
+ });
72
+ export const DEFAULT_TASKS_PATH = ".squad/tasks.json";
73
+ const cache = new Map();
74
+ export function __resetTasksStoreCacheForTests() {
75
+ cache.clear();
76
+ }
77
+ function resolveTasksFile(workspaceRoot, configuredPath) {
78
+ return path.resolve(workspaceRoot, configuredPath ?? DEFAULT_TASKS_PATH);
79
+ }
80
+ const EMPTY_FILE = { version: 1, tasks: [] };
81
+ /**
82
+ * Read tasks.json. Returns an empty file shape if the file does not exist
83
+ * (a fresh repo with no tasks is the common case). Cached by mtime.
84
+ */
85
+ export async function readTasks(workspaceRoot, options = {}) {
86
+ const filePath = resolveTasksFile(workspaceRoot, options.configuredPath);
87
+ const absRoot = path.resolve(workspaceRoot);
88
+ let stat;
89
+ try {
90
+ stat = await fs.stat(filePath);
91
+ }
92
+ catch {
93
+ return EMPTY_FILE;
94
+ }
95
+ if (!stat.isFile()) {
96
+ return EMPTY_FILE;
97
+ }
98
+ const cached = cache.get(absRoot);
99
+ if (cached &&
100
+ cached.filePath === filePath &&
101
+ cached.mtimeMs === stat.mtimeMs) {
102
+ return cached.data;
103
+ }
104
+ let raw;
105
+ try {
106
+ raw = await fs.readFile(filePath, "utf8");
107
+ }
108
+ catch (err) {
109
+ throw new SquadError("CONFIG_READ_FAILED", `failed to read tasks file ${filePath}: ${err.message}`, { source: filePath });
110
+ }
111
+ let parsed;
112
+ try {
113
+ parsed = JSON.parse(raw);
114
+ }
115
+ catch (err) {
116
+ throw new SquadError("INVALID_INPUT", `${filePath}: invalid JSON: ${err.message}`, { source: filePath });
117
+ }
118
+ const validated = tasksFileSchema.safeParse(parsed);
119
+ if (!validated.success) {
120
+ throw new SquadError("INVALID_INPUT", `${filePath}: schema violation: ${validated.error.message}`, { source: filePath, issues: validated.error.issues.length });
121
+ }
122
+ cache.set(absRoot, {
123
+ mtimeMs: stat.mtimeMs,
124
+ filePath,
125
+ data: validated.data,
126
+ });
127
+ return validated.data;
128
+ }
129
+ /**
130
+ * Atomic write: serialise to a tmp file in the same directory, then rename
131
+ * over the target. Rename is atomic on POSIX within the same filesystem.
132
+ * Stable key order + 2-space indent so git diffs stay readable.
133
+ */
134
+ async function writeTasks(workspaceRoot, data, configuredPath) {
135
+ const filePath = resolveTasksFile(workspaceRoot, configuredPath);
136
+ const dir = path.dirname(filePath);
137
+ await fs.mkdir(dir, { recursive: true });
138
+ const validated = tasksFileSchema.safeParse(data);
139
+ if (!validated.success) {
140
+ throw new SquadError("INVALID_INPUT", `tasks schema violation: ${validated.error.message}`, { issues: validated.error.issues.length });
141
+ }
142
+ const ordered = orderTasksFile(validated.data);
143
+ const tmp = `${filePath}.tmp.${process.pid}.${Date.now()}`;
144
+ await fs.writeFile(tmp, JSON.stringify(ordered, null, 2) + "\n", "utf8");
145
+ await fs.rename(tmp, filePath);
146
+ // Invalidate cache.
147
+ cache.delete(path.resolve(workspaceRoot));
148
+ return filePath;
149
+ }
150
+ function orderTasksFile(data) {
151
+ return {
152
+ version: data.version,
153
+ tasks: [...data.tasks]
154
+ .sort((a, b) => a.id - b.id)
155
+ .map((t) => ({
156
+ ...t,
157
+ subtasks: [...t.subtasks].sort((a, b) => a.id - b.id),
158
+ })),
159
+ };
160
+ }
161
+ /**
162
+ * Bulk-add tasks. Allocates ids sequentially when not supplied. Validates that
163
+ * supplied ids are unique and that all dependencies refer to ids that exist
164
+ * either in the existing file or in the same batch.
165
+ *
166
+ * Returns the IDs of the tasks that were appended (in input order).
167
+ */
168
+ export async function recordTasks(workspaceRoot, inputs, options = {}) {
169
+ if (inputs.length === 0) {
170
+ throw new SquadError("INVALID_INPUT", "recordTasks requires at least one task");
171
+ }
172
+ const current = await readTasks(workspaceRoot, options);
173
+ const existingIds = new Set(current.tasks.map((t) => t.id));
174
+ const allIds = new Set(existingIds);
175
+ const ts = new Date().toISOString();
176
+ const newTasks = [];
177
+ let cursor = current.tasks.reduce((m, t) => Math.max(m, t.id), 0);
178
+ for (const input of inputs) {
179
+ let id = input.id;
180
+ if (id === undefined) {
181
+ cursor += 1;
182
+ id = cursor;
183
+ }
184
+ else {
185
+ if (allIds.has(id)) {
186
+ throw new SquadError("INVALID_INPUT", `duplicate task id ${id} (already exists in store or batch)`);
187
+ }
188
+ cursor = Math.max(cursor, id);
189
+ }
190
+ allIds.add(id);
191
+ const task = {
192
+ id,
193
+ title: input.title,
194
+ ...(input.description !== undefined && {
195
+ description: input.description,
196
+ }),
197
+ status: "pending",
198
+ dependencies: input.dependencies ?? [],
199
+ priority: input.priority ?? "medium",
200
+ ...(input.details !== undefined && { details: input.details }),
201
+ ...(input.test_strategy !== undefined && {
202
+ test_strategy: input.test_strategy,
203
+ }),
204
+ ...(input.scope !== undefined && { scope: input.scope }),
205
+ ...(input.agent_hints !== undefined && {
206
+ agent_hints: input.agent_hints,
207
+ }),
208
+ subtasks: [],
209
+ created_at: ts,
210
+ updated_at: ts,
211
+ };
212
+ newTasks.push(task);
213
+ }
214
+ // Validate dependencies after id allocation so forward references in the
215
+ // batch resolve correctly.
216
+ for (const t of newTasks) {
217
+ for (const dep of t.dependencies) {
218
+ if (!allIds.has(dep)) {
219
+ throw new SquadError("INVALID_INPUT", `task ${t.id} depends on unknown id ${dep}`);
220
+ }
221
+ if (dep === t.id) {
222
+ throw new SquadError("INVALID_INPUT", `task ${t.id} cannot depend on itself`);
223
+ }
224
+ }
225
+ }
226
+ const next = {
227
+ version: current.version,
228
+ tasks: [...current.tasks, ...newTasks],
229
+ };
230
+ const filePath = await writeTasks(workspaceRoot, next, options.configuredPath);
231
+ logger.info("tasks recorded", {
232
+ details: { count: newTasks.length, file: filePath },
233
+ });
234
+ return { filePath, ids: newTasks.map((t) => t.id) };
235
+ }
236
+ /**
237
+ * Update task status (or subtask status when subtask_id is provided). Stamps
238
+ * updated_at. Returns the updated task. Throws if the id is not found.
239
+ */
240
+ export async function updateTaskStatus(workspaceRoot, taskId, status, options = {}) {
241
+ const current = await readTasks(workspaceRoot, options);
242
+ const idx = current.tasks.findIndex((t) => t.id === taskId);
243
+ if (idx < 0) {
244
+ throw new SquadError("INVALID_INPUT", `task ${taskId} not found`);
245
+ }
246
+ const ts = new Date().toISOString();
247
+ const original = current.tasks[idx];
248
+ let updated;
249
+ if (options.subtaskId !== undefined) {
250
+ const sIdx = original.subtasks.findIndex((s) => s.id === options.subtaskId);
251
+ if (sIdx < 0) {
252
+ throw new SquadError("INVALID_INPUT", `subtask ${options.subtaskId} not found on task ${taskId}`);
253
+ }
254
+ const newSubtasks = [...original.subtasks];
255
+ newSubtasks[sIdx] = { ...newSubtasks[sIdx], status };
256
+ updated = { ...original, subtasks: newSubtasks, updated_at: ts };
257
+ }
258
+ else {
259
+ updated = { ...original, status, updated_at: ts };
260
+ }
261
+ const nextTasks = [...current.tasks];
262
+ nextTasks[idx] = updated;
263
+ const filePath = await writeTasks(workspaceRoot, { version: current.version, tasks: nextTasks }, options.configuredPath);
264
+ logger.info("task status updated", {
265
+ details: {
266
+ task: taskId,
267
+ ...(options.subtaskId !== undefined && { subtask: options.subtaskId }),
268
+ status,
269
+ },
270
+ });
271
+ return { filePath, task: updated };
272
+ }
273
+ /**
274
+ * Append subtasks to an existing task. Allocates subtask ids sequentially
275
+ * starting from `max(existing.subtasks.id) + 1`. Mechanical only — no LLM
276
+ * decomposition here. The host LLM is responsible for generating the subtask
277
+ * inputs (typically via a future compose_task_expand prompt-pattern).
278
+ */
279
+ export async function expandTask(workspaceRoot, taskId, subtasks, options = {}) {
280
+ if (subtasks.length === 0) {
281
+ throw new SquadError("INVALID_INPUT", "expandTask requires at least one subtask");
282
+ }
283
+ const current = await readTasks(workspaceRoot, options);
284
+ const idx = current.tasks.findIndex((t) => t.id === taskId);
285
+ if (idx < 0) {
286
+ throw new SquadError("INVALID_INPUT", `task ${taskId} not found`);
287
+ }
288
+ const original = current.tasks[idx];
289
+ let cursor = original.subtasks.reduce((m, s) => Math.max(m, s.id), 0);
290
+ const ts = new Date().toISOString();
291
+ const newSubs = subtasks.map((s) => {
292
+ cursor += 1;
293
+ return {
294
+ id: cursor,
295
+ title: s.title,
296
+ ...(s.description !== undefined && { description: s.description }),
297
+ status: "pending",
298
+ dependencies: s.dependencies ?? [],
299
+ ...(s.details !== undefined && { details: s.details }),
300
+ };
301
+ });
302
+ const updated = {
303
+ ...original,
304
+ subtasks: [...original.subtasks, ...newSubs],
305
+ updated_at: ts,
306
+ };
307
+ // Validate that all subtask deps point at sibling subtasks that exist.
308
+ const siblingIds = new Set(updated.subtasks.map((s) => s.id));
309
+ for (const s of newSubs) {
310
+ for (const dep of s.dependencies) {
311
+ if (!siblingIds.has(dep)) {
312
+ throw new SquadError("INVALID_INPUT", `subtask ${s.id} depends on unknown sibling ${dep}`);
313
+ }
314
+ }
315
+ }
316
+ const nextTasks = [...current.tasks];
317
+ nextTasks[idx] = updated;
318
+ const filePath = await writeTasks(workspaceRoot, { version: current.version, tasks: nextTasks }, options.configuredPath);
319
+ return { filePath, task: updated };
320
+ }
321
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/tasks/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEpD;;;;;;;;;;;;;GAaG;AAEH,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC;IAC9B,SAAS;IACT,aAAa;IACb,QAAQ;IACR,MAAM;IACN,SAAS;IACT,WAAW;CACZ,CAAC,CAAC;AAGH,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAG7D,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7B,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC/B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACjC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;IAC5C,MAAM,EAAE,gBAAgB;IACxB,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACtE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;CACzC,CAAC,CAAC;AAGH,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC/B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACjC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;IAC5C,MAAM,EAAE,gBAAgB;IACxB,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACtE,QAAQ,EAAE,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC;IAC9C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE;IACzC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;IAC9C;;;OAGG;IACH,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAC5C;;;;OAIG;IACH,WAAW,EAAE,CAAC;SACX,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;SAChC,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC;SAC7B,QAAQ,EAAE;IACb,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACpD,yCAAyC;IACzC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IACrC,iFAAiF;IACjF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;CACtC,CAAC,CAAC;AAGH,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/B,uFAAuF;IACvF,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAChC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;CACrC,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AAOtD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;AAE5C,MAAM,UAAU,8BAA8B;IAC5C,KAAK,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC;AAED,SAAS,gBAAgB,CACvB,aAAqB,EACrB,cAAkC;IAElC,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,cAAc,IAAI,kBAAkB,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,GAAc,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAExD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,aAAqB,EACrB,UAAuC,EAAE;IAEzC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,aAAa,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACzE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAE5C,IAAI,IAAI,CAAC;IACT,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;QACnB,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAClC,IACE,MAAM;QACN,MAAM,CAAC,QAAQ,KAAK,QAAQ;QAC5B,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,EAC/B,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IAED,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,UAAU,CAClB,oBAAoB,EACpB,6BAA6B,QAAQ,KAAM,GAAa,CAAC,OAAO,EAAE,EAClE,EAAE,MAAM,EAAE,QAAQ,EAAE,CACrB,CAAC;IACJ,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,UAAU,CAClB,eAAe,EACf,GAAG,QAAQ,mBAAoB,GAAa,CAAC,OAAO,EAAE,EACtD,EAAE,MAAM,EAAE,QAAQ,EAAE,CACrB,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACpD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QACvB,MAAM,IAAI,UAAU,CAClB,eAAe,EACf,GAAG,QAAQ,uBAAuB,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,EAC3D,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAC5D,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE;QACjB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,QAAQ;QACR,IAAI,EAAE,SAAS,CAAC,IAAI;KACrB,CAAC,CAAC;IACH,OAAO,SAAS,CAAC,IAAI,CAAC;AACxB,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,UAAU,CACvB,aAAqB,EACrB,IAAe,EACf,cAAuB;IAEvB,MAAM,QAAQ,GAAG,gBAAgB,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;IACjE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEzC,MAAM,SAAS,GAAG,eAAe,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QACvB,MAAM,IAAI,UAAU,CAClB,eAAe,EACf,2BAA2B,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,EACpD,EAAE,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAC1C,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,GAAG,QAAQ,QAAQ,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IAC3D,MAAM,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;IACzE,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAE/B,oBAAoB;IACpB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;IAC1C,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,cAAc,CAAC,IAAe;IACrC,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;aACnB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;aAC3B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,GAAG,CAAC;YACJ,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;SACtD,CAAC,CAAC;KACN,CAAC;AACJ,CAAC;AAeD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,aAAqB,EACrB,MAAyB,EACzB,UAAuC,EAAE;IAEzC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,UAAU,CAClB,eAAe,EACf,wCAAwC,CACzC,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACxD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;IAEpC,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,MAAM,QAAQ,GAAW,EAAE,CAAC;IAC5B,IAAI,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAElE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;QAClB,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,CAAC;YACZ,EAAE,GAAG,MAAM,CAAC;QACd,CAAC;aAAM,CAAC;YACN,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACnB,MAAM,IAAI,UAAU,CAClB,eAAe,EACf,qBAAqB,EAAE,qCAAqC,CAC7D,CAAC;YACJ,CAAC;YACD,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAChC,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEf,MAAM,IAAI,GAAS;YACjB,EAAE;YACF,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,IAAI;gBACrC,WAAW,EAAE,KAAK,CAAC,WAAW;aAC/B,CAAC;YACF,MAAM,EAAE,SAAS;YACjB,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,EAAE;YACtC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,QAAQ;YACpC,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;YAC9D,GAAG,CAAC,KAAK,CAAC,aAAa,KAAK,SAAS,IAAI;gBACvC,aAAa,EAAE,KAAK,CAAC,aAAa;aACnC,CAAC;YACF,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;YACxD,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,IAAI;gBACrC,WAAW,EAAE,KAAK,CAAC,WAAW;aAC/B,CAAC;YACF,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,EAAE;YACd,UAAU,EAAE,EAAE;SACf,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAED,yEAAyE;IACzE,2BAA2B;IAC3B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;YACjC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,IAAI,UAAU,CAClB,eAAe,EACf,QAAQ,CAAC,CAAC,EAAE,0BAA0B,GAAG,EAAE,CAC5C,CAAC;YACJ,CAAC;YACD,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,UAAU,CAClB,eAAe,EACf,QAAQ,CAAC,CAAC,EAAE,0BAA0B,CACvC,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAc;QACtB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC;KACvC,CAAC;IACF,MAAM,QAAQ,GAAG,MAAM,UAAU,CAC/B,aAAa,EACb,IAAI,EACJ,OAAO,CAAC,cAAc,CACvB,CAAC;IAEF,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE;QAC5B,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;KACpD,CAAC,CAAC;IAEH,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,aAAqB,EACrB,MAAc,EACd,MAAkB,EAClB,UAA2D,EAAE;IAE7D,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACxD,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IAC5D,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;QACZ,MAAM,IAAI,UAAU,CAAC,eAAe,EAAE,QAAQ,MAAM,YAAY,CAAC,CAAC;IACpE,CAAC;IACD,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAE,CAAC;IACrC,IAAI,OAAa,CAAC;IAElB,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;QAC5E,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;YACb,MAAM,IAAI,UAAU,CAClB,eAAe,EACf,WAAW,OAAO,CAAC,SAAS,sBAAsB,MAAM,EAAE,CAC3D,CAAC;QACJ,CAAC;QACD,MAAM,WAAW,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC3C,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC,IAAI,CAAE,EAAE,MAAM,EAAE,CAAC;QACtD,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IACnE,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IACpD,CAAC;IAED,MAAM,SAAS,GAAG,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACrC,SAAS,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;IACzB,MAAM,QAAQ,GAAG,MAAM,UAAU,CAC/B,aAAa,EACb,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,EAC9C,OAAO,CAAC,cAAc,CACvB,CAAC;IAEF,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE;QACjC,OAAO,EAAE;YACP,IAAI,EAAE,MAAM;YACZ,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC;YACtE,MAAM;SACP;KACF,CAAC,CAAC;IAEH,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AACrC,CAAC;AASD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,aAAqB,EACrB,MAAc,EACd,QAAwB,EACxB,UAAuC,EAAE;IAEzC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,UAAU,CAClB,eAAe,EACf,0CAA0C,CAC3C,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACxD,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IAC5D,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;QACZ,MAAM,IAAI,UAAU,CAAC,eAAe,EAAE,QAAQ,MAAM,YAAY,CAAC,CAAC;IACpE,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAE,CAAC;IAErC,IAAI,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACtE,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,MAAM,OAAO,GAAc,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC5C,MAAM,IAAI,CAAC,CAAC;QACZ,OAAO;YACL,EAAE,EAAE,MAAM;YACV,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,GAAG,CAAC,CAAC,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YAClE,MAAM,EAAE,SAAkB;YAC1B,YAAY,EAAE,CAAC,CAAC,YAAY,IAAI,EAAE;YAClC,GAAG,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;SACvD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAS;QACpB,GAAG,QAAQ;QACX,QAAQ,EAAE,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,GAAG,OAAO,CAAC;QAC5C,UAAU,EAAE,EAAE;KACf,CAAC;IAEF,uEAAuE;IACvE,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9D,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;YACjC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzB,MAAM,IAAI,UAAU,CAClB,eAAe,EACf,WAAW,CAAC,CAAC,EAAE,+BAA+B,GAAG,EAAE,CACpD,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACrC,SAAS,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;IACzB,MAAM,QAAQ,GAAG,MAAM,UAAU,CAC/B,aAAa,EACb,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,EAC9C,OAAO,CAAC,cAAc,CACvB,CAAC;IAEF,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AACrC,CAAC"}
@@ -1,8 +1,8 @@
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';
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 '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';
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(' ') === -1, 'must not contain NUL byte');
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(['Feature', 'Bug Fix', 'Refactor', 'Performance', 'Security', 'Business Rule'])
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
- const filePaths = workflow.changed_files.files.map((f) => f.path);
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: 'compose_advisory_bundle',
62
- description: 'End-to-end advisory dispatch bundle. Runs compose_squad_workflow, then slice_files_for_agent for each ' +
63
- 'selected agent, then validate_plan_text on the supplied plan. Returns the union output ready for the ' +
64
- 'host to dispatch parallel advisory reviews.',
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":"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"}
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