@sideboard-ai/core 0.1.262 → 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
@@ -44,7 +44,7 @@ import {
44
44
  summarizeTurnStderr,
45
45
  toolDescription,
46
46
  turnFailChatText
47
- } from "./chunk-4F7J6UWD.js";
47
+ } from "./chunk-EK3KVT7I.js";
48
48
  import {
49
49
  SLACK_REPLY_FORMATTING,
50
50
  addWorkspace,
@@ -67,7 +67,7 @@ import {
67
67
  stageAbsolutePathsAsAttachments,
68
68
  stageBuffersAsAttachments,
69
69
  syncWorkspacesFromThreads
70
- } from "./chunk-JTNY5CK4.js";
70
+ } from "./chunk-L5WGAIL2.js";
71
71
  import {
72
72
  addPrStackLayer,
73
73
  agentNicknameFromWorktreePath,
@@ -121,7 +121,7 @@ import {
121
121
  worktreeIdentityTitles,
122
122
  worktreeNameFromPath,
123
123
  worktreeSlugForTicket
124
- } from "./chunk-FSZ7YYFQ.js";
124
+ } from "./chunk-4ALDX5IO.js";
125
125
  import {
126
126
  ATTACHMENTS_DIR,
127
127
  DETACHED_JOBS_DIR,
@@ -171,8 +171,9 @@ import {
171
171
  resolveViewerProfileForRepo,
172
172
  sumUsageList,
173
173
  updateAdvancedSettings,
174
- usageOnLimit
175
- } from "./chunk-VIC6TDYT.js";
174
+ usageOnLimit,
175
+ withTurnScopedCost
176
+ } from "./chunk-36FOBJBF.js";
176
177
  import {
177
178
  writePrivateFile
178
179
  } from "./chunk-NSTQ6QKD.js";
@@ -241,7 +242,11 @@ function pendingInjectedNotices(messages, match = isInjectedNoticeText) {
241
242
  function lastAgentReply(messages) {
242
243
  for (let i = messages.length - 1; i >= 0; i--) {
243
244
  const m = messages[i];
244
- if (m.role === "agent" && !isInjectedNoticeText(m.text)) return m;
245
+ if (m.role !== "agent") continue;
246
+ if (isInjectedNoticeText(m.text)) continue;
247
+ if (m.origin === "continue") continue;
248
+ if (isInternalAgentStatusText(m.text)) continue;
249
+ return m;
245
250
  }
246
251
  return void 0;
247
252
  }
@@ -286,6 +291,56 @@ function deriveTaskState(input) {
286
291
  }
287
292
  }
288
293
 
294
+ // src/mcp/wait-for-turn.ts
295
+ var MCP_WAIT_FOR_TURN_MAX_MS = 45e3;
296
+ function mcpWaitForTurnTimeoutMs(requested) {
297
+ const n = requested ?? MCP_WAIT_FOR_TURN_MAX_MS;
298
+ if (!Number.isFinite(n)) return MCP_WAIT_FOR_TURN_MAX_MS;
299
+ return Math.min(Math.max(1e3, Math.floor(n)), MCP_WAIT_FOR_TURN_MAX_MS);
300
+ }
301
+ 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.";
302
+ 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.";
303
+ 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.";
304
+ var MCP_WAIT_BROKEN_HINT = "Child worktree is broken (missing on disk). Tell the user \u2014 do not treat this as success.";
305
+ 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.";
306
+ 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.";
307
+ function mcpWaitTaskHint(taskState, status) {
308
+ switch (taskState) {
309
+ case "submitted":
310
+ return MCP_WAIT_QUEUED_HINT;
311
+ case "working":
312
+ return MCP_WAIT_STILL_RUNNING_HINT;
313
+ case "input-required":
314
+ return MCP_WAIT_INPUT_REQUIRED_HINT;
315
+ case "canceled":
316
+ return MCP_WAIT_STOPPED_HINT;
317
+ case "failed":
318
+ return status === "broken" ? MCP_WAIT_BROKEN_HINT : MCP_WAIT_ERROR_HINT;
319
+ default:
320
+ return void 0;
321
+ }
322
+ }
323
+ function nonemptyIso(value) {
324
+ const trimmed = value?.trim();
325
+ return trimmed ? trimmed : null;
326
+ }
327
+ function lastActivityAtForWait(stillRunning, liveUpdatedAt, fallbacks) {
328
+ if (stillRunning) return nonemptyIso(liveUpdatedAt);
329
+ for (const value of fallbacks) {
330
+ const iso = nonemptyIso(value);
331
+ if (iso) return iso;
332
+ }
333
+ return null;
334
+ }
335
+ function waitForTurnToolResult(input) {
336
+ return {
337
+ ...input,
338
+ usage: input.usage ?? null,
339
+ hint: mcpWaitTaskHint(input.taskState, input.status),
340
+ incomplete: needsCoordinatorAction(input.taskState)
341
+ };
342
+ }
343
+
289
344
  // src/orchestrator/orchestrator.ts
290
345
  import { randomUUID as randomUUID5 } from "crypto";
291
346
  import { existsSync as existsSync18 } from "fs";
@@ -505,9 +560,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
505
560
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
506
561
  );
507
562
  }
508
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-PHF2MOGW.js");
563
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-6LDUZ2NF.js");
509
564
  if (isGlobalThread2(thread)) {
510
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-TU6656OK.js");
565
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-J7DKHOCH.js");
511
566
  ensureGlobalCoordinatorCwd2(
512
567
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
513
568
  );
@@ -621,8 +676,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
621
676
  continue;
622
677
  }
623
678
  if (parsed.type === "usage") {
624
- usage = applyTurnUsage(usage, parsed.data, parsed.scope ?? "request");
625
- outbound.push(parsed);
679
+ const data = parsed.scope === "turn" ? withTurnScopedCost(parsed.data, thread.messages) : parsed.data;
680
+ usage = applyTurnUsage(usage, data, parsed.scope ?? "request");
681
+ outbound.push({ ...parsed, data });
626
682
  continue;
627
683
  }
628
684
  if (parsed.type === "stdout") {
@@ -1871,38 +1927,6 @@ import {
1871
1927
  writeFileSync as writeFileSync3
1872
1928
  } from "fs";
1873
1929
  import { dirname as dirname3, join as join5 } from "path";
1874
-
1875
- // src/mcp/wait-for-turn.ts
1876
- var MCP_WAIT_FOR_TURN_MAX_MS = 45e3;
1877
- function mcpWaitForTurnTimeoutMs(requested) {
1878
- const n = requested ?? MCP_WAIT_FOR_TURN_MAX_MS;
1879
- if (!Number.isFinite(n)) return MCP_WAIT_FOR_TURN_MAX_MS;
1880
- return Math.min(Math.max(1e3, Math.floor(n)), MCP_WAIT_FOR_TURN_MAX_MS);
1881
- }
1882
- 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.";
1883
- 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.";
1884
- 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.";
1885
- var MCP_WAIT_BROKEN_HINT = "Child worktree is broken (missing on disk). Tell the user \u2014 do not treat this as success.";
1886
- 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.";
1887
- 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.";
1888
- function mcpWaitTaskHint(taskState, status) {
1889
- switch (taskState) {
1890
- case "submitted":
1891
- return MCP_WAIT_QUEUED_HINT;
1892
- case "working":
1893
- return MCP_WAIT_STILL_RUNNING_HINT;
1894
- case "input-required":
1895
- return MCP_WAIT_INPUT_REQUIRED_HINT;
1896
- case "canceled":
1897
- return MCP_WAIT_STOPPED_HINT;
1898
- case "failed":
1899
- return status === "broken" ? MCP_WAIT_BROKEN_HINT : MCP_WAIT_ERROR_HINT;
1900
- default:
1901
- return void 0;
1902
- }
1903
- }
1904
-
1905
- // src/mcp/wait-for-job.ts
1906
1930
  var MAX_JOB_CONTINUES = 8;
1907
1931
  var MAX_JOB_DELTA_LINES = 80;
1908
1932
  var MAX_JOB_DELTA_CHARS = 4e3;
@@ -1937,7 +1961,7 @@ function processGroupAlive(pgid) {
1937
1961
  process.kill(-pgid, 0);
1938
1962
  return true;
1939
1963
  } catch (err) {
1940
- return err && typeof err === "object" && "code" in err && err.code === "EPERM";
1964
+ return Boolean(err && typeof err === "object" && "code" in err && err.code === "EPERM");
1941
1965
  }
1942
1966
  }
1943
1967
  function jobTreeAlive(pid) {
@@ -3437,12 +3461,12 @@ function isIncompleteChildStatus(status) {
3437
3461
  }
3438
3462
  function childHaltNotice(child, status) {
3439
3463
  const title = child.title?.trim() || "Untitled";
3440
- const link = `[${title}](sideboard://thread/${child.id})`;
3464
+ const link = `[${title}](sideboard://chat/${child.id})`;
3441
3465
  const why = child.lastError?.trim();
3442
3466
  const extra = why ? ` lastError: ${why}` : "";
3443
3467
  return [
3444
3468
  `Sideboard: child worktree ${link} ${status} before finishing (status=${status}).${extra}`,
3445
- "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."
3469
+ "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."
3446
3470
  ].join("\n");
3447
3471
  }
3448
3472
  function shouldNotifyParentAfterTurnError(opts) {
@@ -3939,7 +3963,7 @@ function toThreadCard(group) {
3939
3963
  sourceRef: thread.sourceRef,
3940
3964
  repoPath: thread.repoPath,
3941
3965
  prUrl: withPr.prUrl,
3942
- link: `sideboard://thread/${thread.id}`,
3966
+ link: `sideboard://chat/${thread.id}`,
3943
3967
  ...group.length > 1 ? { chatCount: group.length } : {}
3944
3968
  };
3945
3969
  }
@@ -4014,7 +4038,7 @@ function assembleHomeBoard(input) {
4014
4038
  }
4015
4039
  return { columns, hidden, totals };
4016
4040
  }
4017
- 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.";
4041
+ 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.";
4018
4042
 
4019
4043
  // src/threads/create.ts
4020
4044
  function persistCreateAttachments(worktreePath, attachments) {
@@ -4069,7 +4093,7 @@ async function createThread(input, _onSetupLine) {
4069
4093
  });
4070
4094
  await requireAgent(resolved.agent);
4071
4095
  if (input.cowboy) {
4072
- const { cowboyModeEnabled } = await import("./app-settings-OM7H64YM.js");
4096
+ const { cowboyModeEnabled } = await import("./app-settings-MVZPM6WW.js");
4073
4097
  if (!cowboyModeEnabled()) {
4074
4098
  throw new Error(
4075
4099
  "Cowboy mode is off. Enable it in Settings \u2192 Advanced."
@@ -4127,7 +4151,7 @@ async function createThread(input, _onSetupLine) {
4127
4151
  let sourceIsFork = false;
4128
4152
  if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
4129
4153
  if (isAbleTimeConnected() && getIssueSource() === "abletime") {
4130
- const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-OQ4PC52L.js");
4154
+ const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-6AOJI2YZ.js");
4131
4155
  const task = await ensureAbleTimeTask({
4132
4156
  title: title?.trim() || "Untitled work",
4133
4157
  description: input.prompt?.trim() || void 0
@@ -4438,7 +4462,7 @@ async function forkThreadWorktree(input, onSetupLine) {
4438
4462
  const from = requireThread2(input.threadId);
4439
4463
  if (isOrchestratorThread(from)) {
4440
4464
  throw new Error(
4441
- "fork_worktree targets a worktree agent thread (not the orchestrator). Pass a child/worktree thread ref."
4465
+ "fork_workspace targets a worktree agent thread (not the orchestrator). Pass a child/worktree thread ref."
4442
4466
  );
4443
4467
  }
4444
4468
  if (!from.branchName?.trim() || !from.repoPath?.trim()) {
@@ -4554,7 +4578,7 @@ function planOrchestrationQuotaFailover(thread, limitText, opts) {
4554
4578
  }
4555
4579
  function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
4556
4580
  const children = listThreads({ includeArchived: false }).filter((t) => t.parentThreadId === from.id && t.status !== "archived").slice(0, 40).map(
4557
- (t) => `- ${t.title} \xB7 ${t.status} \xB7 ${t.agent} \xB7 sideboard://thread/${t.id}`
4581
+ (t) => `- ${t.title} \xB7 ${t.status} \xB7 ${t.agent} \xB7 sideboard://chat/${t.id}`
4558
4582
  );
4559
4583
  const recent = from.messages.slice(-8).map((m) => {
4560
4584
  const role = m.role === "user" ? "User" : m.role === "agent" ? "Agent" : "Summary";
@@ -4564,7 +4588,7 @@ function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
4564
4588
  const orch = isOrchestratorThread(from);
4565
4589
  const instructions = orch ? [
4566
4590
  "- Continue fleet orchestration from this handoff.",
4567
- "- Prefer Sideboard MCP (list_board, list_threads, get_thread, send_to_thread, \u2026) for live status.",
4591
+ "- Prefer Sideboard MCP (list_board, list_chats, get_chat, send_to_chat, \u2026) for live status.",
4568
4592
  "- Leave model Auto unless there is a specific reason to pin one.",
4569
4593
  `- Do not wait on the limited ${from.agent} account; keep going on ${fallbackAgent}.`
4570
4594
  ] : [
@@ -4583,7 +4607,7 @@ function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
4583
4607
  from.sourceRef?.trim() || "(none)",
4584
4608
  "",
4585
4609
  `## Child threads`,
4586
- children.length ? children.join("\n") : "(none listed \u2014 call list_threads)",
4610
+ children.length ? children.join("\n") : "(none listed \u2014 call list_chats)",
4587
4611
  "",
4588
4612
  `## Recent turns (truncated)`,
4589
4613
  recent.length ? recent.join("\n") : "(none)",
@@ -4732,7 +4756,7 @@ async function adoptThread(input) {
4732
4756
  messages: input.messages ?? []
4733
4757
  });
4734
4758
  writeThread(thread);
4735
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-2XTDS7N2.js");
4759
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-WOQHJFRQ.js");
4736
4760
  await ensureWorkspace2(repoPath);
4737
4761
  const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-5N2KTYIT.js");
4738
4762
  await ensureWorktreeSideboardIgnored2(input.worktreePath);
@@ -6675,18 +6699,18 @@ function formatWorktreeDirective(thread, opts) {
6675
6699
  const dir = worktreeNameFromPath(thread.worktreePath);
6676
6700
  const lines = [
6677
6701
  "Sideboard workspace (mandatory):",
6678
- `- Worktree (your only working directory): ${worktree}`,
6702
+ `- Workspace cwd (git worktree; your only working directory): ${worktree}`,
6679
6703
  `- Branch: ${thread.branchName}`,
6680
6704
  `- Worktree folder nickname (stable, do not rename): ${dir}`
6681
6705
  ];
6682
6706
  if (worktree && repo && worktree !== repo) {
6683
6707
  lines.push(`- Main repo checkout (do NOT edit application code here): ${repo}`);
6684
6708
  lines.push(
6685
- "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."
6709
+ "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."
6686
6710
  );
6687
6711
  } else {
6688
6712
  lines.push(
6689
- "All file operations and shell commands must use this worktree as cwd. Do not switch to another checkout."
6713
+ "All file operations and shell commands must use this workspace as cwd. Do not switch to another checkout."
6690
6714
  );
6691
6715
  }
6692
6716
  lines.push("");
@@ -6699,7 +6723,7 @@ function formatWorktreeDirective(thread, opts) {
6699
6723
  "- 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."
6700
6724
  );
6701
6725
  lines.push(
6702
- "- 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`)."
6726
+ "- 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`)."
6703
6727
  );
6704
6728
  if (thread.prUrl) {
6705
6729
  lines.push(
@@ -6719,14 +6743,14 @@ function formatWorktreeDirective(thread, opts) {
6719
6743
  lines.push(formatDevAccessHint(opts?.activeRuns));
6720
6744
  lines.push("");
6721
6745
  lines.push(
6722
- "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."
6746
+ "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."
6723
6747
  );
6724
6748
  lines.push("");
6725
6749
  lines.push(formatProcessGuideDirective({ worktreePath: thread.worktreePath }));
6726
6750
  return lines.join("\n");
6727
6751
  }
6728
6752
  function formatWorktreeReminder() {
6729
- 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).";
6753
+ 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).";
6730
6754
  }
6731
6755
  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;
6732
6756
  function mentionsPrGoal(prompt) {
@@ -7219,7 +7243,7 @@ function formatScheduledPrompt(name, prompt) {
7219
7243
  ${prompt}`;
7220
7244
  }
7221
7245
  async function defaultDeps() {
7222
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-VLTO5JBR.js");
7246
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-4JSG7BWC.js");
7223
7247
  const orch = getOrchestrator2();
7224
7248
  return {
7225
7249
  findThread: (id) => findThreadByRef(id),
@@ -7537,7 +7561,7 @@ var Orchestrator = class {
7537
7561
  orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
7538
7562
  });
7539
7563
  }
7540
- const { autoCleanupOrphansEnabled } = await import("./app-settings-OM7H64YM.js");
7564
+ const { autoCleanupOrphansEnabled } = await import("./app-settings-MVZPM6WW.js");
7541
7565
  if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
7542
7566
  await cleanupOrphanWorktrees({ repoPaths });
7543
7567
  }
@@ -7752,7 +7776,7 @@ var Orchestrator = class {
7752
7776
  try {
7753
7777
  appendMessage(threadId, {
7754
7778
  role: "agent",
7755
- text: `Session limit on ${thread.agent}. Sideboard continued on account \u201C${plan.fallbackAccountLabel}\u201D in [${next.title}](sideboard://thread/${next.id}).`,
7779
+ text: `Session limit on ${thread.agent}. Sideboard continued on account \u201C${plan.fallbackAccountLabel}\u201D in [${next.title}](sideboard://chat/${next.id}).`,
7756
7780
  ts: (/* @__PURE__ */ new Date()).toISOString()
7757
7781
  });
7758
7782
  this.emit({
@@ -7795,7 +7819,7 @@ var Orchestrator = class {
7795
7819
  try {
7796
7820
  appendMessage(threadId, {
7797
7821
  role: "agent",
7798
- text: `Session limit on ${thread.agent}. Sideboard continued on ${plan.fallbackAgent} (Auto) in [${next.title}](sideboard://thread/${next.id}).`,
7822
+ text: `Session limit on ${thread.agent}. Sideboard continued on ${plan.fallbackAgent} (Auto) in [${next.title}](sideboard://chat/${next.id}).`,
7799
7823
  ts: (/* @__PURE__ */ new Date()).toISOString()
7800
7824
  });
7801
7825
  this.emit({
@@ -7926,7 +7950,7 @@ var Orchestrator = class {
7926
7950
  }
7927
7951
  await setup;
7928
7952
  if (skipSetup) return;
7929
- const { autoRunAfterSetupEnabled } = await import("./app-settings-OM7H64YM.js");
7953
+ const { autoRunAfterSetupEnabled } = await import("./app-settings-MVZPM6WW.js");
7930
7954
  if (autoRunAfterSetupEnabled()) {
7931
7955
  try {
7932
7956
  await this.startDev(threadId);
@@ -8305,7 +8329,7 @@ var Orchestrator = class {
8305
8329
  }
8306
8330
  const isBrightsy = fresh.agent === "brightsy";
8307
8331
  const isOrchestration = isOrchestratorThread(fresh);
8308
- const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-OM7H64YM.js");
8332
+ const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-MVZPM6WW.js");
8309
8333
  const gitAuthMode = getGithubGitAuthMode();
8310
8334
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
8311
8335
  githubSlug: await withTimeout(
@@ -9354,9 +9378,10 @@ var Orchestrator = class {
9354
9378
  const thread = this.healStaleReportedActivity(this.requireThread(threadRef));
9355
9379
  const lastAgent = lastAgentReply(thread.messages);
9356
9380
  const lastError = thread.lastError ?? null;
9357
- const rawText = (lastAgent?.text ?? "").trim();
9358
- const text = (rawText && !isInternalAgentStatusText(rawText) ? rawText : "") || (thread.status === "error" || thread.status === "stopped" || thread.status === "broken" ? lastError ?? "" : "");
9359
9381
  const stillRunning = this.threadLooksLive(thread);
9382
+ const rawText = (lastAgent?.text ?? "").trim();
9383
+ const finishedText = (rawText && !isInternalAgentStatusText(rawText) ? rawText : "") || (thread.status === "error" || thread.status === "stopped" || thread.status === "broken" ? lastError ?? "" : "");
9384
+ const text = stillRunning ? "" : finishedText;
9360
9385
  const live = stillRunning ? readTurnLive(thread.id) : null;
9361
9386
  const liveSummary = live?.summary && !isInternalAgentStatusText(live.summary) ? live.summary : null;
9362
9387
  const queuedHint = stillRunning && thread.status === "queued" && !liveSummary ? "Queued \u2014 waiting for a concurrency slot" : null;
@@ -9373,8 +9398,12 @@ var Orchestrator = class {
9373
9398
  lastError,
9374
9399
  stillRunning,
9375
9400
  progress: liveSummary ?? queuedHint,
9376
- lastActivityAt: live?.updatedAt ?? null,
9377
- usage: lastAgent?.usage ?? null
9401
+ lastActivityAt: lastActivityAtForWait(stillRunning, live?.updatedAt, [
9402
+ thread.messages.at(-1)?.ts,
9403
+ lastAgent?.ts,
9404
+ thread.updatedAt
9405
+ ]),
9406
+ usage: stillRunning ? null : lastAgent?.usage ?? null
9378
9407
  };
9379
9408
  }
9380
9409
  assertNotGlobal(thread, action) {
@@ -9610,7 +9639,7 @@ var Orchestrator = class {
9610
9639
  if (Object.keys(patch).length === 0) continue;
9611
9640
  updateThread(t.id, patch);
9612
9641
  }
9613
- const { autoArchiveOnMergeEnabled } = await import("./app-settings-OM7H64YM.js");
9642
+ const { autoArchiveOnMergeEnabled } = await import("./app-settings-MVZPM6WW.js");
9614
9643
  const latest = this.requireThread(thread.id);
9615
9644
  if (!shouldAutoArchiveOnPrMerge({
9616
9645
  previousPrState: prevState || null,
@@ -9901,7 +9930,7 @@ var Orchestrator = class {
9901
9930
  this.enforceHistoryRetention();
9902
9931
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
9903
9932
  try {
9904
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-2XTDS7N2.js");
9933
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-WOQHJFRQ.js");
9905
9934
  await ensureWorkspace2(thread.repoPath);
9906
9935
  } catch {
9907
9936
  }
@@ -9928,7 +9957,7 @@ var Orchestrator = class {
9928
9957
  await runArchiveScript(thread.repoPath, thread.worktreePath);
9929
9958
  } catch {
9930
9959
  }
9931
- const { deleteBranchOnPurgeEnabled } = await import("./app-settings-OM7H64YM.js");
9960
+ const { deleteBranchOnPurgeEnabled } = await import("./app-settings-MVZPM6WW.js");
9932
9961
  const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
9933
9962
  await removeWorktree(thread.repoPath, thread.worktreePath, {
9934
9963
  deleteBranch: deleteBranch ? thread.branchName : void 0
@@ -9955,7 +9984,7 @@ var Orchestrator = class {
9955
9984
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
9956
9985
  );
9957
9986
  }
9958
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-DDDF3WHV.js");
9987
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-6U2FA5LO.js");
9959
9988
  const slug = thread.worktreePath.split("/").pop();
9960
9989
  const dest = thread.worktreePath;
9961
9990
  await withRepoGitLock(thread.repoPath, async () => {
@@ -10065,7 +10094,7 @@ async function startOrchestration(opts) {
10065
10094
  sourceRef: "default",
10066
10095
  ...createOpts
10067
10096
  }).catch(async () => {
10068
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-DDDF3WHV.js");
10097
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-6U2FA5LO.js");
10069
10098
  const repo = await resolveRepoRoot2(repoPath);
10070
10099
  const def = await resolveDefaultBranch2(repo);
10071
10100
  return orch.createThread({
@@ -10089,10 +10118,11 @@ async function startOrchestration(opts) {
10089
10118
  export {
10090
10119
  isInjectedNoticeText,
10091
10120
  needsCoordinatorAction,
10092
- AGENT_GIT_ACTIONS,
10093
- threadsSharingWorktree,
10094
10121
  mcpWaitForTurnTimeoutMs,
10095
10122
  mcpWaitTaskHint,
10123
+ waitForTurnToolResult,
10124
+ AGENT_GIT_ACTIONS,
10125
+ threadsSharingWorktree,
10096
10126
  mcpWaitForJobTimeoutMs,
10097
10127
  waitForDetachedJob,
10098
10128
  stopDetachedJob,
@@ -4,14 +4,14 @@ import {
4
4
  normalizeAbleTimeCredential,
5
5
  normalizeAbleTimeHost,
6
6
  rewriteAbleTimeError
7
- } from "./chunk-J6ONZP74.js";
7
+ } from "./chunk-6YY7XPPL.js";
8
8
  import {
9
9
  httpFetch
10
10
  } from "./chunk-N7WZ6NIN.js";
11
11
  import {
12
12
  getAbleTimeAccessToken,
13
13
  getAbleTimeHost
14
- } from "./chunk-6PFZ6XO7.js";
14
+ } from "./chunk-2QUQH2SZ.js";
15
15
 
16
16
  // src/integrations/abletime-rest.ts
17
17
  var ABLETIME_REST_PREFIX = "/api/public/v2";
@@ -7,7 +7,7 @@ import {
7
7
  ensureConnectedBrightsyTeamTokens,
8
8
  getConnectedBrightsyTeamsRaw,
9
9
  listConnectedBrightsyTeams
10
- } from "./chunk-LDXSAVWO.js";
10
+ } from "./chunk-GWFVCCJZ.js";
11
11
  import "./chunk-ROPGQRPU.js";
12
12
  import "./chunk-N7WZ6NIN.js";
13
13
  import "./chunk-QVN2WOKJ.js";
@@ -7,19 +7,19 @@ import {
7
7
  enrichWorkspacesWithGithub,
8
8
  ensureGlobalCoordinatorCwd,
9
9
  formatWorkspaceInventory
10
- } from "./chunk-X2OTZ36G.js";
11
- import "./chunk-U3AOJLH3.js";
10
+ } from "./chunk-RKPBIB2U.js";
11
+ import "./chunk-5ZPT5YAV.js";
12
+ import "./chunk-FWNL62VA.js";
12
13
  import "./chunk-2P4XKWV2.js";
13
14
  import "./chunk-6K64FJDD.js";
15
+ import "./chunk-UWQ6UCIB.js";
14
16
  import "./chunk-QVN2WOKJ.js";
15
- import "./chunk-6PFZ6XO7.js";
17
+ import "./chunk-2QUQH2SZ.js";
18
+ import "./chunk-77WWLBCI.js";
16
19
  import "./chunk-4TR3HZFT.js";
17
20
  import "./chunk-WDRMZKVB.js";
18
21
  import "./chunk-3HO2OY5T.js";
19
22
  import "./chunk-JT7R45JB.js";
20
- import "./chunk-FWNL62VA.js";
21
- import "./chunk-UWQ6UCIB.js";
22
- import "./chunk-77WWLBCI.js";
23
23
  import "./chunk-EHT2DRT4.js";
24
24
  export {
25
25
  COORDINATOR_TOOL_PLAYBOOK,
@@ -9,12 +9,12 @@ import {
9
9
  enrichWorkspacesWithGithub,
10
10
  ensureGlobalCoordinatorCwd,
11
11
  formatWorkspaceInventory
12
- } from "./chunk-JTNY5CK4.js";
13
- import "./chunk-FSZ7YYFQ.js";
12
+ } from "./chunk-L5WGAIL2.js";
13
+ import "./chunk-4ALDX5IO.js";
14
14
  import "./chunk-N2WW62LF.js";
15
15
  import "./chunk-DD67JWTN.js";
16
16
  import "./chunk-2UG25RMK.js";
17
- import "./chunk-VIC6TDYT.js";
17
+ import "./chunk-36FOBJBF.js";
18
18
  import "./chunk-NSTQ6QKD.js";
19
19
  import "./chunk-WWUABK6B.js";
20
20
  import "./chunk-FJZWM2ON.js";
@@ -17,12 +17,12 @@ import {
17
17
  orchestratorSessionPoisonedByBuiltins,
18
18
  slackCoordinatorSourceRef,
19
19
  takenTeamSlugsForOrchestration
20
- } from "./chunk-JTNY5CK4.js";
21
- import "./chunk-FSZ7YYFQ.js";
20
+ } from "./chunk-L5WGAIL2.js";
21
+ import "./chunk-4ALDX5IO.js";
22
22
  import "./chunk-N2WW62LF.js";
23
23
  import "./chunk-DD67JWTN.js";
24
24
  import "./chunk-2UG25RMK.js";
25
- import "./chunk-VIC6TDYT.js";
25
+ import "./chunk-36FOBJBF.js";
26
26
  import "./chunk-NSTQ6QKD.js";
27
27
  import "./chunk-WWUABK6B.js";
28
28
  import "./chunk-FJZWM2ON.js";
@@ -15,19 +15,19 @@ import {
15
15
  orchestratorSessionPoisonedByBuiltins,
16
16
  slackCoordinatorSourceRef,
17
17
  takenTeamSlugsForOrchestration
18
- } from "./chunk-X2OTZ36G.js";
19
- import "./chunk-U3AOJLH3.js";
18
+ } from "./chunk-RKPBIB2U.js";
19
+ import "./chunk-5ZPT5YAV.js";
20
+ import "./chunk-FWNL62VA.js";
20
21
  import "./chunk-2P4XKWV2.js";
21
22
  import "./chunk-6K64FJDD.js";
23
+ import "./chunk-UWQ6UCIB.js";
22
24
  import "./chunk-QVN2WOKJ.js";
23
- import "./chunk-6PFZ6XO7.js";
25
+ import "./chunk-2QUQH2SZ.js";
26
+ import "./chunk-77WWLBCI.js";
24
27
  import "./chunk-4TR3HZFT.js";
25
28
  import "./chunk-WDRMZKVB.js";
26
29
  import "./chunk-3HO2OY5T.js";
27
30
  import "./chunk-JT7R45JB.js";
28
- import "./chunk-FWNL62VA.js";
29
- import "./chunk-UWQ6UCIB.js";
30
- import "./chunk-77WWLBCI.js";
31
31
  import {
32
32
  globalAgentCwd
33
33
  } from "./chunk-EHT2DRT4.js";