@wrongstack/sdd 0.287.0 → 0.291.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/dist/board-types.d.ts +11 -1
- package/dist/board-types.d.ts.map +1 -1
- package/dist/index.js +222 -3
- package/dist/index.js.map +3 -3
- package/dist/sdd-board-projector.d.ts +9 -0
- package/dist/sdd-board-projector.d.ts.map +1 -1
- package/dist/sdd-parallel-run.d.ts.map +1 -1
- package/dist/start-sdd-run.d.ts +1 -1
- package/dist/start-sdd-run.d.ts.map +1 -1
- package/dist/task-generator.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/board-types.d.ts
CHANGED
|
@@ -60,13 +60,21 @@ export interface SddDeadlockChain {
|
|
|
60
60
|
/** One entry in the live activity feed (the board's "what just happened" ticker). */
|
|
61
61
|
export interface SddBoardFeedEntry {
|
|
62
62
|
ts: number;
|
|
63
|
-
kind: 'started' | 'completed' | 'failed' | 'retrying' | 'wave' | 'deadlock' | 'verification_failed' | 'conflict' | 'split' | 'supervisor';
|
|
63
|
+
kind: 'started' | 'completed' | 'failed' | 'retrying' | 'wave' | 'deadlock' | 'verification_failed' | 'conflict' | 'split' | 'supervisor' | 'tool' | 'file';
|
|
64
|
+
/** Full task id for durable per-task history; older snapshots may only carry shortId. */
|
|
65
|
+
taskId?: string | undefined;
|
|
64
66
|
/** Short id of the task this entry concerns, when applicable. */
|
|
65
67
|
taskShortId?: string | undefined;
|
|
66
68
|
/** Worker involved, when applicable. */
|
|
67
69
|
agentName?: string | undefined;
|
|
68
70
|
/** Human-readable one-line summary. */
|
|
69
71
|
text: string;
|
|
72
|
+
/** Structured event-log fields used by richer board surfaces. */
|
|
73
|
+
action?: string | undefined;
|
|
74
|
+
detail?: string | undefined;
|
|
75
|
+
filePath?: string | undefined;
|
|
76
|
+
durationMs?: number | undefined;
|
|
77
|
+
ok?: boolean | undefined;
|
|
70
78
|
}
|
|
71
79
|
export interface SddBoardSnapshot {
|
|
72
80
|
runId: string;
|
|
@@ -86,6 +94,8 @@ export interface SddBoardSnapshot {
|
|
|
86
94
|
} | undefined;
|
|
87
95
|
/** Live activity feed — most recent first (capped). */
|
|
88
96
|
feed?: SddBoardFeedEntry[] | undefined;
|
|
97
|
+
/** Per-task event history — most recent first and capped independently per task. */
|
|
98
|
+
taskEvents?: Record<string, SddBoardFeedEntry[]> | undefined;
|
|
89
99
|
/** Run-level default worker model (task overrides take precedence). */
|
|
90
100
|
defaultModel?: string | undefined;
|
|
91
101
|
/** Run-level default worker provider. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"board-types.d.ts","sourceRoot":"","sources":["../src/board-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAGhF,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,SAAS,GACT,QAAQ,GACR,SAAS,GACT,WAAW,GACX,QAAQ,GACR,YAAY,CAAC;AAEjB;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE/E,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC3B,aAAa,EAAE,oBAAoB,CAAC;IACpC,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC/B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvB,qEAAqE;IACrE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,yEAAyE;IACzE,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACtC,6DAA6D;IAC7D,mBAAmB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C;AAED,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,qFAAqF;AACrF,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EACA,SAAS,GACT,WAAW,GACX,QAAQ,GACR,UAAU,GACV,MAAM,GACN,UAAU,GACV,qBAAqB,GACrB,UAAU,GACV,OAAO,GACP,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"board-types.d.ts","sourceRoot":"","sources":["../src/board-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAGhF,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,SAAS,GACT,QAAQ,GACR,SAAS,GACT,WAAW,GACX,QAAQ,GACR,YAAY,CAAC;AAEjB;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE/E,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC3B,aAAa,EAAE,oBAAoB,CAAC;IACpC,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC/B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvB,qEAAqE;IACrE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,yEAAyE;IACzE,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACtC,6DAA6D;IAC7D,mBAAmB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C;AAED,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,qFAAqF;AACrF,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EACA,SAAS,GACT,WAAW,GACX,QAAQ,GACR,UAAU,GACV,MAAM,GACN,UAAU,GACV,qBAAqB,GACrB,UAAU,GACV,OAAO,GACP,YAAY,GACZ,MAAM,GACN,MAAM,CAAC;IACX,yFAAyF;IACzF,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,EAAE,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,YAAY,CAAC;IACvB,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,WAAW,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,gBAAgB,EAAE,CAAA;KAAE,GAAG,SAAS,CAAC;IAClE,uDAAuD;IACvD,IAAI,CAAC,EAAE,iBAAiB,EAAE,GAAG,SAAS,CAAC;IACvC,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,GAAG,SAAS,CAAC;IAC7D,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,yCAAyC;IACzC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,8CAA8C;IAC9C,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACtC,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC;;;OAGG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,CAAC;CACnF;AAED;;;;;;GAMG;AACH;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAOhE;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG;IACjD,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B,CAwEA;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,SAAS,EAChB,GAAG,EAAE;IACH,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,gBAAgB,EAAE,GAAG,SAAS,CAAC;IAChD,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,aAAa,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS,CAAC;CACnF,EACD,GAAG,EAAE,MAAM,GACV,gBAAgB,CAqBlB"}
|
package/dist/index.js
CHANGED
|
@@ -242,6 +242,91 @@ var TaskGenerator = class {
|
|
|
242
242
|
opts;
|
|
243
243
|
async generateFromSpec(spec) {
|
|
244
244
|
const graph = await this.opts.taskTracker.createGraph(spec.id, spec.title);
|
|
245
|
+
const overviewSection = spec.sections?.find((s) => s.type === "overview");
|
|
246
|
+
if (overviewSection?.content) {
|
|
247
|
+
this.opts.taskTracker.addNode({
|
|
248
|
+
title: `Implement: ${spec.title}`,
|
|
249
|
+
description: overviewSection.content,
|
|
250
|
+
type: "feature",
|
|
251
|
+
priority: "high",
|
|
252
|
+
status: "pending",
|
|
253
|
+
estimateHours: 4
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
257
|
+
const sorted = [...spec.requirements ?? []].sort(
|
|
258
|
+
(a, b) => (priorityOrder[a.priority] ?? 9) - (priorityOrder[b.priority] ?? 9)
|
|
259
|
+
);
|
|
260
|
+
for (const req of sorted) {
|
|
261
|
+
const estimateHours = req.priority === "critical" ? 8 : req.priority === "high" ? 4 : req.priority === "medium" ? 2 : 1;
|
|
262
|
+
const tags = [req.type, req.priority];
|
|
263
|
+
const acLines = (req.acceptanceCriteria ?? []).map((ac) => `- ${ac}`).join("\n");
|
|
264
|
+
const blockedLine = req.blockedBy?.length ? `
|
|
265
|
+
|
|
266
|
+
**Blocked by:** ${req.blockedBy.join(", ")}` : "";
|
|
267
|
+
const description = `${req.description}
|
|
268
|
+
|
|
269
|
+
**Type:** ${req.type}` + (acLines ? `
|
|
270
|
+
|
|
271
|
+
**Acceptance Criteria:**
|
|
272
|
+
${acLines}` : "") + blockedLine;
|
|
273
|
+
const metadata = {};
|
|
274
|
+
if (this.opts.verificationFromAcceptance) {
|
|
275
|
+
const cmd = extractVerificationCommand(req.acceptanceCriteria ?? []);
|
|
276
|
+
if (cmd) metadata.verificationCommand = cmd;
|
|
277
|
+
}
|
|
278
|
+
this.opts.taskTracker.addNode({
|
|
279
|
+
title: req.description,
|
|
280
|
+
description,
|
|
281
|
+
type: "feature",
|
|
282
|
+
priority: req.priority,
|
|
283
|
+
status: "pending",
|
|
284
|
+
estimateHours,
|
|
285
|
+
tags,
|
|
286
|
+
specRequirementId: req.id,
|
|
287
|
+
...Object.keys(metadata).length > 0 ? { metadata } : {}
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
if (spec.apiEndpoints?.length) {
|
|
291
|
+
const apiParent = this.opts.taskTracker.addNode({
|
|
292
|
+
title: "API Implementation",
|
|
293
|
+
description: "Implement API endpoints as specified in the spec.",
|
|
294
|
+
type: "feature",
|
|
295
|
+
priority: "high",
|
|
296
|
+
status: "pending",
|
|
297
|
+
estimateHours: 0
|
|
298
|
+
});
|
|
299
|
+
for (const ep of spec.apiEndpoints) {
|
|
300
|
+
const baseHours = 2;
|
|
301
|
+
const authHours = ep.auth ? 1 : 0;
|
|
302
|
+
const reqHours = ep.request ? 1 : 0;
|
|
303
|
+
this.opts.taskTracker.addNode({
|
|
304
|
+
title: `${ep.method} ${ep.path} \u2014 ${ep.description}`,
|
|
305
|
+
description: `${ep.method} ${ep.path}: ${ep.description}`,
|
|
306
|
+
type: "feature",
|
|
307
|
+
priority: "medium",
|
|
308
|
+
status: "pending",
|
|
309
|
+
estimateHours: baseHours + authHours + reqHours,
|
|
310
|
+
parentId: apiParent.id
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
this.opts.taskTracker.addNode({
|
|
315
|
+
title: "Write Tests",
|
|
316
|
+
description: "Write comprehensive tests for the implemented features.",
|
|
317
|
+
type: "test",
|
|
318
|
+
priority: "high",
|
|
319
|
+
status: "pending",
|
|
320
|
+
estimateHours: 4
|
|
321
|
+
});
|
|
322
|
+
this.opts.taskTracker.addNode({
|
|
323
|
+
title: "Update Documentation",
|
|
324
|
+
description: "Update project documentation to reflect the changes.",
|
|
325
|
+
type: "docs",
|
|
326
|
+
priority: "low",
|
|
327
|
+
status: "pending",
|
|
328
|
+
estimateHours: 2
|
|
329
|
+
});
|
|
245
330
|
return graph;
|
|
246
331
|
}
|
|
247
332
|
async generateSubtasks(parentTaskId, spec) {
|
|
@@ -890,11 +975,31 @@ var SddBoardStore = class {
|
|
|
890
975
|
};
|
|
891
976
|
|
|
892
977
|
// src/sdd-board-projector.ts
|
|
978
|
+
import { DefaultSecretScrubber } from "@wrongstack/core";
|
|
979
|
+
function summarizeToolInput(input, scrubber) {
|
|
980
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) return void 0;
|
|
981
|
+
const record = input;
|
|
982
|
+
for (const key of ["filePath", "path"]) {
|
|
983
|
+
const value = record[key];
|
|
984
|
+
if (typeof value === "string" && value.trim()) {
|
|
985
|
+
const compact = scrubber.scrub(value).replace(/\s+/g, " ").trim();
|
|
986
|
+
return compact.length > 240 ? `${compact.slice(0, 239)}\u2026` : compact;
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
if (typeof record["command"] === "string" || typeof record["cmd"] === "string") {
|
|
990
|
+
return "[command omitted]";
|
|
991
|
+
}
|
|
992
|
+
if (typeof record["query"] === "string" || typeof record["pattern"] === "string") {
|
|
993
|
+
return "[query omitted]";
|
|
994
|
+
}
|
|
995
|
+
return void 0;
|
|
996
|
+
}
|
|
893
997
|
var SddBoardProjector = class _SddBoardProjector {
|
|
894
998
|
o;
|
|
895
999
|
now;
|
|
896
1000
|
throttleMs;
|
|
897
1001
|
shortId;
|
|
1002
|
+
scrubber;
|
|
898
1003
|
status = "idle";
|
|
899
1004
|
wave = 0;
|
|
900
1005
|
startedAt;
|
|
@@ -902,6 +1007,9 @@ var SddBoardProjector = class _SddBoardProjector {
|
|
|
902
1007
|
/** Live activity feed, most recent first (capped). */
|
|
903
1008
|
feed = [];
|
|
904
1009
|
static FEED_CAP = 60;
|
|
1010
|
+
/** Rich history is retained independently so a busy board cannot erase a task's log. */
|
|
1011
|
+
taskEvents = /* @__PURE__ */ new Map();
|
|
1012
|
+
static TASK_EVENT_CAP = 250;
|
|
905
1013
|
finished = false;
|
|
906
1014
|
runDeadlocked = false;
|
|
907
1015
|
runStopped = false;
|
|
@@ -919,6 +1027,7 @@ var SddBoardProjector = class _SddBoardProjector {
|
|
|
919
1027
|
this.now = opts.now ?? Date.now;
|
|
920
1028
|
this.throttleMs = opts.throttleMs ?? 250;
|
|
921
1029
|
this.shortId = shortIdMap(opts.graph);
|
|
1030
|
+
this.scrubber = opts.secretScrubber ?? new DefaultSecretScrubber();
|
|
922
1031
|
this.startedAt = this.now();
|
|
923
1032
|
this.unsubs.push(opts.tracker.subscribe(() => this.markDirty()));
|
|
924
1033
|
this.onRun("sdd.run.started", (e) => {
|
|
@@ -951,6 +1060,7 @@ var SddBoardProjector = class _SddBoardProjector {
|
|
|
951
1060
|
this.pushFeed({
|
|
952
1061
|
ts: this.now(),
|
|
953
1062
|
kind: "started",
|
|
1063
|
+
taskId: e.taskId,
|
|
954
1064
|
taskShortId: sid,
|
|
955
1065
|
agentName: e.agentName,
|
|
956
1066
|
text: `${e.agentName || "a worker"} picked up ${sid ?? "a task"}${this.titleOf(e.taskId)}`
|
|
@@ -963,6 +1073,7 @@ var SddBoardProjector = class _SddBoardProjector {
|
|
|
963
1073
|
this.pushFeed({
|
|
964
1074
|
ts: this.now(),
|
|
965
1075
|
kind: "completed",
|
|
1076
|
+
taskId: e.taskId,
|
|
966
1077
|
taskShortId: sid,
|
|
967
1078
|
agentName: agent,
|
|
968
1079
|
text: `${sid ?? "task"}${this.titleOf(e.taskId)} completed${agent ? ` by ${agent}` : ""} \xB7 ${(e.durationMs / 1e3).toFixed(1)}s`
|
|
@@ -974,6 +1085,7 @@ var SddBoardProjector = class _SddBoardProjector {
|
|
|
974
1085
|
this.pushFeed({
|
|
975
1086
|
ts: this.now(),
|
|
976
1087
|
kind: "failed",
|
|
1088
|
+
taskId: e.taskId,
|
|
977
1089
|
taskShortId: sid,
|
|
978
1090
|
agentName: this.assigneeOf(e.taskId),
|
|
979
1091
|
text: `${sid ?? "task"}${this.titleOf(e.taskId)} failed \u2014 ${e.error}`
|
|
@@ -985,6 +1097,7 @@ var SddBoardProjector = class _SddBoardProjector {
|
|
|
985
1097
|
this.pushFeed({
|
|
986
1098
|
ts: this.now(),
|
|
987
1099
|
kind: "retrying",
|
|
1100
|
+
taskId: e.taskId,
|
|
988
1101
|
taskShortId: sid,
|
|
989
1102
|
text: `${sid ?? "task"}${this.titleOf(e.taskId)} retrying (${e.attempt}/${e.maxRetries})`
|
|
990
1103
|
});
|
|
@@ -995,6 +1108,7 @@ var SddBoardProjector = class _SddBoardProjector {
|
|
|
995
1108
|
this.pushFeed({
|
|
996
1109
|
ts: this.now(),
|
|
997
1110
|
kind: "verification_failed",
|
|
1111
|
+
taskId: e.taskId,
|
|
998
1112
|
taskShortId: sid,
|
|
999
1113
|
agentName: this.assigneeOf(e.taskId),
|
|
1000
1114
|
text: `${sid ?? "task"}${this.titleOf(e.taskId)} failed verification \u2014 ${e.reason}`
|
|
@@ -1007,6 +1121,7 @@ var SddBoardProjector = class _SddBoardProjector {
|
|
|
1007
1121
|
this.pushFeed({
|
|
1008
1122
|
ts: this.now(),
|
|
1009
1123
|
kind: "conflict",
|
|
1124
|
+
taskId: e.taskId,
|
|
1010
1125
|
taskShortId: sid,
|
|
1011
1126
|
agentName: this.assigneeOf(e.taskId),
|
|
1012
1127
|
text: `${sid ?? "task"}${this.titleOf(e.taskId)} merge conflict \u2014 ${files} file(s)${files ? `: ${e.conflictFiles.slice(0, 3).join(", ")}${files > 3 ? "\u2026" : ""}` : ""}`
|
|
@@ -1020,6 +1135,7 @@ var SddBoardProjector = class _SddBoardProjector {
|
|
|
1020
1135
|
this.pushFeed({
|
|
1021
1136
|
ts: this.now(),
|
|
1022
1137
|
kind: "completed",
|
|
1138
|
+
taskId: e.taskId,
|
|
1023
1139
|
taskShortId: sid,
|
|
1024
1140
|
text: `${sid ?? "task"}${this.titleOf(e.taskId)} merged \u2192 ${this.runBaseBranch ?? this.o.baseBranch ?? "base"} (${e.sha.slice(0, 8)})`
|
|
1025
1141
|
});
|
|
@@ -1030,6 +1146,7 @@ var SddBoardProjector = class _SddBoardProjector {
|
|
|
1030
1146
|
this.pushFeed({
|
|
1031
1147
|
ts: this.now(),
|
|
1032
1148
|
kind: "split",
|
|
1149
|
+
taskId: e.taskId,
|
|
1033
1150
|
taskShortId: sid,
|
|
1034
1151
|
text: `${sid ?? "task"}${this.titleOf(e.taskId)} split into ${e.subtaskIds.length} sub-task(s)`
|
|
1035
1152
|
});
|
|
@@ -1040,15 +1157,90 @@ var SddBoardProjector = class _SddBoardProjector {
|
|
|
1040
1157
|
this.pushFeed({
|
|
1041
1158
|
ts: this.now(),
|
|
1042
1159
|
kind: "supervisor",
|
|
1160
|
+
taskId: e.taskId,
|
|
1043
1161
|
taskShortId: sid,
|
|
1044
1162
|
text: `supervisor \u2192 ${e.action} for ${sid ?? "task"}${this.titleOf(e.taskId)}${e.rationale ? ` (${e.rationale})` : ""}`
|
|
1045
1163
|
});
|
|
1046
1164
|
this.markDirty();
|
|
1047
1165
|
});
|
|
1166
|
+
this.onTask("subagent.tool_executed", (e, taskId) => {
|
|
1167
|
+
const sid = this.shortId.get(taskId);
|
|
1168
|
+
const detail = summarizeToolInput(e.input, this.scrubber);
|
|
1169
|
+
const agentName = e.agentName ? this.scrubber.scrub(e.agentName) : void 0;
|
|
1170
|
+
const action = this.scrubber.scrub(e.name);
|
|
1171
|
+
this.pushFeed({
|
|
1172
|
+
ts: this.now(),
|
|
1173
|
+
kind: "tool",
|
|
1174
|
+
taskId,
|
|
1175
|
+
taskShortId: sid,
|
|
1176
|
+
agentName,
|
|
1177
|
+
action,
|
|
1178
|
+
detail,
|
|
1179
|
+
durationMs: e.durationMs,
|
|
1180
|
+
ok: e.ok,
|
|
1181
|
+
text: `${agentName ?? "worker"} ran ${action}${detail ? ` \xB7 ${detail}` : ""}`
|
|
1182
|
+
});
|
|
1183
|
+
void this.o.store?.appendEvent(this.o.runId, {
|
|
1184
|
+
ts: this.now(),
|
|
1185
|
+
type: "subagent.tool_executed",
|
|
1186
|
+
payload: {
|
|
1187
|
+
runId: this.o.runId,
|
|
1188
|
+
taskId,
|
|
1189
|
+
subagentId: e.subagentId,
|
|
1190
|
+
agentName,
|
|
1191
|
+
name: action,
|
|
1192
|
+
durationMs: e.durationMs,
|
|
1193
|
+
ok: e.ok,
|
|
1194
|
+
detail
|
|
1195
|
+
}
|
|
1196
|
+
});
|
|
1197
|
+
this.markDirty();
|
|
1198
|
+
});
|
|
1199
|
+
this.onTask("file.event", (e, taskId) => {
|
|
1200
|
+
if (e.scope !== "task") return;
|
|
1201
|
+
const sid = this.shortId.get(taskId);
|
|
1202
|
+
const agentName = this.scrubber.scrub(e.agentName);
|
|
1203
|
+
const filePath = this.scrubber.scrub(e.filePath);
|
|
1204
|
+
this.pushFeed({
|
|
1205
|
+
ts: Date.parse(e.timestamp) || this.now(),
|
|
1206
|
+
kind: "file",
|
|
1207
|
+
taskId,
|
|
1208
|
+
taskShortId: sid,
|
|
1209
|
+
agentName,
|
|
1210
|
+
action: e.operation,
|
|
1211
|
+
filePath,
|
|
1212
|
+
durationMs: e.durationMs,
|
|
1213
|
+
ok: true,
|
|
1214
|
+
text: `${e.operation} ${filePath}`
|
|
1215
|
+
});
|
|
1216
|
+
void this.o.store?.appendEvent(this.o.runId, {
|
|
1217
|
+
ts: this.now(),
|
|
1218
|
+
type: "file.event",
|
|
1219
|
+
payload: {
|
|
1220
|
+
runId: this.o.runId,
|
|
1221
|
+
taskId,
|
|
1222
|
+
agentName,
|
|
1223
|
+
operation: e.operation,
|
|
1224
|
+
filePath,
|
|
1225
|
+
toolName: this.scrubber.scrub(e.toolName),
|
|
1226
|
+
durationMs: e.durationMs,
|
|
1227
|
+
timestamp: e.timestamp
|
|
1228
|
+
}
|
|
1229
|
+
});
|
|
1230
|
+
this.markDirty();
|
|
1231
|
+
});
|
|
1048
1232
|
}
|
|
1049
1233
|
pushFeed(entry) {
|
|
1050
1234
|
this.feed.unshift(entry);
|
|
1051
1235
|
if (this.feed.length > _SddBoardProjector.FEED_CAP) this.feed.length = _SddBoardProjector.FEED_CAP;
|
|
1236
|
+
if (entry.taskId) {
|
|
1237
|
+
const taskFeed = this.taskEvents.get(entry.taskId) ?? [];
|
|
1238
|
+
taskFeed.unshift(entry);
|
|
1239
|
+
if (taskFeed.length > _SddBoardProjector.TASK_EVENT_CAP) {
|
|
1240
|
+
taskFeed.length = _SddBoardProjector.TASK_EVENT_CAP;
|
|
1241
|
+
}
|
|
1242
|
+
this.taskEvents.set(entry.taskId, taskFeed);
|
|
1243
|
+
}
|
|
1052
1244
|
}
|
|
1053
1245
|
/** ` (title…)` suffix for a feed line, or '' when the node/title is missing. */
|
|
1054
1246
|
titleOf(taskId) {
|
|
@@ -1087,6 +1279,18 @@ var SddBoardProjector = class _SddBoardProjector {
|
|
|
1087
1279
|
const off = this.o.events.on(event, wrapped);
|
|
1088
1280
|
this.unsubs.push(off);
|
|
1089
1281
|
}
|
|
1282
|
+
/** Subscribe to task-correlated telemetry and ignore events outside this graph. */
|
|
1283
|
+
onTask(event, handler) {
|
|
1284
|
+
const wrapped = (e) => {
|
|
1285
|
+
const correlated = e;
|
|
1286
|
+
const taskId = correlated.taskId;
|
|
1287
|
+
if (!taskId || !this.o.graph.nodes.has(taskId)) return;
|
|
1288
|
+
if (correlated.runId !== this.o.runId) return;
|
|
1289
|
+
handler(e, taskId);
|
|
1290
|
+
};
|
|
1291
|
+
const off = this.o.events.on(event, wrapped);
|
|
1292
|
+
this.unsubs.push(off);
|
|
1293
|
+
}
|
|
1090
1294
|
resolveStatus(completed, total) {
|
|
1091
1295
|
if (!this.finished) return this.status;
|
|
1092
1296
|
if (this.runDeadlocked) return "deadlocked";
|
|
@@ -1114,6 +1318,9 @@ var SddBoardProjector = class _SddBoardProjector {
|
|
|
1114
1318
|
);
|
|
1115
1319
|
snap.status = this.resolveStatus(snap.progress.completed, snap.progress.total);
|
|
1116
1320
|
snap.feed = this.feed.slice(0, _SddBoardProjector.FEED_CAP);
|
|
1321
|
+
snap.taskEvents = Object.fromEntries(
|
|
1322
|
+
[...this.taskEvents].map(([taskId, entries]) => [taskId, entries.slice()])
|
|
1323
|
+
);
|
|
1117
1324
|
return snap;
|
|
1118
1325
|
}
|
|
1119
1326
|
markDirty() {
|
|
@@ -1987,6 +2194,9 @@ function isExplanatoryText(text) {
|
|
|
1987
2194
|
return lower.startsWith("i'") || lower.startsWith("i will") || lower.startsWith("let me") || lower.startsWith("here's my") || lower.startsWith("here is my") || lower.startsWith("i'm going to") || lower.startsWith("first, let me") || lower.startsWith("sure") || lower.startsWith("of course") || lower.startsWith("okay") || lower.startsWith("ok,") || lower.startsWith("sounds good") || lower.startsWith("no problem") || text.split("\n").length < 3 && !text.includes(".");
|
|
1988
2195
|
}
|
|
1989
2196
|
|
|
2197
|
+
// src/start-sdd-run.ts
|
|
2198
|
+
import { TOKENS } from "@wrongstack/core";
|
|
2199
|
+
|
|
1990
2200
|
// src/sdd-parallel-run.ts
|
|
1991
2201
|
import { expectDefined as expectDefined2 } from "@wrongstack/core";
|
|
1992
2202
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
@@ -2605,7 +2815,10 @@ var SddParallelRun = class {
|
|
|
2605
2815
|
this.coordinator = new DefaultMultiAgentCoordinator(config);
|
|
2606
2816
|
const baseFactory = this.opts.subagentFactory ?? this.defaultFactory();
|
|
2607
2817
|
const filteredFactory = withDisabledToolFiltering(baseFactory);
|
|
2608
|
-
const runner = makeAgentSubagentRunner({
|
|
2818
|
+
const runner = makeAgentSubagentRunner({
|
|
2819
|
+
factory: filteredFactory,
|
|
2820
|
+
hostEvents: this.events
|
|
2821
|
+
});
|
|
2609
2822
|
this.coordinator.setRunner?.(runner);
|
|
2610
2823
|
}
|
|
2611
2824
|
defaultFactory() {
|
|
@@ -2715,7 +2928,12 @@ var SddParallelRun = class {
|
|
|
2715
2928
|
task.description
|
|
2716
2929
|
].join("\n"),
|
|
2717
2930
|
subagentId,
|
|
2718
|
-
...this.timeoutMs ? { timeoutMs: this.timeoutMs } : {}
|
|
2931
|
+
...this.timeoutMs ? { timeoutMs: this.timeoutMs } : {},
|
|
2932
|
+
context: {
|
|
2933
|
+
telemetryTaskId: taskId,
|
|
2934
|
+
telemetryRunId: this.runId,
|
|
2935
|
+
telemetryBoardId: this.opts.graph.id
|
|
2936
|
+
}
|
|
2719
2937
|
});
|
|
2720
2938
|
let result;
|
|
2721
2939
|
try {
|
|
@@ -3048,7 +3266,8 @@ function startSddRun(opts) {
|
|
|
3048
3266
|
specId: opts.graph.specId,
|
|
3049
3267
|
defaultModel: opts.defaultModel,
|
|
3050
3268
|
defaultProvider: opts.defaultProvider,
|
|
3051
|
-
fallbackModels: opts.fallbackModels
|
|
3269
|
+
fallbackModels: opts.fallbackModels,
|
|
3270
|
+
secretScrubber: opts.agent.container?.safeResolve(TOKENS.SecretScrubber)
|
|
3052
3271
|
});
|
|
3053
3272
|
opts.registry?.register({
|
|
3054
3273
|
runId: run.runId,
|