@sideboard-ai/core 0.1.152 → 0.1.155

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 (61) hide show
  1. package/dist/{abletime-223A3LY6.js → abletime-H7LPGIP2.js} +3 -3
  2. package/dist/{abletime-CLC5UJC2.js → abletime-JSTJLXAW.js} +3 -3
  3. package/dist/agents/cursor-runner.js +2 -2
  4. package/dist/{agents-CUKWIM34.js → agents-V24DYZI4.js} +8 -9
  5. package/dist/{agents-VHXCBBBD.js → agents-YVW75KBO.js} +8 -9
  6. package/dist/{app-settings-3CHCNIMD.js → app-settings-H3INSR67.js} +38 -4
  7. package/dist/{app-settings-J3JBCUOT.js → app-settings-VRQI3FIE.js} +38 -4
  8. package/dist/{caffeinate-hold-NBRUWYXO.js → caffeinate-hold-DBKMRZZO.js} +2 -2
  9. package/dist/{caffeinate-hold-X3JNPR42.js → caffeinate-hold-SK2QISPE.js} +2 -2
  10. package/dist/chunk-2F63IMCL.js +959 -0
  11. package/dist/{chunk-4XNSGDXE.js → chunk-3BWVOUQG.js} +244 -1
  12. package/dist/{chunk-7BQNSUR2.js → chunk-46ZTBUVJ.js} +364 -200
  13. package/dist/{chunk-EY6QXPPO.js → chunk-4THE3EY7.js} +6 -6
  14. package/dist/{chunk-TUGKX5BD.js → chunk-7UURXPKD.js} +1 -1
  15. package/dist/{chunk-DCOZABNT.js → chunk-AO35MGOE.js} +1 -1
  16. package/dist/{chunk-3JBMACYX.js → chunk-CJQLPPEJ.js} +387 -15
  17. package/dist/{chunk-CZD4NRDZ.js → chunk-D7EGJ3EI.js} +244 -1
  18. package/dist/{chunk-QZQEXME2.js → chunk-EFVFB2AH.js} +1 -1
  19. package/dist/{chunk-B7XK37WZ.js → chunk-FDCFXMDG.js} +1 -1
  20. package/dist/{chunk-6X7Z34XE.js → chunk-J2OKVOBM.js} +410 -188
  21. package/dist/{chunk-WLV7TRMR.js → chunk-JOK4XWBG.js} +1 -1
  22. package/dist/{chunk-BD2ICC4D.js → chunk-JTJHOYCU.js} +1 -1
  23. package/dist/{chunk-GE7M3QTE.js → chunk-LQMFCS54.js} +387 -15
  24. package/dist/{chunk-G7SIQFBQ.js → chunk-LZ6QMEQC.js} +1 -1
  25. package/dist/{chunk-EUXOHTUK.js → chunk-LZQULFIT.js} +1 -1
  26. package/dist/{chunk-KLBOWJ74.js → chunk-OCQPTUR7.js} +1 -1
  27. package/dist/{chunk-GFQ57XAX.js → chunk-QZEZXYVV.js} +13 -13
  28. package/dist/chunk-RNC3GR6L.js +905 -0
  29. package/dist/{chunk-VHX673DI.js → chunk-WLPXZFRE.js} +1 -1
  30. package/dist/{chunk-7F4XE6UG.js → chunk-XD2BAANL.js} +5 -5
  31. package/dist/{connected-teams-XO766HB4.js → connected-teams-DBWAMP7G.js} +2 -2
  32. package/dist/{connected-teams-I2WZZZFA.js → connected-teams-WGONUQOF.js} +2 -2
  33. package/dist/{coordinator-prompt-WGFRYCHE.js → coordinator-prompt-7FHKCWXB.js} +5 -5
  34. package/dist/{coordinator-prompt-TBX4MOFM.js → coordinator-prompt-KX2FVVYT.js} +5 -5
  35. package/dist/{cursor-recover-NOQYOFRF.js → cursor-recover-L5MD6MBO.js} +1 -1
  36. package/dist/{cursor-recover-QSLWEZNA.js → cursor-recover-NDMLLNYX.js} +2 -2
  37. package/dist/{global-workspace-IY5QAV5C.js → global-workspace-2BRRKSDN.js} +5 -6
  38. package/dist/{global-workspace-BHLUJ46D.js → global-workspace-4LHCZ2DC.js} +5 -6
  39. package/dist/index.cjs +1889 -777
  40. package/dist/index.d.cts +222 -12
  41. package/dist/index.d.ts +222 -12
  42. package/dist/index.js +304 -108
  43. package/dist/mcp/run-stdio.cjs +1747 -1240
  44. package/dist/mcp/run-stdio.js +232 -80
  45. package/dist/{orchestrator-256DFPSX.js → orchestrator-3FWEKDAQ.js} +9 -11
  46. package/dist/{orchestrator-NUA6SEV7.js → orchestrator-HC7XVGJB.js} +10 -12
  47. package/dist/{paths-UMEDHOS5.js → paths-53TLA7VQ.js} +1 -1
  48. package/dist/{paths-QCI3MTO5.js → paths-RRCLNSJB.js} +1 -1
  49. package/dist/{thread-store-WGASXXXR.js → thread-store-KBFBHT5G.js} +2 -2
  50. package/dist/{thread-store-57ZLHR3A.js → thread-store-MVQU6HPJ.js} +2 -2
  51. package/dist/{workspaces-4FSXVIZM.js → workspaces-5UNDTN4G.js} +5 -7
  52. package/dist/{workspaces-NECIQTAO.js → workspaces-MQYNZXUK.js} +5 -7
  53. package/dist/{worktree-HTUM35NT.js → worktree-PEWDAX5O.js} +4 -4
  54. package/dist/{worktree-DPIREDFR.js → worktree-T4SWFSTT.js} +4 -4
  55. package/package.json +1 -1
  56. package/dist/chunk-2U6QF3PT.js +0 -211
  57. package/dist/chunk-67TIJ7S5.js +0 -122
  58. package/dist/chunk-7TIUOYBK.js +0 -213
  59. package/dist/chunk-G4MTYUWS.js +0 -592
  60. package/dist/chunk-K2ANSHUO.js +0 -120
  61. package/dist/chunk-SN6CMKF6.js +0 -538
@@ -24,18 +24,19 @@ import {
24
24
  stripBrightsyNdjsonNoise,
25
25
  sumUsageList,
26
26
  toolDescription
27
- } from "./chunk-GFQ57XAX.js";
27
+ } from "./chunk-QZEZXYVV.js";
28
28
  import {
29
+ SLACK_REPLY_FORMATTING,
29
30
  addWorkspace,
30
- ensureWorkspace,
31
- removeWorkspace,
32
- syncWorkspacesFromThreads
33
- } from "./chunk-K2ANSHUO.js";
34
- import {
35
31
  assertOrchestratorCapableAgent,
36
32
  attachmentsFromWorktreePaths,
37
33
  coerceOrchestratorAgent,
34
+ coordinatorSystemPrompt,
35
+ coordinatorTurnReminder,
38
36
  createGlobalChat,
37
+ enrichWorkspacesWithGithub,
38
+ ensureGlobalCoordinatorCwd,
39
+ ensureWorkspace,
39
40
  healOrchestrationSoccerTitles,
40
41
  isCloudCoordinatorThread,
41
42
  isGlobalRepoPath,
@@ -45,16 +46,11 @@ import {
45
46
  isSlackCoordinatorThread,
46
47
  orchestratorSessionPoisonedByBuiltins,
47
48
  persistPendingFileAttachments,
49
+ removeWorkspace,
48
50
  stageAbsolutePathsAsAttachments,
49
- stageBuffersAsAttachments
50
- } from "./chunk-G4MTYUWS.js";
51
- import {
52
- SLACK_REPLY_FORMATTING,
53
- coordinatorSystemPrompt,
54
- coordinatorTurnReminder,
55
- enrichWorkspacesWithGithub,
56
- ensureGlobalCoordinatorCwd
57
- } from "./chunk-2U6QF3PT.js";
51
+ stageBuffersAsAttachments,
52
+ syncWorkspacesFromThreads
53
+ } from "./chunk-2F63IMCL.js";
58
54
  import {
59
55
  addPrStackLayer,
60
56
  allocateTeamName,
@@ -102,7 +98,7 @@ import {
102
98
  withRepoGitLock,
103
99
  worktreeDisplayLabelForGroup,
104
100
  worktreeNameFromPath
105
- } from "./chunk-GE7M3QTE.js";
101
+ } from "./chunk-LQMFCS54.js";
106
102
  import {
107
103
  ATTACHMENTS_DIR,
108
104
  LEGACY_ATTACHMENTS_DIR
@@ -143,13 +139,13 @@ import {
143
139
  saveAppSettings,
144
140
  updateAdvancedSettings,
145
141
  writeSecureJson
146
- } from "./chunk-4XNSGDXE.js";
142
+ } from "./chunk-3BWVOUQG.js";
147
143
  import {
148
144
  stripNestedElectronEnv
149
145
  } from "./chunk-4TR3HZFT.js";
150
146
  import {
151
147
  releaseCaffeinateHoldForThread
152
- } from "./chunk-DCOZABNT.js";
148
+ } from "./chunk-AO35MGOE.js";
153
149
  import {
154
150
  writePrivateFile
155
151
  } from "./chunk-JT7R45JB.js";
@@ -164,7 +160,7 @@ import {
164
160
  updateThread,
165
161
  withThreadLock,
166
162
  writeThread
167
- } from "./chunk-TUGKX5BD.js";
163
+ } from "./chunk-7UURXPKD.js";
168
164
  import {
169
165
  appDataDir,
170
166
  findConventionSetup,
@@ -174,9 +170,10 @@ import {
174
170
  sideboardReposDir,
175
171
  sideboardWorkspacesDir,
176
172
  threadLivePath,
173
+ threadsDir,
177
174
  workspaceSettingsSourceLabel,
178
175
  worktreesRoot
179
- } from "./chunk-QZQEXME2.js";
176
+ } from "./chunk-EFVFB2AH.js";
180
177
  import {
181
178
  ensureWorktreeSideboardIgnored
182
179
  } from "./chunk-QQKDGPUI.js";
@@ -460,7 +457,7 @@ async function continueSourceThread(threadId, prompt) {
460
457
  await continueOnReply(threadId, prompt);
461
458
  return;
462
459
  }
463
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-NUA6SEV7.js");
460
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-HC7XVGJB.js");
464
461
  await getOrchestrator2().send(threadId, prompt);
465
462
  } catch {
466
463
  }
@@ -720,7 +717,7 @@ async function pollSlackOutboundWatches(opts) {
720
717
  }
721
718
 
722
719
  // src/orchestrator/orchestrator.ts
723
- import { existsSync as existsSync16 } from "fs";
720
+ import { existsSync as existsSync17 } from "fs";
724
721
 
725
722
  // src/agents/spawn.ts
726
723
  import { createInterface } from "readline";
@@ -740,9 +737,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
740
737
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
741
738
  );
742
739
  }
743
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-IY5QAV5C.js");
740
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-2BRRKSDN.js");
744
741
  if (isGlobalThread2(thread)) {
745
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-WGFRYCHE.js");
742
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-7FHKCWXB.js");
746
743
  ensureGlobalCoordinatorCwd2(
747
744
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
748
745
  );
@@ -1997,6 +1994,8 @@ async function attachAbort(handle, signal) {
1997
1994
  async function runSetupScript(repoPath, worktreePath, onLine, opts) {
1998
1995
  const settings = loadWorkspaceSettings(worktreePath, repoPath);
1999
1996
  if (!settings?.setup) return { ran: false, exitCode: null, source: null };
1997
+ const source = workspaceSettingsSourceLabel(worktreePath, repoPath);
1998
+ onLine?.(`[setup] ${source ?? "settings.toml"}`);
2000
1999
  const handle = await spawnWorkspaceScript(settings.setup, {
2001
2000
  worktreePath,
2002
2001
  repoPath,
@@ -2007,7 +2006,7 @@ async function runSetupScript(repoPath, worktreePath, onLine, opts) {
2007
2006
  return {
2008
2007
  ran: true,
2009
2008
  exitCode,
2010
- source: workspaceSettingsSourceLabel(worktreePath, repoPath),
2009
+ source,
2011
2010
  kill: handle.kill
2012
2011
  };
2013
2012
  }
@@ -2136,9 +2135,122 @@ async function startDevServer(repoPath, worktreePath, onLine, opts) {
2136
2135
  };
2137
2136
  }
2138
2137
 
2139
- // src/git/orphan-cleanup.ts
2140
- import { existsSync as existsSync5, readdirSync as readdirSync2, statSync } from "fs";
2138
+ // src/store/setup-log.ts
2139
+ import { existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
2141
2140
  import { join as join6 } from "path";
2141
+ var EMPTY = {
2142
+ output: "",
2143
+ running: false,
2144
+ exitCode: null,
2145
+ source: null
2146
+ };
2147
+ var memory = /* @__PURE__ */ new Map();
2148
+ var persistTimers = /* @__PURE__ */ new Map();
2149
+ function setupLogPath(threadId) {
2150
+ return join6(threadsDir(), `${threadId}.setup.log.json`);
2151
+ }
2152
+ function emptySetupLog() {
2153
+ return { ...EMPTY };
2154
+ }
2155
+ function mergeSetupOutput(prev, incoming) {
2156
+ if (!prev) return incoming;
2157
+ if (!incoming) return prev;
2158
+ if (prev === incoming) return prev;
2159
+ if (prev.startsWith(incoming) || prev.endsWith(incoming)) return prev;
2160
+ if (incoming.startsWith(prev) || incoming.endsWith(prev)) return incoming;
2161
+ return incoming.length >= prev.length ? incoming : prev;
2162
+ }
2163
+ function clone(snap) {
2164
+ return { ...snap };
2165
+ }
2166
+ function persistNow(threadId) {
2167
+ const timer = persistTimers.get(threadId);
2168
+ if (timer) {
2169
+ clearTimeout(timer);
2170
+ persistTimers.delete(threadId);
2171
+ }
2172
+ const snap = memory.get(threadId);
2173
+ if (!snap) return;
2174
+ try {
2175
+ writeFileSync2(setupLogPath(threadId), `${JSON.stringify(snap)}
2176
+ `, "utf8");
2177
+ } catch {
2178
+ }
2179
+ }
2180
+ function schedulePersist(threadId) {
2181
+ if (persistTimers.has(threadId)) return;
2182
+ persistTimers.set(
2183
+ threadId,
2184
+ setTimeout(() => {
2185
+ persistTimers.delete(threadId);
2186
+ persistNow(threadId);
2187
+ }, 100)
2188
+ );
2189
+ }
2190
+ function loadFromDisk(threadId) {
2191
+ const path = setupLogPath(threadId);
2192
+ if (!existsSync5(path)) return null;
2193
+ try {
2194
+ const raw = JSON.parse(readFileSync5(path, "utf8"));
2195
+ return {
2196
+ output: typeof raw.output === "string" ? raw.output : "",
2197
+ running: Boolean(raw.running),
2198
+ exitCode: typeof raw.exitCode === "number" ? raw.exitCode : null,
2199
+ source: typeof raw.source === "string" ? raw.source : null
2200
+ };
2201
+ } catch {
2202
+ return null;
2203
+ }
2204
+ }
2205
+ function readSetupLog(threadId) {
2206
+ const cached = memory.get(threadId);
2207
+ if (cached) return clone(cached);
2208
+ const disk = loadFromDisk(threadId);
2209
+ if (disk) {
2210
+ memory.set(threadId, disk);
2211
+ return clone(disk);
2212
+ }
2213
+ return emptySetupLog();
2214
+ }
2215
+ function beginSetupLog(threadId) {
2216
+ const snap = {
2217
+ output: "",
2218
+ running: true,
2219
+ exitCode: null,
2220
+ source: null
2221
+ };
2222
+ memory.set(threadId, snap);
2223
+ persistNow(threadId);
2224
+ return clone(snap);
2225
+ }
2226
+ function appendSetupLog(threadId, line) {
2227
+ const current = memory.get(threadId) ?? readSetupLog(threadId);
2228
+ const snap = {
2229
+ ...current,
2230
+ output: current.output ? `${current.output}
2231
+ ${line}` : line,
2232
+ running: true
2233
+ };
2234
+ memory.set(threadId, snap);
2235
+ schedulePersist(threadId);
2236
+ return clone(snap);
2237
+ }
2238
+ function finishSetupLog(threadId, exitCode, source) {
2239
+ const current = memory.get(threadId) ?? readSetupLog(threadId);
2240
+ const snap = {
2241
+ ...current,
2242
+ running: false,
2243
+ exitCode,
2244
+ source: source ?? current.source
2245
+ };
2246
+ memory.set(threadId, snap);
2247
+ persistNow(threadId);
2248
+ return clone(snap);
2249
+ }
2250
+
2251
+ // src/git/orphan-cleanup.ts
2252
+ import { existsSync as existsSync6, readdirSync as readdirSync2, statSync } from "fs";
2253
+ import { join as join7 } from "path";
2142
2254
  function isSideboardWorktreePath(path) {
2143
2255
  return path.includes("/.sideboard/worktrees/") || path.includes("/sideboard/workspaces/");
2144
2256
  }
@@ -2149,7 +2261,7 @@ async function findOrphanWorktrees(repoPaths) {
2149
2261
  repoPaths?.length ? repoPaths : threads.map((t) => t.repoPath).filter(Boolean)
2150
2262
  );
2151
2263
  const homeRoot = sideboardWorkspacesDir();
2152
- if (existsSync5(homeRoot)) {
2264
+ if (existsSync6(homeRoot)) {
2153
2265
  try {
2154
2266
  for (const entry of readdirSync2(homeRoot, { withFileTypes: true })) {
2155
2267
  if (!entry.isDirectory()) continue;
@@ -2161,7 +2273,7 @@ async function findOrphanWorktrees(repoPaths) {
2161
2273
  const orphans = [];
2162
2274
  const seen = /* @__PURE__ */ new Set();
2163
2275
  for (const repoPath of repos) {
2164
- if (!repoPath || !existsSync5(repoPath)) continue;
2276
+ if (!repoPath || !existsSync6(repoPath)) continue;
2165
2277
  try {
2166
2278
  const wts = await listWorktrees(repoPath);
2167
2279
  for (const wt of wts) {
@@ -2182,12 +2294,12 @@ async function findOrphanWorktrees(repoPaths) {
2182
2294
  }
2183
2295
  try {
2184
2296
  const root = worktreesRoot(repoPath);
2185
- if (existsSync5(root)) {
2297
+ if (existsSync6(root)) {
2186
2298
  for (const entry of readdirSync2(root, { withFileTypes: true })) {
2187
2299
  if (!entry.isDirectory()) continue;
2188
- const path = join6(root, entry.name).replace(/\/$/, "");
2300
+ const path = join7(root, entry.name).replace(/\/$/, "");
2189
2301
  if (known.has(path) || seen.has(path)) continue;
2190
- if (!existsSync5(join6(path, ".git"))) continue;
2302
+ if (!existsSync6(join7(path, ".git"))) continue;
2191
2303
  seen.add(path);
2192
2304
  let mtimeMs = 0;
2193
2305
  try {
@@ -2336,8 +2448,8 @@ async function applyThreadIntoMain(thread, opts) {
2336
2448
  }
2337
2449
 
2338
2450
  // src/git/clone-repo.ts
2339
- import { existsSync as existsSync6 } from "fs";
2340
- import { basename as basename2, join as join7 } from "path";
2451
+ import { existsSync as existsSync7 } from "fs";
2452
+ import { basename as basename2, join as join8 } from "path";
2341
2453
  import { execa as execa4 } from "execa";
2342
2454
  async function cloneRepoIntoSideboard(opts) {
2343
2455
  const url = opts.url.trim();
@@ -2348,8 +2460,8 @@ async function cloneRepoIntoSideboard(opts) {
2348
2460
  name = leaf || "repo";
2349
2461
  }
2350
2462
  name = name.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "repo";
2351
- const dest = join7(sideboardReposDir(), name);
2352
- if (existsSync6(dest)) {
2463
+ const dest = join8(sideboardReposDir(), name);
2464
+ if (existsSync7(dest)) {
2353
2465
  const repoPath2 = await resolveRepoRoot(dest);
2354
2466
  const workspace2 = await ensureWorkspace(repoPath2);
2355
2467
  return { repoPath: repoPath2, workspace: workspace2 };
@@ -2366,13 +2478,13 @@ async function cloneRepoIntoSideboard(opts) {
2366
2478
  }
2367
2479
 
2368
2480
  // src/store/desktop-host.ts
2369
- import { readFileSync as readFileSync5, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
2370
- import { join as join8 } from "path";
2481
+ import { readFileSync as readFileSync6, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
2482
+ import { join as join9 } from "path";
2371
2483
  function desktopHostPidPath() {
2372
- return join8(appDataDir(), "desktop-host.pid");
2484
+ return join9(appDataDir(), "desktop-host.pid");
2373
2485
  }
2374
2486
  function claimDesktopHost(pid = process.pid) {
2375
- writeFileSync2(desktopHostPidPath(), `${pid}
2487
+ writeFileSync3(desktopHostPidPath(), `${pid}
2376
2488
  `, "utf8");
2377
2489
  }
2378
2490
  function releaseDesktopHost(pid = process.pid) {
@@ -2384,7 +2496,7 @@ function releaseDesktopHost(pid = process.pid) {
2384
2496
  }
2385
2497
  function readDesktopHostPid() {
2386
2498
  try {
2387
- const pid = Number.parseInt(readFileSync5(desktopHostPidPath(), "utf8").trim(), 10);
2499
+ const pid = Number.parseInt(readFileSync6(desktopHostPidPath(), "utf8").trim(), 10);
2388
2500
  if (!Number.isFinite(pid) || pid <= 0) return null;
2389
2501
  return pid;
2390
2502
  } catch {
@@ -2451,7 +2563,7 @@ function notifyParentOfChildHalt(child, status, send) {
2451
2563
  }
2452
2564
 
2453
2565
  // src/threads/create.ts
2454
- import { existsSync as existsSync7 } from "fs";
2566
+ import { existsSync as existsSync8 } from "fs";
2455
2567
 
2456
2568
  // src/detect/detect.ts
2457
2569
  async function detectAgents() {
@@ -2622,12 +2734,19 @@ function urlsMatch(a, b) {
2622
2734
  const norm = (u) => u.trim().replace(/\/+$/, "").toLowerCase();
2623
2735
  return Boolean(a && b && norm(a) === norm(b));
2624
2736
  }
2737
+ function threadPrUrlMatchesNumber(thread, number) {
2738
+ if (!Number.isFinite(number) || number < 1) return false;
2739
+ const url = (thread.prUrl ?? "").trim();
2740
+ if (!url) return false;
2741
+ return new RegExp(`/pull/${number}(?:/|$|[?#])`, "i").test(url);
2742
+ }
2625
2743
  function threadMatchesPr(thread, pr) {
2626
2744
  const num = String(pr.number);
2627
2745
  if (thread.sourceType === "pr" && normalizeIssueKey(thread.sourceRef ?? "") === num) {
2628
2746
  return true;
2629
2747
  }
2630
2748
  if (thread.prUrl && pr.url && urlsMatch(thread.prUrl, pr.url)) return true;
2749
+ if (threadPrUrlMatchesNumber(thread, pr.number)) return true;
2631
2750
  const head = pr.headRefName.trim().toLowerCase();
2632
2751
  if (!head) return false;
2633
2752
  const branch = (thread.branchName ?? "").trim().toLowerCase();
@@ -2680,22 +2799,65 @@ function findLiveThreadForCreate(input, threads) {
2680
2799
  (t) => threadMatchesPr(t, {
2681
2800
  number: Number.isFinite(number) ? number : -1,
2682
2801
  title: input.title ?? "",
2683
- url: "",
2684
- headRefName: ""
2802
+ url: input.prUrl ?? "",
2803
+ headRefName: input.headRefName ?? ""
2685
2804
  })
2686
2805
  );
2687
2806
  }
2688
2807
  if (input.sourceType === "branch") {
2689
2808
  if (isDefaultBranchCreateRef(input.sourceRef)) return void 0;
2690
- return live.find(
2809
+ const byBranch = live.find(
2691
2810
  (t) => threadMatchesBranch(t, {
2692
2811
  ref: input.sourceRef,
2693
2812
  repoPath: input.repoPath
2694
2813
  })
2695
2814
  );
2815
+ if (byBranch) return byBranch;
2816
+ if (input.prUrl || input.headRefName) {
2817
+ const number = Number(normalizeIssueKey(input.sourceRef));
2818
+ return live.find(
2819
+ (t) => threadMatchesPr(t, {
2820
+ number: Number.isFinite(number) ? number : -1,
2821
+ title: input.title ?? "",
2822
+ url: input.prUrl ?? "",
2823
+ headRefName: input.headRefName ?? input.sourceRef
2824
+ })
2825
+ );
2826
+ }
2827
+ return void 0;
2696
2828
  }
2697
2829
  return void 0;
2698
2830
  }
2831
+ function findLiveThreadForCreateSource(source, threads, prs) {
2832
+ const found = findLiveThreadForCreate(
2833
+ {
2834
+ sourceType: source.kind,
2835
+ sourceRef: source.ref,
2836
+ repoPath: source.repoPath,
2837
+ title: source.title,
2838
+ prUrl: source.url,
2839
+ headRefName: source.headRefName
2840
+ },
2841
+ threads
2842
+ );
2843
+ if (found) return found;
2844
+ if (source.kind !== "branch" || !prs?.length) return void 0;
2845
+ if (isDefaultBranchCreateRef(source.ref)) return void 0;
2846
+ const head = normalizeBranchRef(source.ref);
2847
+ const pr = prs.find((p) => normalizeBranchRef(p.headRefName) === head);
2848
+ if (!pr) return void 0;
2849
+ return findLiveThreadForCreate(
2850
+ {
2851
+ sourceType: "pr",
2852
+ sourceRef: String(pr.number),
2853
+ repoPath: source.repoPath,
2854
+ title: pr.title,
2855
+ prUrl: pr.url,
2856
+ headRefName: pr.headRefName
2857
+ },
2858
+ threads
2859
+ );
2860
+ }
2699
2861
  function boardPinIdentity(pin) {
2700
2862
  const ref = normalizeIssueKey(pin.ref);
2701
2863
  if (pin.kind === "ticket" && (pin.provider === "linear" || !pin.repoPath)) {
@@ -2925,42 +3087,53 @@ function assembleHomeBoard(input) {
2925
3087
  }
2926
3088
  return { columns, hidden, totals };
2927
3089
  }
2928
- var HOME_BOARD_AGENT_HINT = "Home is a Kanban of worktrees (one card per checkout; sibling chat tabs nest as inner cards). create_thread reuses a live worktree for the same ticket, PR, or named branch \u2014 do not recreate it. Columns are the path to merge: New (no PR) \u2192 Draft (draft PR) \u2192 Review (open PR) \u2192 Merged. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats stay in the sidebar. Do not invent status.";
3090
+ var HOME_BOARD_AGENT_HINT = "Home is a Kanban of worktrees (one card per checkout; sibling chat tabs nest as inner cards). Do not create a second worktree for a ticket, PR, or named branch that already has a live checkout \u2014 create_thread / start_board_card return that thread (alreadyStarted). Creating from the default branch still opens a new isolated worktree. Columns are the path to merge: New (no PR) \u2192 Draft (draft PR) \u2192 Review (open PR) \u2192 Merged. Archive removes the card to Settings \u2192 History. Queued/running are activity on the card, not columns. Orchestration chats stay in the sidebar. Do not invent status.";
2929
3091
 
2930
3092
  // src/threads/create.ts
2931
3093
  function persistCreateAttachments(worktreePath, attachments) {
2932
3094
  return persistPendingFileAttachments(worktreePath, attachments ?? []);
2933
3095
  }
3096
+ function liveThreadsForCreate() {
3097
+ return listThreads({ includeArchived: false }).map((t) => ({
3098
+ ...t,
3099
+ repoPath: canonicalizeRepoPath(t.repoPath)
3100
+ }));
3101
+ }
3102
+ function reuseLiveThread(input, repoPath, match) {
3103
+ if (input.reuseExisting === false) return void 0;
3104
+ const existing = findLiveThreadForCreate(
3105
+ {
3106
+ sourceType: match.sourceType,
3107
+ sourceRef: match.sourceRef,
3108
+ repoPath,
3109
+ title: match.title ?? input.title,
3110
+ cowboy: input.cowboy,
3111
+ prUrl: match.prUrl,
3112
+ headRefName: match.headRefName
3113
+ },
3114
+ liveThreadsForCreate()
3115
+ );
3116
+ if (!existing) return void 0;
3117
+ const thread = readThread(existing.id) ?? existing;
3118
+ if (!input.attachments?.length) return thread;
3119
+ return updateThread(thread.id, {
3120
+ attachments: persistCreateAttachments(thread.worktreePath, [
3121
+ ...thread.attachments,
3122
+ ...input.attachments
3123
+ ])
3124
+ });
3125
+ }
2934
3126
  async function createThread(input, _onSetupLine) {
2935
3127
  const repoPath = await resolveRepoRoot(input.repoPath);
2936
- if (!existsSync7(repoPath)) {
3128
+ if (!existsSync8(repoPath)) {
2937
3129
  throw new Error(`Repo not found: ${repoPath}`);
2938
3130
  }
2939
- if (input.reuseExisting !== false) {
2940
- const existing = findLiveThreadForCreate(
2941
- {
2942
- sourceType: input.sourceType,
2943
- sourceRef: input.sourceRef,
2944
- repoPath,
2945
- title: input.title,
2946
- cowboy: input.cowboy
2947
- },
2948
- listThreads({ includeArchived: false }).map((t) => ({
2949
- ...t,
2950
- repoPath: canonicalizeRepoPath(t.repoPath)
2951
- }))
2952
- );
2953
- if (existing) {
2954
- const thread2 = readThread(existing.id) ?? existing;
2955
- if (!input.attachments?.length) return thread2;
2956
- return updateThread(thread2.id, {
2957
- attachments: persistCreateAttachments(thread2.worktreePath, [
2958
- ...thread2.attachments,
2959
- ...input.attachments
2960
- ])
2961
- });
2962
- }
2963
- }
3131
+ const reused = reuseLiveThread(input, repoPath, {
3132
+ sourceType: input.sourceType,
3133
+ sourceRef: input.sourceRef,
3134
+ title: input.title
3135
+ });
3136
+ if (reused) return reused;
2964
3137
  const resolved = resolveNewThreadOptions({
2965
3138
  agent: input.agent,
2966
3139
  model: input.model,
@@ -2969,7 +3142,7 @@ async function createThread(input, _onSetupLine) {
2969
3142
  });
2970
3143
  await requireAgent(resolved.agent);
2971
3144
  if (input.cowboy) {
2972
- const { cowboyModeEnabled } = await import("./app-settings-3CHCNIMD.js");
3145
+ const { cowboyModeEnabled } = await import("./app-settings-H3INSR67.js");
2973
3146
  if (!cowboyModeEnabled()) {
2974
3147
  throw new Error(
2975
3148
  "Cowboy mode is off. Enable it in Settings \u2192 Advanced."
@@ -3027,7 +3200,7 @@ async function createThread(input, _onSetupLine) {
3027
3200
  let sourceIsFork = false;
3028
3201
  if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
3029
3202
  if (isAbleTimeConnected() && getIssueSource() === "abletime") {
3030
- const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-223A3LY6.js");
3203
+ const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-H7LPGIP2.js");
3031
3204
  const task = await ensureAbleTimeTask({
3032
3205
  title: title?.trim() || "Untitled work",
3033
3206
  description: input.prompt?.trim() || void 0
@@ -3037,6 +3210,12 @@ async function createThread(input, _onSetupLine) {
3037
3210
  persistedSourceRef = task.identifier;
3038
3211
  title = title?.trim() || task.title;
3039
3212
  attachments = [...attachments, issueAttachmentForAbleTimeTask(task)];
3213
+ const reusedTicket = reuseLiveThread(
3214
+ { ...input, sourceType: "ticket", sourceRef, title, attachments },
3215
+ repoPath,
3216
+ { sourceType: "ticket", sourceRef, title }
3217
+ );
3218
+ if (reusedTicket) return reusedTicket;
3040
3219
  }
3041
3220
  }
3042
3221
  let prUrl = null;
@@ -3046,6 +3225,14 @@ async function createThread(input, _onSetupLine) {
3046
3225
  if (!Number.isFinite(num)) throw new Error(`Invalid PR number: ${input.sourceRef}`);
3047
3226
  const pr = await getPr(repoPath, num);
3048
3227
  if (!pr) throw new Error(`PR #${num} not found`);
3228
+ const reusedPr = reuseLiveThread(input, repoPath, {
3229
+ sourceType: "pr",
3230
+ sourceRef: String(pr.number),
3231
+ title: input.title ?? pr.title,
3232
+ prUrl: pr.url,
3233
+ headRefName: pr.headRefName
3234
+ });
3235
+ if (reusedPr) return reusedPr;
3049
3236
  sourceIsFork = pr.isCrossRepository;
3050
3237
  prUrl = pr.url;
3051
3238
  const localFetchBranch = `sideboard-pr-${pr.number}`;
@@ -3058,9 +3245,19 @@ async function createThread(input, _onSetupLine) {
3058
3245
  sourceRef = await resolveDefaultBranch(repoPath);
3059
3246
  } else {
3060
3247
  const existing = await getPrForHeadBranch(repoPath, sourceRef);
3061
- if (existing?.url) {
3062
- prUrl = existing.url;
3063
- prTitle = existing.title;
3248
+ if (existing) {
3249
+ const reusedPr = reuseLiveThread(input, repoPath, {
3250
+ sourceType: "pr",
3251
+ sourceRef: String(existing.number),
3252
+ title: input.title ?? existing.title,
3253
+ prUrl: existing.url,
3254
+ headRefName: existing.headRefName
3255
+ });
3256
+ if (reusedPr) return reusedPr;
3257
+ if (existing.url) {
3258
+ prUrl = existing.url;
3259
+ prTitle = existing.title;
3260
+ }
3064
3261
  }
3065
3262
  }
3066
3263
  } else if (sourceType === "adopt") {
@@ -3100,7 +3297,7 @@ async function createThread(input, _onSetupLine) {
3100
3297
  return readThread(thread.id) ?? thread;
3101
3298
  }
3102
3299
  async function listLinearIssues(agent, repoPath) {
3103
- const { getAdapter: getAdapter2 } = await import("./agents-VHXCBBBD.js");
3300
+ const { getAdapter: getAdapter2 } = await import("./agents-YVW75KBO.js");
3104
3301
  await requireAgent(agent, { requireLinear: true });
3105
3302
  const adapter = getAdapter2(agent);
3106
3303
  if (!adapter.listLinearIssues) {
@@ -3123,11 +3320,11 @@ function shouldRemoveWorktreeOnTeardown(thread) {
3123
3320
 
3124
3321
  // src/store/turn-live.ts
3125
3322
  import {
3126
- existsSync as existsSync8,
3323
+ existsSync as existsSync9,
3127
3324
  renameSync,
3128
3325
  unlinkSync as unlinkSync2,
3129
- writeFileSync as writeFileSync3,
3130
- readFileSync as readFileSync6
3326
+ writeFileSync as writeFileSync4,
3327
+ readFileSync as readFileSync7
3131
3328
  } from "fs";
3132
3329
  var buffers = /* @__PURE__ */ new Map();
3133
3330
  var FLUSH_MS = 800;
@@ -3204,7 +3401,7 @@ function writeTurnLive(threadId, progress) {
3204
3401
  const path = threadLivePath(threadId);
3205
3402
  const tmp = `${path}.${process.pid}.tmp`;
3206
3403
  try {
3207
- writeFileSync3(tmp, JSON.stringify(progress), "utf8");
3404
+ writeFileSync4(tmp, JSON.stringify(progress), "utf8");
3208
3405
  renameSync(tmp, path);
3209
3406
  } catch {
3210
3407
  try {
@@ -3215,9 +3412,9 @@ function writeTurnLive(threadId, progress) {
3215
3412
  }
3216
3413
  function readTurnLive(threadId) {
3217
3414
  const path = threadLivePath(threadId);
3218
- if (!existsSync8(path)) return null;
3415
+ if (!existsSync9(path)) return null;
3219
3416
  try {
3220
- const raw = JSON.parse(readFileSync6(path, "utf8"));
3417
+ const raw = JSON.parse(readFileSync7(path, "utf8"));
3221
3418
  if (!raw || typeof raw.summary !== "string") return null;
3222
3419
  return raw;
3223
3420
  } catch {
@@ -3229,7 +3426,7 @@ function clearTurnLive(threadId) {
3229
3426
  if (buf?.timer) clearTimeout(buf.timer);
3230
3427
  buffers.delete(threadId);
3231
3428
  const path = threadLivePath(threadId);
3232
- if (!existsSync8(path)) return;
3429
+ if (!existsSync9(path)) return;
3233
3430
  try {
3234
3431
  unlinkSync2(path);
3235
3432
  } catch {
@@ -3254,9 +3451,13 @@ function shouldReadThreadToHealReconcile(eventType, lastCheckAt, now) {
3254
3451
  // src/orchestrator/setup-last-error.ts
3255
3452
  function shouldStampSetupLastError(opts) {
3256
3453
  if (opts.turnInFlight) return false;
3257
- if (opts.status === "running") return false;
3454
+ if (opts.status === "running" || opts.status === "queued") return false;
3455
+ if (opts.hasQueuedPrompt) return false;
3258
3456
  return true;
3259
3457
  }
3458
+ function isSetupLastError(err) {
3459
+ return /^Setup (exited|failed)\b/i.test(err?.trim() ?? "");
3460
+ }
3260
3461
  function isStaleLastErrorDuringTurn(err) {
3261
3462
  return Boolean(err?.trim());
3262
3463
  }
@@ -3413,26 +3614,26 @@ function createQuotaFailoverChat(from, fallbackAgent, limitText) {
3413
3614
  import { execFileSync } from "child_process";
3414
3615
  import {
3415
3616
  copyFileSync as copyFileSync2,
3416
- existsSync as existsSync9,
3617
+ existsSync as existsSync10,
3417
3618
  mkdtempSync,
3418
3619
  readdirSync as readdirSync3,
3419
- readFileSync as readFileSync7,
3620
+ readFileSync as readFileSync8,
3420
3621
  rmSync
3421
3622
  } from "fs";
3422
3623
  import { tmpdir } from "os";
3423
- import { join as join9 } from "path";
3624
+ import { join as join10 } from "path";
3424
3625
  import { createRequire } from "module";
3425
- var CONDUCTOR_APP_SUPPORT = join9(
3626
+ var CONDUCTOR_APP_SUPPORT = join10(
3426
3627
  process.env.HOME ?? "",
3427
3628
  "Library",
3428
3629
  "Application Support",
3429
3630
  "com.conductor.app"
3430
3631
  );
3431
- var CONDUCTOR_DB = join9(CONDUCTOR_APP_SUPPORT, "conductor.db");
3432
- var CURSOR_SDK_STORE = join9(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
3632
+ var CONDUCTOR_DB = join10(CONDUCTOR_APP_SUPPORT, "conductor.db");
3633
+ var CURSOR_SDK_STORE = join10(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
3433
3634
  function thisModuleFile() {
3434
3635
  const cjsFile = typeof __filename !== "undefined" ? __filename : "";
3435
- return cjsFile || process.argv[1] || join9(process.cwd(), "package.json");
3636
+ return cjsFile || process.argv[1] || join10(process.cwd(), "package.json");
3436
3637
  }
3437
3638
  function openReadonlySqlite(file) {
3438
3639
  const req = createRequire(thisModuleFile());
@@ -3450,7 +3651,7 @@ function mapAgentType(raw) {
3450
3651
  return null;
3451
3652
  }
3452
3653
  function resolveConductorCursorAgentId(workspacePath) {
3453
- if (!workspacePath || !existsSync9(CURSOR_SDK_STORE)) return null;
3654
+ if (!workspacePath || !existsSync10(CURSOR_SDK_STORE)) return null;
3454
3655
  const normalized = workspacePath.replace(/\/$/, "");
3455
3656
  let best = null;
3456
3657
  let hashes;
@@ -3460,11 +3661,11 @@ function resolveConductorCursorAgentId(workspacePath) {
3460
3661
  return null;
3461
3662
  }
3462
3663
  for (const hash of hashes) {
3463
- const agentsFile = join9(CURSOR_SDK_STORE, hash, "agents.ndjson");
3464
- if (!existsSync9(agentsFile)) continue;
3664
+ const agentsFile = join10(CURSOR_SDK_STORE, hash, "agents.ndjson");
3665
+ if (!existsSync10(agentsFile)) continue;
3465
3666
  let text;
3466
3667
  try {
3467
- text = readFileSync7(agentsFile, "utf8");
3668
+ text = readFileSync8(agentsFile, "utf8");
3468
3669
  } catch {
3469
3670
  continue;
3470
3671
  }
@@ -3488,7 +3689,7 @@ function resolveConductorCursorAgentId(workspacePath) {
3488
3689
  return best?.agentId ?? null;
3489
3690
  }
3490
3691
  async function adoptThread(input) {
3491
- if (!existsSync9(input.worktreePath)) {
3692
+ if (!existsSync10(input.worktreePath)) {
3492
3693
  throw new Error(`Worktree not found: ${input.worktreePath}`);
3493
3694
  }
3494
3695
  const repoPath = await resolveRepoRoot(input.worktreePath);
@@ -3507,7 +3708,7 @@ async function adoptThread(input) {
3507
3708
  messages: input.messages ?? []
3508
3709
  });
3509
3710
  writeThread(thread);
3510
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-4FSXVIZM.js");
3711
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-5UNDTN4G.js");
3511
3712
  await ensureWorkspace2(repoPath);
3512
3713
  const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-X54WSOXM.js");
3513
3714
  await ensureWorktreeSideboardIgnored2(input.worktreePath);
@@ -3517,16 +3718,16 @@ function conductorDbPath() {
3517
3718
  return CONDUCTOR_DB;
3518
3719
  }
3519
3720
  function listConductorWorkspaces() {
3520
- if (!existsSync9(CONDUCTOR_DB)) {
3721
+ if (!existsSync10(CONDUCTOR_DB)) {
3521
3722
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
3522
3723
  }
3523
- const tmp = mkdtempSync(join9(tmpdir(), "sideboard-conductor-"));
3524
- const snapshot = join9(tmp, "conductor.db");
3724
+ const tmp = mkdtempSync(join10(tmpdir(), "sideboard-conductor-"));
3725
+ const snapshot = join10(tmp, "conductor.db");
3525
3726
  try {
3526
3727
  copyFileSync2(CONDUCTOR_DB, snapshot);
3527
3728
  for (const suffix of ["-wal", "-shm"]) {
3528
3729
  const src = `${CONDUCTOR_DB}${suffix}`;
3529
- if (existsSync9(src)) {
3730
+ if (existsSync10(src)) {
3530
3731
  try {
3531
3732
  copyFileSync2(src, `${snapshot}${suffix}`);
3532
3733
  } catch {
@@ -3608,16 +3809,16 @@ function listConductorWorkspaces() {
3608
3809
  }
3609
3810
  }
3610
3811
  function importConductorWorkspace(workspaceId) {
3611
- if (!existsSync9(CONDUCTOR_DB)) {
3812
+ if (!existsSync10(CONDUCTOR_DB)) {
3612
3813
  throw new Error(`Conductor DB not found at ${CONDUCTOR_DB}`);
3613
3814
  }
3614
- const tmp = mkdtempSync(join9(tmpdir(), "sideboard-conductor-"));
3615
- const snapshot = join9(tmp, "conductor.db");
3815
+ const tmp = mkdtempSync(join10(tmpdir(), "sideboard-conductor-"));
3816
+ const snapshot = join10(tmp, "conductor.db");
3616
3817
  try {
3617
3818
  copyFileSync2(CONDUCTOR_DB, snapshot);
3618
3819
  for (const suffix of ["-wal", "-shm"]) {
3619
3820
  const src = `${CONDUCTOR_DB}${suffix}`;
3620
- if (existsSync9(src)) {
3821
+ if (existsSync10(src)) {
3621
3822
  try {
3622
3823
  copyFileSync2(src, `${snapshot}${suffix}`);
3623
3824
  } catch {
@@ -3637,7 +3838,7 @@ function importConductorWorkspace(workspaceId) {
3637
3838
  ).get(workspaceId);
3638
3839
  if (!row) throw new Error(`Conductor workspace not found: ${workspaceId}`);
3639
3840
  const worktreePath = String(row.workspacePath);
3640
- if (!existsSync9(worktreePath)) {
3841
+ if (!existsSync10(worktreePath)) {
3641
3842
  throw new Error(`Conductor worktree missing on disk: ${worktreePath}`);
3642
3843
  }
3643
3844
  let sessionId = null;
@@ -3708,7 +3909,7 @@ async function importConductorWorkspaceAsync(workspaceId) {
3708
3909
  }
3709
3910
 
3710
3911
  // src/threads/stack-layers.ts
3711
- import { existsSync as existsSync10 } from "fs";
3912
+ import { existsSync as existsSync11 } from "fs";
3712
3913
  function stackIdFrom(stack) {
3713
3914
  if (stack.stackNumber != null) return `gh-stack-${stack.stackNumber}`;
3714
3915
  const key = stack.layers.map((l) => l.branchName).join("|");
@@ -3771,7 +3972,7 @@ async function openStackLayer(input, _onSetupLine) {
3771
3972
  let createdWorktree = false;
3772
3973
  const trees = await listWorktrees(repoPath);
3773
3974
  const checkedOut = trees.find((w) => w.branch === branchName);
3774
- if (checkedOut?.path && existsSync10(checkedOut.path)) {
3975
+ if (checkedOut?.path && existsSync11(checkedOut.path)) {
3775
3976
  if (input.reuseExistingWorktree !== false) {
3776
3977
  worktreePath = checkedOut.path;
3777
3978
  } else {
@@ -3913,7 +4114,7 @@ async function initStackFromThread(input, onSetupLine) {
3913
4114
  async function createPrStack(input, onSetupLine) {
3914
4115
  await requireAgent(input.agent);
3915
4116
  const repoPath = await resolveRepoRoot(input.repoPath);
3916
- if (!existsSync10(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
4117
+ if (!existsSync11(repoPath)) throw new Error(`Repo not found: ${repoPath}`);
3917
4118
  if (!input.branches.length) throw new Error("At least one branch name required");
3918
4119
  const status = await detectGhStack(repoPath);
3919
4120
  if (!status.available) throw new Error(status.reason);
@@ -3980,7 +4181,7 @@ async function createPrStack(input, onSetupLine) {
3980
4181
  }
3981
4182
  }
3982
4183
  const claimed = new Set(threads.map((t) => t.worktreePath));
3983
- if (!claimed.has(bootstrap.worktreePath) && existsSync10(bootstrap.worktreePath)) {
4184
+ if (!claimed.has(bootstrap.worktreePath) && existsSync11(bootstrap.worktreePath)) {
3984
4185
  try {
3985
4186
  await removeWorktree(repoPath, bootstrap.worktreePath, {
3986
4187
  deleteBranch: bootstrap.branchName
@@ -4002,10 +4203,10 @@ function stackAgentDefaultsFrom(input) {
4002
4203
  }
4003
4204
 
4004
4205
  // src/diff/diff.ts
4005
- import { existsSync as existsSync11, mkdirSync as mkdirSync3, readFileSync as readFileSync8, statSync as statSync2, writeFileSync as writeFileSync4 } from "fs";
4006
- import { dirname as dirname3, join as join10 } from "path";
4206
+ import { existsSync as existsSync12, mkdirSync as mkdirSync3, readFileSync as readFileSync9, statSync as statSync2, writeFileSync as writeFileSync5 } from "fs";
4207
+ import { dirname as dirname3, join as join11 } from "path";
4007
4208
  async function inspectGitWorktree(worktreePath) {
4008
- if (!worktreePath || !existsSync11(worktreePath)) return "missing_worktree";
4209
+ if (!worktreePath || !existsSync12(worktreePath)) return "missing_worktree";
4009
4210
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
4010
4211
  reject: false
4011
4212
  });
@@ -4013,7 +4214,7 @@ async function inspectGitWorktree(worktreePath) {
4013
4214
  return "ok";
4014
4215
  }
4015
4216
  async function initializeGitRepository(worktreePath) {
4016
- if (!worktreePath || !existsSync11(worktreePath)) {
4217
+ if (!worktreePath || !existsSync12(worktreePath)) {
4017
4218
  throw new Error("Worktree not found");
4018
4219
  }
4019
4220
  const status = await inspectGitWorktree(worktreePath);
@@ -4149,11 +4350,11 @@ new file mode 100644
4149
4350
  };
4150
4351
  }
4151
4352
  async function untrackedPatch(worktreePath, path, maxHunk) {
4152
- const abs = join10(worktreePath, path);
4353
+ const abs = join11(worktreePath, path);
4153
4354
  try {
4154
4355
  const st = statSync2(abs);
4155
4356
  if (st.isFile() && st.size > maxHunk) {
4156
- const buf = readFileSync8(abs).subarray(0, maxHunk);
4357
+ const buf = readFileSync9(abs).subarray(0, maxHunk);
4157
4358
  return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
4158
4359
  }
4159
4360
  } catch {
@@ -4654,7 +4855,7 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
4654
4855
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
4655
4856
  assertSafeRelativePath(relativePath);
4656
4857
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
4657
- const abs = join10(worktreePath, relativePath);
4858
+ const abs = join11(worktreePath, relativePath);
4658
4859
  const st = statSync2(abs);
4659
4860
  if (!st.isFile()) {
4660
4861
  throw new Error(`Not a file: ${relativePath}`);
@@ -4664,7 +4865,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
4664
4865
  `File too large to upload (${st.size} bytes; max ${maxBytes})`
4665
4866
  );
4666
4867
  }
4667
- const buf = readFileSync8(abs);
4868
+ const buf = readFileSync9(abs);
4668
4869
  return {
4669
4870
  path: relativePath,
4670
4871
  contentBase64: buf.toString("base64"),
@@ -4674,12 +4875,12 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
4674
4875
  function readWorktreeFile(worktreePath, relativePath, opts) {
4675
4876
  assertSafeRelativePath(relativePath);
4676
4877
  const maxBytes = opts?.maxBytes ?? 2e5;
4677
- const abs = join10(worktreePath, relativePath);
4878
+ const abs = join11(worktreePath, relativePath);
4678
4879
  const st = statSync2(abs);
4679
4880
  if (!st.isFile()) {
4680
4881
  throw new Error(`Not a file: ${relativePath}`);
4681
4882
  }
4682
- const buf = readFileSync8(abs);
4883
+ const buf = readFileSync9(abs);
4683
4884
  if (isImageRelativePath(relativePath)) {
4684
4885
  const maxImageBytes = Math.max(maxBytes, 15e6);
4685
4886
  const truncated2 = buf.length > maxImageBytes;
@@ -4722,9 +4923,9 @@ function assertSafeRelativePath(relativePath) {
4722
4923
  }
4723
4924
  function writeWorktreeFile(worktreePath, relativePath, content) {
4724
4925
  assertSafeRelativePath(relativePath);
4725
- const abs = join10(worktreePath, relativePath);
4926
+ const abs = join11(worktreePath, relativePath);
4726
4927
  mkdirSync3(dirname3(abs), { recursive: true });
4727
- writeFileSync4(abs, content, "utf8");
4928
+ writeFileSync5(abs, content, "utf8");
4728
4929
  return { path: relativePath };
4729
4930
  }
4730
4931
  async function getDiffSummary(worktreePath, repoPath, opts) {
@@ -4849,9 +5050,9 @@ async function confirmLand(thread, opts) {
4849
5050
  }
4850
5051
 
4851
5052
  // src/skills/discover.ts
4852
- import { existsSync as existsSync12, readdirSync as readdirSync4, readFileSync as readFileSync9, statSync as statSync3 } from "fs";
5053
+ import { existsSync as existsSync13, readdirSync as readdirSync4, readFileSync as readFileSync10, statSync as statSync3 } from "fs";
4853
5054
  import { homedir } from "os";
4854
- import { join as join11 } from "path";
5055
+ import { join as join12 } from "path";
4855
5056
 
4856
5057
  // src/skills/bundled/long-running.ts
4857
5058
  var LONG_RUNNING_SKILL_COMMAND = "long-running";
@@ -4980,7 +5181,7 @@ function parseFrontmatter(content) {
4980
5181
  }
4981
5182
  function readSkill(skillMd, source) {
4982
5183
  try {
4983
- const content = readFileSync9(skillMd, "utf8");
5184
+ const content = readFileSync10(skillMd, "utf8");
4984
5185
  const { name: fmName, description } = parseFrontmatter(content);
4985
5186
  const dirName = skillMd.split("/").slice(-2, -1)[0] || "skill";
4986
5187
  const name = fmName || dirName;
@@ -4999,7 +5200,7 @@ function readSkill(skillMd, source) {
4999
5200
  }
5000
5201
  }
5001
5202
  function scanSkillsDir(dir, source, out) {
5002
- if (!existsSync12(dir)) return;
5203
+ if (!existsSync13(dir)) return;
5003
5204
  let entries;
5004
5205
  try {
5005
5206
  entries = readdirSync4(dir);
@@ -5008,8 +5209,8 @@ function scanSkillsDir(dir, source, out) {
5008
5209
  }
5009
5210
  for (const entry of entries) {
5010
5211
  if (entry.startsWith(".")) continue;
5011
- const skillMd = join11(dir, entry, "SKILL.md");
5012
- if (!existsSync12(skillMd)) continue;
5212
+ const skillMd = join12(dir, entry, "SKILL.md");
5213
+ if (!existsSync13(skillMd)) continue;
5013
5214
  try {
5014
5215
  if (!statSync3(skillMd).isFile()) continue;
5015
5216
  } catch {
@@ -5020,7 +5221,7 @@ function scanSkillsDir(dir, source, out) {
5020
5221
  }
5021
5222
  }
5022
5223
  function scanClaudePluginSkills(pluginsRoot, out) {
5023
- if (!existsSync12(pluginsRoot)) return;
5224
+ if (!existsSync13(pluginsRoot)) return;
5024
5225
  const walk = (dir, depth, lookingForSkillsDir) => {
5025
5226
  if (depth > 7) return;
5026
5227
  let entries;
@@ -5030,12 +5231,12 @@ function scanClaudePluginSkills(pluginsRoot, out) {
5030
5231
  return;
5031
5232
  }
5032
5233
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
5033
- const skill = readSkill(join11(dir, "SKILL.md"), "cli");
5234
+ const skill = readSkill(join12(dir, "SKILL.md"), "cli");
5034
5235
  if (skill) out.push(skill);
5035
5236
  }
5036
5237
  for (const entry of entries) {
5037
5238
  if (entry === "node_modules" || entry === ".git") continue;
5038
- const full = join11(dir, entry);
5239
+ const full = join12(dir, entry);
5039
5240
  try {
5040
5241
  if (!statSync3(full).isDirectory()) continue;
5041
5242
  } catch {
@@ -5055,17 +5256,17 @@ function discoverSkills(worktreePath) {
5055
5256
  const home = homedir();
5056
5257
  const collected = [];
5057
5258
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
5058
- scanSkillsDir(join11(worktreePath, rel), "workspace", collected);
5259
+ scanSkillsDir(join12(worktreePath, rel), "workspace", collected);
5059
5260
  }
5060
5261
  for (const abs of [
5061
- join11(home, ".claude/skills"),
5062
- join11(home, ".cursor/skills"),
5063
- join11(home, ".sideboard/skills"),
5064
- join11(home, ".brightsy/skills")
5262
+ join12(home, ".claude/skills"),
5263
+ join12(home, ".cursor/skills"),
5264
+ join12(home, ".sideboard/skills"),
5265
+ join12(home, ".brightsy/skills")
5065
5266
  ]) {
5066
5267
  scanSkillsDir(abs, "user", collected);
5067
5268
  }
5068
- scanClaudePluginSkills(join11(home, ".claude/plugins"), collected);
5269
+ scanClaudePluginSkills(join12(home, ".claude/plugins"), collected);
5069
5270
  collected.push(...bundledSkills());
5070
5271
  const rank = {
5071
5272
  workspace: 0,
@@ -5091,7 +5292,7 @@ function readSkillBody(skillPath, maxChars = 12e3) {
5091
5292
  \u2026(truncated)` : body;
5092
5293
  }
5093
5294
  }
5094
- const raw = readFileSync9(skillPath, "utf8");
5295
+ const raw = readFileSync10(skillPath, "utf8");
5095
5296
  if (raw.startsWith("---")) {
5096
5297
  const end = raw.indexOf("\n---", 3);
5097
5298
  if (end >= 0) {
@@ -5184,26 +5385,26 @@ function expandComposerPrompt(worktreePath, prompt, opts) {
5184
5385
  }
5185
5386
 
5186
5387
  // src/agents/instructions.ts
5187
- import { existsSync as existsSync14, readFileSync as readFileSync10, statSync as statSync4 } from "fs";
5188
- import { join as join13 } from "path";
5388
+ import { existsSync as existsSync15, readFileSync as readFileSync11, statSync as statSync4 } from "fs";
5389
+ import { join as join14 } from "path";
5189
5390
 
5190
5391
  // src/skills/detached-job-path.ts
5191
- import { existsSync as existsSync13 } from "fs";
5192
- import { dirname as dirname4, join as join12 } from "path";
5392
+ import { existsSync as existsSync14 } from "fs";
5393
+ import { dirname as dirname4, join as join13 } from "path";
5193
5394
  import { fileURLToPath } from "url";
5194
5395
  function packagedDetachedJobPath() {
5195
5396
  const dir = packagedMcpDir();
5196
5397
  if (!dir) return null;
5197
- const script = join12(dir, "scripts", "detached-job.js");
5198
- return existsSync13(script) ? script : null;
5398
+ const script = join13(dir, "scripts", "detached-job.js");
5399
+ return existsSync14(script) ? script : null;
5199
5400
  }
5200
5401
  function resolveDetachedJobScript() {
5201
5402
  const packaged = packagedDetachedJobPath();
5202
5403
  if (packaged) return packaged;
5203
5404
  let dir = dirname4(fileURLToPath(import.meta.url));
5204
5405
  for (let i = 0; i < 8; i++) {
5205
- const candidate = join12(dir, "scripts", "detached-job.js");
5206
- if (existsSync13(candidate)) return candidate;
5406
+ const candidate = join13(dir, "scripts", "detached-job.js");
5407
+ if (existsSync14(candidate)) return candidate;
5207
5408
  const parent = dirname4(dir);
5208
5409
  if (parent === dir) break;
5209
5410
  dir = parent;
@@ -5408,11 +5609,11 @@ function loadAgentInstructions(worktreePath, agent) {
5408
5609
  const out = [];
5409
5610
  for (const rel of candidates) {
5410
5611
  if (seenPaths.has(rel)) continue;
5411
- const abs = join13(worktreePath, rel);
5412
- if (!existsSync14(abs)) continue;
5612
+ const abs = join14(worktreePath, rel);
5613
+ if (!existsSync15(abs)) continue;
5413
5614
  try {
5414
5615
  if (!statSync4(abs).isFile()) continue;
5415
- let content = readFileSync10(abs, "utf8");
5616
+ let content = readFileSync11(abs, "utf8");
5416
5617
  if (!content.trim()) continue;
5417
5618
  if (content.length > MAX_CHARS_PER_FILE) {
5418
5619
  content = `${content.slice(0, MAX_CHARS_PER_FILE)}
@@ -5732,8 +5933,8 @@ async function syncThreadBranchFromGit(threadId) {
5732
5933
 
5733
5934
  // src/store/schedules.ts
5734
5935
  import { randomUUID as randomUUID4 } from "crypto";
5735
- import { existsSync as existsSync15, readFileSync as readFileSync11 } from "fs";
5736
- import { join as join14 } from "path";
5936
+ import { existsSync as existsSync16, readFileSync as readFileSync12 } from "fs";
5937
+ import { join as join15 } from "path";
5737
5938
  import { Cron } from "croner";
5738
5939
  var DURATION_RE = /^(\d+)(s|m|h|d)$/i;
5739
5940
  var UNIT_MS = {
@@ -5743,7 +5944,7 @@ var UNIT_MS = {
5743
5944
  d: 864e5
5744
5945
  };
5745
5946
  function schedulesPath() {
5746
- return join14(appDataDir(), "schedules.json");
5947
+ return join15(appDataDir(), "schedules.json");
5747
5948
  }
5748
5949
  function parseDurationMs(every) {
5749
5950
  const m = every.trim().match(DURATION_RE);
@@ -5849,9 +6050,9 @@ function normalizeTask(raw) {
5849
6050
  }
5850
6051
  function readAll() {
5851
6052
  const path = schedulesPath();
5852
- if (!existsSync15(path)) return [];
6053
+ if (!existsSync16(path)) return [];
5853
6054
  try {
5854
- const parsed = JSON.parse(readFileSync11(path, "utf8"));
6055
+ const parsed = JSON.parse(readFileSync12(path, "utf8"));
5855
6056
  if (!Array.isArray(parsed)) return [];
5856
6057
  return parsed.map((row) => {
5857
6058
  try {
@@ -5977,7 +6178,7 @@ function formatScheduledPrompt(name, prompt) {
5977
6178
  ${prompt}`;
5978
6179
  }
5979
6180
  async function defaultDeps() {
5980
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-NUA6SEV7.js");
6181
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-HC7XVGJB.js");
5981
6182
  const orch = getOrchestrator2();
5982
6183
  return {
5983
6184
  findThread: (id) => findThreadByRef(id),
@@ -6217,7 +6418,7 @@ var Orchestrator = class {
6217
6418
  }
6218
6419
  continue;
6219
6420
  }
6220
- if (!existsSync16(thread.worktreePath)) {
6421
+ if (!existsSync17(thread.worktreePath)) {
6221
6422
  setStatus(thread.id, "broken", "Worktree missing on disk");
6222
6423
  this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
6223
6424
  continue;
@@ -6236,7 +6437,7 @@ var Orchestrator = class {
6236
6437
  orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
6237
6438
  });
6238
6439
  }
6239
- const { autoCleanupOrphansEnabled } = await import("./app-settings-3CHCNIMD.js");
6440
+ const { autoCleanupOrphansEnabled } = await import("./app-settings-H3INSR67.js");
6240
6441
  if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
6241
6442
  await cleanupOrphanWorktrees({ repoPaths });
6242
6443
  }
@@ -6476,7 +6677,7 @@ var Orchestrator = class {
6476
6677
  }
6477
6678
  await setup;
6478
6679
  if (skipSetup) return;
6479
- const { autoRunAfterSetupEnabled } = await import("./app-settings-3CHCNIMD.js");
6680
+ const { autoRunAfterSetupEnabled } = await import("./app-settings-H3INSR67.js");
6480
6681
  if (autoRunAfterSetupEnabled()) {
6481
6682
  try {
6482
6683
  await this.startDev(threadId);
@@ -6487,21 +6688,11 @@ var Orchestrator = class {
6487
6688
  /** Run workspace setup after a new worktree is created (no-op if none configured). */
6488
6689
  async runSetupAfterCreate(threadId) {
6489
6690
  try {
6490
- await this.runSetup(threadId);
6691
+ await this.runSetup(threadId, { stampLastError: false });
6491
6692
  } catch (err) {
6492
6693
  const message = err instanceof Error ? err.message : String(err);
6493
6694
  if (/no setup script/i.test(message)) return;
6494
6695
  if (/already running/i.test(message)) return;
6495
- const live = readThread(threadId);
6496
- if (!shouldStampSetupLastError({
6497
- turnInFlight: this.activeTurns.has(threadId) || this.startingTurns.has(threadId),
6498
- status: live?.status
6499
- })) {
6500
- return;
6501
- }
6502
- updateThread(threadId, {
6503
- lastError: `Setup failed: ${message}`
6504
- });
6505
6696
  }
6506
6697
  }
6507
6698
  listWorkspaces() {
@@ -6784,7 +6975,7 @@ var Orchestrator = class {
6784
6975
  }
6785
6976
  const isBrightsy = fresh.agent === "brightsy";
6786
6977
  const isOrchestration = isOrchestratorThread(fresh);
6787
- const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-3CHCNIMD.js");
6978
+ const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-H3INSR67.js");
6788
6979
  const gitAuthMode = getGithubGitAuthMode();
6789
6980
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
6790
6981
  githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
@@ -6890,7 +7081,7 @@ var Orchestrator = class {
6890
7081
  if (!this.stoppedTurns.has(threadId) && this.requireThread(threadId).agent === "cursor" && exitCode !== 0 && !assistantText && parts.length === 0) {
6891
7082
  const sessionId = result.sessionId || this.requireThread(threadId).sessionId || "";
6892
7083
  if (sessionId) {
6893
- const { recoverFinishedCursorRun } = await import("./cursor-recover-QSLWEZNA.js");
7084
+ const { recoverFinishedCursorRun } = await import("./cursor-recover-NDMLLNYX.js");
6894
7085
  for (let i = 0; i < 8; i++) {
6895
7086
  const recovered = recoverFinishedCursorRun({
6896
7087
  agentId: sessionId,
@@ -7280,7 +7471,16 @@ var Orchestrator = class {
7280
7471
  getActiveRuns(threadRef) {
7281
7472
  return this.requireThread(threadRef).activeRuns ?? [];
7282
7473
  }
7283
- async runSetup(threadRef) {
7474
+ getSetupLog(threadRef) {
7475
+ const thread = this.getThread(threadRef);
7476
+ if (!thread) return readSetupLog(threadRef);
7477
+ const snap = readSetupLog(thread.id);
7478
+ if (snap.running && !this.processes.has(`${thread.id}:setup`)) {
7479
+ return { ...snap, running: false };
7480
+ }
7481
+ return snap;
7482
+ }
7483
+ async runSetup(threadRef, opts) {
7284
7484
  const thread = this.requireThread(threadRef);
7285
7485
  this.assertNotGlobal(thread, "Setup");
7286
7486
  const key = `${thread.id}:setup`;
@@ -7293,34 +7493,49 @@ var Orchestrator = class {
7293
7493
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
7294
7494
  kill: () => abort.abort()
7295
7495
  });
7496
+ beginSetupLog(thread.id);
7296
7497
  this.emit({ type: "setup_started", threadId: thread.id });
7498
+ let finished = false;
7499
+ const finish = (exitCode, source) => {
7500
+ if (finished) return;
7501
+ finished = true;
7502
+ finishSetupLog(thread.id, exitCode, source);
7503
+ this.emit({ type: "setup_finished", threadId: thread.id, exitCode });
7504
+ };
7297
7505
  try {
7298
7506
  const setup = await runWorkspaceSetup(
7299
7507
  thread.repoPath,
7300
7508
  thread.worktreePath,
7301
7509
  (line) => {
7510
+ appendSetupLog(thread.id, line);
7302
7511
  this.emit({ type: "setup_output", threadId: thread.id, line });
7303
7512
  },
7304
7513
  { signal: abort.signal }
7305
7514
  );
7306
7515
  if (!setup.ran) {
7307
- throw new Error(
7308
- "No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)"
7309
- );
7516
+ const line = "No setup script in .sideboard/settings.toml, .conductor/settings.toml, .cursor/worktrees.json, or script/setup (bin/setup, scripts/setup)";
7517
+ appendSetupLog(thread.id, line);
7518
+ this.emit({ type: "setup_output", threadId: thread.id, line });
7519
+ finish(null, null);
7520
+ throw new Error(line);
7310
7521
  }
7311
7522
  if (setup.exitCode !== 0 && setup.exitCode !== null) {
7312
7523
  const live = readThread(thread.id);
7313
- if (shouldStampSetupLastError({
7524
+ if ((opts?.stampLastError ?? true) && shouldStampSetupLastError({
7314
7525
  turnInFlight: this.activeTurns.has(thread.id) || this.startingTurns.has(thread.id),
7315
- status: live?.status
7526
+ status: live?.status,
7527
+ hasQueuedPrompt: Boolean(live?.queue?.length)
7316
7528
  })) {
7317
7529
  updateThread(thread.id, {
7318
7530
  lastError: `Setup exited ${setup.exitCode}`
7319
7531
  });
7320
7532
  }
7321
7533
  }
7322
- this.emit({ type: "setup_finished", threadId: thread.id, exitCode: setup.exitCode });
7534
+ finish(setup.exitCode, setup.source);
7323
7535
  return { exitCode: setup.exitCode, source: setup.source };
7536
+ } catch (err) {
7537
+ finish(null, null);
7538
+ throw err;
7324
7539
  } finally {
7325
7540
  this.processes.delete(key);
7326
7541
  }
@@ -7647,7 +7862,7 @@ var Orchestrator = class {
7647
7862
  updateThread(thread.id, { title: meta.title });
7648
7863
  }
7649
7864
  }
7650
- const { autoArchiveOnMergeEnabled } = await import("./app-settings-3CHCNIMD.js");
7865
+ const { autoArchiveOnMergeEnabled } = await import("./app-settings-H3INSR67.js");
7651
7866
  const latest = this.requireThread(thread.id);
7652
7867
  if (!shouldAutoArchiveOnPrMerge({
7653
7868
  previousPrState: prevState || null,
@@ -7964,7 +8179,7 @@ var Orchestrator = class {
7964
8179
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
7965
8180
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
7966
8181
  try {
7967
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-4FSXVIZM.js");
8182
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-5UNDTN4G.js");
7968
8183
  await ensureWorkspace2(thread.repoPath);
7969
8184
  } catch {
7970
8185
  }
@@ -7991,7 +8206,7 @@ var Orchestrator = class {
7991
8206
  await runArchiveScript(thread.repoPath, thread.worktreePath);
7992
8207
  } catch {
7993
8208
  }
7994
- const { deleteBranchOnPurgeEnabled } = await import("./app-settings-3CHCNIMD.js");
8209
+ const { deleteBranchOnPurgeEnabled } = await import("./app-settings-H3INSR67.js");
7995
8210
  const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
7996
8211
  await removeWorktree(thread.repoPath, thread.worktreePath, {
7997
8212
  deleteBranch: deleteBranch ? thread.branchName : void 0
@@ -8006,19 +8221,19 @@ var Orchestrator = class {
8006
8221
  throw new Error("Thread is not archived");
8007
8222
  }
8008
8223
  if (isGlobalThread(thread)) {
8009
- const { globalAgentCwd } = await import("./paths-UMEDHOS5.js");
8224
+ const { globalAgentCwd } = await import("./paths-53TLA7VQ.js");
8010
8225
  updateThread(thread.id, { worktreePath: globalAgentCwd() });
8011
8226
  const restored2 = setStatus(thread.id, "idle");
8012
8227
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
8013
8228
  return restored2;
8014
8229
  }
8015
- if (!existsSync16(thread.worktreePath)) {
8230
+ if (!existsSync17(thread.worktreePath)) {
8016
8231
  if (isCowboyThread(thread) || isPrimaryCheckoutThread(thread)) {
8017
8232
  throw new Error(
8018
8233
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
8019
8234
  );
8020
8235
  }
8021
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-DPIREDFR.js");
8236
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-T4SWFSTT.js");
8022
8237
  const slug = thread.worktreePath.split("/").pop();
8023
8238
  const dest = thread.worktreePath;
8024
8239
  await withRepoGitLock(thread.repoPath, async () => {
@@ -8128,7 +8343,7 @@ async function startOrchestration(opts) {
8128
8343
  sourceRef: "default",
8129
8344
  ...createOpts
8130
8345
  }).catch(async () => {
8131
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-DPIREDFR.js");
8346
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-T4SWFSTT.js");
8132
8347
  const repo = await resolveRepoRoot2(repoPath);
8133
8348
  const def = await resolveDefaultBranch2(repo);
8134
8349
  return orch.createThread({
@@ -8138,7 +8353,7 @@ async function startOrchestration(opts) {
8138
8353
  repoPath: repo
8139
8354
  });
8140
8355
  });
8141
- const { updateThread: upd } = await import("./thread-store-WGASXXXR.js");
8356
+ const { updateThread: upd } = await import("./thread-store-KBFBHT5G.js");
8142
8357
  const updated = upd(thread.id, {
8143
8358
  sourceType: "orchestration",
8144
8359
  sourceRef: goal
@@ -8150,6 +8365,9 @@ async function startOrchestration(opts) {
8150
8365
  }
8151
8366
 
8152
8367
  export {
8368
+ emptySetupLog,
8369
+ mergeSetupOutput,
8370
+ readSetupLog,
8153
8371
  schedulesPath,
8154
8372
  parseDurationMs,
8155
8373
  defaultScheduleName,
@@ -8284,6 +8502,7 @@ export {
8284
8502
  issueNeedsWorkspacePick,
8285
8503
  isAccountWideIssueSource,
8286
8504
  findLiveThreadForCreate,
8505
+ findLiveThreadForCreateSource,
8287
8506
  boardPinIdentity,
8288
8507
  findBoardPin,
8289
8508
  syncBoardPins,
@@ -8298,6 +8517,9 @@ export {
8298
8517
  isPrimaryCheckoutThread,
8299
8518
  shouldRemoveWorktreeOnTeardown,
8300
8519
  readTurnLive,
8520
+ shouldStampSetupLastError,
8521
+ isSetupLastError,
8522
+ isStaleLastErrorDuringTurn,
8301
8523
  forkThreadWorktree,
8302
8524
  resolveConductorCursorAgentId,
8303
8525
  adoptThread,