@wrongstack/sdd 0.289.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.
@@ -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":"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"}
1
+ {"version":3,"file":"board-types.d.ts","sourceRoot":"","sources":["../src/board-types.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -975,11 +975,31 @@ var SddBoardStore = class {
975
975
  };
976
976
 
977
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
+ }
978
997
  var SddBoardProjector = class _SddBoardProjector {
979
998
  o;
980
999
  now;
981
1000
  throttleMs;
982
1001
  shortId;
1002
+ scrubber;
983
1003
  status = "idle";
984
1004
  wave = 0;
985
1005
  startedAt;
@@ -987,6 +1007,9 @@ var SddBoardProjector = class _SddBoardProjector {
987
1007
  /** Live activity feed, most recent first (capped). */
988
1008
  feed = [];
989
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;
990
1013
  finished = false;
991
1014
  runDeadlocked = false;
992
1015
  runStopped = false;
@@ -1004,6 +1027,7 @@ var SddBoardProjector = class _SddBoardProjector {
1004
1027
  this.now = opts.now ?? Date.now;
1005
1028
  this.throttleMs = opts.throttleMs ?? 250;
1006
1029
  this.shortId = shortIdMap(opts.graph);
1030
+ this.scrubber = opts.secretScrubber ?? new DefaultSecretScrubber();
1007
1031
  this.startedAt = this.now();
1008
1032
  this.unsubs.push(opts.tracker.subscribe(() => this.markDirty()));
1009
1033
  this.onRun("sdd.run.started", (e) => {
@@ -1036,6 +1060,7 @@ var SddBoardProjector = class _SddBoardProjector {
1036
1060
  this.pushFeed({
1037
1061
  ts: this.now(),
1038
1062
  kind: "started",
1063
+ taskId: e.taskId,
1039
1064
  taskShortId: sid,
1040
1065
  agentName: e.agentName,
1041
1066
  text: `${e.agentName || "a worker"} picked up ${sid ?? "a task"}${this.titleOf(e.taskId)}`
@@ -1048,6 +1073,7 @@ var SddBoardProjector = class _SddBoardProjector {
1048
1073
  this.pushFeed({
1049
1074
  ts: this.now(),
1050
1075
  kind: "completed",
1076
+ taskId: e.taskId,
1051
1077
  taskShortId: sid,
1052
1078
  agentName: agent,
1053
1079
  text: `${sid ?? "task"}${this.titleOf(e.taskId)} completed${agent ? ` by ${agent}` : ""} \xB7 ${(e.durationMs / 1e3).toFixed(1)}s`
@@ -1059,6 +1085,7 @@ var SddBoardProjector = class _SddBoardProjector {
1059
1085
  this.pushFeed({
1060
1086
  ts: this.now(),
1061
1087
  kind: "failed",
1088
+ taskId: e.taskId,
1062
1089
  taskShortId: sid,
1063
1090
  agentName: this.assigneeOf(e.taskId),
1064
1091
  text: `${sid ?? "task"}${this.titleOf(e.taskId)} failed \u2014 ${e.error}`
@@ -1070,6 +1097,7 @@ var SddBoardProjector = class _SddBoardProjector {
1070
1097
  this.pushFeed({
1071
1098
  ts: this.now(),
1072
1099
  kind: "retrying",
1100
+ taskId: e.taskId,
1073
1101
  taskShortId: sid,
1074
1102
  text: `${sid ?? "task"}${this.titleOf(e.taskId)} retrying (${e.attempt}/${e.maxRetries})`
1075
1103
  });
@@ -1080,6 +1108,7 @@ var SddBoardProjector = class _SddBoardProjector {
1080
1108
  this.pushFeed({
1081
1109
  ts: this.now(),
1082
1110
  kind: "verification_failed",
1111
+ taskId: e.taskId,
1083
1112
  taskShortId: sid,
1084
1113
  agentName: this.assigneeOf(e.taskId),
1085
1114
  text: `${sid ?? "task"}${this.titleOf(e.taskId)} failed verification \u2014 ${e.reason}`
@@ -1092,6 +1121,7 @@ var SddBoardProjector = class _SddBoardProjector {
1092
1121
  this.pushFeed({
1093
1122
  ts: this.now(),
1094
1123
  kind: "conflict",
1124
+ taskId: e.taskId,
1095
1125
  taskShortId: sid,
1096
1126
  agentName: this.assigneeOf(e.taskId),
1097
1127
  text: `${sid ?? "task"}${this.titleOf(e.taskId)} merge conflict \u2014 ${files} file(s)${files ? `: ${e.conflictFiles.slice(0, 3).join(", ")}${files > 3 ? "\u2026" : ""}` : ""}`
@@ -1105,6 +1135,7 @@ var SddBoardProjector = class _SddBoardProjector {
1105
1135
  this.pushFeed({
1106
1136
  ts: this.now(),
1107
1137
  kind: "completed",
1138
+ taskId: e.taskId,
1108
1139
  taskShortId: sid,
1109
1140
  text: `${sid ?? "task"}${this.titleOf(e.taskId)} merged \u2192 ${this.runBaseBranch ?? this.o.baseBranch ?? "base"} (${e.sha.slice(0, 8)})`
1110
1141
  });
@@ -1115,6 +1146,7 @@ var SddBoardProjector = class _SddBoardProjector {
1115
1146
  this.pushFeed({
1116
1147
  ts: this.now(),
1117
1148
  kind: "split",
1149
+ taskId: e.taskId,
1118
1150
  taskShortId: sid,
1119
1151
  text: `${sid ?? "task"}${this.titleOf(e.taskId)} split into ${e.subtaskIds.length} sub-task(s)`
1120
1152
  });
@@ -1125,15 +1157,90 @@ var SddBoardProjector = class _SddBoardProjector {
1125
1157
  this.pushFeed({
1126
1158
  ts: this.now(),
1127
1159
  kind: "supervisor",
1160
+ taskId: e.taskId,
1128
1161
  taskShortId: sid,
1129
1162
  text: `supervisor \u2192 ${e.action} for ${sid ?? "task"}${this.titleOf(e.taskId)}${e.rationale ? ` (${e.rationale})` : ""}`
1130
1163
  });
1131
1164
  this.markDirty();
1132
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
+ });
1133
1232
  }
1134
1233
  pushFeed(entry) {
1135
1234
  this.feed.unshift(entry);
1136
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
+ }
1137
1244
  }
1138
1245
  /** ` (title…)` suffix for a feed line, or '' when the node/title is missing. */
1139
1246
  titleOf(taskId) {
@@ -1172,6 +1279,18 @@ var SddBoardProjector = class _SddBoardProjector {
1172
1279
  const off = this.o.events.on(event, wrapped);
1173
1280
  this.unsubs.push(off);
1174
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
+ }
1175
1294
  resolveStatus(completed, total) {
1176
1295
  if (!this.finished) return this.status;
1177
1296
  if (this.runDeadlocked) return "deadlocked";
@@ -1199,6 +1318,9 @@ var SddBoardProjector = class _SddBoardProjector {
1199
1318
  );
1200
1319
  snap.status = this.resolveStatus(snap.progress.completed, snap.progress.total);
1201
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
+ );
1202
1324
  return snap;
1203
1325
  }
1204
1326
  markDirty() {
@@ -2072,6 +2194,9 @@ function isExplanatoryText(text) {
2072
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(".");
2073
2195
  }
2074
2196
 
2197
+ // src/start-sdd-run.ts
2198
+ import { TOKENS } from "@wrongstack/core";
2199
+
2075
2200
  // src/sdd-parallel-run.ts
2076
2201
  import { expectDefined as expectDefined2 } from "@wrongstack/core";
2077
2202
  import { randomUUID as randomUUID2 } from "node:crypto";
@@ -2690,7 +2815,10 @@ var SddParallelRun = class {
2690
2815
  this.coordinator = new DefaultMultiAgentCoordinator(config);
2691
2816
  const baseFactory = this.opts.subagentFactory ?? this.defaultFactory();
2692
2817
  const filteredFactory = withDisabledToolFiltering(baseFactory);
2693
- const runner = makeAgentSubagentRunner({ factory: filteredFactory });
2818
+ const runner = makeAgentSubagentRunner({
2819
+ factory: filteredFactory,
2820
+ hostEvents: this.events
2821
+ });
2694
2822
  this.coordinator.setRunner?.(runner);
2695
2823
  }
2696
2824
  defaultFactory() {
@@ -2800,7 +2928,12 @@ var SddParallelRun = class {
2800
2928
  task.description
2801
2929
  ].join("\n"),
2802
2930
  subagentId,
2803
- ...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
+ }
2804
2937
  });
2805
2938
  let result;
2806
2939
  try {
@@ -3133,7 +3266,8 @@ function startSddRun(opts) {
3133
3266
  specId: opts.graph.specId,
3134
3267
  defaultModel: opts.defaultModel,
3135
3268
  defaultProvider: opts.defaultProvider,
3136
- fallbackModels: opts.fallbackModels
3269
+ fallbackModels: opts.fallbackModels,
3270
+ secretScrubber: opts.agent.container?.safeResolve(TOKENS.SecretScrubber)
3137
3271
  });
3138
3272
  opts.registry?.register({
3139
3273
  runId: run.runId,