@sideboard-ai/core 0.1.261 → 0.1.263

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 (55) hide show
  1. package/dist/{abletime-OQ4PC52L.js → abletime-6AOJI2YZ.js} +4 -4
  2. package/dist/{abletime-CDGINDXG.js → abletime-U75ZGDIX.js} +5 -5
  3. package/dist/{abletime-oauth-KX2TDFTE.js → abletime-oauth-LOAHGG4X.js} +3 -3
  4. package/dist/{abletime-oauth-5A5EOH2A.js → abletime-oauth-TA2YDCYX.js} +4 -4
  5. package/dist/{abletime-rest-UEHOBLXD.js → abletime-rest-CTA5WV26.js} +4 -4
  6. package/dist/{abletime-rest-PUGKYTRR.js → abletime-rest-YZPFM6IY.js} +3 -3
  7. package/dist/agents/claude-runner.cjs +463 -0
  8. package/dist/agents/claude-runner.d.cts +1 -0
  9. package/dist/agents/claude-runner.d.ts +1 -0
  10. package/dist/agents/claude-runner.js +134 -0
  11. package/dist/agents/cursor-runner.cjs +388 -7
  12. package/dist/agents/cursor-runner.js +34 -7
  13. package/dist/{agents-J2P4KNEY.js → agents-3TUMFSMH.js} +10 -9
  14. package/dist/{agents-IKVUGW5H.js → agents-6FWDRVA2.js} +4 -4
  15. package/dist/{app-settings-OM7H64YM.js → app-settings-MVZPM6WW.js} +1 -1
  16. package/dist/{app-settings-VQEUCONM.js → app-settings-RKFFUIFQ.js} +2 -2
  17. package/dist/{chunk-6PFZ6XO7.js → chunk-2QUQH2SZ.js} +81 -6
  18. package/dist/{chunk-VIC6TDYT.js → chunk-36FOBJBF.js} +76 -3
  19. package/dist/{chunk-ABPNIYRS.js → chunk-3H7O27X2.js} +389 -102
  20. package/dist/{chunk-FSZ7YYFQ.js → chunk-4ALDX5IO.js} +5 -3
  21. package/dist/{chunk-5OKJDCBK.js → chunk-5PK53SAP.js} +5 -5
  22. package/dist/{chunk-U3AOJLH3.js → chunk-5ZPT5YAV.js} +8 -6
  23. package/dist/{chunk-YFTO7U2A.js → chunk-6YOXQVJ7.js} +3 -3
  24. package/dist/{chunk-J6ONZP74.js → chunk-6YY7XPPL.js} +5 -5
  25. package/dist/{chunk-WV7KJH2E.js → chunk-A5SAYFJ4.js} +1 -0
  26. package/dist/{chunk-B6XFBNYM.js → chunk-BOMSJUXW.js} +2 -2
  27. package/dist/{chunk-S7VDDJ34.js → chunk-CEOTK5GZ.js} +3 -3
  28. package/dist/{chunk-4F7J6UWD.js → chunk-EK3KVT7I.js} +515 -139
  29. package/dist/{chunk-HHEKVR6C.js → chunk-F5MFNUAA.js} +40 -2
  30. package/dist/{chunk-KVQX62XI.js → chunk-K7B25HO4.js} +3 -3
  31. package/dist/{chunk-JTNY5CK4.js → chunk-L5WGAIL2.js} +46 -46
  32. package/dist/chunk-NYBFYFK7.js +415 -0
  33. package/dist/{chunk-GIZQAOHZ.js → chunk-QX6QUZVD.js} +121 -91
  34. package/dist/{chunk-X2OTZ36G.js → chunk-RKPBIB2U.js} +52 -52
  35. package/dist/{chunk-W5PWGEKS.js → chunk-T3AYRQJZ.js} +107 -77
  36. package/dist/{chunk-D554YCHG.js → chunk-YKYEHDMX.js} +2 -2
  37. package/dist/connected-teams-RU6VATCM.js +1 -1
  38. package/dist/{coordinator-prompt-VQHQ3RIX.js → coordinator-prompt-HZCQZ6C5.js} +6 -6
  39. package/dist/{coordinator-prompt-TU6656OK.js → coordinator-prompt-J7DKHOCH.js} +3 -3
  40. package/dist/{global-workspace-PHF2MOGW.js → global-workspace-6LDUZ2NF.js} +3 -3
  41. package/dist/{global-workspace-47NZVA44.js → global-workspace-TI26K25J.js} +6 -6
  42. package/dist/index.cjs +1712 -721
  43. package/dist/index.d.cts +181 -41
  44. package/dist/index.d.ts +181 -41
  45. package/dist/index.js +693 -285
  46. package/dist/mcp/run-stdio.cjs +10469 -9896
  47. package/dist/mcp/run-stdio.js +193 -168
  48. package/dist/{orchestrator-VLTO5JBR.js → orchestrator-4JSG7BWC.js} +5 -5
  49. package/dist/{orchestrator-OCG4QVA5.js → orchestrator-5YU46YNS.js} +11 -10
  50. package/dist/{workspaces-I7TWFTJM.js → workspaces-QJ3XIPUJ.js} +6 -6
  51. package/dist/{workspaces-2XTDS7N2.js → workspaces-WOQHJFRQ.js} +3 -3
  52. package/dist/{worktree-DDDF3WHV.js → worktree-6U2FA5LO.js} +2 -2
  53. package/dist/{worktree-YASFE65H.js → worktree-KQA4ON2G.js} +5 -5
  54. package/package.json +4 -3
  55. /package/dist/{chunk-LDXSAVWO.js → chunk-GWFVCCJZ.js} +0 -0
@@ -20,7 +20,7 @@ import {
20
20
  resolveQuotaFallbackAgent,
21
21
  stripBrightsyNdjsonNoise,
22
22
  toolDescription
23
- } from "./chunk-ABPNIYRS.js";
23
+ } from "./chunk-3H7O27X2.js";
24
24
  import {
25
25
  titleFromPrompt
26
26
  } from "./chunk-7H655NEW.js";
@@ -51,7 +51,7 @@ import {
51
51
  stageAbsolutePathsAsAttachments,
52
52
  stageBuffersAsAttachments,
53
53
  syncWorkspacesFromThreads
54
- } from "./chunk-X2OTZ36G.js";
54
+ } from "./chunk-RKPBIB2U.js";
55
55
  import {
56
56
  addPrStackLayer,
57
57
  agentNicknameFromWorktreePath,
@@ -105,7 +105,19 @@ import {
105
105
  worktreeIdentityTitles,
106
106
  worktreeNameFromPath,
107
107
  worktreeSlugForTicket
108
- } from "./chunk-U3AOJLH3.js";
108
+ } from "./chunk-5ZPT5YAV.js";
109
+ import {
110
+ appendMessage,
111
+ createEmptyThread,
112
+ deleteThreadRecord,
113
+ findThreadByRef,
114
+ listThreads,
115
+ readThread,
116
+ setStatus,
117
+ updateThread,
118
+ withThreadLock,
119
+ writeThread
120
+ } from "./chunk-FWNL62VA.js";
109
121
  import {
110
122
  ensureWorktreeSideboardIgnored
111
123
  } from "./chunk-2P4XKWV2.js";
@@ -131,7 +143,7 @@ import {
131
143
  shouldRetryFailedAgentTurn,
132
144
  summarizeTurnStderr,
133
145
  turnFailChatText
134
- } from "./chunk-WV7KJH2E.js";
146
+ } from "./chunk-A5SAYFJ4.js";
135
147
  import {
136
148
  ATTACHMENTS_DIR,
137
149
  DETACHED_JOBS_DIR,
@@ -176,8 +188,9 @@ import {
176
188
  saveAppSettings,
177
189
  sumUsageList,
178
190
  updateAdvancedSettings,
179
- usageOnLimit
180
- } from "./chunk-6PFZ6XO7.js";
191
+ usageOnLimit,
192
+ withTurnScopedCost
193
+ } from "./chunk-2QUQH2SZ.js";
181
194
  import {
182
195
  stripNestedElectronEnv
183
196
  } from "./chunk-4TR3HZFT.js";
@@ -197,18 +210,6 @@ import {
197
210
  import {
198
211
  writePrivateFile
199
212
  } from "./chunk-JT7R45JB.js";
200
- import {
201
- appendMessage,
202
- createEmptyThread,
203
- deleteThreadRecord,
204
- findThreadByRef,
205
- listThreads,
206
- readThread,
207
- setStatus,
208
- updateThread,
209
- withThreadLock,
210
- writeThread
211
- } from "./chunk-FWNL62VA.js";
212
213
  import {
213
214
  annotateDevAccessRuns,
214
215
  appDataDir,
@@ -249,7 +250,11 @@ function pendingInjectedNotices(messages, match = isInjectedNoticeText) {
249
250
  function lastAgentReply(messages) {
250
251
  for (let i = messages.length - 1; i >= 0; i--) {
251
252
  const m = messages[i];
252
- if (m.role === "agent" && !isInjectedNoticeText(m.text)) return m;
253
+ if (m.role !== "agent") continue;
254
+ if (isInjectedNoticeText(m.text)) continue;
255
+ if (m.origin === "continue") continue;
256
+ if (isInternalAgentStatusText(m.text)) continue;
257
+ return m;
253
258
  }
254
259
  return void 0;
255
260
  }
@@ -297,6 +302,56 @@ function deriveTaskState(input) {
297
302
  }
298
303
  }
299
304
 
305
+ // src/mcp/wait-for-turn.ts
306
+ var MCP_WAIT_FOR_TURN_MAX_MS = 45e3;
307
+ function mcpWaitForTurnTimeoutMs(requested) {
308
+ const n = requested ?? MCP_WAIT_FOR_TURN_MAX_MS;
309
+ if (!Number.isFinite(n)) return MCP_WAIT_FOR_TURN_MAX_MS;
310
+ return Math.min(Math.max(1e3, Math.floor(n)), MCP_WAIT_FOR_TURN_MAX_MS);
311
+ }
312
+ var MCP_WAIT_STILL_RUNNING_HINT = "Child is still working. Call wait_for_turn again. Do not send_to_chat a check-in (that steers / interrupts) or assume a hang while progress is updating.";
313
+ var MCP_WAIT_QUEUED_HINT = "Child is queued waiting for a concurrency slot \u2014 it has not started yet. Call wait_for_turn again. Do not send_to_chat a check-in (that steers / interrupts), force_stop, or assume it failed to start.";
314
+ var MCP_WAIT_STOPPED_HINT = "Child was stopped before the turn finished. Do not treat this as success. send_to_chat to resume, or tell the user.";
315
+ var MCP_WAIT_BROKEN_HINT = "Child worktree is broken (missing on disk). Tell the user \u2014 do not treat this as success.";
316
+ var MCP_WAIT_ERROR_HINT = "Child turn failed. lastError/text is the failure \u2014 switch agent, tell the user, or retry. Do not treat empty text as success.";
317
+ var MCP_WAIT_INPUT_REQUIRED_HINT = "Child asked the user a question (ask_user). taskState is input-required. Wait for the user to answer in that chat \u2014 do not send_to_chat a check-in.";
318
+ function mcpWaitTaskHint(taskState, status) {
319
+ switch (taskState) {
320
+ case "submitted":
321
+ return MCP_WAIT_QUEUED_HINT;
322
+ case "working":
323
+ return MCP_WAIT_STILL_RUNNING_HINT;
324
+ case "input-required":
325
+ return MCP_WAIT_INPUT_REQUIRED_HINT;
326
+ case "canceled":
327
+ return MCP_WAIT_STOPPED_HINT;
328
+ case "failed":
329
+ return status === "broken" ? MCP_WAIT_BROKEN_HINT : MCP_WAIT_ERROR_HINT;
330
+ default:
331
+ return void 0;
332
+ }
333
+ }
334
+ function nonemptyIso(value) {
335
+ const trimmed = value?.trim();
336
+ return trimmed ? trimmed : null;
337
+ }
338
+ function lastActivityAtForWait(stillRunning, liveUpdatedAt, fallbacks) {
339
+ if (stillRunning) return nonemptyIso(liveUpdatedAt);
340
+ for (const value of fallbacks) {
341
+ const iso = nonemptyIso(value);
342
+ if (iso) return iso;
343
+ }
344
+ return null;
345
+ }
346
+ function waitForTurnToolResult(input) {
347
+ return {
348
+ ...input,
349
+ usage: input.usage ?? null,
350
+ hint: mcpWaitTaskHint(input.taskState, input.status),
351
+ incomplete: needsCoordinatorAction(input.taskState)
352
+ };
353
+ }
354
+
300
355
  // src/orchestrator/orchestrator.ts
301
356
  import { randomUUID as randomUUID5 } from "crypto";
302
357
  import { existsSync as existsSync18 } from "fs";
@@ -457,9 +512,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
457
512
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
458
513
  );
459
514
  }
460
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-47NZVA44.js");
515
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-TI26K25J.js");
461
516
  if (isGlobalThread2(thread)) {
462
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-VQHQ3RIX.js");
517
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-HZCQZ6C5.js");
463
518
  ensureGlobalCoordinatorCwd2(
464
519
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
465
520
  );
@@ -573,8 +628,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
573
628
  continue;
574
629
  }
575
630
  if (parsed.type === "usage") {
576
- usage = applyTurnUsage(usage, parsed.data, parsed.scope ?? "request");
577
- outbound.push(parsed);
631
+ const data = parsed.scope === "turn" ? withTurnScopedCost(parsed.data, thread.messages) : parsed.data;
632
+ usage = applyTurnUsage(usage, data, parsed.scope ?? "request");
633
+ outbound.push({ ...parsed, data });
578
634
  continue;
579
635
  }
580
636
  if (parsed.type === "stdout") {
@@ -1876,38 +1932,6 @@ import {
1876
1932
  writeFileSync as writeFileSync3
1877
1933
  } from "fs";
1878
1934
  import { dirname as dirname3, join as join5 } from "path";
1879
-
1880
- // src/mcp/wait-for-turn.ts
1881
- var MCP_WAIT_FOR_TURN_MAX_MS = 45e3;
1882
- function mcpWaitForTurnTimeoutMs(requested) {
1883
- const n = requested ?? MCP_WAIT_FOR_TURN_MAX_MS;
1884
- if (!Number.isFinite(n)) return MCP_WAIT_FOR_TURN_MAX_MS;
1885
- return Math.min(Math.max(1e3, Math.floor(n)), MCP_WAIT_FOR_TURN_MAX_MS);
1886
- }
1887
- var MCP_WAIT_STILL_RUNNING_HINT = "Child is still working. Call wait_for_turn again. Do not send_to_thread a check-in (that steers / interrupts) or assume a hang while progress is updating.";
1888
- var MCP_WAIT_QUEUED_HINT = "Child is queued waiting for a concurrency slot \u2014 it has not started yet. Call wait_for_turn again. Do not send_to_thread a check-in (that steers / interrupts), force_stop, or assume it failed to start.";
1889
- var MCP_WAIT_STOPPED_HINT = "Child was stopped before the turn finished. Do not treat this as success. send_to_thread to resume, or tell the user.";
1890
- var MCP_WAIT_BROKEN_HINT = "Child worktree is broken (missing on disk). Tell the user \u2014 do not treat this as success.";
1891
- var MCP_WAIT_ERROR_HINT = "Child turn failed. lastError/text is the failure \u2014 switch agent, tell the user, or retry. Do not treat empty text as success.";
1892
- var MCP_WAIT_INPUT_REQUIRED_HINT = "Child asked the user a question (ask_user). taskState is input-required. Wait for the user to answer in that chat \u2014 do not send_to_thread a check-in.";
1893
- function mcpWaitTaskHint(taskState, status) {
1894
- switch (taskState) {
1895
- case "submitted":
1896
- return MCP_WAIT_QUEUED_HINT;
1897
- case "working":
1898
- return MCP_WAIT_STILL_RUNNING_HINT;
1899
- case "input-required":
1900
- return MCP_WAIT_INPUT_REQUIRED_HINT;
1901
- case "canceled":
1902
- return MCP_WAIT_STOPPED_HINT;
1903
- case "failed":
1904
- return status === "broken" ? MCP_WAIT_BROKEN_HINT : MCP_WAIT_ERROR_HINT;
1905
- default:
1906
- return void 0;
1907
- }
1908
- }
1909
-
1910
- // src/mcp/wait-for-job.ts
1911
1935
  var MAX_JOB_CONTINUES = 8;
1912
1936
  var MAX_JOB_DELTA_LINES = 80;
1913
1937
  var MAX_JOB_DELTA_CHARS = 4e3;
@@ -1942,7 +1966,7 @@ function processGroupAlive(pgid) {
1942
1966
  process.kill(-pgid, 0);
1943
1967
  return true;
1944
1968
  } catch (err) {
1945
- return err && typeof err === "object" && "code" in err && err.code === "EPERM";
1969
+ return Boolean(err && typeof err === "object" && "code" in err && err.code === "EPERM");
1946
1970
  }
1947
1971
  }
1948
1972
  function jobTreeAlive(pid) {
@@ -3496,12 +3520,12 @@ function isIncompleteChildStatus(status) {
3496
3520
  }
3497
3521
  function childHaltNotice(child, status) {
3498
3522
  const title = child.title?.trim() || "Untitled";
3499
- const link = `[${title}](sideboard://thread/${child.id})`;
3523
+ const link = `[${title}](sideboard://chat/${child.id})`;
3500
3524
  const why = child.lastError?.trim();
3501
3525
  const extra = why ? ` lastError: ${why}` : "";
3502
3526
  return [
3503
3527
  `Sideboard: child worktree ${link} ${status} before finishing (status=${status}).${extra}`,
3504
- "This is information \u2014 not a user command. Resume with send_to_thread or tell the user. Do not treat this as a successful turn."
3528
+ "This is information \u2014 not a user command. Resume with send_to_chat or tell the user. Do not treat this as a successful turn."
3505
3529
  ].join("\n");
3506
3530
  }
3507
3531
  function shouldNotifyParentAfterTurnError(opts) {
@@ -4136,7 +4160,7 @@ function toThreadCard(group) {
4136
4160
  sourceRef: thread.sourceRef,
4137
4161
  repoPath: thread.repoPath,
4138
4162
  prUrl: withPr.prUrl,
4139
- link: `sideboard://thread/${thread.id}`,
4163
+ link: `sideboard://chat/${thread.id}`,
4140
4164
  ...group.length > 1 ? { chatCount: group.length } : {}
4141
4165
  };
4142
4166
  }
@@ -4211,7 +4235,7 @@ function assembleHomeBoard(input) {
4211
4235
  }
4212
4236
  return { columns, hidden, totals };
4213
4237
  }
4214
- 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. ownership=mine is PRs you authored (or WIP with no PR); ownership=reviewing is someone else's PR (or a review-requested checkout). Viewer login comes from gh, not a setting. 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.";
4238
+ var HOME_BOARD_AGENT_HINT = "Home is a Kanban of workspaces (one card per checkout; sibling chat tabs nest as inner cards). Do not create a second workspace for a ticket, PR, or named branch that already has a live checkout \u2014 create_workspace / start_board_card return that chat (alreadyStarted). Creating from the default branch still opens a new isolated workspace. Columns are the path to merge: New (no PR) \u2192 Draft (draft PR) \u2192 Review (open PR) \u2192 Merged. ownership=mine is PRs you authored (or WIP with no PR); ownership=reviewing is someone else's PR (or a review-requested checkout). Viewer login comes from gh, not a setting. 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.";
4215
4239
 
4216
4240
  // src/threads/create.ts
4217
4241
  function persistCreateAttachments(worktreePath, attachments) {
@@ -4266,7 +4290,7 @@ async function createThread(input, _onSetupLine) {
4266
4290
  });
4267
4291
  await requireAgent(resolved.agent);
4268
4292
  if (input.cowboy) {
4269
- const { cowboyModeEnabled } = await import("./app-settings-VQEUCONM.js");
4293
+ const { cowboyModeEnabled } = await import("./app-settings-RKFFUIFQ.js");
4270
4294
  if (!cowboyModeEnabled()) {
4271
4295
  throw new Error(
4272
4296
  "Cowboy mode is off. Enable it in Settings \u2192 Advanced."
@@ -4324,7 +4348,7 @@ async function createThread(input, _onSetupLine) {
4324
4348
  let sourceIsFork = false;
4325
4349
  if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
4326
4350
  if (isAbleTimeConnected() && getIssueSource() === "abletime") {
4327
- const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-CDGINDXG.js");
4351
+ const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-U75ZGDIX.js");
4328
4352
  const task = await ensureAbleTimeTask({
4329
4353
  title: title?.trim() || "Untitled work",
4330
4354
  description: input.prompt?.trim() || void 0
@@ -4434,7 +4458,7 @@ async function createThread(input, _onSetupLine) {
4434
4458
  return readThread(thread.id) ?? thread;
4435
4459
  }
4436
4460
  async function listLinearIssues(agent, repoPath) {
4437
- const { getAdapter: getAdapter2 } = await import("./agents-J2P4KNEY.js");
4461
+ const { getAdapter: getAdapter2 } = await import("./agents-3TUMFSMH.js");
4438
4462
  await requireAgent(agent, { requireLinear: true });
4439
4463
  const adapter = getAdapter2(agent);
4440
4464
  if (!adapter.listLinearIssues) {
@@ -4647,7 +4671,7 @@ async function forkThreadWorktree(input, onSetupLine) {
4647
4671
  const from = requireThread2(input.threadId);
4648
4672
  if (isOrchestratorThread(from)) {
4649
4673
  throw new Error(
4650
- "fork_worktree targets a worktree agent thread (not the orchestrator). Pass a child/worktree thread ref."
4674
+ "fork_workspace targets a worktree agent thread (not the orchestrator). Pass a child/worktree thread ref."
4651
4675
  );
4652
4676
  }
4653
4677
  if (!from.branchName?.trim() || !from.repoPath?.trim()) {
@@ -4763,7 +4787,7 @@ function planOrchestrationQuotaFailover(thread, limitText, opts) {
4763
4787
  }
4764
4788
  function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
4765
4789
  const children = listThreads({ includeArchived: false }).filter((t) => t.parentThreadId === from.id && t.status !== "archived").slice(0, 40).map(
4766
- (t) => `- ${t.title} \xB7 ${t.status} \xB7 ${t.agent} \xB7 sideboard://thread/${t.id}`
4790
+ (t) => `- ${t.title} \xB7 ${t.status} \xB7 ${t.agent} \xB7 sideboard://chat/${t.id}`
4767
4791
  );
4768
4792
  const recent = from.messages.slice(-8).map((m) => {
4769
4793
  const role = m.role === "user" ? "User" : m.role === "agent" ? "Agent" : "Summary";
@@ -4773,7 +4797,7 @@ function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
4773
4797
  const orch = isOrchestratorThread(from);
4774
4798
  const instructions = orch ? [
4775
4799
  "- Continue fleet orchestration from this handoff.",
4776
- "- Prefer Sideboard MCP (list_board, list_threads, get_thread, send_to_thread, \u2026) for live status.",
4800
+ "- Prefer Sideboard MCP (list_board, list_chats, get_chat, send_to_chat, \u2026) for live status.",
4777
4801
  "- Leave model Auto unless there is a specific reason to pin one.",
4778
4802
  `- Do not wait on the limited ${from.agent} account; keep going on ${fallbackAgent}.`
4779
4803
  ] : [
@@ -4792,7 +4816,7 @@ function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
4792
4816
  from.sourceRef?.trim() || "(none)",
4793
4817
  "",
4794
4818
  `## Child threads`,
4795
- children.length ? children.join("\n") : "(none listed \u2014 call list_threads)",
4819
+ children.length ? children.join("\n") : "(none listed \u2014 call list_chats)",
4796
4820
  "",
4797
4821
  `## Recent turns (truncated)`,
4798
4822
  recent.length ? recent.join("\n") : "(none)",
@@ -4941,7 +4965,7 @@ async function adoptThread(input) {
4941
4965
  messages: input.messages ?? []
4942
4966
  });
4943
4967
  writeThread(thread);
4944
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-I7TWFTJM.js");
4968
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-QJ3XIPUJ.js");
4945
4969
  await ensureWorkspace2(repoPath);
4946
4970
  const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-RXZPTCNH.js");
4947
4971
  await ensureWorktreeSideboardIgnored2(input.worktreePath);
@@ -6897,18 +6921,18 @@ function formatWorktreeDirective(thread, opts) {
6897
6921
  const dir = worktreeNameFromPath(thread.worktreePath);
6898
6922
  const lines = [
6899
6923
  "Sideboard workspace (mandatory):",
6900
- `- Worktree (your only working directory): ${worktree}`,
6924
+ `- Workspace cwd (git worktree; your only working directory): ${worktree}`,
6901
6925
  `- Branch: ${thread.branchName}`,
6902
6926
  `- Worktree folder nickname (stable, do not rename): ${dir}`
6903
6927
  ];
6904
6928
  if (worktree && repo && worktree !== repo) {
6905
6929
  lines.push(`- Main repo checkout (do NOT edit application code here): ${repo}`);
6906
6930
  lines.push(
6907
- "Stay inside the worktree for all Reads, Edits, Writes, installs, tests, and git commands. The main repo is a separate checkout used as the git base/remote \u2014 changing files there breaks isolation for this thread and other worktrees."
6931
+ "Stay inside this workspace for all Reads, Edits, Writes, installs, tests, and git commands. The main repo is a separate checkout used as the git base/remote \u2014 changing files there breaks isolation for this workspace and other checkouts."
6908
6932
  );
6909
6933
  } else {
6910
6934
  lines.push(
6911
- "All file operations and shell commands must use this worktree as cwd. Do not switch to another checkout."
6935
+ "All file operations and shell commands must use this workspace as cwd. Do not switch to another checkout."
6912
6936
  );
6913
6937
  }
6914
6938
  lines.push("");
@@ -6921,7 +6945,7 @@ function formatWorktreeDirective(thread, opts) {
6921
6945
  "- PR title/body and commit messages state what the change does and why (inspect the diff/commits and the user request) \u2014 never the worktree nickname or placeholder branch. Concise imperative title (Conventional Commits when it fits: feat:/fix:/chore:/docs:); body = intent, key changes, test notes."
6922
6946
  );
6923
6947
  lines.push(
6924
- "- Stay on this thread branch. Never push to main/master or merge locally into the main checkout. Merge the PR only when this turn is a Merge PR request or the user explicitly asked \u2014 via GitHub from this worktree (`gh pr merge` / `gh stack merge`)."
6948
+ "- Stay on this workspace branch. Never push to main/master or merge locally into the main checkout. Merge the PR only when this turn is a Merge PR request or the user explicitly asked \u2014 via GitHub from this worktree (`gh pr merge` / `gh stack merge`)."
6925
6949
  );
6926
6950
  if (thread.prUrl) {
6927
6951
  lines.push(
@@ -6941,14 +6965,14 @@ function formatWorktreeDirective(thread, opts) {
6941
6965
  lines.push(formatDevAccessHint(opts?.activeRuns));
6942
6966
  lines.push("");
6943
6967
  lines.push(
6944
- "Schedules: `create_schedule` / `list_schedules` (`at` / `every` / `cron`). `threadId=self` continues this chat; omit threadId for a new Global chat. Fires only while Sideboard.app is running. A future job turns on Settings \u2192 Advanced \u2192 Caffeinate while schedules are enabled."
6968
+ "Schedules: `create_schedule` / `list_schedules` (`at` / `every` / `cron`). `chatId=self` continues this chat; omit chatId for a new Global chat. Fires only while Sideboard.app is running. A future job turns on Settings \u2192 Advanced \u2192 Caffeinate while schedules are enabled."
6945
6969
  );
6946
6970
  lines.push("");
6947
6971
  lines.push(formatProcessGuideDirective({ worktreePath: thread.worktreePath }));
6948
6972
  return lines.join("\n");
6949
6973
  }
6950
6974
  function formatWorktreeReminder() {
6951
- return "Sideboard worktree: stay in this cwd for all file and git work. Push and open PRs against origin, never upstream. Do not edit the main repo checkout. If a goal is given (Greptile 5/5, CI green), watch-fix-push until it lands \u2014 do not watch after every push. Schedules: create_schedule (at / every / cron; threadId=self for this chat).";
6975
+ return "Sideboard workspace: stay in this cwd for all file and git work. Push and open PRs against origin, never upstream. Do not edit the main repo checkout. If a goal is given (Greptile 5/5, CI green), watch-fix-push until it lands \u2014 do not watch after every push. Schedules: create_schedule (at / every / cron; chatId=self for this chat).";
6952
6976
  }
6953
6977
  var PR_GOAL_RE = /greptile|\bci\b.*\b(green|pass)|checks?\s+(pass|green)|until\s+.*\b(pass|green|merge|clean)|\bfix ci\b|watch[- ]fix[- ]push/i;
6954
6978
  function mentionsPrGoal(prompt) {
@@ -7634,7 +7658,7 @@ function formatScheduledPrompt(name, prompt) {
7634
7658
  ${prompt}`;
7635
7659
  }
7636
7660
  async function defaultDeps() {
7637
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-OCG4QVA5.js");
7661
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-5YU46YNS.js");
7638
7662
  const orch = getOrchestrator2();
7639
7663
  return {
7640
7664
  findThread: (id) => findThreadByRef(id),
@@ -7952,7 +7976,7 @@ var Orchestrator = class {
7952
7976
  orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
7953
7977
  });
7954
7978
  }
7955
- const { autoCleanupOrphansEnabled } = await import("./app-settings-VQEUCONM.js");
7979
+ const { autoCleanupOrphansEnabled } = await import("./app-settings-RKFFUIFQ.js");
7956
7980
  if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
7957
7981
  await cleanupOrphanWorktrees({ repoPaths });
7958
7982
  }
@@ -8167,7 +8191,7 @@ var Orchestrator = class {
8167
8191
  try {
8168
8192
  appendMessage(threadId, {
8169
8193
  role: "agent",
8170
- text: `Session limit on ${thread.agent}. Sideboard continued on account \u201C${plan.fallbackAccountLabel}\u201D in [${next.title}](sideboard://thread/${next.id}).`,
8194
+ text: `Session limit on ${thread.agent}. Sideboard continued on account \u201C${plan.fallbackAccountLabel}\u201D in [${next.title}](sideboard://chat/${next.id}).`,
8171
8195
  ts: (/* @__PURE__ */ new Date()).toISOString()
8172
8196
  });
8173
8197
  this.emit({
@@ -8210,7 +8234,7 @@ var Orchestrator = class {
8210
8234
  try {
8211
8235
  appendMessage(threadId, {
8212
8236
  role: "agent",
8213
- text: `Session limit on ${thread.agent}. Sideboard continued on ${plan.fallbackAgent} (Auto) in [${next.title}](sideboard://thread/${next.id}).`,
8237
+ text: `Session limit on ${thread.agent}. Sideboard continued on ${plan.fallbackAgent} (Auto) in [${next.title}](sideboard://chat/${next.id}).`,
8214
8238
  ts: (/* @__PURE__ */ new Date()).toISOString()
8215
8239
  });
8216
8240
  this.emit({
@@ -8341,7 +8365,7 @@ var Orchestrator = class {
8341
8365
  }
8342
8366
  await setup;
8343
8367
  if (skipSetup) return;
8344
- const { autoRunAfterSetupEnabled } = await import("./app-settings-VQEUCONM.js");
8368
+ const { autoRunAfterSetupEnabled } = await import("./app-settings-RKFFUIFQ.js");
8345
8369
  if (autoRunAfterSetupEnabled()) {
8346
8370
  try {
8347
8371
  await this.startDev(threadId);
@@ -8720,7 +8744,7 @@ var Orchestrator = class {
8720
8744
  }
8721
8745
  const isBrightsy = fresh.agent === "brightsy";
8722
8746
  const isOrchestration = isOrchestratorThread(fresh);
8723
- const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-VQEUCONM.js");
8747
+ const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-RKFFUIFQ.js");
8724
8748
  const gitAuthMode = getGithubGitAuthMode();
8725
8749
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
8726
8750
  githubSlug: await withTimeout(
@@ -9769,9 +9793,10 @@ var Orchestrator = class {
9769
9793
  const thread = this.healStaleReportedActivity(this.requireThread(threadRef));
9770
9794
  const lastAgent = lastAgentReply(thread.messages);
9771
9795
  const lastError = thread.lastError ?? null;
9772
- const rawText = (lastAgent?.text ?? "").trim();
9773
- const text = (rawText && !isInternalAgentStatusText(rawText) ? rawText : "") || (thread.status === "error" || thread.status === "stopped" || thread.status === "broken" ? lastError ?? "" : "");
9774
9796
  const stillRunning = this.threadLooksLive(thread);
9797
+ const rawText = (lastAgent?.text ?? "").trim();
9798
+ const finishedText = (rawText && !isInternalAgentStatusText(rawText) ? rawText : "") || (thread.status === "error" || thread.status === "stopped" || thread.status === "broken" ? lastError ?? "" : "");
9799
+ const text = stillRunning ? "" : finishedText;
9775
9800
  const live = stillRunning ? readTurnLive(thread.id) : null;
9776
9801
  const liveSummary = live?.summary && !isInternalAgentStatusText(live.summary) ? live.summary : null;
9777
9802
  const queuedHint = stillRunning && thread.status === "queued" && !liveSummary ? "Queued \u2014 waiting for a concurrency slot" : null;
@@ -9788,8 +9813,12 @@ var Orchestrator = class {
9788
9813
  lastError,
9789
9814
  stillRunning,
9790
9815
  progress: liveSummary ?? queuedHint,
9791
- lastActivityAt: live?.updatedAt ?? null,
9792
- usage: lastAgent?.usage ?? null
9816
+ lastActivityAt: lastActivityAtForWait(stillRunning, live?.updatedAt, [
9817
+ thread.messages.at(-1)?.ts,
9818
+ lastAgent?.ts,
9819
+ thread.updatedAt
9820
+ ]),
9821
+ usage: stillRunning ? null : lastAgent?.usage ?? null
9793
9822
  };
9794
9823
  }
9795
9824
  assertNotGlobal(thread, action) {
@@ -10025,7 +10054,7 @@ var Orchestrator = class {
10025
10054
  if (Object.keys(patch).length === 0) continue;
10026
10055
  updateThread(t.id, patch);
10027
10056
  }
10028
- const { autoArchiveOnMergeEnabled } = await import("./app-settings-VQEUCONM.js");
10057
+ const { autoArchiveOnMergeEnabled } = await import("./app-settings-RKFFUIFQ.js");
10029
10058
  const latest = this.requireThread(thread.id);
10030
10059
  if (!shouldAutoArchiveOnPrMerge({
10031
10060
  previousPrState: prevState || null,
@@ -10316,7 +10345,7 @@ var Orchestrator = class {
10316
10345
  this.enforceHistoryRetention();
10317
10346
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
10318
10347
  try {
10319
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-I7TWFTJM.js");
10348
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-QJ3XIPUJ.js");
10320
10349
  await ensureWorkspace2(thread.repoPath);
10321
10350
  } catch {
10322
10351
  }
@@ -10343,7 +10372,7 @@ var Orchestrator = class {
10343
10372
  await runArchiveScript(thread.repoPath, thread.worktreePath);
10344
10373
  } catch {
10345
10374
  }
10346
- const { deleteBranchOnPurgeEnabled } = await import("./app-settings-VQEUCONM.js");
10375
+ const { deleteBranchOnPurgeEnabled } = await import("./app-settings-RKFFUIFQ.js");
10347
10376
  const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
10348
10377
  await removeWorktree(thread.repoPath, thread.worktreePath, {
10349
10378
  deleteBranch: deleteBranch ? thread.branchName : void 0
@@ -10370,7 +10399,7 @@ var Orchestrator = class {
10370
10399
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
10371
10400
  );
10372
10401
  }
10373
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-YASFE65H.js");
10402
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-KQA4ON2G.js");
10374
10403
  const slug = thread.worktreePath.split("/").pop();
10375
10404
  const dest = thread.worktreePath;
10376
10405
  await withRepoGitLock(thread.repoPath, async () => {
@@ -10480,7 +10509,7 @@ async function startOrchestration(opts) {
10480
10509
  sourceRef: "default",
10481
10510
  ...createOpts
10482
10511
  }).catch(async () => {
10483
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-YASFE65H.js");
10512
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-KQA4ON2G.js");
10484
10513
  const repo = await resolveRepoRoot2(repoPath);
10485
10514
  const def = await resolveDefaultBranch2(repo);
10486
10515
  return orch.createThread({
@@ -10566,6 +10595,9 @@ export {
10566
10595
  needsCoordinatorAction,
10567
10596
  endedOnAskUser,
10568
10597
  deriveTaskState,
10598
+ mcpWaitForTurnTimeoutMs,
10599
+ mcpWaitTaskHint,
10600
+ waitForTurnToolResult,
10569
10601
  applyPromptCacheTtlEnv,
10570
10602
  spawnAgentTurn,
10571
10603
  AGENT_GIT_ACTIONS,
@@ -10637,8 +10669,6 @@ export {
10637
10669
  worktreeRunPortsPath,
10638
10670
  loadWorktreeRunPorts,
10639
10671
  saveWorktreeRunPorts,
10640
- mcpWaitForTurnTimeoutMs,
10641
- mcpWaitTaskHint,
10642
10672
  mcpWaitForJobTimeoutMs,
10643
10673
  waitForDetachedJob,
10644
10674
  stopDetachedJob,