@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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +3 -2
- package/CHANGELOG.md +271 -17
- package/INSTALL.md +156 -24
- package/README.md +278 -27
- 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 → senior-dev-reviewer.md} +33 -1
- 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/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 +8 -1
- package/dist/resources/agent-loader.js +83 -48
- 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/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/package.json +11 -1
- package/skills/squad/SKILL.md +454 -0
- package/tools/_tasks-io.mjs +69 -0
- package/tools/list-tasks.mjs +110 -0
- package/tools/next-task.mjs +131 -0
- package/tools/post-review.mjs +212 -0
- package/tools/record-learning.mjs +145 -0
- package/tools/record-tasks.mjs +186 -0
- package/tools/update-task-status.mjs +114 -0
- /package/{agents → shared}/Skill-Squad-Dev.md +0 -0
- /package/{agents → shared}/Skill-Squad-Review.md +0 -0
- /package/{agents → shared}/_Severity-and-Ownership.md +0 -0
|
@@ -1,31 +1,35 @@
|
|
|
1
|
-
import { promises as fs } from
|
|
2
|
-
import path from
|
|
3
|
-
import os from
|
|
4
|
-
import { fileURLToPath } from
|
|
5
|
-
import { AGENTS } from
|
|
6
|
-
import { SquadError } from
|
|
7
|
-
import { logger } from
|
|
8
|
-
import { validateOverrideDir, validateOverrideFile, rejectionToError, getAllowlistSize, __resetOverrideAllowlistCache, } from
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { AGENTS } from "../config/ownership-matrix.js";
|
|
6
|
+
import { SquadError } from "../errors.js";
|
|
7
|
+
import { logger } from "../observability/logger.js";
|
|
8
|
+
import { validateOverrideDir, validateOverrideFile, rejectionToError, getAllowlistSize, __resetOverrideAllowlistCache, } from "../util/override-allowlist.js";
|
|
9
9
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
10
|
const AGENT_FILE_MAP = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
"product-owner": "product-owner.md",
|
|
12
|
+
"tech-lead-planner": "tech-lead-planner.md",
|
|
13
|
+
"tech-lead-consolidator": "tech-lead-consolidator.md",
|
|
14
|
+
"senior-architect": "senior-architect.md",
|
|
15
|
+
"senior-dba": "senior-dba.md",
|
|
16
|
+
"senior-developer": "senior-developer.md",
|
|
17
|
+
"senior-dev-reviewer": "senior-dev-reviewer.md",
|
|
18
|
+
"senior-dev-security": "senior-dev-security.md",
|
|
19
|
+
"senior-qa": "senior-qa.md",
|
|
20
20
|
};
|
|
21
|
-
export const SHARED_FILES = [
|
|
21
|
+
export const SHARED_FILES = [
|
|
22
|
+
"_Severity-and-Ownership.md",
|
|
23
|
+
"Skill-Squad-Dev.md",
|
|
24
|
+
"Skill-Squad-Review.md",
|
|
25
|
+
];
|
|
22
26
|
function defaultLocalDir() {
|
|
23
|
-
if (process.platform ===
|
|
24
|
-
const appdata = process.env.APPDATA ?? path.join(os.homedir(),
|
|
25
|
-
return path.join(appdata,
|
|
27
|
+
if (process.platform === "win32") {
|
|
28
|
+
const appdata = process.env.APPDATA ?? path.join(os.homedir(), "AppData", "Roaming");
|
|
29
|
+
return path.join(appdata, "squad-mcp", "agents");
|
|
26
30
|
}
|
|
27
|
-
const xdg = process.env.XDG_CONFIG_HOME ?? path.join(os.homedir(),
|
|
28
|
-
return path.join(xdg,
|
|
31
|
+
const xdg = process.env.XDG_CONFIG_HOME ?? path.join(os.homedir(), ".config");
|
|
32
|
+
return path.join(xdg, "squad-mcp", "agents");
|
|
29
33
|
}
|
|
30
34
|
/**
|
|
31
35
|
* Returns the configured override directory and whether it was set explicitly
|
|
@@ -33,13 +37,22 @@ function defaultLocalDir() {
|
|
|
33
37
|
*/
|
|
34
38
|
export function getLocalDir() {
|
|
35
39
|
const env = process.env.SQUAD_AGENTS_DIR;
|
|
36
|
-
if (env !== undefined && env !==
|
|
40
|
+
if (env !== undefined && env !== "") {
|
|
37
41
|
return { rawDir: env, explicit: true };
|
|
38
42
|
}
|
|
39
43
|
return { rawDir: defaultLocalDir(), explicit: false };
|
|
40
44
|
}
|
|
41
45
|
export function getEmbeddedDir() {
|
|
42
|
-
return path.resolve(__dirname,
|
|
46
|
+
return path.resolve(__dirname, "..", "..", "agents");
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Path to the shared docs directory at repo root (`<repo>/shared/`). Lives
|
|
50
|
+
* outside `agents/` so the Claude Code plugin manifest's agent validator does
|
|
51
|
+
* not see non-agent files. Mirrors to `<localOverrideDir>/shared/` when the
|
|
52
|
+
* user runs init_local_config.
|
|
53
|
+
*/
|
|
54
|
+
export function getEmbeddedSharedDir() {
|
|
55
|
+
return path.resolve(__dirname, "..", "..", "shared");
|
|
43
56
|
}
|
|
44
57
|
async function exists(p) {
|
|
45
58
|
try {
|
|
@@ -86,7 +99,7 @@ export function __resetAgentLoaderForTests() {
|
|
|
86
99
|
*/
|
|
87
100
|
async function createSecureDir(dir) {
|
|
88
101
|
await fs.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
89
|
-
if (process.platform !==
|
|
102
|
+
if (process.platform !== "win32") {
|
|
90
103
|
await fs.chmod(dir, 0o700);
|
|
91
104
|
}
|
|
92
105
|
}
|
|
@@ -98,7 +111,7 @@ async function createSecureDir(dir) {
|
|
|
98
111
|
*/
|
|
99
112
|
async function copyFileSecure(src, dst) {
|
|
100
113
|
await fs.copyFile(src, dst);
|
|
101
|
-
if (process.platform !==
|
|
114
|
+
if (process.platform !== "win32") {
|
|
102
115
|
await fs.chmod(dst, 0o600);
|
|
103
116
|
}
|
|
104
117
|
}
|
|
@@ -111,7 +124,7 @@ async function copyFileSecure(src, dst) {
|
|
|
111
124
|
* not produce duplicate warnings.
|
|
112
125
|
*/
|
|
113
126
|
async function checkOverrideDirPerms(dir) {
|
|
114
|
-
if (process.platform ===
|
|
127
|
+
if (process.platform === "win32")
|
|
115
128
|
return;
|
|
116
129
|
if (permWarnEmitted)
|
|
117
130
|
return;
|
|
@@ -119,10 +132,10 @@ async function checkOverrideDirPerms(dir) {
|
|
|
119
132
|
try {
|
|
120
133
|
const s = await fs.stat(dir);
|
|
121
134
|
if ((s.mode & 0o002) !== 0) {
|
|
122
|
-
logger.warn(
|
|
135
|
+
logger.warn("override directory is world-writable", {
|
|
123
136
|
details: {
|
|
124
137
|
configured_path: dir,
|
|
125
|
-
mode:
|
|
138
|
+
mode: "0o" + (s.mode & 0o777).toString(8),
|
|
126
139
|
recommendation: `chmod 700 ${dir}`,
|
|
127
140
|
},
|
|
128
141
|
});
|
|
@@ -137,7 +150,7 @@ async function ensureEmbeddedDir() {
|
|
|
137
150
|
return;
|
|
138
151
|
const dir = getEmbeddedDir();
|
|
139
152
|
if (!(await exists(dir))) {
|
|
140
|
-
throw new SquadError(
|
|
153
|
+
throw new SquadError("AGENT_DIR_MISSING", `embedded agents directory missing at ${dir}`);
|
|
141
154
|
}
|
|
142
155
|
embeddedAsserted = true;
|
|
143
156
|
}
|
|
@@ -164,7 +177,7 @@ async function resolveOverride() {
|
|
|
164
177
|
if (!(await isDirectory(rawDir))) {
|
|
165
178
|
if (explicit && !overrideMissingWarnEmitted) {
|
|
166
179
|
overrideMissingWarnEmitted = true;
|
|
167
|
-
logger.warn(
|
|
180
|
+
logger.warn("SQUAD_AGENTS_DIR set but directory not found; falling back to embedded defaults", {
|
|
168
181
|
details: { configured_path: rawDir },
|
|
169
182
|
});
|
|
170
183
|
}
|
|
@@ -176,14 +189,14 @@ async function resolveOverride() {
|
|
|
176
189
|
if (explicit) {
|
|
177
190
|
const size = await getAllowlistSize();
|
|
178
191
|
const err = rejectionToError(result, size);
|
|
179
|
-
logger.warn(
|
|
192
|
+
logger.warn("SQUAD_AGENTS_DIR rejected", {
|
|
180
193
|
error_code: err.code,
|
|
181
194
|
details: { reason: result.reason, configured_path: rawDir },
|
|
182
195
|
});
|
|
183
196
|
throw err;
|
|
184
197
|
}
|
|
185
198
|
// Platform-default rejection: log warn, fall back silently. Rare.
|
|
186
|
-
logger.warn(
|
|
199
|
+
logger.warn("platform default agent directory failed validation", {
|
|
187
200
|
details: { reason: result.reason, configured_path: rawDir },
|
|
188
201
|
});
|
|
189
202
|
overrideValidationCache.set(rawDir, null);
|
|
@@ -195,13 +208,15 @@ async function resolveOverride() {
|
|
|
195
208
|
resolved_path: result.resolvedPath,
|
|
196
209
|
allowlist_match: result.allowlistMatch,
|
|
197
210
|
has_unsafe_override: result.unsafeOverride,
|
|
198
|
-
source: explicit ?
|
|
211
|
+
source: explicit ? "env" : "platform_default",
|
|
199
212
|
};
|
|
200
213
|
if (result.unsafeOverride) {
|
|
201
|
-
logger.warn(
|
|
214
|
+
logger.warn("agent override active (unsafe escape hatch)", {
|
|
215
|
+
details: fields,
|
|
216
|
+
});
|
|
202
217
|
}
|
|
203
218
|
else {
|
|
204
|
-
logger.info(
|
|
219
|
+
logger.info("agent override active", { details: fields });
|
|
205
220
|
}
|
|
206
221
|
}
|
|
207
222
|
await checkOverrideDirPerms(result.resolvedPath);
|
|
@@ -214,7 +229,7 @@ async function resolveOverride() {
|
|
|
214
229
|
*/
|
|
215
230
|
function assertKnownAgent(name) {
|
|
216
231
|
if (!Object.prototype.hasOwnProperty.call(AGENT_FILE_MAP, name)) {
|
|
217
|
-
throw new SquadError(
|
|
232
|
+
throw new SquadError("UNKNOWN_AGENT", `unknown agent: ${name}`, { name });
|
|
218
233
|
}
|
|
219
234
|
}
|
|
220
235
|
export async function resolveAgentFile(name) {
|
|
@@ -233,19 +248,22 @@ export async function resolveAgentFile(name) {
|
|
|
233
248
|
export async function resolveSharedFile(file) {
|
|
234
249
|
await ensureEmbeddedDir();
|
|
235
250
|
if (!SHARED_FILES.includes(file)) {
|
|
236
|
-
throw new SquadError(
|
|
251
|
+
throw new SquadError("INVALID_INPUT", `shared file not allowed: ${file}`, {
|
|
252
|
+
file,
|
|
253
|
+
});
|
|
237
254
|
}
|
|
238
255
|
const override = await resolveOverride();
|
|
239
256
|
if (override) {
|
|
240
|
-
|
|
257
|
+
// Override mirrors source layout: `<localOverrideDir>/shared/<file>`.
|
|
258
|
+
const overrideFile = await validateOverrideFile(override.resolvedPath, path.join("shared", file));
|
|
241
259
|
if (overrideFile)
|
|
242
260
|
return overrideFile;
|
|
243
261
|
}
|
|
244
|
-
return path.join(
|
|
262
|
+
return path.join(getEmbeddedSharedDir(), file);
|
|
245
263
|
}
|
|
246
264
|
export async function readAgentDefinition(name) {
|
|
247
265
|
const filePath = await resolveAgentFile(name);
|
|
248
|
-
return fs.readFile(filePath,
|
|
266
|
+
return fs.readFile(filePath, "utf8");
|
|
249
267
|
}
|
|
250
268
|
export async function listAvailableAgents() {
|
|
251
269
|
// Trigger validation so misconfigured overrides surface here too.
|
|
@@ -275,16 +293,33 @@ export async function initLocalConfig(force = false) {
|
|
|
275
293
|
const created = [];
|
|
276
294
|
const skipped = [];
|
|
277
295
|
// SECURITY: file names come from hardcoded constants only; never accept user-supplied names here.
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
296
|
+
// Agent files mirror to <rawDir>/<file>.md.
|
|
297
|
+
// Shared docs mirror to <rawDir>/shared/<file>.md (matches the source layout
|
|
298
|
+
// since the dir was lifted out of agents/ in v0.6.1 to satisfy the Claude
|
|
299
|
+
// Code plugin manifest validator).
|
|
300
|
+
const targets = [
|
|
301
|
+
...Object.values(AGENT_FILE_MAP).map((file) => ({
|
|
302
|
+
src: path.join(getEmbeddedDir(), file),
|
|
303
|
+
dst: path.join(rawDir, file),
|
|
304
|
+
rel: file,
|
|
305
|
+
})),
|
|
306
|
+
...SHARED_FILES.map((file) => ({
|
|
307
|
+
src: path.join(getEmbeddedSharedDir(), file),
|
|
308
|
+
dst: path.join(rawDir, "shared", file),
|
|
309
|
+
rel: path.join("shared", file),
|
|
310
|
+
})),
|
|
311
|
+
];
|
|
312
|
+
for (const { src, dst, rel } of targets) {
|
|
281
313
|
if ((await exists(dst)) && !force) {
|
|
282
|
-
skipped.push(
|
|
314
|
+
skipped.push(rel);
|
|
283
315
|
continue;
|
|
284
316
|
}
|
|
285
|
-
const
|
|
317
|
+
const parent = path.dirname(dst);
|
|
318
|
+
if (parent !== rawDir) {
|
|
319
|
+
await createSecureDir(parent);
|
|
320
|
+
}
|
|
286
321
|
await copyFileSecure(src, dst);
|
|
287
|
-
created.push(
|
|
322
|
+
created.push(rel);
|
|
288
323
|
}
|
|
289
324
|
return { created, skipped, dir: rawDir };
|
|
290
325
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-loader.js","sourceRoot":"","sources":["../../src/resources/agent-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,MAAM,EAAkB,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,6BAA6B,GAE9B,MAAM,+BAA+B,CAAC;AAEvC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE/D,MAAM,cAAc,GAA8B;IAChD,
|
|
1
|
+
{"version":3,"file":"agent-loader.js","sourceRoot":"","sources":["../../src/resources/agent-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { AgentName } from "../config/ownership-matrix.js";
|
|
2
|
+
import type { Task, TaskStatus } from "./store.js";
|
|
3
|
+
/**
|
|
4
|
+
* Pure selection helpers over the in-memory tasks list. Stateless. Used by
|
|
5
|
+
* the next_task and list_tasks MCP tools.
|
|
6
|
+
*/
|
|
7
|
+
export interface ListTasksOptions {
|
|
8
|
+
/** Filter to one or more statuses. */
|
|
9
|
+
status?: TaskStatus[];
|
|
10
|
+
/**
|
|
11
|
+
* When set, return only tasks whose `agent_hints` includes ANY of these
|
|
12
|
+
* agents. Tasks without agent_hints are repo-wide and always pass.
|
|
13
|
+
*/
|
|
14
|
+
agent?: AgentName;
|
|
15
|
+
/**
|
|
16
|
+
* When set, return only tasks whose `scope` glob matches at least one of
|
|
17
|
+
* these paths. Tasks without scope are repo-wide and always pass.
|
|
18
|
+
*/
|
|
19
|
+
changed_files?: string[];
|
|
20
|
+
/** Cap result count. Default unlimited. */
|
|
21
|
+
limit?: number;
|
|
22
|
+
}
|
|
23
|
+
export declare function listTasks(tasks: Task[], opts?: ListTasksOptions): Task[];
|
|
24
|
+
export interface NextTaskOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Treat these statuses as "complete" for dependency checks. Defaults to
|
|
27
|
+
* just `done`. A task whose deps are all `done` is considered ready.
|
|
28
|
+
*/
|
|
29
|
+
done_statuses?: TaskStatus[];
|
|
30
|
+
/**
|
|
31
|
+
* Statuses considered eligible for selection. Defaults to `pending`.
|
|
32
|
+
* Use `["pending", "blocked"]` to also surface blocked tasks (with a hint
|
|
33
|
+
* the caller can show the user — handled outside this function).
|
|
34
|
+
*/
|
|
35
|
+
candidate_statuses?: TaskStatus[];
|
|
36
|
+
agent?: AgentName;
|
|
37
|
+
changed_files?: string[];
|
|
38
|
+
}
|
|
39
|
+
export interface NextTaskResult {
|
|
40
|
+
task: Task | null;
|
|
41
|
+
/** Reason "task is null": no candidates, or all blocked by deps. */
|
|
42
|
+
reason: "no_candidates" | "all_blocked" | "ok";
|
|
43
|
+
/**
|
|
44
|
+
* Tasks that match candidate filters but have unmet dependencies. Useful
|
|
45
|
+
* for the caller to show "X is next when Y completes".
|
|
46
|
+
*/
|
|
47
|
+
blocked: Array<{
|
|
48
|
+
task: Task;
|
|
49
|
+
missing_deps: number[];
|
|
50
|
+
}>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Pick the next ready task. A task is ready when:
|
|
54
|
+
* - its status is in `candidate_statuses` (default `["pending"]`)
|
|
55
|
+
* - every id in its `dependencies` refers to a task whose status is in
|
|
56
|
+
* `done_statuses` (default `["done"]`)
|
|
57
|
+
* - it passes the agent / changed_files filters
|
|
58
|
+
*
|
|
59
|
+
* Tiebreakers (in order): priority (high < medium < low), then id ascending.
|
|
60
|
+
*
|
|
61
|
+
* Returns the task plus a structured result so the caller can distinguish
|
|
62
|
+
* "no candidates" from "all blocked by deps" (different UX).
|
|
63
|
+
*/
|
|
64
|
+
export declare function nextTask(tasks: Task[], opts?: NextTaskOptions): NextTaskResult;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { matchesGlob } from "../config/squad-yaml.js";
|
|
2
|
+
export function listTasks(tasks, opts = {}) {
|
|
3
|
+
let out = tasks;
|
|
4
|
+
if (opts.status && opts.status.length > 0) {
|
|
5
|
+
const set = new Set(opts.status);
|
|
6
|
+
out = out.filter((t) => set.has(t.status));
|
|
7
|
+
}
|
|
8
|
+
if (opts.agent !== undefined) {
|
|
9
|
+
const wantedAgent = opts.agent;
|
|
10
|
+
out = out.filter((t) => {
|
|
11
|
+
if (!t.agent_hints || t.agent_hints.length === 0)
|
|
12
|
+
return true;
|
|
13
|
+
return t.agent_hints.includes(wantedAgent);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
if (opts.changed_files && opts.changed_files.length > 0) {
|
|
17
|
+
const files = opts.changed_files;
|
|
18
|
+
out = out.filter((t) => {
|
|
19
|
+
if (!t.scope)
|
|
20
|
+
return true;
|
|
21
|
+
return files.some((f) => matchesGlob(t.scope, f));
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
if (opts.limit !== undefined && opts.limit > 0) {
|
|
25
|
+
out = out.slice(0, opts.limit);
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
const PRIORITY_RANK = {
|
|
30
|
+
high: 0,
|
|
31
|
+
medium: 1,
|
|
32
|
+
low: 2,
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Pick the next ready task. A task is ready when:
|
|
36
|
+
* - its status is in `candidate_statuses` (default `["pending"]`)
|
|
37
|
+
* - every id in its `dependencies` refers to a task whose status is in
|
|
38
|
+
* `done_statuses` (default `["done"]`)
|
|
39
|
+
* - it passes the agent / changed_files filters
|
|
40
|
+
*
|
|
41
|
+
* Tiebreakers (in order): priority (high < medium < low), then id ascending.
|
|
42
|
+
*
|
|
43
|
+
* Returns the task plus a structured result so the caller can distinguish
|
|
44
|
+
* "no candidates" from "all blocked by deps" (different UX).
|
|
45
|
+
*/
|
|
46
|
+
export function nextTask(tasks, opts = {}) {
|
|
47
|
+
const doneSet = new Set(opts.done_statuses ?? ["done"]);
|
|
48
|
+
const candidateStatuses = opts.candidate_statuses ?? ["pending"];
|
|
49
|
+
// Build done-id index over the FULL task list — deps may point at any task,
|
|
50
|
+
// not just ones passing the filters.
|
|
51
|
+
const doneIds = new Set(tasks.filter((t) => doneSet.has(t.status)).map((t) => t.id));
|
|
52
|
+
// Filter to candidates (status + agent + scope).
|
|
53
|
+
const filterOpts = { status: candidateStatuses };
|
|
54
|
+
if (opts.agent !== undefined)
|
|
55
|
+
filterOpts.agent = opts.agent;
|
|
56
|
+
if (opts.changed_files !== undefined)
|
|
57
|
+
filterOpts.changed_files = opts.changed_files;
|
|
58
|
+
const candidates = listTasks(tasks, filterOpts);
|
|
59
|
+
if (candidates.length === 0) {
|
|
60
|
+
return { task: null, reason: "no_candidates", blocked: [] };
|
|
61
|
+
}
|
|
62
|
+
const ready = [];
|
|
63
|
+
const blocked = [];
|
|
64
|
+
for (const t of candidates) {
|
|
65
|
+
const missing = t.dependencies.filter((d) => !doneIds.has(d));
|
|
66
|
+
if (missing.length === 0) {
|
|
67
|
+
ready.push(t);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
blocked.push({ task: t, missing_deps: missing });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (ready.length === 0) {
|
|
74
|
+
return { task: null, reason: "all_blocked", blocked };
|
|
75
|
+
}
|
|
76
|
+
ready.sort((a, b) => {
|
|
77
|
+
const p = PRIORITY_RANK[a.priority] - PRIORITY_RANK[b.priority];
|
|
78
|
+
if (p !== 0)
|
|
79
|
+
return p;
|
|
80
|
+
return a.id - b.id;
|
|
81
|
+
});
|
|
82
|
+
return { task: ready[0], reason: "ok", blocked };
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select.js","sourceRoot":"","sources":["../../src/tasks/select.ts"],"names":[],"mappings":"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"}
|