@sideboard-ai/core 0.1.212 → 0.1.214

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
@@ -42,7 +42,7 @@ import {
42
42
  summarizeTurnStderr,
43
43
  toolDescription,
44
44
  turnFailChatText
45
- } from "./chunk-IA5IPGZI.js";
45
+ } from "./chunk-7MTVRNP4.js";
46
46
  import {
47
47
  SLACK_REPLY_FORMATTING,
48
48
  addWorkspace,
@@ -65,7 +65,7 @@ import {
65
65
  stageAbsolutePathsAsAttachments,
66
66
  stageBuffersAsAttachments,
67
67
  syncWorkspacesFromThreads
68
- } from "./chunk-WNVQJZ7P.js";
68
+ } from "./chunk-KFD2OXCE.js";
69
69
  import {
70
70
  addPrStackLayer,
71
71
  allocateTeamName,
@@ -115,7 +115,7 @@ import {
115
115
  worktreeDisplayLabelForGroup,
116
116
  worktreeNameFromPath,
117
117
  worktreeSlugForTicket
118
- } from "./chunk-VPQXJYIW.js";
118
+ } from "./chunk-XYKVRRC2.js";
119
119
  import {
120
120
  ATTACHMENTS_DIR,
121
121
  DETACHED_JOBS_DIR,
@@ -133,7 +133,7 @@ import {
133
133
  updateThread,
134
134
  withThreadLock,
135
135
  writeThread
136
- } from "./chunk-GHKFSBES.js";
136
+ } from "./chunk-HY2GFZ5S.js";
137
137
  import {
138
138
  ensureWorktreeSideboardIgnored
139
139
  } from "./chunk-SYFVUF2C.js";
@@ -417,7 +417,7 @@ async function continueSourceThread(threadId, prompt) {
417
417
  await continueOnReply(threadId, prompt);
418
418
  return;
419
419
  }
420
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-DW4HDWLA.js");
420
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-MI7A5DQZ.js");
421
421
  await getOrchestrator2().send(threadId, prompt);
422
422
  } catch {
423
423
  }
@@ -810,9 +810,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
810
810
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
811
811
  );
812
812
  }
813
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-RHABXQWB.js");
813
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-KT3FRHZL.js");
814
814
  if (isGlobalThread2(thread)) {
815
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-EHRDZ2ZU.js");
815
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-LE2GQZ2X.js");
816
816
  ensureGlobalCoordinatorCwd2(
817
817
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
818
818
  );
@@ -2317,6 +2317,29 @@ ${line}` : line;
2317
2317
  }
2318
2318
  var memory = /* @__PURE__ */ new Map();
2319
2319
  var persistTimers = /* @__PURE__ */ new Map();
2320
+ function fromSnapshot(snap) {
2321
+ return {
2322
+ chunks: snap.output ? [snap.output] : [],
2323
+ length: snap.output.length,
2324
+ running: snap.running,
2325
+ exitCode: snap.exitCode,
2326
+ source: snap.source
2327
+ };
2328
+ }
2329
+ function materialize(mem) {
2330
+ let output = mem.chunks.join("\n");
2331
+ if (output.length > MAX_SETUP_LOG_CHARS) {
2332
+ output = appendSetupOutput("", output);
2333
+ mem.chunks = [output];
2334
+ mem.length = output.length;
2335
+ }
2336
+ return {
2337
+ output,
2338
+ running: mem.running,
2339
+ exitCode: mem.exitCode,
2340
+ source: mem.source
2341
+ };
2342
+ }
2320
2343
  function setupLogPath(threadId) {
2321
2344
  return join7(threadsDir(), `${threadId}.setup.log.json`);
2322
2345
  }
@@ -2327,20 +2350,22 @@ function setupLogKeyForWorktree(worktreePath) {
2327
2350
  function emptySetupLog() {
2328
2351
  return { ...EMPTY };
2329
2352
  }
2330
- function clone(snap) {
2331
- return { ...snap };
2332
- }
2353
+ var PERSIST_DEBOUNCE_MS = 500;
2333
2354
  function persistNow(threadId) {
2334
2355
  const timer = persistTimers.get(threadId);
2335
2356
  if (timer) {
2336
2357
  clearTimeout(timer);
2337
2358
  persistTimers.delete(threadId);
2338
2359
  }
2339
- const snap = memory.get(threadId);
2340
- if (!snap) return;
2360
+ const mem = memory.get(threadId);
2361
+ if (!mem) return;
2341
2362
  try {
2342
- writeFileSync2(setupLogPath(threadId), `${JSON.stringify(snap)}
2343
- `, "utf8");
2363
+ writeFileSync2(
2364
+ setupLogPath(threadId),
2365
+ `${JSON.stringify(materialize(mem))}
2366
+ `,
2367
+ "utf8"
2368
+ );
2344
2369
  } catch {
2345
2370
  }
2346
2371
  }
@@ -2351,7 +2376,7 @@ function schedulePersist(threadId) {
2351
2376
  setTimeout(() => {
2352
2377
  persistTimers.delete(threadId);
2353
2378
  persistNow(threadId);
2354
- }, 100)
2379
+ }, PERSIST_DEBOUNCE_MS)
2355
2380
  );
2356
2381
  }
2357
2382
  function loadFromDisk(threadId) {
@@ -2369,49 +2394,50 @@ function loadFromDisk(threadId) {
2369
2394
  return null;
2370
2395
  }
2371
2396
  }
2397
+ function memFor(threadId) {
2398
+ const cached = memory.get(threadId);
2399
+ if (cached) return cached;
2400
+ const mem = fromSnapshot(loadFromDisk(threadId) ?? emptySetupLog());
2401
+ memory.set(threadId, mem);
2402
+ return mem;
2403
+ }
2372
2404
  function readSetupLog(threadId) {
2373
2405
  const cached = memory.get(threadId);
2374
- if (cached) return clone(cached);
2406
+ if (cached) return materialize(cached);
2375
2407
  const disk = loadFromDisk(threadId);
2376
2408
  if (disk) {
2377
- memory.set(threadId, disk);
2378
- return clone(disk);
2409
+ memory.set(threadId, fromSnapshot(disk));
2410
+ return disk;
2379
2411
  }
2380
2412
  return emptySetupLog();
2381
2413
  }
2382
2414
  function beginSetupLog(threadId) {
2383
- const snap = {
2384
- output: "",
2415
+ const mem = {
2416
+ chunks: [],
2417
+ length: 0,
2385
2418
  running: true,
2386
2419
  exitCode: null,
2387
2420
  source: null
2388
2421
  };
2389
- memory.set(threadId, snap);
2422
+ memory.set(threadId, mem);
2390
2423
  persistNow(threadId);
2391
- return clone(snap);
2424
+ return materialize(mem);
2392
2425
  }
2393
2426
  function appendSetupLog(threadId, line) {
2394
- const current = memory.get(threadId) ?? readSetupLog(threadId);
2395
- const snap = {
2396
- ...current,
2397
- output: appendSetupOutput(current.output, line),
2398
- running: true
2399
- };
2400
- memory.set(threadId, snap);
2427
+ const mem = memFor(threadId);
2428
+ mem.chunks.push(line);
2429
+ mem.length += line.length + 1;
2430
+ mem.running = true;
2431
+ if (mem.length > MAX_SETUP_LOG_CHARS * 2) materialize(mem);
2401
2432
  schedulePersist(threadId);
2402
- return clone(snap);
2403
2433
  }
2404
2434
  function finishSetupLog(threadId, exitCode, source) {
2405
- const current = memory.get(threadId) ?? readSetupLog(threadId);
2406
- const snap = {
2407
- ...current,
2408
- running: false,
2409
- exitCode,
2410
- source: source ?? current.source
2411
- };
2412
- memory.set(threadId, snap);
2435
+ const mem = memFor(threadId);
2436
+ mem.running = false;
2437
+ mem.exitCode = exitCode;
2438
+ mem.source = source ?? mem.source;
2413
2439
  persistNow(threadId);
2414
- return clone(snap);
2440
+ return materialize(mem);
2415
2441
  }
2416
2442
 
2417
2443
  // src/git/orphan-cleanup.ts
@@ -3903,6 +3929,33 @@ function shouldRemoveWorktreeOnTeardown(thread) {
3903
3929
  return !isCowboyThread(thread) && !isPrimaryCheckoutThread(thread);
3904
3930
  }
3905
3931
 
3932
+ // src/util/line-coalescer.ts
3933
+ function createLineCoalescer(onChunk, opts) {
3934
+ const delayMs = opts?.delayMs ?? 50;
3935
+ const maxLines = opts?.maxLines ?? 200;
3936
+ let buffer = [];
3937
+ let timer = null;
3938
+ const flush2 = () => {
3939
+ if (timer) {
3940
+ clearTimeout(timer);
3941
+ timer = null;
3942
+ }
3943
+ if (buffer.length === 0) return;
3944
+ const chunk = buffer.join("\n");
3945
+ buffer = [];
3946
+ onChunk(chunk);
3947
+ };
3948
+ const push = (line) => {
3949
+ buffer.push(line);
3950
+ if (buffer.length >= maxLines) {
3951
+ flush2();
3952
+ return;
3953
+ }
3954
+ if (!timer) timer = setTimeout(flush2, delayMs);
3955
+ };
3956
+ return { push, flush: flush2 };
3957
+ }
3958
+
3906
3959
  // src/store/turn-live.ts
3907
3960
  import {
3908
3961
  existsSync as existsSync11,
@@ -4314,7 +4367,7 @@ async function adoptThread(input) {
4314
4367
  messages: input.messages ?? []
4315
4368
  });
4316
4369
  writeThread(thread);
4317
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-VIUUE4RT.js");
4370
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-KM7KTLVO.js");
4318
4371
  await ensureWorkspace2(repoPath);
4319
4372
  const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-N5X5I422.js");
4320
4373
  await ensureWorktreeSideboardIgnored2(input.worktreePath);
@@ -5521,6 +5574,29 @@ function writeWorktreeFile(worktreePath, relativePath, content) {
5521
5574
  writeFileSync6(abs, content, "utf8");
5522
5575
  return { path: relativePath };
5523
5576
  }
5577
+ async function getWorktreeDirtyStat(worktreePath) {
5578
+ const status = await inspectGitWorktree(worktreePath);
5579
+ if (status !== "ok") {
5580
+ return { additions: 0, deletions: 0, dirty: false };
5581
+ }
5582
+ const head = await git(["rev-parse", "--verify", "HEAD"], worktreePath, {
5583
+ reject: false,
5584
+ timeoutMs: 4e3
5585
+ });
5586
+ if (head.exitCode !== 0) {
5587
+ return { additions: 0, deletions: 0, dirty: await isDirty(worktreePath) };
5588
+ }
5589
+ const [num, dirty] = await Promise.all([
5590
+ gitDiff(["--numstat", "HEAD"], worktreePath, { timeoutMs: 4e3 }),
5591
+ isDirty(worktreePath)
5592
+ ]);
5593
+ const counts = statFromNumstat(num.stdout);
5594
+ return {
5595
+ additions: counts.additions,
5596
+ deletions: counts.deletions,
5597
+ dirty: dirty || counts.additions > 0 || counts.deletions > 0
5598
+ };
5599
+ }
5524
5600
  async function getDiffSummary(worktreePath, repoPath, opts) {
5525
5601
  const full = await getDiff(worktreePath, repoPath, {
5526
5602
  maxHunkChars: opts?.maxHunkChars ?? 2e3,
@@ -6744,7 +6820,7 @@ function formatScheduledPrompt(name, prompt) {
6744
6820
  ${prompt}`;
6745
6821
  }
6746
6822
  async function defaultDeps() {
6747
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-DW4HDWLA.js");
6823
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-MI7A5DQZ.js");
6748
6824
  const orch = getOrchestrator2();
6749
6825
  return {
6750
6826
  findThread: (id) => findThreadByRef(id),
@@ -6875,6 +6951,7 @@ function resolveOrchChildFollowUp(requested) {
6875
6951
  return followUpBehavior();
6876
6952
  }
6877
6953
  var STALE_AGENT_PID_WAIT_MS = 2500;
6954
+ var LIGHT_RECONCILE_THROTTLE_MS = 1e4;
6878
6955
  function writeLiveStatus(threadId, status, lastError) {
6879
6956
  const latest = readThread(threadId);
6880
6957
  if (!latest || latest.status === "archived") return latest;
@@ -6889,6 +6966,8 @@ var Orchestrator = class {
6889
6966
  startingTurns = /* @__PURE__ */ new Set();
6890
6967
  /** Last sync thread-file read for false-stop heal (throttled per thread). */
6891
6968
  lastReconcileHealAt = /* @__PURE__ */ new Map();
6969
+ /** Per-repo timestamp of the last `reconcile(repo, { light: true })`. */
6970
+ lightReconcileAt = /* @__PURE__ */ new Map();
6892
6971
  /**
6893
6972
  * Threads intentionally force-stopped. Prevents runTurn from re-asserting
6894
6973
  * `running` after spawn, and from overwriting `stopped` with idle/error when
@@ -6974,6 +7053,20 @@ var Orchestrator = class {
6974
7053
  async reconcile(repoPath, opts) {
6975
7054
  const reclaimStaleTurns = opts?.reclaimStaleTurns === true;
6976
7055
  const drainQueues = opts?.drainQueues !== false;
7056
+ if (opts?.light && repoPath) {
7057
+ const last = this.lightReconcileAt.get(repoPath) ?? 0;
7058
+ if (Date.now() - last < LIGHT_RECONCILE_THROTTLE_MS) return;
7059
+ this.lightReconcileAt.set(repoPath, Date.now());
7060
+ for (const thread of listThreads()) {
7061
+ if (isGlobalThread(thread) || thread.repoPath !== repoPath) continue;
7062
+ if (!existsSync19(thread.worktreePath)) {
7063
+ setStatus(thread.id, "broken", "Worktree missing on disk");
7064
+ this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
7065
+ }
7066
+ }
7067
+ await this.reconcileOrphans([repoPath]);
7068
+ return;
7069
+ }
6977
7070
  healOrchestrationSoccerTitles();
6978
7071
  for (const thread of listThreads({ includeArchived: true })) {
6979
7072
  if (thread.status === "archived") continue;
@@ -7006,6 +7099,21 @@ var Orchestrator = class {
7006
7099
  }
7007
7100
  }
7008
7101
  const repoPaths = (repoPath ? [repoPath] : [...new Set(listThreads({ includeArchived: true }).map((t) => t.repoPath))]).filter((p) => !isGlobalRepoPath(p));
7102
+ await this.reconcileOrphans(repoPaths);
7103
+ try {
7104
+ if (shouldRunHistoryCleanup()) {
7105
+ cleanupArchivedHistory();
7106
+ }
7107
+ } catch {
7108
+ }
7109
+ if (drainQueues) {
7110
+ this.adoptPersistedQueues();
7111
+ }
7112
+ this.schedulePendingQuotaResumes();
7113
+ armSchedules();
7114
+ }
7115
+ /** Surface (and, when enabled, clean up) worktrees git knows about but no thread owns. */
7116
+ async reconcileOrphans(repoPaths) {
7009
7117
  try {
7010
7118
  const orphans = await findOrphanWorktrees(repoPaths);
7011
7119
  if (orphans.length) {
@@ -7020,17 +7128,6 @@ var Orchestrator = class {
7020
7128
  }
7021
7129
  } catch {
7022
7130
  }
7023
- try {
7024
- if (shouldRunHistoryCleanup()) {
7025
- cleanupArchivedHistory();
7026
- }
7027
- } catch {
7028
- }
7029
- if (drainQueues) {
7030
- this.adoptPersistedQueues();
7031
- }
7032
- this.schedulePendingQuotaResumes();
7033
- armSchedules();
7034
7131
  }
7035
7132
  /**
7036
7133
  * Adopt queues persisted by another process (MCP stdio / CLI) into this
@@ -7264,7 +7361,7 @@ var Orchestrator = class {
7264
7361
  return listThreads({ includeArchived });
7265
7362
  }
7266
7363
  getThread(idOrRef) {
7267
- return findThreadByRef(idOrRef) ?? readThread(idOrRef);
7364
+ return readThread(idOrRef) ?? findThreadByRef(idOrRef);
7268
7365
  }
7269
7366
  async createThread(input) {
7270
7367
  const prior = new Set(
@@ -8120,17 +8217,18 @@ var Orchestrator = class {
8120
8217
  }
8121
8218
  }
8122
8219
  }
8220
+ const runOutput = createLineCoalescer((chunk) => {
8221
+ this.emit({
8222
+ type: "run_output",
8223
+ threadId: thread.id,
8224
+ scriptName: resolvedName,
8225
+ line: chunk
8226
+ });
8227
+ });
8123
8228
  const handle = await startDevServer(
8124
8229
  thread.repoPath,
8125
8230
  thread.worktreePath,
8126
- (line) => {
8127
- this.emit({
8128
- type: "run_output",
8129
- threadId: thread.id,
8130
- scriptName: resolvedName,
8131
- line
8132
- });
8133
- },
8231
+ runOutput.push,
8134
8232
  { scriptName: resolvedName }
8135
8233
  );
8136
8234
  if (!handle) {
@@ -8176,6 +8274,7 @@ var Orchestrator = class {
8176
8274
  scriptName: resolvedName
8177
8275
  });
8178
8276
  void handle.done.then(() => {
8277
+ runOutput.flush();
8179
8278
  this.processes.delete(runKey);
8180
8279
  if (isDefault) this.processes.delete(worktreeDevProcessKey(thread.worktreePath));
8181
8280
  const latest = mergeWorktreeActiveRuns(threadsSharingWorktree(thread.worktreePath));
@@ -8261,9 +8360,14 @@ var Orchestrator = class {
8261
8360
  (t) => this.processes.has(`${t.id}:setup`)
8262
8361
  );
8263
8362
  }
8264
- writeSetupLog(threadId, worktreePath, fn) {
8363
+ /**
8364
+ * The worktree-keyed log is canonical (`resolveWorktreeSetupLog` prefers it
8365
+ * whenever it has output/running/exitCode); per-chat keys only exist for
8366
+ * records that predate it. Writing one key halves the sync persists during
8367
+ * `pnpm install`.
8368
+ */
8369
+ writeSetupLog(worktreePath, fn) {
8265
8370
  fn(setupLogKeyForWorktree(worktreePath));
8266
- fn(threadId);
8267
8371
  }
8268
8372
  async runSetup(threadRef, opts) {
8269
8373
  const thread = this.requireThread(threadRef);
@@ -8278,14 +8382,18 @@ var Orchestrator = class {
8278
8382
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
8279
8383
  kill: () => abort.abort()
8280
8384
  });
8281
- this.writeSetupLog(thread.id, thread.worktreePath, beginSetupLog);
8385
+ this.writeSetupLog(thread.worktreePath, beginSetupLog);
8282
8386
  this.emit({ type: "setup_started", threadId: thread.id });
8387
+ const output = createLineCoalescer((chunk) => {
8388
+ this.writeSetupLog(thread.worktreePath, (logKey) => appendSetupLog(logKey, chunk));
8389
+ this.emit({ type: "setup_output", threadId: thread.id, line: chunk });
8390
+ });
8283
8391
  let finished = false;
8284
8392
  const finish = (exitCode, source) => {
8285
8393
  if (finished) return;
8286
8394
  finished = true;
8395
+ output.flush();
8287
8396
  this.writeSetupLog(
8288
- thread.id,
8289
8397
  thread.worktreePath,
8290
8398
  (logKey) => finishSetupLog(logKey, exitCode, source)
8291
8399
  );
@@ -8295,24 +8403,12 @@ var Orchestrator = class {
8295
8403
  const setup = await runWorkspaceSetup(
8296
8404
  thread.repoPath,
8297
8405
  thread.worktreePath,
8298
- (line) => {
8299
- this.writeSetupLog(
8300
- thread.id,
8301
- thread.worktreePath,
8302
- (logKey) => appendSetupLog(logKey, line)
8303
- );
8304
- this.emit({ type: "setup_output", threadId: thread.id, line });
8305
- },
8406
+ output.push,
8306
8407
  { signal: abort.signal }
8307
8408
  );
8308
8409
  if (!setup.ran) {
8309
8410
  const line = "No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)";
8310
- this.writeSetupLog(
8311
- thread.id,
8312
- thread.worktreePath,
8313
- (logKey) => appendSetupLog(logKey, line)
8314
- );
8315
- this.emit({ type: "setup_output", threadId: thread.id, line });
8411
+ output.push(line);
8316
8412
  finish(null, null);
8317
8413
  throw new Error(line);
8318
8414
  }
@@ -8518,6 +8614,11 @@ var Orchestrator = class {
8518
8614
  lastTurnBase: this.turnBaselines.get(thread.id) ?? null
8519
8615
  });
8520
8616
  }
8617
+ async worktreeDirtyStat(threadRef) {
8618
+ const thread = this.requireThread(threadRef);
8619
+ this.assertNotGlobal(thread, "Diff");
8620
+ return getWorktreeDirtyStat(thread.worktreePath);
8621
+ }
8521
8622
  async diffSummary(threadRef) {
8522
8623
  const thread = this.requireThread(threadRef);
8523
8624
  this.assertNotGlobal(thread, "Diff");
@@ -8966,7 +9067,7 @@ var Orchestrator = class {
8966
9067
  this.enforceHistoryRetention();
8967
9068
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
8968
9069
  try {
8969
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-VIUUE4RT.js");
9070
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-KM7KTLVO.js");
8970
9071
  await ensureWorkspace2(thread.repoPath);
8971
9072
  } catch {
8972
9073
  }
@@ -9020,7 +9121,7 @@ var Orchestrator = class {
9020
9121
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
9021
9122
  );
9022
9123
  }
9023
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-3MEG62KB.js");
9124
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-VXRI7LYM.js");
9024
9125
  const slug = thread.worktreePath.split("/").pop();
9025
9126
  const dest = thread.worktreePath;
9026
9127
  await withRepoGitLock(thread.repoPath, async () => {
@@ -9130,7 +9231,7 @@ async function startOrchestration(opts) {
9130
9231
  sourceRef: "default",
9131
9232
  ...createOpts
9132
9233
  }).catch(async () => {
9133
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-3MEG62KB.js");
9234
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-VXRI7LYM.js");
9134
9235
  const repo = await resolveRepoRoot2(repoPath);
9135
9236
  const def = await resolveDefaultBranch2(repo);
9136
9237
  return orch.createThread({
@@ -9140,7 +9241,7 @@ async function startOrchestration(opts) {
9140
9241
  repoPath: repo
9141
9242
  });
9142
9243
  });
9143
- const { updateThread: upd } = await import("./thread-store-MSMBQ3V4.js");
9244
+ const { updateThread: upd } = await import("./thread-store-KDPPXJJ3.js");
9144
9245
  const updated = upd(thread.id, {
9145
9246
  sourceType: "orchestration",
9146
9247
  sourceRef: goal
@@ -9192,6 +9293,7 @@ export {
9192
9293
  waitForPidExit,
9193
9294
  resolveSendFollowUp,
9194
9295
  resolveOrchChildFollowUp,
9296
+ LIGHT_RECONCILE_THROTTLE_MS,
9195
9297
  Orchestrator,
9196
9298
  getOrchestrator,
9197
9299
  startOrchestration
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  isOrchestratorThread
3
- } from "./chunk-2PE6SZCM.js";
3
+ } from "./chunk-FNGXKY5W.js";
4
4
  import {
5
5
  codexUnattendedGitConfigArgs,
6
6
  mergeAgentGitAuthEnv,
7
7
  resolveAgentGitAuthEnv,
8
8
  resolveCodexGitWritableRoots
9
- } from "./chunk-NRKDRQM3.js";
9
+ } from "./chunk-NI243N27.js";
10
10
  import {
11
11
  applyConnectedTeamToCli,
12
12
  brightsyMcpServerName,
@@ -1903,7 +1903,7 @@ var claudeAdapter = {
1903
1903
  );
1904
1904
  }
1905
1905
  const mode = permissionMode(thread);
1906
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-NG2TBUI5.js");
1906
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-6P236KKG.js");
1907
1907
  const isOrchestrator = isOrchestratorThread2(thread);
1908
1908
  const injectedServers = await buildInjectedMcpServers({
1909
1909
  includeSideboard: true,
@@ -5,7 +5,7 @@ import {
5
5
  resolveRepoRoot,
6
6
  takenSlugsFromThread,
7
7
  teamSlugFromName
8
- } from "./chunk-NRKDRQM3.js";
8
+ } from "./chunk-NI243N27.js";
9
9
  import {
10
10
  ATTACHMENTS_DIR,
11
11
  attachmentsGitignoreBody
@@ -28,7 +28,7 @@ import {
28
28
  listThreads,
29
29
  updateThread,
30
30
  writeThread
31
- } from "./chunk-JJ3ONQ4Q.js";
31
+ } from "./chunk-3IMSQNTS.js";
32
32
  import {
33
33
  appDataDir,
34
34
  globalAgentCwd,
@@ -146,6 +146,7 @@ function forgetThread(id) {
146
146
  const cache = cacheForDir();
147
147
  cache.byId.delete(id);
148
148
  cache.mtimeMs.delete(id);
149
+ selfWriteMtimes.delete(id);
149
150
  }
150
151
  function invalidateThreadListCache() {
151
152
  listCache = null;
@@ -169,20 +170,28 @@ function readThread(id) {
169
170
  rememberThread(thread, mtimeMs);
170
171
  return thread;
171
172
  }
173
+ var selfWriteMtimes = /* @__PURE__ */ new Map();
172
174
  function writeThread(thread, opts) {
173
175
  const path = threadFilePath(idPath(thread.id));
174
176
  const tmp = `${path}.${process.pid}.tmp`;
175
177
  const next = opts?.touch === false ? { ...thread } : { ...thread, updatedAt: nowIso() };
176
178
  writeFileSync(tmp, JSON.stringify(next, null, 2), "utf8");
177
179
  renameSync(tmp, path);
178
- rememberThread(next, fileMtimeMs(path) ?? Date.now());
180
+ const mtimeMs = fileMtimeMs(path) ?? Date.now();
181
+ rememberThread(next, mtimeMs);
182
+ selfWriteMtimes.set(thread.id, mtimeMs);
183
+ }
184
+ function isSelfWrittenRecord(id) {
185
+ const ours = selfWriteMtimes.get(id);
186
+ if (ours == null) return false;
187
+ return fileMtimeMs(threadFilePath(id)) === ours;
179
188
  }
180
189
  function idPath(id) {
181
190
  return id;
182
191
  }
183
192
  function isThreadRecordFile(nameOrPath) {
184
193
  const name = basename(nameOrPath);
185
- return name.endsWith(".json") && !name.endsWith(".live.json");
194
+ return name.endsWith(".json") && !name.endsWith(".live.json") && !name.endsWith(".setup.log.json");
186
195
  }
187
196
  function listThreads(opts) {
188
197
  const cache = cacheForDir();
@@ -258,6 +267,7 @@ export {
258
267
  invalidateThreadRecord,
259
268
  readThread,
260
269
  writeThread,
270
+ isSelfWrittenRecord,
261
271
  isThreadRecordFile,
262
272
  listThreads,
263
273
  deleteThreadRecord,
@@ -7,7 +7,7 @@ import {
7
7
  resolveRepoRoot,
8
8
  takenSlugsFromThread,
9
9
  teamSlugFromName
10
- } from "./chunk-VPQXJYIW.js";
10
+ } from "./chunk-XYKVRRC2.js";
11
11
  import {
12
12
  ATTACHMENTS_DIR,
13
13
  attachmentsGitignoreBody
@@ -17,7 +17,7 @@ import {
17
17
  listThreads,
18
18
  updateThread,
19
19
  writeThread
20
- } from "./chunk-GHKFSBES.js";
20
+ } from "./chunk-HY2GFZ5S.js";
21
21
  import {
22
22
  assertOrchestratorCapableAgent,
23
23
  formatAccountProfilePlaybookLine,
@@ -10,7 +10,7 @@ import {
10
10
  } from "./chunk-L5CIEBLR.js";
11
11
  import {
12
12
  listThreads
13
- } from "./chunk-JJ3ONQ4Q.js";
13
+ } from "./chunk-3IMSQNTS.js";
14
14
  import {
15
15
  worktreesRoot
16
16
  } from "./chunk-WFUDY6PC.js";
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-D6JWYJ4P.js";
6
6
  import {
7
7
  listThreads
8
- } from "./chunk-GHKFSBES.js";
8
+ } from "./chunk-HY2GFZ5S.js";
9
9
  import {
10
10
  ensureWorktreeSideboardIgnored
11
11
  } from "./chunk-SYFVUF2C.js";
@@ -7,15 +7,15 @@ import {
7
7
  enrichWorkspacesWithGithub,
8
8
  ensureGlobalCoordinatorCwd,
9
9
  formatWorkspaceInventory
10
- } from "./chunk-2PE6SZCM.js";
11
- import "./chunk-NRKDRQM3.js";
10
+ } from "./chunk-FNGXKY5W.js";
11
+ import "./chunk-NI243N27.js";
12
12
  import "./chunk-6K64FJDD.js";
13
13
  import "./chunk-QQKDGPUI.js";
14
14
  import "./chunk-L5CIEBLR.js";
15
15
  import "./chunk-4TR3HZFT.js";
16
16
  import "./chunk-WDRMZKVB.js";
17
17
  import "./chunk-JT7R45JB.js";
18
- import "./chunk-JJ3ONQ4Q.js";
18
+ import "./chunk-3IMSQNTS.js";
19
19
  import "./chunk-7J72QJOM.js";
20
20
  import "./chunk-77WWLBCI.js";
21
21
  import "./chunk-WFUDY6PC.js";
@@ -9,10 +9,10 @@ import {
9
9
  enrichWorkspacesWithGithub,
10
10
  ensureGlobalCoordinatorCwd,
11
11
  formatWorkspaceInventory
12
- } from "./chunk-WNVQJZ7P.js";
13
- import "./chunk-VPQXJYIW.js";
12
+ } from "./chunk-KFD2OXCE.js";
13
+ import "./chunk-XYKVRRC2.js";
14
14
  import "./chunk-D6JWYJ4P.js";
15
- import "./chunk-GHKFSBES.js";
15
+ import "./chunk-HY2GFZ5S.js";
16
16
  import "./chunk-X5B3OS5I.js";
17
17
  import "./chunk-SYFVUF2C.js";
18
18
  import "./chunk-FNQNJOHY.js";