@sideboard-ai/core 0.1.212 → 0.1.213

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 (31) hide show
  1. package/dist/{agents-GQANI7M5.js → agents-HETHRRZJ.js} +4 -4
  2. package/dist/{agents-A2U3K7VK.js → agents-WBDDLRBY.js} +4 -4
  3. package/dist/{chunk-JJ3ONQ4Q.js → chunk-3IMSQNTS.js} +12 -2
  4. package/dist/{chunk-IA5IPGZI.js → chunk-7MTVRNP4.js} +3 -3
  5. package/dist/{chunk-DINKOGEU.js → chunk-C32SBNA3.js} +187 -84
  6. package/dist/{chunk-MS6HGW2H.js → chunk-D2IKXMF3.js} +185 -83
  7. package/dist/{chunk-IRCAWYTN.js → chunk-DFTVZEZY.js} +3 -3
  8. package/dist/{chunk-2PE6SZCM.js → chunk-FNGXKY5W.js} +2 -2
  9. package/dist/{chunk-GHKFSBES.js → chunk-HY2GFZ5S.js} +12 -2
  10. package/dist/{chunk-WNVQJZ7P.js → chunk-KFD2OXCE.js} +2 -2
  11. package/dist/{chunk-NRKDRQM3.js → chunk-NI243N27.js} +1 -1
  12. package/dist/{chunk-VPQXJYIW.js → chunk-XYKVRRC2.js} +1 -1
  13. package/dist/{coordinator-prompt-LMTMWCPN.js → coordinator-prompt-FQX6ALAI.js} +3 -3
  14. package/dist/{coordinator-prompt-EHRDZ2ZU.js → coordinator-prompt-LE2GQZ2X.js} +3 -3
  15. package/dist/{global-workspace-NG2TBUI5.js → global-workspace-6P236KKG.js} +3 -3
  16. package/dist/{global-workspace-RHABXQWB.js → global-workspace-KT3FRHZL.js} +3 -3
  17. package/dist/index.cjs +199 -75
  18. package/dist/index.d.cts +59 -3
  19. package/dist/index.d.ts +59 -3
  20. package/dist/index.js +11 -5
  21. package/dist/mcp/run-stdio.cjs +193 -75
  22. package/dist/mcp/run-stdio.js +5 -5
  23. package/dist/{orchestrator-DW4HDWLA.js → orchestrator-MI7A5DQZ.js} +7 -5
  24. package/dist/{orchestrator-333M3JAU.js → orchestrator-WVZPTHBV.js} +7 -5
  25. package/dist/{thread-store-MSMBQ3V4.js → thread-store-KDPPXJJ3.js} +3 -1
  26. package/dist/{thread-store-4M6WETL6.js → thread-store-N6WQIWZ4.js} +3 -1
  27. package/dist/{workspaces-VIUUE4RT.js → workspaces-KM7KTLVO.js} +3 -3
  28. package/dist/{workspaces-FRR6Y4BY.js → workspaces-R5LJCJRB.js} +3 -3
  29. package/dist/{worktree-GKUOHXXB.js → worktree-MDMTCAHX.js} +2 -2
  30. package/dist/{worktree-3MEG62KB.js → worktree-VXRI7LYM.js} +2 -2
  31. package/package.json +1 -1
@@ -841,6 +841,7 @@ __export(thread_store_exports, {
841
841
  findThreadByRef: () => findThreadByRef,
842
842
  invalidateThreadListCache: () => invalidateThreadListCache,
843
843
  invalidateThreadRecord: () => invalidateThreadRecord,
844
+ isSelfWrittenRecord: () => isSelfWrittenRecord,
844
845
  isThreadRecordFile: () => isThreadRecordFile,
845
846
  listThreads: () => listThreads,
846
847
  normalizeThread: () => normalizeThread,
@@ -970,6 +971,7 @@ function forgetThread(id) {
970
971
  const cache = cacheForDir();
971
972
  cache.byId.delete(id);
972
973
  cache.mtimeMs.delete(id);
974
+ selfWriteMtimes.delete(id);
973
975
  }
974
976
  function invalidateThreadListCache() {
975
977
  listCache = null;
@@ -999,14 +1001,21 @@ function writeThread(thread, opts) {
999
1001
  const next = opts?.touch === false ? { ...thread } : { ...thread, updatedAt: nowIso() };
1000
1002
  (0, import_node_fs8.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
1001
1003
  (0, import_node_fs8.renameSync)(tmp, path);
1002
- rememberThread(next, fileMtimeMs(path) ?? Date.now());
1004
+ const mtimeMs = fileMtimeMs(path) ?? Date.now();
1005
+ rememberThread(next, mtimeMs);
1006
+ selfWriteMtimes.set(thread.id, mtimeMs);
1007
+ }
1008
+ function isSelfWrittenRecord(id) {
1009
+ const ours = selfWriteMtimes.get(id);
1010
+ if (ours == null) return false;
1011
+ return fileMtimeMs(threadFilePath(id)) === ours;
1003
1012
  }
1004
1013
  function idPath(id) {
1005
1014
  return id;
1006
1015
  }
1007
1016
  function isThreadRecordFile(nameOrPath) {
1008
1017
  const name = (0, import_node_path9.basename)(nameOrPath);
1009
- return name.endsWith(".json") && !name.endsWith(".live.json");
1018
+ return name.endsWith(".json") && !name.endsWith(".live.json") && !name.endsWith(".setup.log.json");
1010
1019
  }
1011
1020
  function listThreads(opts) {
1012
1021
  const cache = cacheForDir();
@@ -1072,7 +1081,7 @@ function findThreadByRef(ref) {
1072
1081
  (t) => t.id === ref || t.id.startsWith(ref) || t.branchName === ref || t.title === ref
1073
1082
  ) ?? null;
1074
1083
  }
1075
- var import_node_crypto2, import_node_fs8, import_node_path9, import_proper_lockfile, listCache;
1084
+ var import_node_crypto2, import_node_fs8, import_node_path9, import_proper_lockfile, listCache, selfWriteMtimes;
1076
1085
  var init_thread_store = __esm({
1077
1086
  "src/store/thread-store.ts"() {
1078
1087
  "use strict";
@@ -1084,6 +1093,7 @@ var init_thread_store = __esm({
1084
1093
  init_cursor_store();
1085
1094
  init_paths();
1086
1095
  listCache = null;
1096
+ selfWriteMtimes = /* @__PURE__ */ new Map();
1087
1097
  }
1088
1098
  });
1089
1099
 
@@ -14372,6 +14382,29 @@ ${line}` : line;
14372
14382
  const nl = cut.indexOf("\n");
14373
14383
  return nl >= 0 && nl < cut.length - 1 ? cut.slice(nl + 1) : cut;
14374
14384
  }
14385
+ function fromSnapshot(snap) {
14386
+ return {
14387
+ chunks: snap.output ? [snap.output] : [],
14388
+ length: snap.output.length,
14389
+ running: snap.running,
14390
+ exitCode: snap.exitCode,
14391
+ source: snap.source
14392
+ };
14393
+ }
14394
+ function materialize(mem) {
14395
+ let output = mem.chunks.join("\n");
14396
+ if (output.length > MAX_SETUP_LOG_CHARS) {
14397
+ output = appendSetupOutput("", output);
14398
+ mem.chunks = [output];
14399
+ mem.length = output.length;
14400
+ }
14401
+ return {
14402
+ output,
14403
+ running: mem.running,
14404
+ exitCode: mem.exitCode,
14405
+ source: mem.source
14406
+ };
14407
+ }
14375
14408
  function setupLogPath(threadId) {
14376
14409
  return (0, import_node_path38.join)(threadsDir(), `${threadId}.setup.log.json`);
14377
14410
  }
@@ -14382,20 +14415,21 @@ function setupLogKeyForWorktree(worktreePath) {
14382
14415
  function emptySetupLog() {
14383
14416
  return { ...EMPTY };
14384
14417
  }
14385
- function clone(snap) {
14386
- return { ...snap };
14387
- }
14388
14418
  function persistNow(threadId) {
14389
14419
  const timer = persistTimers.get(threadId);
14390
14420
  if (timer) {
14391
14421
  clearTimeout(timer);
14392
14422
  persistTimers.delete(threadId);
14393
14423
  }
14394
- const snap = memory.get(threadId);
14395
- if (!snap) return;
14424
+ const mem = memory.get(threadId);
14425
+ if (!mem) return;
14396
14426
  try {
14397
- (0, import_node_fs37.writeFileSync)(setupLogPath(threadId), `${JSON.stringify(snap)}
14398
- `, "utf8");
14427
+ (0, import_node_fs37.writeFileSync)(
14428
+ setupLogPath(threadId),
14429
+ `${JSON.stringify(materialize(mem))}
14430
+ `,
14431
+ "utf8"
14432
+ );
14399
14433
  } catch {
14400
14434
  }
14401
14435
  }
@@ -14406,7 +14440,7 @@ function schedulePersist(threadId) {
14406
14440
  setTimeout(() => {
14407
14441
  persistTimers.delete(threadId);
14408
14442
  persistNow(threadId);
14409
- }, 100)
14443
+ }, PERSIST_DEBOUNCE_MS)
14410
14444
  );
14411
14445
  }
14412
14446
  function loadFromDisk(threadId) {
@@ -14424,51 +14458,52 @@ function loadFromDisk(threadId) {
14424
14458
  return null;
14425
14459
  }
14426
14460
  }
14461
+ function memFor(threadId) {
14462
+ const cached = memory.get(threadId);
14463
+ if (cached) return cached;
14464
+ const mem = fromSnapshot(loadFromDisk(threadId) ?? emptySetupLog());
14465
+ memory.set(threadId, mem);
14466
+ return mem;
14467
+ }
14427
14468
  function readSetupLog(threadId) {
14428
14469
  const cached = memory.get(threadId);
14429
- if (cached) return clone(cached);
14470
+ if (cached) return materialize(cached);
14430
14471
  const disk = loadFromDisk(threadId);
14431
14472
  if (disk) {
14432
- memory.set(threadId, disk);
14433
- return clone(disk);
14473
+ memory.set(threadId, fromSnapshot(disk));
14474
+ return disk;
14434
14475
  }
14435
14476
  return emptySetupLog();
14436
14477
  }
14437
14478
  function beginSetupLog(threadId) {
14438
- const snap = {
14439
- output: "",
14479
+ const mem = {
14480
+ chunks: [],
14481
+ length: 0,
14440
14482
  running: true,
14441
14483
  exitCode: null,
14442
14484
  source: null
14443
14485
  };
14444
- memory.set(threadId, snap);
14486
+ memory.set(threadId, mem);
14445
14487
  persistNow(threadId);
14446
- return clone(snap);
14488
+ return materialize(mem);
14447
14489
  }
14448
14490
  function appendSetupLog(threadId, line) {
14449
- const current = memory.get(threadId) ?? readSetupLog(threadId);
14450
- const snap = {
14451
- ...current,
14452
- output: appendSetupOutput(current.output, line),
14453
- running: true
14454
- };
14455
- memory.set(threadId, snap);
14491
+ const mem = memFor(threadId);
14492
+ mem.chunks.push(line);
14493
+ mem.length += line.length + 1;
14494
+ mem.running = true;
14495
+ if (mem.length > MAX_SETUP_LOG_CHARS * 2) materialize(mem);
14456
14496
  schedulePersist(threadId);
14457
- return clone(snap);
14458
14497
  }
14459
14498
  function finishSetupLog(threadId, exitCode, source) {
14460
- const current = memory.get(threadId) ?? readSetupLog(threadId);
14461
- const snap = {
14462
- ...current,
14463
- running: false,
14464
- exitCode,
14465
- source: source ?? current.source
14466
- };
14467
- memory.set(threadId, snap);
14499
+ const mem = memFor(threadId);
14500
+ mem.running = false;
14501
+ mem.exitCode = exitCode;
14502
+ mem.source = source ?? mem.source;
14468
14503
  persistNow(threadId);
14469
- return clone(snap);
14504
+ return materialize(mem);
14470
14505
  }
14471
- var import_node_crypto8, import_node_fs37, import_node_path38, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers;
14506
+ var import_node_crypto8, import_node_fs37, import_node_path38, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers, PERSIST_DEBOUNCE_MS;
14472
14507
  var init_setup_log = __esm({
14473
14508
  "src/store/setup-log.ts"() {
14474
14509
  "use strict";
@@ -14486,6 +14521,7 @@ var init_setup_log = __esm({
14486
14521
  MAX_SETUP_LOG_CHARS = 256e3;
14487
14522
  memory = /* @__PURE__ */ new Map();
14488
14523
  persistTimers = /* @__PURE__ */ new Map();
14524
+ PERSIST_DEBOUNCE_MS = 500;
14489
14525
  }
14490
14526
  });
14491
14527
 
@@ -17526,6 +17562,38 @@ var init_cowboy = __esm({
17526
17562
  }
17527
17563
  });
17528
17564
 
17565
+ // src/util/line-coalescer.ts
17566
+ function createLineCoalescer(onChunk, opts) {
17567
+ const delayMs = opts?.delayMs ?? 50;
17568
+ const maxLines = opts?.maxLines ?? 200;
17569
+ let buffer = [];
17570
+ let timer = null;
17571
+ const flush2 = () => {
17572
+ if (timer) {
17573
+ clearTimeout(timer);
17574
+ timer = null;
17575
+ }
17576
+ if (buffer.length === 0) return;
17577
+ const chunk = buffer.join("\n");
17578
+ buffer = [];
17579
+ onChunk(chunk);
17580
+ };
17581
+ const push = (line) => {
17582
+ buffer.push(line);
17583
+ if (buffer.length >= maxLines) {
17584
+ flush2();
17585
+ return;
17586
+ }
17587
+ if (!timer) timer = setTimeout(flush2, delayMs);
17588
+ };
17589
+ return { push, flush: flush2 };
17590
+ }
17591
+ var init_line_coalescer = __esm({
17592
+ "src/util/line-coalescer.ts"() {
17593
+ "use strict";
17594
+ }
17595
+ });
17596
+
17529
17597
  // src/store/turn-live.ts
17530
17598
  function trimParts(parts) {
17531
17599
  if (parts.length <= MAX_PARTS) return parts;
@@ -19175,6 +19243,29 @@ function writeWorktreeFile(worktreePath, relativePath, content) {
19175
19243
  (0, import_node_fs46.writeFileSync)(abs, content, "utf8");
19176
19244
  return { path: relativePath };
19177
19245
  }
19246
+ async function getWorktreeDirtyStat(worktreePath) {
19247
+ const status = await inspectGitWorktree(worktreePath);
19248
+ if (status !== "ok") {
19249
+ return { additions: 0, deletions: 0, dirty: false };
19250
+ }
19251
+ const head = await git(["rev-parse", "--verify", "HEAD"], worktreePath, {
19252
+ reject: false,
19253
+ timeoutMs: 4e3
19254
+ });
19255
+ if (head.exitCode !== 0) {
19256
+ return { additions: 0, deletions: 0, dirty: await isDirty(worktreePath) };
19257
+ }
19258
+ const [num2, dirty] = await Promise.all([
19259
+ gitDiff(["--numstat", "HEAD"], worktreePath, { timeoutMs: 4e3 }),
19260
+ isDirty(worktreePath)
19261
+ ]);
19262
+ const counts = statFromNumstat(num2.stdout);
19263
+ return {
19264
+ additions: counts.additions,
19265
+ deletions: counts.deletions,
19266
+ dirty: dirty || counts.additions > 0 || counts.deletions > 0
19267
+ };
19268
+ }
19178
19269
  async function getDiffSummary(worktreePath, repoPath, opts) {
19179
19270
  const full = await getDiff(worktreePath, repoPath, {
19180
19271
  maxHunkChars: opts?.maxHunkChars ?? 2e3,
@@ -20993,6 +21084,7 @@ var init_title = __esm({
20993
21084
  // src/orchestrator/orchestrator.ts
20994
21085
  var orchestrator_exports = {};
20995
21086
  __export(orchestrator_exports, {
21087
+ LIGHT_RECONCILE_THROTTLE_MS: () => LIGHT_RECONCILE_THROTTLE_MS,
20996
21088
  LIVE_TURN_SPAWN_GRACE_MS: () => LIVE_TURN_SPAWN_GRACE_MS,
20997
21089
  Orchestrator: () => Orchestrator,
20998
21090
  getOrchestrator: () => getOrchestrator,
@@ -21096,7 +21188,7 @@ async function startOrchestration(opts) {
21096
21188
  }
21097
21189
  return updated;
21098
21190
  }
21099
- var import_node_events, import_node_fs54, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, Orchestrator, singleton;
21191
+ var import_node_events, import_node_fs54, LIVE_TURN_SPAWN_GRACE_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton;
21100
21192
  var init_orchestrator = __esm({
21101
21193
  "src/orchestrator/orchestrator.ts"() {
21102
21194
  "use strict";
@@ -21130,6 +21222,7 @@ var init_orchestrator = __esm({
21130
21222
  init_orchestrator_capable();
21131
21223
  init_chat_tabs();
21132
21224
  init_enqueue_by_key();
21225
+ init_line_coalescer();
21133
21226
  init_run();
21134
21227
  init_repo_git_lock();
21135
21228
  init_turn_live();
@@ -21163,6 +21256,7 @@ var init_orchestrator = __esm({
21163
21256
  init_coordinator_prompt();
21164
21257
  LIVE_TURN_SPAWN_GRACE_MS = 15e3;
21165
21258
  STALE_AGENT_PID_WAIT_MS = 2500;
21259
+ LIGHT_RECONCILE_THROTTLE_MS = 1e4;
21166
21260
  Orchestrator = class {
21167
21261
  events = new import_node_events.EventEmitter();
21168
21262
  processes = /* @__PURE__ */ new Map();
@@ -21172,6 +21266,8 @@ var init_orchestrator = __esm({
21172
21266
  startingTurns = /* @__PURE__ */ new Set();
21173
21267
  /** Last sync thread-file read for false-stop heal (throttled per thread). */
21174
21268
  lastReconcileHealAt = /* @__PURE__ */ new Map();
21269
+ /** Per-repo timestamp of the last `reconcile(repo, { light: true })`. */
21270
+ lightReconcileAt = /* @__PURE__ */ new Map();
21175
21271
  /**
21176
21272
  * Threads intentionally force-stopped. Prevents runTurn from re-asserting
21177
21273
  * `running` after spawn, and from overwriting `stopped` with idle/error when
@@ -21257,6 +21353,20 @@ var init_orchestrator = __esm({
21257
21353
  async reconcile(repoPath, opts) {
21258
21354
  const reclaimStaleTurns = opts?.reclaimStaleTurns === true;
21259
21355
  const drainQueues = opts?.drainQueues !== false;
21356
+ if (opts?.light && repoPath) {
21357
+ const last = this.lightReconcileAt.get(repoPath) ?? 0;
21358
+ if (Date.now() - last < LIGHT_RECONCILE_THROTTLE_MS) return;
21359
+ this.lightReconcileAt.set(repoPath, Date.now());
21360
+ for (const thread of listThreads()) {
21361
+ if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
21362
+ if (!(0, import_node_fs54.existsSync)(thread.worktreePath)) {
21363
+ setStatus(thread.id, "broken", "Worktree missing on disk");
21364
+ this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
21365
+ }
21366
+ }
21367
+ await this.reconcileOrphans([repoPath]);
21368
+ return;
21369
+ }
21260
21370
  healOrchestrationSoccerTitles();
21261
21371
  for (const thread of listThreads({ includeArchived: true })) {
21262
21372
  if (thread.status === "archived") continue;
@@ -21289,6 +21399,21 @@ var init_orchestrator = __esm({
21289
21399
  }
21290
21400
  }
21291
21401
  const repoPaths = (repoPath ? [repoPath] : [...new Set(listThreads({ includeArchived: true }).map((t) => t.repoPath))]).filter((p) => !isGlobalRepoPath(p));
21402
+ await this.reconcileOrphans(repoPaths);
21403
+ try {
21404
+ if (shouldRunHistoryCleanup()) {
21405
+ cleanupArchivedHistory();
21406
+ }
21407
+ } catch {
21408
+ }
21409
+ if (drainQueues) {
21410
+ this.adoptPersistedQueues();
21411
+ }
21412
+ this.schedulePendingQuotaResumes();
21413
+ armSchedules();
21414
+ }
21415
+ /** Surface (and, when enabled, clean up) worktrees git knows about but no thread owns. */
21416
+ async reconcileOrphans(repoPaths) {
21292
21417
  try {
21293
21418
  const orphans = await findOrphanWorktrees(repoPaths);
21294
21419
  if (orphans.length) {
@@ -21303,17 +21428,6 @@ var init_orchestrator = __esm({
21303
21428
  }
21304
21429
  } catch {
21305
21430
  }
21306
- try {
21307
- if (shouldRunHistoryCleanup()) {
21308
- cleanupArchivedHistory();
21309
- }
21310
- } catch {
21311
- }
21312
- if (drainQueues) {
21313
- this.adoptPersistedQueues();
21314
- }
21315
- this.schedulePendingQuotaResumes();
21316
- armSchedules();
21317
21431
  }
21318
21432
  /**
21319
21433
  * Adopt queues persisted by another process (MCP stdio / CLI) into this
@@ -21547,7 +21661,7 @@ var init_orchestrator = __esm({
21547
21661
  return listThreads({ includeArchived });
21548
21662
  }
21549
21663
  getThread(idOrRef) {
21550
- return findThreadByRef(idOrRef) ?? readThread(idOrRef);
21664
+ return readThread(idOrRef) ?? findThreadByRef(idOrRef);
21551
21665
  }
21552
21666
  async createThread(input) {
21553
21667
  const prior = new Set(
@@ -22403,17 +22517,18 @@ var init_orchestrator = __esm({
22403
22517
  }
22404
22518
  }
22405
22519
  }
22520
+ const runOutput = createLineCoalescer((chunk) => {
22521
+ this.emit({
22522
+ type: "run_output",
22523
+ threadId: thread.id,
22524
+ scriptName: resolvedName,
22525
+ line: chunk
22526
+ });
22527
+ });
22406
22528
  const handle = await startDevServer(
22407
22529
  thread.repoPath,
22408
22530
  thread.worktreePath,
22409
- (line) => {
22410
- this.emit({
22411
- type: "run_output",
22412
- threadId: thread.id,
22413
- scriptName: resolvedName,
22414
- line
22415
- });
22416
- },
22531
+ runOutput.push,
22417
22532
  { scriptName: resolvedName }
22418
22533
  );
22419
22534
  if (!handle) {
@@ -22459,6 +22574,7 @@ var init_orchestrator = __esm({
22459
22574
  scriptName: resolvedName
22460
22575
  });
22461
22576
  void handle.done.then(() => {
22577
+ runOutput.flush();
22462
22578
  this.processes.delete(runKey);
22463
22579
  if (isDefault) this.processes.delete(worktreeDevProcessKey(thread.worktreePath));
22464
22580
  const latest = mergeWorktreeActiveRuns(threadsSharingWorktree(thread.worktreePath));
@@ -22544,9 +22660,14 @@ var init_orchestrator = __esm({
22544
22660
  (t) => this.processes.has(`${t.id}:setup`)
22545
22661
  );
22546
22662
  }
22547
- writeSetupLog(threadId, worktreePath, fn) {
22663
+ /**
22664
+ * The worktree-keyed log is canonical (`resolveWorktreeSetupLog` prefers it
22665
+ * whenever it has output/running/exitCode); per-chat keys only exist for
22666
+ * records that predate it. Writing one key halves the sync persists during
22667
+ * `pnpm install`.
22668
+ */
22669
+ writeSetupLog(worktreePath, fn) {
22548
22670
  fn(setupLogKeyForWorktree(worktreePath));
22549
- fn(threadId);
22550
22671
  }
22551
22672
  async runSetup(threadRef, opts) {
22552
22673
  const thread = this.requireThread(threadRef);
@@ -22561,14 +22682,18 @@ var init_orchestrator = __esm({
22561
22682
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
22562
22683
  kill: () => abort.abort()
22563
22684
  });
22564
- this.writeSetupLog(thread.id, thread.worktreePath, beginSetupLog);
22685
+ this.writeSetupLog(thread.worktreePath, beginSetupLog);
22565
22686
  this.emit({ type: "setup_started", threadId: thread.id });
22687
+ const output = createLineCoalescer((chunk) => {
22688
+ this.writeSetupLog(thread.worktreePath, (logKey) => appendSetupLog(logKey, chunk));
22689
+ this.emit({ type: "setup_output", threadId: thread.id, line: chunk });
22690
+ });
22566
22691
  let finished = false;
22567
22692
  const finish = (exitCode, source) => {
22568
22693
  if (finished) return;
22569
22694
  finished = true;
22695
+ output.flush();
22570
22696
  this.writeSetupLog(
22571
- thread.id,
22572
22697
  thread.worktreePath,
22573
22698
  (logKey) => finishSetupLog(logKey, exitCode, source)
22574
22699
  );
@@ -22578,24 +22703,12 @@ var init_orchestrator = __esm({
22578
22703
  const setup = await runWorkspaceSetup(
22579
22704
  thread.repoPath,
22580
22705
  thread.worktreePath,
22581
- (line) => {
22582
- this.writeSetupLog(
22583
- thread.id,
22584
- thread.worktreePath,
22585
- (logKey) => appendSetupLog(logKey, line)
22586
- );
22587
- this.emit({ type: "setup_output", threadId: thread.id, line });
22588
- },
22706
+ output.push,
22589
22707
  { signal: abort.signal }
22590
22708
  );
22591
22709
  if (!setup.ran) {
22592
22710
  const line = "No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)";
22593
- this.writeSetupLog(
22594
- thread.id,
22595
- thread.worktreePath,
22596
- (logKey) => appendSetupLog(logKey, line)
22597
- );
22598
- this.emit({ type: "setup_output", threadId: thread.id, line });
22711
+ output.push(line);
22599
22712
  finish(null, null);
22600
22713
  throw new Error(line);
22601
22714
  }
@@ -22801,6 +22914,11 @@ var init_orchestrator = __esm({
22801
22914
  lastTurnBase: this.turnBaselines.get(thread.id) ?? null
22802
22915
  });
22803
22916
  }
22917
+ async worktreeDirtyStat(threadRef) {
22918
+ const thread = this.requireThread(threadRef);
22919
+ this.assertNotGlobal(thread, "Diff");
22920
+ return getWorktreeDirtyStat(thread.worktreePath);
22921
+ }
22804
22922
  async diffSummary(threadRef) {
22805
22923
  const thread = this.requireThread(threadRef);
22806
22924
  this.assertNotGlobal(thread, "Diff");
@@ -50,7 +50,7 @@ import {
50
50
  syncBoardPins,
51
51
  updateSchedule,
52
52
  waitForDetachedJob
53
- } from "../chunk-MS6HGW2H.js";
53
+ } from "../chunk-D2IKXMF3.js";
54
54
  import "../chunk-JFOPOMK7.js";
55
55
  import "../chunk-YWI3IBP2.js";
56
56
  import {
@@ -61,12 +61,12 @@ import {
61
61
  materializeSystemCaBundle,
62
62
  sideboardMcpProfile,
63
63
  trustSystemCertificates
64
- } from "../chunk-IA5IPGZI.js";
64
+ } from "../chunk-7MTVRNP4.js";
65
65
  import {
66
66
  GLOBAL_WORKSPACE_ID,
67
67
  isCloudCoordinatorThread,
68
68
  listWorkspaces
69
- } from "../chunk-WNVQJZ7P.js";
69
+ } from "../chunk-KFD2OXCE.js";
70
70
  import "../chunk-3OHR73VK.js";
71
71
  import "../chunk-Y4MIXGPA.js";
72
72
  import "../chunk-YVE4PXCJ.js";
@@ -84,9 +84,9 @@ import {
84
84
  resolveListPrsOptions,
85
85
  resolveRepoRoot,
86
86
  warmGithubAgentAuth
87
- } from "../chunk-VPQXJYIW.js";
87
+ } from "../chunk-XYKVRRC2.js";
88
88
  import "../chunk-D6JWYJ4P.js";
89
- import "../chunk-GHKFSBES.js";
89
+ import "../chunk-HY2GFZ5S.js";
90
90
  import "../chunk-X5B3OS5I.js";
91
91
  import "../chunk-SYFVUF2C.js";
92
92
  import {
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import {
4
+ LIGHT_RECONCILE_THROTTLE_MS,
4
5
  LIVE_TURN_SPAWN_GRACE_MS,
5
6
  Orchestrator,
6
7
  getOrchestrator,
@@ -9,17 +10,17 @@ import {
9
10
  resolveSendFollowUp,
10
11
  startOrchestration,
11
12
  waitForPidExit
12
- } from "./chunk-MS6HGW2H.js";
13
+ } from "./chunk-D2IKXMF3.js";
13
14
  import "./chunk-JFOPOMK7.js";
14
15
  import "./chunk-YWI3IBP2.js";
15
- import "./chunk-IA5IPGZI.js";
16
- import "./chunk-WNVQJZ7P.js";
16
+ import "./chunk-7MTVRNP4.js";
17
+ import "./chunk-KFD2OXCE.js";
17
18
  import "./chunk-3OHR73VK.js";
18
19
  import "./chunk-Y4MIXGPA.js";
19
20
  import "./chunk-VKQGAWHY.js";
20
- import "./chunk-VPQXJYIW.js";
21
+ import "./chunk-XYKVRRC2.js";
21
22
  import "./chunk-D6JWYJ4P.js";
22
- import "./chunk-GHKFSBES.js";
23
+ import "./chunk-HY2GFZ5S.js";
23
24
  import "./chunk-X5B3OS5I.js";
24
25
  import "./chunk-SYFVUF2C.js";
25
26
  import "./chunk-FNQNJOHY.js";
@@ -29,6 +30,7 @@ import "./chunk-KGZBYWZ3.js";
29
30
  import "./chunk-EQNRWDLN.js";
30
31
  import "./chunk-FJZWM2ON.js";
31
32
  export {
33
+ LIGHT_RECONCILE_THROTTLE_MS,
32
34
  LIVE_TURN_SPAWN_GRACE_MS,
33
35
  Orchestrator,
34
36
  getOrchestrator,
@@ -1,4 +1,5 @@
1
1
  import {
2
+ LIGHT_RECONCILE_THROTTLE_MS,
2
3
  LIVE_TURN_SPAWN_GRACE_MS,
3
4
  Orchestrator,
4
5
  getOrchestrator,
@@ -7,11 +8,11 @@ import {
7
8
  resolveSendFollowUp,
8
9
  startOrchestration,
9
10
  waitForPidExit
10
- } from "./chunk-DINKOGEU.js";
11
+ } from "./chunk-C32SBNA3.js";
11
12
  import "./chunk-DJU54RYW.js";
12
- import "./chunk-IRCAWYTN.js";
13
- import "./chunk-2PE6SZCM.js";
14
- import "./chunk-NRKDRQM3.js";
13
+ import "./chunk-DFTVZEZY.js";
14
+ import "./chunk-FNGXKY5W.js";
15
+ import "./chunk-NI243N27.js";
15
16
  import "./chunk-6K64FJDD.js";
16
17
  import "./chunk-QQKDGPUI.js";
17
18
  import "./chunk-SALM35KD.js";
@@ -24,12 +25,13 @@ import "./chunk-4TR3HZFT.js";
24
25
  import "./chunk-WDRMZKVB.js";
25
26
  import "./chunk-4TYXWPAJ.js";
26
27
  import "./chunk-JT7R45JB.js";
27
- import "./chunk-JJ3ONQ4Q.js";
28
+ import "./chunk-3IMSQNTS.js";
28
29
  import "./chunk-7J72QJOM.js";
29
30
  import "./chunk-77WWLBCI.js";
30
31
  import "./chunk-WFUDY6PC.js";
31
32
  import "./chunk-UFHNSFAS.js";
32
33
  export {
34
+ LIGHT_RECONCILE_THROTTLE_MS,
33
35
  LIVE_TURN_SPAWN_GRACE_MS,
34
36
  Orchestrator,
35
37
  getOrchestrator,
@@ -7,6 +7,7 @@ import {
7
7
  findThreadByRef,
8
8
  invalidateThreadListCache,
9
9
  invalidateThreadRecord,
10
+ isSelfWrittenRecord,
10
11
  isThreadRecordFile,
11
12
  listThreads,
12
13
  normalizeThread,
@@ -16,7 +17,7 @@ import {
16
17
  updateThread,
17
18
  withThreadLock,
18
19
  writeThread
19
- } from "./chunk-GHKFSBES.js";
20
+ } from "./chunk-HY2GFZ5S.js";
20
21
  import "./chunk-X5B3OS5I.js";
21
22
  import "./chunk-KGZBYWZ3.js";
22
23
  import "./chunk-EQNRWDLN.js";
@@ -27,6 +28,7 @@ export {
27
28
  findThreadByRef,
28
29
  invalidateThreadListCache,
29
30
  invalidateThreadRecord,
31
+ isSelfWrittenRecord,
30
32
  isThreadRecordFile,
31
33
  listThreads,
32
34
  normalizeThread,
@@ -5,6 +5,7 @@ import {
5
5
  findThreadByRef,
6
6
  invalidateThreadListCache,
7
7
  invalidateThreadRecord,
8
+ isSelfWrittenRecord,
8
9
  isThreadRecordFile,
9
10
  listThreads,
10
11
  normalizeThread,
@@ -14,7 +15,7 @@ import {
14
15
  updateThread,
15
16
  withThreadLock,
16
17
  writeThread
17
- } from "./chunk-JJ3ONQ4Q.js";
18
+ } from "./chunk-3IMSQNTS.js";
18
19
  import "./chunk-7J72QJOM.js";
19
20
  import "./chunk-77WWLBCI.js";
20
21
  import "./chunk-WFUDY6PC.js";
@@ -25,6 +26,7 @@ export {
25
26
  findThreadByRef,
26
27
  invalidateThreadListCache,
27
28
  invalidateThreadRecord,
29
+ isSelfWrittenRecord,
28
30
  isThreadRecordFile,
29
31
  listThreads,
30
32
  normalizeThread,
@@ -6,10 +6,10 @@ import {
6
6
  listWorkspaces,
7
7
  removeWorkspace,
8
8
  syncWorkspacesFromThreads
9
- } from "./chunk-WNVQJZ7P.js";
10
- import "./chunk-VPQXJYIW.js";
9
+ } from "./chunk-KFD2OXCE.js";
10
+ import "./chunk-XYKVRRC2.js";
11
11
  import "./chunk-D6JWYJ4P.js";
12
- import "./chunk-GHKFSBES.js";
12
+ import "./chunk-HY2GFZ5S.js";
13
13
  import "./chunk-X5B3OS5I.js";
14
14
  import "./chunk-SYFVUF2C.js";
15
15
  import "./chunk-FNQNJOHY.js";
@@ -4,15 +4,15 @@ import {
4
4
  listWorkspaces,
5
5
  removeWorkspace,
6
6
  syncWorkspacesFromThreads
7
- } from "./chunk-2PE6SZCM.js";
8
- import "./chunk-NRKDRQM3.js";
7
+ } from "./chunk-FNGXKY5W.js";
8
+ import "./chunk-NI243N27.js";
9
9
  import "./chunk-6K64FJDD.js";
10
10
  import "./chunk-QQKDGPUI.js";
11
11
  import "./chunk-L5CIEBLR.js";
12
12
  import "./chunk-4TR3HZFT.js";
13
13
  import "./chunk-WDRMZKVB.js";
14
14
  import "./chunk-JT7R45JB.js";
15
- import "./chunk-JJ3ONQ4Q.js";
15
+ import "./chunk-3IMSQNTS.js";
16
16
  import "./chunk-7J72QJOM.js";
17
17
  import "./chunk-77WWLBCI.js";
18
18
  import "./chunk-WFUDY6PC.js";