@sideboard-ai/core 0.1.143 → 0.1.145

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-OEEOIKUB.js → agents-4WOO4WN4.js} +4 -4
  2. package/dist/{agents-E5AAMHDY.js → agents-VFBNZHI4.js} +4 -4
  3. package/dist/{chunk-OHWN4JEL.js → chunk-2C5RE7K4.js} +1 -1
  4. package/dist/{chunk-EAP4SMR3.js → chunk-335KQKWX.js} +68 -18
  5. package/dist/{chunk-KP4OJUPH.js → chunk-3EMJ5LVV.js} +68 -18
  6. package/dist/{chunk-HC5N3BDL.js → chunk-3UD2LW4P.js} +2 -2
  7. package/dist/{chunk-UG5N7ET3.js → chunk-DN7UA3UT.js} +1 -1
  8. package/dist/{chunk-R2W7A2UO.js → chunk-G3KLNP2B.js} +2 -2
  9. package/dist/{chunk-O3JEC2UJ.js → chunk-JSYIBLBK.js} +77 -8
  10. package/dist/{chunk-4D4PEBGB.js → chunk-LWRNRMYY.js} +2 -2
  11. package/dist/{chunk-4Q45TLZ5.js → chunk-QS5JJ2IM.js} +77 -8
  12. package/dist/{chunk-CG25RYQQ.js → chunk-TTJ6EYZC.js} +3 -3
  13. package/dist/{chunk-VHTIHOHE.js → chunk-UJWGZM4K.js} +3 -3
  14. package/dist/{chunk-FADNFPZO.js → chunk-XUYIJY6D.js} +2 -2
  15. package/dist/{coordinator-prompt-2LD3C74O.js → coordinator-prompt-J2WBXGLP.js} +2 -2
  16. package/dist/{coordinator-prompt-FBX7Y4EM.js → coordinator-prompt-JSX22ULD.js} +2 -2
  17. package/dist/{global-workspace-NG7SU3GV.js → global-workspace-6WR7OGMI.js} +3 -3
  18. package/dist/{global-workspace-OCV77UYF.js → global-workspace-AQESFS7I.js} +3 -3
  19. package/dist/index.cjs +140 -12
  20. package/dist/index.d.cts +20 -1
  21. package/dist/index.d.ts +20 -1
  22. package/dist/index.js +10 -6
  23. package/dist/mcp/run-stdio.cjs +136 -12
  24. package/dist/mcp/run-stdio.js +6 -6
  25. package/dist/{orchestrator-TDJZKQPT.js → orchestrator-WWQBBIPP.js} +6 -6
  26. package/dist/{orchestrator-VIFXOHF4.js → orchestrator-XPGJV7JK.js} +6 -6
  27. package/dist/{workspaces-4FUQW5LD.js → workspaces-V3RNE5ZX.js} +4 -4
  28. package/dist/{workspaces-PU5YHQ7Z.js → workspaces-WALT3MJB.js} +4 -4
  29. package/dist/{worktree-GKLPPNWR.js → worktree-3NLPMA7K.js} +5 -1
  30. package/dist/{worktree-Z22HTSCU.js → worktree-TUZX7F7P.js} +5 -1
  31. package/package.json +1 -1
@@ -36,7 +36,7 @@ import {
36
36
  resolveQuotaFallbackAgent,
37
37
  turnCostUsdFromCursorUsage,
38
38
  whichOnPath
39
- } from "./chunk-CG25RYQQ.js";
39
+ } from "./chunk-TTJ6EYZC.js";
40
40
  import "./chunk-ED4UPEJX.js";
41
41
  import "./chunk-S42XV45P.js";
42
42
  import "./chunk-6GN5WPYZ.js";
@@ -45,9 +45,9 @@ import {
45
45
  assertOrchestratorCapableAgent,
46
46
  coerceOrchestratorAgent,
47
47
  isOrchestratorCapableAgent
48
- } from "./chunk-FADNFPZO.js";
49
- import "./chunk-OHWN4JEL.js";
50
- import "./chunk-4Q45TLZ5.js";
48
+ } from "./chunk-XUYIJY6D.js";
49
+ import "./chunk-2C5RE7K4.js";
50
+ import "./chunk-QS5JJ2IM.js";
51
51
  import "./chunk-B3SJXYIJ.js";
52
52
  import "./chunk-EUXOHTUK.js";
53
53
  import {
@@ -30,7 +30,7 @@ import {
30
30
  resolveLoginCommand,
31
31
  resolveQuotaFallbackAgent,
32
32
  whichOnPath
33
- } from "./chunk-VHTIHOHE.js";
33
+ } from "./chunk-UJWGZM4K.js";
34
34
  import "./chunk-KBWND62T.js";
35
35
  import "./chunk-M267JPEA.js";
36
36
  import {
@@ -38,8 +38,8 @@ import {
38
38
  assertOrchestratorCapableAgent,
39
39
  coerceOrchestratorAgent,
40
40
  isOrchestratorCapableAgent
41
- } from "./chunk-R2W7A2UO.js";
42
- import "./chunk-UG5N7ET3.js";
41
+ } from "./chunk-G3KLNP2B.js";
42
+ import "./chunk-DN7UA3UT.js";
43
43
  import "./chunk-ELBYOGVA.js";
44
44
  import {
45
45
  cursorSdkMessageToEvents,
@@ -47,7 +47,7 @@ import {
47
47
  preferredCursorCostCents,
48
48
  turnCostUsdFromCursorUsage
49
49
  } from "./chunk-WT5HSFOU.js";
50
- import "./chunk-O3JEC2UJ.js";
50
+ import "./chunk-JSYIBLBK.js";
51
51
  import "./chunk-FKOIHGKV.js";
52
52
  import "./chunk-I77RYPOH.js";
53
53
  import "./chunk-4TR3HZFT.js";
@@ -2,7 +2,7 @@
2
2
 
3
3
  import {
4
4
  resolveGithubRepoSlug
5
- } from "./chunk-4Q45TLZ5.js";
5
+ } from "./chunk-QS5JJ2IM.js";
6
6
  import {
7
7
  resolveThreadDefaults
8
8
  } from "./chunk-BGQBELGJ.js";
@@ -32,13 +32,13 @@ import {
32
32
  summarizeTurnStderr,
33
33
  toolDescription,
34
34
  turnFailChatText
35
- } from "./chunk-CG25RYQQ.js";
35
+ } from "./chunk-TTJ6EYZC.js";
36
36
  import {
37
37
  addWorkspace,
38
38
  ensureWorkspace,
39
39
  removeWorkspace,
40
40
  syncWorkspacesFromThreads
41
- } from "./chunk-4D4PEBGB.js";
41
+ } from "./chunk-LWRNRMYY.js";
42
42
  import {
43
43
  extractPresentedPlan,
44
44
  readPlanFile,
@@ -63,14 +63,14 @@ import {
63
63
  persistPendingFileAttachments,
64
64
  stageAbsolutePathsAsAttachments,
65
65
  stageBuffersAsAttachments
66
- } from "./chunk-FADNFPZO.js";
66
+ } from "./chunk-XUYIJY6D.js";
67
67
  import {
68
68
  SLACK_REPLY_FORMATTING,
69
69
  coordinatorSystemPrompt,
70
70
  coordinatorTurnReminder,
71
71
  enrichWorkspacesWithGithub,
72
72
  ensureGlobalCoordinatorCwd
73
- } from "./chunk-OHWN4JEL.js";
73
+ } from "./chunk-2C5RE7K4.js";
74
74
  import {
75
75
  addPrStackLayer,
76
76
  allocateTeamName,
@@ -97,6 +97,7 @@ import {
97
97
  isPlaceholderBranch,
98
98
  isSideboardScratchPath,
99
99
  listWorktrees,
100
+ markPrReady,
100
101
  mergeAgentGitAuthEnv,
101
102
  mergePr,
102
103
  normalizeWorktreePath,
@@ -115,7 +116,7 @@ import {
115
116
  withRepoGitLock,
116
117
  worktreeDisplayLabelForGroup,
117
118
  worktreeNameFromPath
118
- } from "./chunk-4Q45TLZ5.js";
119
+ } from "./chunk-QS5JJ2IM.js";
119
120
  import {
120
121
  ATTACHMENTS_DIR,
121
122
  LEGACY_ATTACHMENTS_DIR
@@ -388,7 +389,7 @@ async function continueSourceThread(threadId, prompt) {
388
389
  await continueOnReply(threadId, prompt);
389
390
  return;
390
391
  }
391
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-TDJZKQPT.js");
392
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-WWQBBIPP.js");
392
393
  await getOrchestrator2().send(threadId, prompt);
393
394
  } catch {
394
395
  }
@@ -729,9 +730,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
729
730
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
730
731
  );
731
732
  }
732
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-OCV77UYF.js");
733
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-AQESFS7I.js");
733
734
  if (isGlobalThread2(thread)) {
734
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-FBX7Y4EM.js");
735
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-JSX22ULD.js");
735
736
  ensureGlobalCoordinatorCwd2(
736
737
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
737
738
  );
@@ -3000,7 +3001,7 @@ async function createThread(input, _onSetupLine) {
3000
3001
  return readThread(thread.id) ?? thread;
3001
3002
  }
3002
3003
  async function listLinearIssues(agent, repoPath) {
3003
- const { getAdapter: getAdapter2 } = await import("./agents-OEEOIKUB.js");
3004
+ const { getAdapter: getAdapter2 } = await import("./agents-4WOO4WN4.js");
3004
3005
  await requireAgent(agent, { requireLinear: true });
3005
3006
  const adapter = getAdapter2(agent);
3006
3007
  if (!adapter.listLinearIssues) {
@@ -3151,6 +3152,16 @@ function shouldReadThreadToHealReconcile(eventType, lastCheckAt, now) {
3151
3152
  return true;
3152
3153
  }
3153
3154
 
3155
+ // src/orchestrator/setup-last-error.ts
3156
+ function shouldStampSetupLastError(opts) {
3157
+ if (opts.turnInFlight) return false;
3158
+ if (opts.status === "running") return false;
3159
+ return true;
3160
+ }
3161
+ function isStaleLastErrorDuringTurn(err) {
3162
+ return Boolean(err?.trim());
3163
+ }
3164
+
3154
3165
  // src/threads/fork-worktree.ts
3155
3166
  function requireThread2(idOrRef) {
3156
3167
  const thread = findThreadByRef(idOrRef) ?? null;
@@ -3397,7 +3408,7 @@ async function adoptThread(input) {
3397
3408
  messages: input.messages ?? []
3398
3409
  });
3399
3410
  writeThread(thread);
3400
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-4FUQW5LD.js");
3411
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-V3RNE5ZX.js");
3401
3412
  await ensureWorkspace2(repoPath);
3402
3413
  return thread;
3403
3414
  }
@@ -5596,7 +5607,7 @@ function formatScheduledPrompt(name, prompt) {
5596
5607
  ${prompt}`;
5597
5608
  }
5598
5609
  async function defaultDeps() {
5599
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-TDJZKQPT.js");
5610
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-WWQBBIPP.js");
5600
5611
  const orch = getOrchestrator2();
5601
5612
  return {
5602
5613
  findThread: (id) => findThreadByRef(id),
@@ -6077,6 +6088,13 @@ var Orchestrator = class {
6077
6088
  const message = err instanceof Error ? err.message : String(err);
6078
6089
  if (/no setup script/i.test(message)) return;
6079
6090
  if (/already running/i.test(message)) return;
6091
+ const live = readThread(threadId);
6092
+ if (!shouldStampSetupLastError({
6093
+ turnInFlight: this.activeTurns.has(threadId) || this.startingTurns.has(threadId),
6094
+ status: live?.status
6095
+ })) {
6096
+ return;
6097
+ }
6080
6098
  updateThread(threadId, {
6081
6099
  lastError: `Setup failed: ${message}`
6082
6100
  });
@@ -6423,7 +6441,7 @@ var Orchestrator = class {
6423
6441
  )) {
6424
6442
  this.lastReconcileHealAt.set(threadId, now);
6425
6443
  const live = readThread(threadId);
6426
- if (live?.lastError?.includes("reconciled on startup") && (this.activeTurns.has(threadId) || this.startingTurns.has(threadId))) {
6444
+ if (isStaleLastErrorDuringTurn(live?.lastError) && (this.activeTurns.has(threadId) || this.startingTurns.has(threadId))) {
6427
6445
  setStatus(threadId, "running");
6428
6446
  this.emit({ type: "status_changed", threadId, status: "running" });
6429
6447
  }
@@ -6880,9 +6898,15 @@ var Orchestrator = class {
6880
6898
  );
6881
6899
  }
6882
6900
  if (setup.exitCode !== 0 && setup.exitCode !== null) {
6883
- updateThread(thread.id, {
6884
- lastError: `Setup exited ${setup.exitCode}`
6885
- });
6901
+ const live = readThread(thread.id);
6902
+ if (shouldStampSetupLastError({
6903
+ turnInFlight: this.activeTurns.has(thread.id) || this.startingTurns.has(thread.id),
6904
+ status: live?.status
6905
+ })) {
6906
+ updateThread(thread.id, {
6907
+ lastError: `Setup exited ${setup.exitCode}`
6908
+ });
6909
+ }
6886
6910
  }
6887
6911
  this.emit({ type: "setup_finished", threadId: thread.id, exitCode: setup.exitCode });
6888
6912
  return { exitCode: setup.exitCode, source: setup.source };
@@ -7108,6 +7132,32 @@ var Orchestrator = class {
7108
7132
  }
7109
7133
  return result;
7110
7134
  }
7135
+ async markPrReady(threadRef) {
7136
+ const { thread, selectors, cwd } = await this.withPrSelector(threadRef);
7137
+ this.assertNotGlobal(thread, "Ready for review");
7138
+ const selector = selectors[0];
7139
+ if (!selector) throw new Error("No pull request linked to this thread");
7140
+ const result = await markPrReady(cwd, selector);
7141
+ const meta = await getPrMeta(cwd, selector);
7142
+ if (meta) {
7143
+ await this.persistPrMetaAndMaybeArchive(thread, { ...meta, isDraft: false });
7144
+ return { url: meta.url || result.url, state: meta.state || result.state, isDraft: false };
7145
+ }
7146
+ await this.persistPrMetaAndMaybeArchive(thread, {
7147
+ number: 0,
7148
+ title: thread.prTitle ?? thread.title,
7149
+ url: result.url || thread.prUrl || "",
7150
+ state: result.state || "OPEN",
7151
+ isDraft: false,
7152
+ reviewDecision: null,
7153
+ baseRefName: "",
7154
+ headRefName: "",
7155
+ isInMergeQueue: false,
7156
+ mergeable: null,
7157
+ mergeStateStatus: null
7158
+ });
7159
+ return { ...result, isDraft: false };
7160
+ }
7111
7161
  async mergePr(threadRef) {
7112
7162
  const { thread, selectors, cwd } = await this.withPrSelector(threadRef);
7113
7163
  this.assertNotGlobal(thread, "Merge PR");
@@ -7493,7 +7543,7 @@ var Orchestrator = class {
7493
7543
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
7494
7544
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
7495
7545
  try {
7496
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-4FUQW5LD.js");
7546
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-V3RNE5ZX.js");
7497
7547
  await ensureWorkspace2(thread.repoPath);
7498
7548
  } catch {
7499
7549
  }
@@ -7547,7 +7597,7 @@ var Orchestrator = class {
7547
7597
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
7548
7598
  );
7549
7599
  }
7550
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-Z22HTSCU.js");
7600
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-TUZX7F7P.js");
7551
7601
  const slug = thread.worktreePath.split("/").pop();
7552
7602
  const dest = thread.worktreePath;
7553
7603
  await withRepoGitLock(thread.repoPath, async () => {
@@ -7655,7 +7705,7 @@ async function startOrchestration(opts) {
7655
7705
  sourceRef: "default",
7656
7706
  ...createOpts
7657
7707
  }).catch(async () => {
7658
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-Z22HTSCU.js");
7708
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-TUZX7F7P.js");
7659
7709
  const repo = await resolveRepoRoot2(repoPath);
7660
7710
  const def = await resolveDefaultBranch2(repo);
7661
7711
  return orch.createThread({
@@ -18,13 +18,13 @@ import {
18
18
  stripBrightsyNdjsonNoise,
19
19
  sumUsageList,
20
20
  toolDescription
21
- } from "./chunk-VHTIHOHE.js";
21
+ } from "./chunk-UJWGZM4K.js";
22
22
  import {
23
23
  addWorkspace,
24
24
  ensureWorkspace,
25
25
  removeWorkspace,
26
26
  syncWorkspacesFromThreads
27
- } from "./chunk-HC5N3BDL.js";
27
+ } from "./chunk-3UD2LW4P.js";
28
28
  import {
29
29
  assertOrchestratorCapableAgent,
30
30
  attachmentsFromWorktreePaths,
@@ -41,14 +41,14 @@ import {
41
41
  persistPendingFileAttachments,
42
42
  stageAbsolutePathsAsAttachments,
43
43
  stageBuffersAsAttachments
44
- } from "./chunk-R2W7A2UO.js";
44
+ } from "./chunk-G3KLNP2B.js";
45
45
  import {
46
46
  SLACK_REPLY_FORMATTING,
47
47
  coordinatorSystemPrompt,
48
48
  coordinatorTurnReminder,
49
49
  enrichWorkspacesWithGithub,
50
50
  ensureGlobalCoordinatorCwd
51
- } from "./chunk-UG5N7ET3.js";
51
+ } from "./chunk-DN7UA3UT.js";
52
52
  import {
53
53
  httpFetch
54
54
  } from "./chunk-ELBYOGVA.js";
@@ -104,6 +104,7 @@ import {
104
104
  isPlaceholderBranch,
105
105
  isSideboardScratchPath,
106
106
  listWorktrees,
107
+ markPrReady,
107
108
  mergeAgentGitAuthEnv,
108
109
  mergePr,
109
110
  normalizeWorktreePath,
@@ -122,7 +123,7 @@ import {
122
123
  withRepoGitLock,
123
124
  worktreeDisplayLabelForGroup,
124
125
  worktreeNameFromPath
125
- } from "./chunk-O3JEC2UJ.js";
126
+ } from "./chunk-JSYIBLBK.js";
126
127
  import {
127
128
  ATTACHMENTS_DIR,
128
129
  LEGACY_ATTACHMENTS_DIR
@@ -453,7 +454,7 @@ async function continueSourceThread(threadId, prompt) {
453
454
  await continueOnReply(threadId, prompt);
454
455
  return;
455
456
  }
456
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-VIFXOHF4.js");
457
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-XPGJV7JK.js");
457
458
  await getOrchestrator2().send(threadId, prompt);
458
459
  } catch {
459
460
  }
@@ -733,9 +734,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
733
734
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
734
735
  );
735
736
  }
736
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-NG7SU3GV.js");
737
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-6WR7OGMI.js");
737
738
  if (isGlobalThread2(thread)) {
738
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-2LD3C74O.js");
739
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-J2WBXGLP.js");
739
740
  ensureGlobalCoordinatorCwd2(
740
741
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
741
742
  );
@@ -3068,7 +3069,7 @@ async function createThread(input, _onSetupLine) {
3068
3069
  return readThread(thread.id) ?? thread;
3069
3070
  }
3070
3071
  async function listLinearIssues(agent, repoPath) {
3071
- const { getAdapter: getAdapter2 } = await import("./agents-E5AAMHDY.js");
3072
+ const { getAdapter: getAdapter2 } = await import("./agents-VFBNZHI4.js");
3072
3073
  await requireAgent(agent, { requireLinear: true });
3073
3074
  const adapter = getAdapter2(agent);
3074
3075
  if (!adapter.listLinearIssues) {
@@ -3219,6 +3220,16 @@ function shouldReadThreadToHealReconcile(eventType, lastCheckAt, now) {
3219
3220
  return true;
3220
3221
  }
3221
3222
 
3223
+ // src/orchestrator/setup-last-error.ts
3224
+ function shouldStampSetupLastError(opts) {
3225
+ if (opts.turnInFlight) return false;
3226
+ if (opts.status === "running") return false;
3227
+ return true;
3228
+ }
3229
+ function isStaleLastErrorDuringTurn(err) {
3230
+ return Boolean(err?.trim());
3231
+ }
3232
+
3222
3233
  // src/threads/fork-worktree.ts
3223
3234
  function requireThread2(idOrRef) {
3224
3235
  const thread = findThreadByRef(idOrRef) ?? null;
@@ -3465,7 +3476,7 @@ async function adoptThread(input) {
3465
3476
  messages: input.messages ?? []
3466
3477
  });
3467
3478
  writeThread(thread);
3468
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-PU5YHQ7Z.js");
3479
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-WALT3MJB.js");
3469
3480
  await ensureWorkspace2(repoPath);
3470
3481
  return thread;
3471
3482
  }
@@ -5913,7 +5924,7 @@ function formatScheduledPrompt(name, prompt) {
5913
5924
  ${prompt}`;
5914
5925
  }
5915
5926
  async function defaultDeps() {
5916
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-VIFXOHF4.js");
5927
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-XPGJV7JK.js");
5917
5928
  const orch = getOrchestrator2();
5918
5929
  return {
5919
5930
  findThread: (id) => findThreadByRef(id),
@@ -6394,6 +6405,13 @@ var Orchestrator = class {
6394
6405
  const message = err instanceof Error ? err.message : String(err);
6395
6406
  if (/no setup script/i.test(message)) return;
6396
6407
  if (/already running/i.test(message)) return;
6408
+ const live = readThread(threadId);
6409
+ if (!shouldStampSetupLastError({
6410
+ turnInFlight: this.activeTurns.has(threadId) || this.startingTurns.has(threadId),
6411
+ status: live?.status
6412
+ })) {
6413
+ return;
6414
+ }
6397
6415
  updateThread(threadId, {
6398
6416
  lastError: `Setup failed: ${message}`
6399
6417
  });
@@ -6740,7 +6758,7 @@ var Orchestrator = class {
6740
6758
  )) {
6741
6759
  this.lastReconcileHealAt.set(threadId, now);
6742
6760
  const live = readThread(threadId);
6743
- if (live?.lastError?.includes("reconciled on startup") && (this.activeTurns.has(threadId) || this.startingTurns.has(threadId))) {
6761
+ if (isStaleLastErrorDuringTurn(live?.lastError) && (this.activeTurns.has(threadId) || this.startingTurns.has(threadId))) {
6744
6762
  setStatus(threadId, "running");
6745
6763
  this.emit({ type: "status_changed", threadId, status: "running" });
6746
6764
  }
@@ -7197,9 +7215,15 @@ var Orchestrator = class {
7197
7215
  );
7198
7216
  }
7199
7217
  if (setup.exitCode !== 0 && setup.exitCode !== null) {
7200
- updateThread(thread.id, {
7201
- lastError: `Setup exited ${setup.exitCode}`
7202
- });
7218
+ const live = readThread(thread.id);
7219
+ if (shouldStampSetupLastError({
7220
+ turnInFlight: this.activeTurns.has(thread.id) || this.startingTurns.has(thread.id),
7221
+ status: live?.status
7222
+ })) {
7223
+ updateThread(thread.id, {
7224
+ lastError: `Setup exited ${setup.exitCode}`
7225
+ });
7226
+ }
7203
7227
  }
7204
7228
  this.emit({ type: "setup_finished", threadId: thread.id, exitCode: setup.exitCode });
7205
7229
  return { exitCode: setup.exitCode, source: setup.source };
@@ -7425,6 +7449,32 @@ var Orchestrator = class {
7425
7449
  }
7426
7450
  return result;
7427
7451
  }
7452
+ async markPrReady(threadRef) {
7453
+ const { thread, selectors, cwd } = await this.withPrSelector(threadRef);
7454
+ this.assertNotGlobal(thread, "Ready for review");
7455
+ const selector = selectors[0];
7456
+ if (!selector) throw new Error("No pull request linked to this thread");
7457
+ const result = await markPrReady(cwd, selector);
7458
+ const meta = await getPrMeta(cwd, selector);
7459
+ if (meta) {
7460
+ await this.persistPrMetaAndMaybeArchive(thread, { ...meta, isDraft: false });
7461
+ return { url: meta.url || result.url, state: meta.state || result.state, isDraft: false };
7462
+ }
7463
+ await this.persistPrMetaAndMaybeArchive(thread, {
7464
+ number: 0,
7465
+ title: thread.prTitle ?? thread.title,
7466
+ url: result.url || thread.prUrl || "",
7467
+ state: result.state || "OPEN",
7468
+ isDraft: false,
7469
+ reviewDecision: null,
7470
+ baseRefName: "",
7471
+ headRefName: "",
7472
+ isInMergeQueue: false,
7473
+ mergeable: null,
7474
+ mergeStateStatus: null
7475
+ });
7476
+ return { ...result, isDraft: false };
7477
+ }
7428
7478
  async mergePr(threadRef) {
7429
7479
  const { thread, selectors, cwd } = await this.withPrSelector(threadRef);
7430
7480
  this.assertNotGlobal(thread, "Merge PR");
@@ -7810,7 +7860,7 @@ var Orchestrator = class {
7810
7860
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
7811
7861
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
7812
7862
  try {
7813
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-PU5YHQ7Z.js");
7863
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-WALT3MJB.js");
7814
7864
  await ensureWorkspace2(thread.repoPath);
7815
7865
  } catch {
7816
7866
  }
@@ -7864,7 +7914,7 @@ var Orchestrator = class {
7864
7914
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
7865
7915
  );
7866
7916
  }
7867
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-GKLPPNWR.js");
7917
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-3NLPMA7K.js");
7868
7918
  const slug = thread.worktreePath.split("/").pop();
7869
7919
  const dest = thread.worktreePath;
7870
7920
  await withRepoGitLock(thread.repoPath, async () => {
@@ -7972,7 +8022,7 @@ async function startOrchestration(opts) {
7972
8022
  sourceRef: "default",
7973
8023
  ...createOpts
7974
8024
  }).catch(async () => {
7975
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-GKLPPNWR.js");
8025
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-3NLPMA7K.js");
7976
8026
  const repo = await resolveRepoRoot2(repoPath);
7977
8027
  const def = await resolveDefaultBranch2(repo);
7978
8028
  return orch.createThread({
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  isGlobalRepoPath
3
- } from "./chunk-R2W7A2UO.js";
3
+ } from "./chunk-G3KLNP2B.js";
4
4
  import {
5
5
  ensureGhPreferOrigin,
6
6
  resolveRepoRoot
7
- } from "./chunk-O3JEC2UJ.js";
7
+ } from "./chunk-JSYIBLBK.js";
8
8
  import {
9
9
  appDataDir
10
10
  } from "./chunk-QZQEXME2.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveGithubRepoSlug
3
- } from "./chunk-O3JEC2UJ.js";
3
+ } from "./chunk-JSYIBLBK.js";
4
4
  import {
5
5
  resolveThreadDefaults
6
6
  } from "./chunk-I77RYPOH.js";
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  ensureGlobalCoordinatorCwd
3
- } from "./chunk-UG5N7ET3.js";
3
+ } from "./chunk-DN7UA3UT.js";
4
4
  import {
5
5
  allocateTeamName,
6
6
  takenSlugsFromThread,
7
7
  teamSlugFromName
8
- } from "./chunk-O3JEC2UJ.js";
8
+ } from "./chunk-JSYIBLBK.js";
9
9
  import {
10
10
  ATTACHMENTS_DIR,
11
11
  attachmentsGitignoreBody
@@ -2396,6 +2396,32 @@ async function listWorktrees(repoPath) {
2396
2396
  if (current) entries.push(current);
2397
2397
  return entries;
2398
2398
  }
2399
+ async function countUnpushedVsOrigin(worktreePath) {
2400
+ const head = await git(["rev-parse", "--abbrev-ref", "HEAD"], worktreePath, {
2401
+ reject: false
2402
+ });
2403
+ const branch = head.stdout.trim();
2404
+ if (branch && branch !== "HEAD") {
2405
+ const remote = await git(
2406
+ ["rev-list", "--count", `origin/${branch}..HEAD`],
2407
+ worktreePath,
2408
+ { reject: false }
2409
+ );
2410
+ if (remote.exitCode === 0) {
2411
+ const n = Number(remote.stdout.trim());
2412
+ return Number.isFinite(n) ? n : 1;
2413
+ }
2414
+ const all = await git(["rev-list", "--count", "HEAD"], worktreePath, {
2415
+ reject: false
2416
+ });
2417
+ if (all.exitCode === 0) {
2418
+ const n = Number(all.stdout.trim());
2419
+ if (Number.isFinite(n) && n > 0) return n;
2420
+ }
2421
+ return 1;
2422
+ }
2423
+ return 1;
2424
+ }
2399
2425
  async function isDirty(worktreePath) {
2400
2426
  const { stdout } = await git(["status", "--porcelain"], worktreePath);
2401
2427
  for (const line of stdout.split("\n")) {
@@ -2459,6 +2485,54 @@ async function pushBranch(worktreePath, branchName) {
2459
2485
  const httpsErr = (basicPush.stderr || bearer.stderr || bearer.stdout).trim();
2460
2486
  throw new Error(httpsErr || sshErr || `git push origin ${branchName} failed`);
2461
2487
  }
2488
+ async function runPrReady(cwd, selector, slug) {
2489
+ const readyArgs = ["pr", "ready", selector];
2490
+ if (slug) readyArgs.push("--repo", slug);
2491
+ const ready = await gh(readyArgs, cwd, { reject: false });
2492
+ if (ready.exitCode !== 0) {
2493
+ throw new Error(
2494
+ ready.stderr.trim() || ready.stdout.trim() || "Could not mark draft pull request as ready"
2495
+ );
2496
+ }
2497
+ }
2498
+ async function markPrReady(cwd, selector) {
2499
+ const slug = await resolveGithubRepoSlug(cwd);
2500
+ const viewArgs = ["pr", "view", selector, "--json", "url,state,isDraft"];
2501
+ if (slug) viewArgs.push("--repo", slug);
2502
+ const before = await gh(viewArgs, cwd, { reject: false });
2503
+ if (before.exitCode !== 0 || !before.stdout.trim()) {
2504
+ throw new Error(before.stderr.trim() || "Could not load pull request");
2505
+ }
2506
+ let url = "";
2507
+ let state = "";
2508
+ let isDraft = false;
2509
+ try {
2510
+ const parsed = JSON.parse(before.stdout);
2511
+ url = String(parsed.url ?? "");
2512
+ state = String(parsed.state ?? "").toUpperCase();
2513
+ isDraft = Boolean(parsed.isDraft);
2514
+ } catch {
2515
+ throw new Error("Could not parse pull request details");
2516
+ }
2517
+ if (state === "MERGED" || state === "CLOSED") {
2518
+ return { url, state, isDraft: false };
2519
+ }
2520
+ if (isDraft) {
2521
+ if (await isDirty(cwd)) {
2522
+ throw new Error(
2523
+ "Commit and push local work before marking the pull request ready for review."
2524
+ );
2525
+ }
2526
+ const unpushed = await countUnpushedVsOrigin(cwd);
2527
+ if (unpushed > 0) {
2528
+ throw new Error(
2529
+ "Push this branch to origin before marking the pull request ready for review."
2530
+ );
2531
+ }
2532
+ await runPrReady(cwd, selector, slug);
2533
+ }
2534
+ return { url, state: state || "OPEN", isDraft: false };
2535
+ }
2462
2536
  async function mergePr(cwd, selector, opts) {
2463
2537
  const slug = await resolveGithubRepoSlug(cwd);
2464
2538
  const viewArgs = ["pr", "view", selector, "--json", "url,state,isDraft,number"];
@@ -2493,14 +2567,7 @@ async function mergePr(cwd, selector, opts) {
2493
2567
  return { url, state: "MERGED" };
2494
2568
  }
2495
2569
  if (isDraft) {
2496
- const readyArgs = ["pr", "ready", selector];
2497
- if (slug) readyArgs.push("--repo", slug);
2498
- const ready = await gh(readyArgs, cwd, { reject: false });
2499
- if (ready.exitCode !== 0) {
2500
- throw new Error(
2501
- ready.stderr.trim() || ready.stdout.trim() || "Could not mark draft pull request as ready"
2502
- );
2503
- }
2570
+ await runPrReady(cwd, selector, slug);
2504
2571
  }
2505
2572
  const method = opts?.method ?? "squash";
2506
2573
  const mergeFlag = method === "rebase" ? "--rebase" : method === "merge" ? "--merge" : "--squash";
@@ -2729,11 +2796,13 @@ export {
2729
2796
  createExistingBranchWorktree,
2730
2797
  removeWorktree,
2731
2798
  listWorktrees,
2799
+ countUnpushedVsOrigin,
2732
2800
  isDirty,
2733
2801
  isSideboardScratchPath,
2734
2802
  currentBranch,
2735
2803
  commitAll,
2736
2804
  pushBranch,
2805
+ markPrReady,
2737
2806
  mergePr,
2738
2807
  createOrUpdatePr,
2739
2808
  suggestSlug,
@@ -2,11 +2,11 @@
2
2
 
3
3
  import {
4
4
  isGlobalRepoPath
5
- } from "./chunk-FADNFPZO.js";
5
+ } from "./chunk-XUYIJY6D.js";
6
6
  import {
7
7
  ensureGhPreferOrigin,
8
8
  resolveRepoRoot
9
- } from "./chunk-4Q45TLZ5.js";
9
+ } from "./chunk-QS5JJ2IM.js";
10
10
  import {
11
11
  appDataDir
12
12
  } from "./chunk-BD2ICC4D.js";