@wrongstack/sdd 0.292.1 → 0.295.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/index.js CHANGED
@@ -356,7 +356,7 @@ import {
356
356
  } from "@wrongstack/core/tasking";
357
357
 
358
358
  // src/task-flow.ts
359
- import { SddError, ERROR_CODES } from "@wrongstack/core";
359
+ import { SddError, ERROR_CODES } from "@wrongstack/core/types";
360
360
  import { DefaultTaskStore, TaskTracker } from "@wrongstack/core/tasking";
361
361
  var TaskFlow = class {
362
362
  constructor(opts) {
@@ -549,7 +549,7 @@ var SpecDrivenDev = class {
549
549
  import * as fsp from "node:fs/promises";
550
550
  import * as path from "node:path";
551
551
  import { randomUUID } from "node:crypto";
552
- import { atomicWrite, ensureDir } from "@wrongstack/core";
552
+ import { atomicWrite, ensureDir } from "@wrongstack/core/utils";
553
553
  var SpecStore = class {
554
554
  baseDir;
555
555
  indexPath;
@@ -663,7 +663,7 @@ var SpecStore = class {
663
663
  // src/task-graph-store.ts
664
664
  import * as fsp2 from "node:fs/promises";
665
665
  import * as path2 from "node:path";
666
- import { atomicWrite as atomicWrite2, ensureDir as ensureDir2 } from "@wrongstack/core";
666
+ import { atomicWrite as atomicWrite2, ensureDir as ensureDir2 } from "@wrongstack/core/utils";
667
667
  function graphToJSON(graph) {
668
668
  const serialisable = {
669
669
  ...graph,
@@ -762,7 +762,7 @@ var TaskGraphStore = class {
762
762
  };
763
763
 
764
764
  // src/board-types.ts
765
- import { computeTaskProgress } from "@wrongstack/core/types";
765
+ import { computeTaskProgress } from "@wrongstack/core/tasking";
766
766
  function shortIdMap(graph) {
767
767
  const nodes = Array.from(graph.nodes.values()).sort((a, b) => a.createdAt - b.createdAt);
768
768
  const m = /* @__PURE__ */ new Map();
@@ -854,13 +854,34 @@ function buildBoardSnapshot(graph, run, now) {
854
854
  // src/sdd-board-store.ts
855
855
  import * as fsp3 from "node:fs/promises";
856
856
  import * as path3 from "node:path";
857
- import { atomicWrite as atomicWrite3, ensureDir as ensureDir3 } from "@wrongstack/core";
857
+ import { atomicWrite as atomicWrite3, ensureDir as ensureDir3, withFileLock } from "@wrongstack/core/utils";
858
+ var DEFAULT_EVENT_MAX_BYTES = 16 * 1024 * 1024;
859
+ var DEFAULT_EVENT_KEEP_BYTES = 8 * 1024 * 1024;
860
+ var DEFAULT_EVENT_SIZE_CHECK_EVERY = 100;
858
861
  var SddBoardStore = class {
859
862
  baseDir;
860
863
  indexPath;
864
+ eventMaxBytes;
865
+ eventKeepBytes;
866
+ eventSizeCheckEvery;
867
+ eventChains = /* @__PURE__ */ new Map();
868
+ eventWritesSinceCheck = /* @__PURE__ */ new Map();
869
+ controlDrains = /* @__PURE__ */ new Map();
870
+ baseDirReady;
871
+ cachedIndex;
872
+ cachedIndexSignature = null;
861
873
  constructor(opts) {
862
874
  this.baseDir = opts.baseDir;
863
875
  this.indexPath = path3.join(this.baseDir, "_index.json");
876
+ this.eventMaxBytes = Math.max(1024, Math.floor(opts.eventMaxBytes ?? DEFAULT_EVENT_MAX_BYTES));
877
+ this.eventKeepBytes = Math.min(
878
+ this.eventMaxBytes,
879
+ Math.max(0, Math.floor(opts.eventKeepBytes ?? DEFAULT_EVENT_KEEP_BYTES))
880
+ );
881
+ this.eventSizeCheckEvery = Math.max(
882
+ 1,
883
+ Math.floor(opts.eventSizeCheckEvery ?? DEFAULT_EVENT_SIZE_CHECK_EVERY)
884
+ );
864
885
  }
865
886
  snapshotPath(runId) {
866
887
  return path3.join(this.baseDir, `${this.safe(runId)}.json`);
@@ -872,7 +893,7 @@ var SddBoardStore = class {
872
893
  return path3.join(this.baseDir, `${this.safe(runId)}.control.jsonl`);
873
894
  }
874
895
  async saveSnapshot(snapshot) {
875
- await ensureDir3(this.baseDir);
896
+ await this.ensureBaseDir();
876
897
  await atomicWrite3(this.snapshotPath(snapshot.runId), JSON.stringify(snapshot, null, 2), {
877
898
  mode: 384
878
899
  });
@@ -888,7 +909,12 @@ var SddBoardStore = class {
888
909
  }
889
910
  async list() {
890
911
  const index = await this.readIndex();
891
- return index.entries.sort((a, b) => b.updatedAt - a.updatedAt);
912
+ return index.entries.map((entry) => ({ ...entry }));
913
+ }
914
+ /** Latest board metadata without cloning/sorting the complete index. */
915
+ async latest() {
916
+ const entry = (await this.readIndex()).entries[0];
917
+ return entry ? { ...entry } : void 0;
892
918
  }
893
919
  async loadLatestForSpec(specId) {
894
920
  const entry = (await this.list()).find((e) => e.specId === specId);
@@ -896,63 +922,160 @@ var SddBoardStore = class {
896
922
  }
897
923
  /** Append one line to the board's JSONL event log (best-effort, never throws). */
898
924
  async appendEvent(runId, event) {
899
- try {
900
- await ensureDir3(this.baseDir);
901
- await fsp3.appendFile(this.eventsPath(runId), `${JSON.stringify(event)}
902
- `, { mode: 384 });
903
- } catch {
904
- }
925
+ const filePath = this.eventsPath(runId);
926
+ const previous = this.eventChains.get(filePath) ?? Promise.resolve();
927
+ const write = previous.then(() => this.appendEventInternal(filePath, event)).catch(() => void 0);
928
+ this.eventChains.set(filePath, write);
929
+ await write;
930
+ if (this.eventChains.get(filePath) === write) this.eventChains.delete(filePath);
905
931
  }
906
932
  /** Append a control command (used by readers to steer a CLI-owned run). */
907
933
  async appendControl(runId, command) {
908
- await ensureDir3(this.baseDir);
909
- await fsp3.appendFile(this.controlPath(runId), `${JSON.stringify(command)}
910
- `, { mode: 384 });
934
+ await this.ensureBaseDir();
935
+ const filePath = this.controlPath(runId);
936
+ await withFileLock(
937
+ filePath,
938
+ () => fsp3.appendFile(filePath, `${JSON.stringify(command)}
939
+ `, { mode: 384 })
940
+ );
911
941
  }
912
942
  /** Read + truncate the control queue (the run drains it). Returns parsed commands. */
913
943
  async drainControl(runId) {
914
- const p = this.controlPath(runId);
915
- let raw;
916
- try {
917
- raw = await fsp3.readFile(p, "utf8");
918
- } catch {
944
+ const filePath = this.controlPath(runId);
945
+ const active = this.controlDrains.get(filePath);
946
+ if (active) {
947
+ await active;
919
948
  return [];
920
949
  }
950
+ const drain = this.drainControlInternal(filePath);
951
+ this.controlDrains.set(filePath, drain);
921
952
  try {
922
- await fsp3.writeFile(p, "", { mode: 384 });
923
- } catch {
953
+ return await drain;
954
+ } finally {
955
+ if (this.controlDrains.get(filePath) === drain) this.controlDrains.delete(filePath);
924
956
  }
925
- return raw.split("\n").filter((l) => l.trim()).map((l) => {
926
- try {
927
- return JSON.parse(l);
928
- } catch {
929
- return null;
930
- }
931
- }).filter((c) => c !== null);
932
957
  }
933
958
  async delete(runId) {
959
+ const eventPath = this.eventsPath(runId);
960
+ await this.eventChains.get(eventPath)?.catch(() => void 0);
961
+ this.eventChains.delete(eventPath);
934
962
  await Promise.allSettled([
935
963
  fsp3.unlink(this.snapshotPath(runId)),
936
- fsp3.unlink(this.eventsPath(runId)),
964
+ fsp3.unlink(eventPath),
937
965
  fsp3.unlink(this.controlPath(runId))
938
966
  ]);
967
+ this.eventWritesSinceCheck.delete(eventPath);
939
968
  await this.removeFromIndex(runId);
940
969
  }
941
970
  // ── internal ────────────────────────────────────────────────────────────
942
971
  safe(runId) {
943
972
  return runId.replace(/[^a-zA-Z0-9._-]/g, "_");
944
973
  }
974
+ async ensureBaseDir() {
975
+ this.baseDirReady ??= ensureDir3(this.baseDir).catch((error) => {
976
+ this.baseDirReady = void 0;
977
+ throw error;
978
+ });
979
+ await this.baseDirReady;
980
+ }
981
+ async appendEventInternal(filePath, event) {
982
+ await this.ensureBaseDir();
983
+ await fsp3.appendFile(filePath, `${JSON.stringify(event)}
984
+ `, { mode: 384 });
985
+ const writes = (this.eventWritesSinceCheck.get(filePath) ?? 0) + 1;
986
+ if (writes < this.eventSizeCheckEvery) {
987
+ this.eventWritesSinceCheck.set(filePath, writes);
988
+ return;
989
+ }
990
+ this.eventWritesSinceCheck.set(filePath, 0);
991
+ const stat2 = await fsp3.stat(filePath);
992
+ if (stat2.size <= this.eventMaxBytes) return;
993
+ await this.compactEventTail(filePath, stat2.size);
994
+ }
995
+ async compactEventTail(filePath, size) {
996
+ if (this.eventKeepBytes === 0) {
997
+ await atomicWrite3(filePath, "", { mode: 384 });
998
+ return;
999
+ }
1000
+ const handle = await fsp3.open(filePath, "r");
1001
+ let retained;
1002
+ try {
1003
+ const length = Math.min(size, this.eventKeepBytes);
1004
+ const start = size - length;
1005
+ const buffer = Buffer.allocUnsafe(length);
1006
+ const { bytesRead } = await handle.read(buffer, 0, length, start);
1007
+ retained = buffer.subarray(0, bytesRead);
1008
+ if (start > 0 && retained.length > 0) {
1009
+ const previous = Buffer.allocUnsafe(1);
1010
+ const preceding = await handle.read(previous, 0, 1, start - 1);
1011
+ if (preceding.bytesRead !== 1 || previous[0] !== 10) {
1012
+ const firstNewline = retained.indexOf(10);
1013
+ retained = firstNewline >= 0 ? retained.subarray(firstNewline + 1) : retained.subarray(0, 0);
1014
+ }
1015
+ }
1016
+ } finally {
1017
+ await handle.close();
1018
+ }
1019
+ await atomicWrite3(filePath, retained, { mode: 384 });
1020
+ }
1021
+ async drainControlInternal(filePath) {
1022
+ try {
1023
+ const stat2 = await fsp3.stat(filePath);
1024
+ if (stat2.size === 0) return [];
1025
+ } catch {
1026
+ return [];
1027
+ }
1028
+ return withFileLock(filePath, async () => {
1029
+ let raw;
1030
+ try {
1031
+ const stat2 = await fsp3.stat(filePath);
1032
+ if (stat2.size === 0) return [];
1033
+ raw = await fsp3.readFile(filePath, "utf8");
1034
+ } catch {
1035
+ return [];
1036
+ }
1037
+ try {
1038
+ await fsp3.truncate(filePath, 0);
1039
+ } catch {
1040
+ return [];
1041
+ }
1042
+ return raw.split("\n").filter((line) => line.trim()).map((line) => {
1043
+ try {
1044
+ return JSON.parse(line);
1045
+ } catch {
1046
+ return null;
1047
+ }
1048
+ }).filter(
1049
+ (command) => command !== null
1050
+ );
1051
+ });
1052
+ }
945
1053
  async readIndex() {
1054
+ const signature = await this.indexSignature();
1055
+ if (this.cachedIndex && sameIndexSignature(signature, this.cachedIndexSignature)) {
1056
+ return this.cachedIndex;
1057
+ }
946
1058
  try {
947
1059
  const raw = await fsp3.readFile(this.indexPath, "utf8");
948
1060
  const parsed = JSON.parse(raw);
949
- if (parsed?.version === 1) return parsed;
1061
+ if (parsed?.version === 1) {
1062
+ parsed.entries.sort((a, b) => b.updatedAt - a.updatedAt);
1063
+ this.cachedIndex = parsed;
1064
+ this.cachedIndexSignature = signature;
1065
+ return parsed;
1066
+ }
950
1067
  } catch {
951
1068
  }
952
- return { version: 1, entries: [] };
1069
+ this.cachedIndex = { version: 1, entries: [] };
1070
+ this.cachedIndexSignature = signature;
1071
+ return this.cachedIndex;
953
1072
  }
954
1073
  async updateIndex(snapshot) {
955
- const index = await this.readIndex();
1074
+ const current = await this.readIndex();
1075
+ const index = {
1076
+ version: 1,
1077
+ entries: current.entries.map((entry2) => ({ ...entry2 }))
1078
+ };
956
1079
  const entry = {
957
1080
  runId: snapshot.runId,
958
1081
  specId: snapshot.specId,
@@ -965,17 +1088,37 @@ var SddBoardStore = class {
965
1088
  const idx = index.entries.findIndex((e) => e.runId === snapshot.runId);
966
1089
  if (idx >= 0) index.entries[idx] = entry;
967
1090
  else index.entries.push(entry);
1091
+ index.entries.sort((a, b) => b.updatedAt - a.updatedAt);
968
1092
  await atomicWrite3(this.indexPath, JSON.stringify(index, null, 2), { mode: 384 });
1093
+ this.cachedIndex = index;
1094
+ this.cachedIndexSignature = await this.indexSignature();
969
1095
  }
970
1096
  async removeFromIndex(runId) {
971
- const index = await this.readIndex();
972
- index.entries = index.entries.filter((e) => e.runId !== runId);
1097
+ const current = await this.readIndex();
1098
+ const index = {
1099
+ version: 1,
1100
+ entries: current.entries.filter((entry) => entry.runId !== runId).map((entry) => ({ ...entry }))
1101
+ };
973
1102
  await atomicWrite3(this.indexPath, JSON.stringify(index, null, 2), { mode: 384 });
1103
+ this.cachedIndex = index;
1104
+ this.cachedIndexSignature = await this.indexSignature();
1105
+ }
1106
+ async indexSignature() {
1107
+ try {
1108
+ const stat2 = await fsp3.stat(this.indexPath);
1109
+ return { size: stat2.size, mtimeMs: stat2.mtimeMs, ctimeMs: stat2.ctimeMs };
1110
+ } catch {
1111
+ return null;
1112
+ }
974
1113
  }
975
1114
  };
1115
+ function sameIndexSignature(a, b) {
1116
+ if (a === null || b === null) return a === b;
1117
+ return a.size === b.size && a.mtimeMs === b.mtimeMs && a.ctimeMs === b.ctimeMs;
1118
+ }
976
1119
 
977
1120
  // src/sdd-board-projector.ts
978
- import { DefaultSecretScrubber } from "@wrongstack/core";
1121
+ import { DefaultSecretScrubber } from "@wrongstack/core/security";
979
1122
  function summarizeToolInput(input, scrubber) {
980
1123
  if (!input || typeof input !== "object" || Array.isArray(input)) return void 0;
981
1124
  const record = input;
@@ -1020,8 +1163,10 @@ var SddBoardProjector = class _SddBoardProjector {
1020
1163
  dirty = false;
1021
1164
  timer = null;
1022
1165
  unsubs = [];
1023
- /** Tail of in-flight persistence, so callers can await a settled state. */
1024
- lastSave = Promise.resolve();
1166
+ /** Latest snapshot waiting behind an in-flight disk write. */
1167
+ pendingSnapshot;
1168
+ /** At most one persistence loop runs; intermediate snapshots are coalesced. */
1169
+ saveLoop;
1025
1170
  constructor(opts) {
1026
1171
  this.o = opts;
1027
1172
  this.now = opts.now ?? Date.now;
@@ -1257,7 +1402,12 @@ var SddBoardProjector = class _SddBoardProjector {
1257
1402
  }
1258
1403
  /** Resolve once all in-flight snapshot persistence has settled. */
1259
1404
  async drain() {
1260
- await this.lastSave;
1405
+ for (; ; ) {
1406
+ const observed = this.saveLoop;
1407
+ if (!observed) return;
1408
+ await observed;
1409
+ if (observed === this.saveLoop && !this.pendingSnapshot) return;
1410
+ }
1261
1411
  }
1262
1412
  /** Stop projecting and release subscriptions. */
1263
1413
  dispose() {
@@ -1345,8 +1495,25 @@ var SddBoardProjector = class _SddBoardProjector {
1345
1495
  snapshot: snap
1346
1496
  });
1347
1497
  if (this.o.store) {
1348
- const store = this.o.store;
1349
- this.lastSave = this.lastSave.then(() => store.saveSnapshot(snap)).catch(() => {
1498
+ this.pendingSnapshot = snap;
1499
+ this.startSaveLoop(this.o.store);
1500
+ }
1501
+ }
1502
+ startSaveLoop(store) {
1503
+ if (this.saveLoop) return;
1504
+ const loop = this.persistPendingSnapshots(store);
1505
+ this.saveLoop = loop;
1506
+ void loop.finally(() => {
1507
+ if (this.saveLoop !== loop) return;
1508
+ this.saveLoop = void 0;
1509
+ if (this.pendingSnapshot) this.startSaveLoop(store);
1510
+ });
1511
+ }
1512
+ async persistPendingSnapshots(store) {
1513
+ while (this.pendingSnapshot) {
1514
+ const snapshot = this.pendingSnapshot;
1515
+ this.pendingSnapshot = void 0;
1516
+ await store.saveSnapshot(snapshot).catch(() => {
1350
1517
  });
1351
1518
  }
1352
1519
  }
@@ -1371,9 +1538,8 @@ var SddRunRegistry = class {
1371
1538
  };
1372
1539
 
1373
1540
  // src/spec-builder.ts
1374
- import { expectDefined } from "@wrongstack/core";
1375
- import { toErrorMessage } from "@wrongstack/core";
1376
- import { SddError as SddError2, ERROR_CODES as ERROR_CODES2 } from "@wrongstack/core";
1541
+ import { expectDefined, toErrorMessage } from "@wrongstack/core/utils";
1542
+ import { SddError as SddError2, ERROR_CODES as ERROR_CODES2 } from "@wrongstack/core/types";
1377
1543
  function buildQuestioningPrompt(session, min, max) {
1378
1544
  const answered = session.answers.length;
1379
1545
  const remaining = Math.max(0, min - answered);
@@ -1595,7 +1761,7 @@ var AISpecBuilder = class {
1595
1761
  try {
1596
1762
  const fsp5 = await import("node:fs/promises");
1597
1763
  const path4 = await import("node:path");
1598
- const { atomicWrite: atomicWrite4 } = await import("@wrongstack/core");
1764
+ const { atomicWrite: atomicWrite4 } = await import("@wrongstack/core/utils");
1599
1765
  await fsp5.mkdir(path4.dirname(this.sessionPath), { recursive: true });
1600
1766
  await atomicWrite4(this.sessionPath, JSON.stringify(this.session, null, 2));
1601
1767
  } catch {
@@ -2195,14 +2361,13 @@ function isExplanatoryText(text) {
2195
2361
  }
2196
2362
 
2197
2363
  // src/start-sdd-run.ts
2198
- import { TOKENS } from "@wrongstack/core";
2364
+ import { TOKENS } from "@wrongstack/core/kernel";
2199
2365
 
2200
2366
  // src/sdd-parallel-run.ts
2201
- import { expectDefined as expectDefined2 } from "@wrongstack/core";
2367
+ import { expectDefined as expectDefined2 } from "@wrongstack/core/utils";
2202
2368
  import { randomUUID as randomUUID2 } from "node:crypto";
2203
- import { makeAgentSubagentRunner, withDisabledToolFiltering, DefaultMultiAgentCoordinator } from "@wrongstack/core/coordination";
2204
- import { assignNickname } from "@wrongstack/core";
2205
- import { SddError as SddError3, ERROR_CODES as ERROR_CODES3 } from "@wrongstack/core";
2369
+ import { assignNickname, makeAgentSubagentRunner, withDisabledToolFiltering, DefaultMultiAgentCoordinator } from "@wrongstack/core/coordination";
2370
+ import { SddError as SddError3, ERROR_CODES as ERROR_CODES3 } from "@wrongstack/core/types";
2206
2371
 
2207
2372
  // src/sdd-task-decomposer.ts
2208
2373
  var SddTaskDecomposer = class {
@@ -3341,7 +3506,7 @@ function startSddRun(opts) {
3341
3506
 
3342
3507
  // src/sdd-lifecycle.ts
3343
3508
  import * as fsp4 from "node:fs/promises";
3344
- import { WorktreeManager } from "@wrongstack/core";
3509
+ import { WorktreeManager } from "@wrongstack/core/worktree";
3345
3510
  async function cleanupSddWorktrees(projectRoot) {
3346
3511
  const wt = new WorktreeManager({ projectRoot });
3347
3512
  return wt.cleanupAllManaged();
@@ -3581,8 +3746,8 @@ function templateToMarkdown(template, title) {
3581
3746
  }
3582
3747
 
3583
3748
  // src/task-visualizer.ts
3584
- import { computeTaskProgress as computeTaskProgress2 } from "@wrongstack/core/types";
3585
- import { truncate } from "@wrongstack/core";
3749
+ import { computeTaskProgress as computeTaskProgress2 } from "@wrongstack/core/tasking";
3750
+ import { truncate as truncate2 } from "@wrongstack/core/utils";
3586
3751
  var STATUS_ICON = {
3587
3752
  pending: "\u25CB",
3588
3753
  in_progress: "\u25D0",
@@ -3649,14 +3814,14 @@ function renderNode(graph, nodeId, lines, rendered, childrenMap, compact, prefix
3649
3814
  const icon = STATUS_ICON[node.status];
3650
3815
  const prioIcon = PRIORITY_ICON[node.priority];
3651
3816
  const typeIcon = TYPE_ICON[node.type];
3652
- const title = compact ? truncate(node.title, 40) : node.title;
3817
+ const title = compact ? truncate2(node.title, 40) : node.title;
3653
3818
  const blockedBy = childrenMap.get(nodeId) ?? [];
3654
3819
  const depsStr = blockedBy.length > 0 ? ` \u2190 [${blockedBy.map((d) => graph.nodes.get(d)?.title?.slice(0, 12) ?? "?").join(", ")}]` : "";
3655
3820
  lines.push(`${prefix}${icon} ${typeIcon} ${prioIcon} ${title}${depsStr}`);
3656
3821
  if (!compact && node.description) {
3657
3822
  const descLines = node.description.split("\n").slice(0, 3);
3658
3823
  for (const dl of descLines) {
3659
- lines.push(`${prefix} \u2514 ${truncate(dl, 60)}`);
3824
+ lines.push(`${prefix} \u2514 ${truncate2(dl, 60)}`);
3660
3825
  }
3661
3826
  }
3662
3827
  const dependents = graph.edges.filter((e) => e.type === "depends_on" && e.to === nodeId).map((e) => e.from).filter((id) => graph.nodes.has(id));
@@ -3734,8 +3899,8 @@ function renderSpecAnalysis(spec, analysis) {
3734
3899
  }
3735
3900
 
3736
3901
  // src/critical-path.ts
3737
- import { expectDefined as expectDefined3 } from "@wrongstack/core";
3738
- import { topologicalSort } from "@wrongstack/core/types";
3902
+ import { expectDefined as expectDefined3 } from "@wrongstack/core/utils";
3903
+ import { topologicalSort } from "@wrongstack/core/tasking";
3739
3904
  function analyzeCriticalPath(graph) {
3740
3905
  const nodes = Array.from(graph.nodes.values());
3741
3906
  const topoOrder = topologicalSort(graph);
@@ -3907,7 +4072,7 @@ function computeParallelGroups(graph, blockedByMap) {
3907
4072
  }
3908
4073
 
3909
4074
  // src/spec-versioning.ts
3910
- import { assertNever } from "@wrongstack/core";
4075
+ import { assertNever } from "@wrongstack/core/utils";
3911
4076
  var SpecVersioning = class {
3912
4077
  versions = /* @__PURE__ */ new Map();
3913
4078
  /** Record a new version of a spec. */
@@ -4243,7 +4408,7 @@ function createAutoExecutor(opts) {
4243
4408
  }
4244
4409
 
4245
4410
  // src/sdd-supervisor.ts
4246
- import { parseModelRef } from "@wrongstack/core";
4411
+ import { parseModelRef } from "@wrongstack/core/agent";
4247
4412
  var SddSupervisor = class {
4248
4413
  constructor(opts) {
4249
4414
  this.opts = opts;
@@ -4338,7 +4503,7 @@ function makeCommandVerifier(options = {}) {
4338
4503
  import {
4339
4504
  readBundledInstructionText,
4340
4505
  renderInstructionTemplate
4341
- } from "@wrongstack/core";
4506
+ } from "@wrongstack/core/utils";
4342
4507
  var TASK_TYPES2 = /* @__PURE__ */ new Set(["feature", "bugfix", "refactor", "docs", "test", "chore"]);
4343
4508
  var PRIORITIES = /* @__PURE__ */ new Set(["critical", "high", "medium", "low"]);
4344
4509
  function extractJsonArray(text) {
@@ -4398,12 +4563,12 @@ function makeLlmSubtaskGenerator(opts) {
4398
4563
  }
4399
4564
 
4400
4565
  // src/conflict-resolver.ts
4401
- import { readFile as readFile4, writeFile as writeFile2 } from "node:fs/promises";
4566
+ import { readFile as readFile4, writeFile } from "node:fs/promises";
4402
4567
  import { join as join4, isAbsolute } from "node:path";
4403
4568
  import {
4404
4569
  readBundledInstructionText as readBundledInstructionText2,
4405
4570
  renderInstructionTemplate as renderInstructionTemplate2
4406
- } from "@wrongstack/core";
4571
+ } from "@wrongstack/core/utils";
4407
4572
  var START = "<<<<<<<";
4408
4573
  var BASE = "|||||||";
4409
4574
  var SEP = "=======";
@@ -4455,7 +4620,7 @@ function makePreferSideConflictResolver(side) {
4455
4620
  const resolved = resolveConflictText(content, side);
4456
4621
  if (hasConflictMarkers(resolved)) return false;
4457
4622
  try {
4458
- await writeFile2(abs, resolved, "utf8");
4623
+ await writeFile(abs, resolved, "utf8");
4459
4624
  } catch {
4460
4625
  return false;
4461
4626
  }
@@ -4505,7 +4670,7 @@ function makeLlmConflictResolver(opts) {
4505
4670
  return false;
4506
4671
  }
4507
4672
  try {
4508
- await writeFile2(abs, resolved, "utf8");
4673
+ await writeFile(abs, resolved, "utf8");
4509
4674
  } catch {
4510
4675
  return false;
4511
4676
  }