@sideboard-ai/core 0.1.199 → 0.1.201

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 (39) hide show
  1. package/dist/{abletime-3CSCNAXU.js → abletime-345SE3B4.js} +2 -2
  2. package/dist/{abletime-H74RNIKV.js → abletime-KGPD3UUJ.js} +2 -2
  3. package/dist/{agents-BOYOK56K.js → agents-HB6N3XJL.js} +7 -5
  4. package/dist/{agents-AVH44CBS.js → agents-KFAGRM46.js} +7 -5
  5. package/dist/{app-settings-MMPLJHWF.js → app-settings-AXCURTZJ.js} +9 -1
  6. package/dist/{app-settings-FMTDH5RD.js → app-settings-V6IHESEQ.js} +9 -1
  7. package/dist/{chunk-DU2ICKLA.js → chunk-3TOGAUQT.js} +23 -9
  8. package/dist/{chunk-S4EEYOSU.js → chunk-54RSAMBH.js} +3 -3
  9. package/dist/{chunk-CA7PWMQ7.js → chunk-7AHAABKN.js} +1 -1
  10. package/dist/{chunk-PPVN3APP.js → chunk-AHPIU2VP.js} +113 -64
  11. package/dist/{chunk-2IQ6W47G.js → chunk-CXFW5LIH.js} +40 -3
  12. package/dist/{chunk-KJBYIIJU.js → chunk-DFUES6QU.js} +5 -0
  13. package/dist/{chunk-CTABTALL.js → chunk-EXZMNINM.js} +60 -43
  14. package/dist/{chunk-CJFBSQIB.js → chunk-INNLWYXW.js} +5 -0
  15. package/dist/{chunk-HQKGK4KO.js → chunk-ISV5IFH3.js} +40 -3
  16. package/dist/{chunk-BLOKJY4U.js → chunk-LJHC62LZ.js} +3 -3
  17. package/dist/{chunk-PTAMHXBT.js → chunk-PGQGP4FD.js} +1 -1
  18. package/dist/{chunk-QFABSE3Q.js → chunk-RPX6VDW7.js} +2 -2
  19. package/dist/{chunk-KI4YI72Y.js → chunk-RV3ZKE4Y.js} +45 -31
  20. package/dist/{chunk-DU4ID3DA.js → chunk-STPZQR5B.js} +2 -2
  21. package/dist/{coordinator-prompt-ROWPLVQ3.js → coordinator-prompt-BH4EHFOO.js} +4 -4
  22. package/dist/{coordinator-prompt-LB3GA3U4.js → coordinator-prompt-TY5FHAXC.js} +4 -4
  23. package/dist/{global-workspace-V2A4YKZ6.js → global-workspace-5AZEEQRU.js} +4 -4
  24. package/dist/{global-workspace-C5XKWCRH.js → global-workspace-NLLAPQJI.js} +4 -4
  25. package/dist/index.cjs +13458 -13261
  26. package/dist/index.d.cts +54 -14
  27. package/dist/index.d.ts +54 -14
  28. package/dist/index.js +93 -9
  29. package/dist/mcp/run-stdio.cjs +92 -24
  30. package/dist/mcp/run-stdio.js +9 -9
  31. package/dist/{orchestrator-AJGDZEAS.js → orchestrator-47JZUHRC.js} +6 -6
  32. package/dist/{orchestrator-NCGYNVYN.js → orchestrator-SWWQQFFD.js} +6 -6
  33. package/dist/{thread-store-M4B52FUS.js → thread-store-2SS5V5CN.js} +3 -1
  34. package/dist/{thread-store-CO77HV2K.js → thread-store-ZGVWPVHP.js} +3 -1
  35. package/dist/{workspaces-WIRJQ6HA.js → workspaces-PEWYWVHZ.js} +4 -4
  36. package/dist/{workspaces-GWEKIS3B.js → workspaces-RP76JH3J.js} +4 -4
  37. package/dist/{worktree-QA4J75FI.js → worktree-72TZWUSH.js} +3 -3
  38. package/dist/{worktree-UI5WJC3A.js → worktree-ZQEUKSNE.js} +3 -3
  39. package/package.json +1 -1
@@ -38,7 +38,7 @@ import {
38
38
  summarizeTurnStderr,
39
39
  toolDescription,
40
40
  turnFailChatText
41
- } from "./chunk-DU2ICKLA.js";
41
+ } from "./chunk-3TOGAUQT.js";
42
42
  import {
43
43
  SLACK_REPLY_FORMATTING,
44
44
  addWorkspace,
@@ -61,7 +61,7 @@ import {
61
61
  stageAbsolutePathsAsAttachments,
62
62
  stageBuffersAsAttachments,
63
63
  syncWorkspacesFromThreads
64
- } from "./chunk-S4EEYOSU.js";
64
+ } from "./chunk-54RSAMBH.js";
65
65
  import {
66
66
  extractPresentedPlan,
67
67
  readPlanFile,
@@ -116,7 +116,7 @@ import {
116
116
  worktreeDisplayLabelForGroup,
117
117
  worktreeNameFromPath,
118
118
  worktreeSlugForTicket
119
- } from "./chunk-QFABSE3Q.js";
119
+ } from "./chunk-RPX6VDW7.js";
120
120
  import {
121
121
  ATTACHMENTS_DIR,
122
122
  DETACHED_JOBS_DIR,
@@ -134,7 +134,7 @@ import {
134
134
  updateThread,
135
135
  withThreadLock,
136
136
  writeThread
137
- } from "./chunk-CJFBSQIB.js";
137
+ } from "./chunk-INNLWYXW.js";
138
138
  import {
139
139
  ensureWorktreeSideboardIgnored
140
140
  } from "./chunk-SYFVUF2C.js";
@@ -160,7 +160,6 @@ import {
160
160
  isSecureFileEncrypted,
161
161
  loadAppSettings,
162
162
  orchestrationQuotaFallbackAgent,
163
- orchestrationQuotaOnLimit,
164
163
  readSecureJson,
165
164
  resolveEffectiveIssueSource,
166
165
  resolveNewThreadOptions,
@@ -169,8 +168,9 @@ import {
169
168
  resolveViewerProfileForRepo,
170
169
  stripNestedElectronEnv,
171
170
  updateAdvancedSettings,
171
+ usageOnLimit,
172
172
  writeSecureJson
173
- } from "./chunk-HQKGK4KO.js";
173
+ } from "./chunk-ISV5IFH3.js";
174
174
  import {
175
175
  writePrivateFile
176
176
  } from "./chunk-NSTQ6QKD.js";
@@ -408,7 +408,7 @@ async function continueSourceThread(threadId, prompt) {
408
408
  await continueOnReply(threadId, prompt);
409
409
  return;
410
410
  }
411
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-AJGDZEAS.js");
411
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-47JZUHRC.js");
412
412
  await getOrchestrator2().send(threadId, prompt);
413
413
  } catch {
414
414
  }
@@ -801,9 +801,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
801
801
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
802
802
  );
803
803
  }
804
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-C5XKWCRH.js");
804
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-NLLAPQJI.js");
805
805
  if (isGlobalThread2(thread)) {
806
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-ROWPLVQ3.js");
806
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-BH4EHFOO.js");
807
807
  ensureGlobalCoordinatorCwd2(
808
808
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
809
809
  );
@@ -3599,7 +3599,7 @@ async function createThread(input, _onSetupLine) {
3599
3599
  });
3600
3600
  await requireAgent(resolved.agent);
3601
3601
  if (input.cowboy) {
3602
- const { cowboyModeEnabled } = await import("./app-settings-FMTDH5RD.js");
3602
+ const { cowboyModeEnabled } = await import("./app-settings-V6IHESEQ.js");
3603
3603
  if (!cowboyModeEnabled()) {
3604
3604
  throw new Error(
3605
3605
  "Cowboy mode is off. Enable it in Settings \u2192 Advanced."
@@ -3657,7 +3657,7 @@ async function createThread(input, _onSetupLine) {
3657
3657
  let sourceIsFork = false;
3658
3658
  if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
3659
3659
  if (isAbleTimeConnected() && getIssueSource() === "abletime") {
3660
- const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-H74RNIKV.js");
3660
+ const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-KGPD3UUJ.js");
3661
3661
  const task = await ensureAbleTimeTask({
3662
3662
  title: title?.trim() || "Untitled work",
3663
3663
  description: input.prompt?.trim() || void 0
@@ -3969,12 +3969,18 @@ async function forkThreadWorktree(input, onSetupLine) {
3969
3969
  // src/orchestrator/quota-failover.ts
3970
3970
  import { randomUUID as randomUUID3 } from "crypto";
3971
3971
  function planOrchestrationQuotaFailover(thread, limitText, opts) {
3972
- if (!isOrchestratorThread(thread)) return null;
3973
3972
  if (!isSessionQuotaLimit(limitText)) return null;
3974
- const onLimit = opts?.onLimit ?? orchestrationQuotaOnLimit();
3973
+ const onLimit = opts?.onLimit ?? usageOnLimit();
3975
3974
  const resumeAt = parseSessionQuotaResetAt(limitText, opts?.now);
3975
+ if (onLimit === "keep_going" || onLimit === "confirm") {
3976
+ return {
3977
+ action: "none",
3978
+ reason: onLimit === "confirm" ? "Settings: confirm with user; no automatic continue." : "Settings: keep going; no automatic continue.",
3979
+ limitText
3980
+ };
3981
+ }
3976
3982
  if (thread.quotaContinuedFromId) {
3977
- if (resumeAt) {
3983
+ if (onLimit === "switch_agent" && resumeAt) {
3978
3984
  return {
3979
3985
  action: "wait_reset",
3980
3986
  reason: "Already continued once; waiting for quota reset instead.",
@@ -3984,7 +3990,7 @@ function planOrchestrationQuotaFailover(thread, limitText, opts) {
3984
3990
  }
3985
3991
  return {
3986
3992
  action: "none",
3987
- reason: "Already continued once; no parseable reset time.",
3993
+ reason: "Already continued once; no further automatic continue.",
3988
3994
  limitText
3989
3995
  };
3990
3996
  }
@@ -4021,8 +4027,19 @@ function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
4021
4027
  const text = m.text.trim().replace(/\s+/g, " ").slice(0, 280);
4022
4028
  return text ? `- ${role}: ${text}` : null;
4023
4029
  }).filter(Boolean);
4030
+ const orch = isOrchestratorThread(from);
4031
+ const instructions = orch ? [
4032
+ "- Continue fleet orchestration from this handoff.",
4033
+ "- Prefer Sideboard MCP (list_board, list_threads, get_thread, send_to_thread, \u2026) for live status.",
4034
+ "- Leave model Auto unless there is a specific reason to pin one.",
4035
+ `- Do not wait on the limited ${from.agent} account; keep going on ${fallbackAgent}.`
4036
+ ] : [
4037
+ "- Continue this worktree chat from the handoff.",
4038
+ "- Leave model Auto unless there is a specific reason to pin one.",
4039
+ `- Do not wait on the limited ${from.agent} account; keep going on ${fallbackAgent}.`
4040
+ ];
4024
4041
  const body = [
4025
- `# Orchestration handoff`,
4042
+ `# ${orch ? "Orchestration" : "Chat"} handoff`,
4026
4043
  "",
4027
4044
  `Previous chat: ${from.title} (\`${from.id}\`) on **${from.agent}** hit a session/usage limit.`,
4028
4045
  `Limit: ${limitText.trim()}`,
@@ -4038,23 +4055,20 @@ function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
4038
4055
  recent.length ? recent.join("\n") : "(none)",
4039
4056
  "",
4040
4057
  `## Instructions`,
4041
- `- Continue fleet orchestration from this handoff.`,
4042
- `- Prefer Sideboard MCP (list_board, list_threads, get_thread, send_to_thread, \u2026) for live status.`,
4043
- `- Leave model Auto unless there is a specific reason to pin one.`,
4044
- `- Do not wait on the limited ${from.agent} account; keep going on ${fallbackAgent}.`
4058
+ ...instructions
4045
4059
  ].join("\n");
4046
4060
  return {
4047
4061
  id: randomUUID3(),
4048
- name: "Orchestration quota handoff.md",
4062
+ name: orch ? "Orchestration quota handoff.md" : "Quota handoff.md",
4049
4063
  kind: "transcript",
4050
4064
  content: body
4051
4065
  };
4052
4066
  }
4053
4067
  var QUOTA_CONTINUE_PROMPT = (fromAgent, fallback) => [
4054
- `${fromAgent} hit a session/usage limit. Continue this orchestration on ${fallback} using the attached handoff.`,
4055
- "Call list_board or list_threads for live fleet status, then proceed with the goal. Leave model Auto unless needed."
4068
+ `${fromAgent} hit a session/usage limit. Continue this chat on ${fallback} using the attached handoff.`,
4069
+ "Proceed with the goal. Leave model Auto unless needed."
4056
4070
  ].join(" ");
4057
- var QUOTA_RESUME_PROMPT = "Session/usage limit window should have reset. Continue the orchestration from where you left off. Use list_board or list_threads for fleet status.";
4071
+ var QUOTA_RESUME_PROMPT = "Session/usage limit window should have reset. Continue this chat from where you left off.";
4058
4072
  function createQuotaFailoverChat(from, fallbackAgent, limitText) {
4059
4073
  const handoff = buildQuotaHandoffAttachment(from, limitText, fallbackAgent);
4060
4074
  const tab = createChatTab({
@@ -4063,12 +4077,15 @@ function createQuotaFailoverChat(from, fallbackAgent, limitText) {
4063
4077
  model: null,
4064
4078
  attachments: [handoff]
4065
4079
  });
4066
- return updateThread(tab.id, {
4067
- parentThreadId: from.id,
4080
+ const patch = {
4068
4081
  quotaContinuedFromId: from.id,
4069
- sourceRef: from.sourceRef,
4070
- sourceType: "orchestration"
4071
- });
4082
+ sourceRef: from.sourceRef
4083
+ };
4084
+ if (isOrchestratorThread(from)) {
4085
+ patch.parentThreadId = from.id;
4086
+ patch.sourceType = "orchestration";
4087
+ }
4088
+ return updateThread(tab.id, patch);
4072
4089
  }
4073
4090
 
4074
4091
  // src/threads/adopt.ts
@@ -4169,7 +4186,7 @@ async function adoptThread(input) {
4169
4186
  messages: input.messages ?? []
4170
4187
  });
4171
4188
  writeThread(thread);
4172
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-WIRJQ6HA.js");
4189
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-PEWYWVHZ.js");
4173
4190
  await ensureWorkspace2(repoPath);
4174
4191
  const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-N5X5I422.js");
4175
4192
  await ensureWorktreeSideboardIgnored2(input.worktreePath);
@@ -6547,7 +6564,7 @@ function formatScheduledPrompt(name, prompt) {
6547
6564
  ${prompt}`;
6548
6565
  }
6549
6566
  async function defaultDeps() {
6550
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-AJGDZEAS.js");
6567
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-47JZUHRC.js");
6551
6568
  const orch = getOrchestrator2();
6552
6569
  return {
6553
6570
  findThread: (id) => findThreadByRef(id),
@@ -6822,7 +6839,7 @@ var Orchestrator = class {
6822
6839
  orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
6823
6840
  });
6824
6841
  }
6825
- const { autoCleanupOrphansEnabled } = await import("./app-settings-FMTDH5RD.js");
6842
+ const { autoCleanupOrphansEnabled } = await import("./app-settings-V6IHESEQ.js");
6826
6843
  if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
6827
6844
  await cleanupOrphanWorktrees({ repoPaths });
6828
6845
  }
@@ -6933,8 +6950,8 @@ var Orchestrator = class {
6933
6950
  await this.send(threadId, QUOTA_RESUME_PROMPT);
6934
6951
  }
6935
6952
  /**
6936
- * Host-side continue when an orchestration chat hits a provider session/usage
6937
- * limit (not context size): switch agent (Auto) or wait until reset.
6953
+ * Host-side continue when any chat hits a provider session/usage limit
6954
+ * (not context size): switch agent (Auto) or wait until reset.
6938
6955
  */
6939
6956
  async maybeHandleOrchestrationQuotaFailover(threadId, limitText) {
6940
6957
  const thread = findThreadByRef(threadId);
@@ -6947,7 +6964,7 @@ var Orchestrator = class {
6947
6964
  setStatus(threadId, "idle", null);
6948
6965
  appendMessage(threadId, {
6949
6966
  role: "agent",
6950
- text: `Sideboard will auto-retry this orchestration around ${plan.resumeAt.toLocaleString()} when the session limit resets.`,
6967
+ text: `Sideboard will auto-retry this chat around ${plan.resumeAt.toLocaleString()} when the session limit resets.`,
6951
6968
  ts: (/* @__PURE__ */ new Date()).toISOString()
6952
6969
  });
6953
6970
  this.emit({
@@ -7101,7 +7118,7 @@ var Orchestrator = class {
7101
7118
  }
7102
7119
  await setup;
7103
7120
  if (skipSetup) return;
7104
- const { autoRunAfterSetupEnabled } = await import("./app-settings-FMTDH5RD.js");
7121
+ const { autoRunAfterSetupEnabled } = await import("./app-settings-V6IHESEQ.js");
7105
7122
  if (autoRunAfterSetupEnabled()) {
7106
7123
  try {
7107
7124
  await this.startDev(threadId);
@@ -7425,7 +7442,7 @@ var Orchestrator = class {
7425
7442
  }
7426
7443
  const isBrightsy = fresh.agent === "brightsy";
7427
7444
  const isOrchestration = isOrchestratorThread(fresh);
7428
- const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-FMTDH5RD.js");
7445
+ const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-V6IHESEQ.js");
7429
7446
  const gitAuthMode = getGithubGitAuthMode();
7430
7447
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
7431
7448
  githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
@@ -8410,7 +8427,7 @@ var Orchestrator = class {
8410
8427
  updateThread(thread.id, { title: meta.title });
8411
8428
  }
8412
8429
  }
8413
- const { autoArchiveOnMergeEnabled } = await import("./app-settings-FMTDH5RD.js");
8430
+ const { autoArchiveOnMergeEnabled } = await import("./app-settings-V6IHESEQ.js");
8414
8431
  const latest = this.requireThread(thread.id);
8415
8432
  if (!shouldAutoArchiveOnPrMerge({
8416
8433
  previousPrState: prevState || null,
@@ -8702,7 +8719,7 @@ var Orchestrator = class {
8702
8719
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
8703
8720
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
8704
8721
  try {
8705
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-WIRJQ6HA.js");
8722
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-PEWYWVHZ.js");
8706
8723
  await ensureWorkspace2(thread.repoPath);
8707
8724
  } catch {
8708
8725
  }
@@ -8729,7 +8746,7 @@ var Orchestrator = class {
8729
8746
  await runArchiveScript(thread.repoPath, thread.worktreePath);
8730
8747
  } catch {
8731
8748
  }
8732
- const { deleteBranchOnPurgeEnabled } = await import("./app-settings-FMTDH5RD.js");
8749
+ const { deleteBranchOnPurgeEnabled } = await import("./app-settings-V6IHESEQ.js");
8733
8750
  const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
8734
8751
  await removeWorktree(thread.repoPath, thread.worktreePath, {
8735
8752
  deleteBranch: deleteBranch ? thread.branchName : void 0
@@ -8756,7 +8773,7 @@ var Orchestrator = class {
8756
8773
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
8757
8774
  );
8758
8775
  }
8759
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-UI5WJC3A.js");
8776
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-ZQEUKSNE.js");
8760
8777
  const slug = thread.worktreePath.split("/").pop();
8761
8778
  const dest = thread.worktreePath;
8762
8779
  await withRepoGitLock(thread.repoPath, async () => {
@@ -8866,7 +8883,7 @@ async function startOrchestration(opts) {
8866
8883
  sourceRef: "default",
8867
8884
  ...createOpts
8868
8885
  }).catch(async () => {
8869
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-UI5WJC3A.js");
8886
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-ZQEUKSNE.js");
8870
8887
  const repo = await resolveRepoRoot2(repoPath);
8871
8888
  const def = await resolveDefaultBranch2(repo);
8872
8889
  return orch.createThread({
@@ -8876,7 +8893,7 @@ async function startOrchestration(opts) {
8876
8893
  repoPath: repo
8877
8894
  });
8878
8895
  });
8879
- const { updateThread: upd } = await import("./thread-store-CO77HV2K.js");
8896
+ const { updateThread: upd } = await import("./thread-store-ZGVWPVHP.js");
8880
8897
  const updated = upd(thread.id, {
8881
8898
  sourceType: "orchestration",
8882
8899
  sourceRef: goal
@@ -139,6 +139,10 @@ function forgetThread(id) {
139
139
  function invalidateThreadListCache() {
140
140
  listCache = null;
141
141
  }
142
+ function invalidateThreadRecord(id) {
143
+ if (!id) return;
144
+ forgetThread(id);
145
+ }
142
146
  function readThread(id) {
143
147
  const path = threadFilePath(id);
144
148
  const mtimeMs = fileMtimeMs(path);
@@ -231,6 +235,7 @@ export {
231
235
  createEmptyThread,
232
236
  withThreadLock,
233
237
  invalidateThreadListCache,
238
+ invalidateThreadRecord,
234
239
  readThread,
235
240
  writeThread,
236
241
  isThreadRecordFile,
@@ -380,6 +380,24 @@ function normalizeVault(raw) {
380
380
  return out;
381
381
  }
382
382
 
383
+ // src/store/usage-on-limit.ts
384
+ var USAGE_ON_LIMIT_VALUES = [
385
+ "keep_going",
386
+ "confirm",
387
+ "switch_agent",
388
+ "wait_reset"
389
+ ];
390
+ function isUsageOnLimit(value) {
391
+ return value === "keep_going" || value === "confirm" || value === "switch_agent" || value === "wait_reset";
392
+ }
393
+ function resolveUsageOnLimit(advanced = {}) {
394
+ if (isUsageOnLimit(advanced.usageOnLimit)) return advanced.usageOnLimit;
395
+ if (advanced.confirmClaudeUsageOverLimit) return "confirm";
396
+ if (advanced.orchestrationQuotaOnLimit === "wait_reset") return "wait_reset";
397
+ if (advanced.orchestrationQuotaOnLimit === "switch_agent") return "switch_agent";
398
+ return "keep_going";
399
+ }
400
+
383
401
  // src/store/issue-source-labels.ts
384
402
  var ISSUE_SOURCE_LABELS = {
385
403
  github: "GitHub",
@@ -781,6 +799,9 @@ function normalizeAdvanced(raw) {
781
799
  if (typeof source.showCost === "boolean") {
782
800
  out.showCost = source.showCost;
783
801
  }
802
+ if (isUsageOnLimit(source.usageOnLimit)) {
803
+ out.usageOnLimit = source.usageOnLimit;
804
+ }
784
805
  if (typeof source.confirmClaudeUsageOverLimit === "boolean") {
785
806
  out.confirmClaudeUsageOverLimit = source.confirmClaudeUsageOverLimit;
786
807
  }
@@ -1659,8 +1680,16 @@ function updateAdvancedSettings(patch) {
1659
1680
  if (typeof patch.showCost === "boolean") {
1660
1681
  advanced.showCost = patch.showCost;
1661
1682
  }
1662
- if (typeof patch.confirmClaudeUsageOverLimit === "boolean") {
1683
+ if (isUsageOnLimit(patch.usageOnLimit)) {
1684
+ advanced.usageOnLimit = patch.usageOnLimit;
1685
+ advanced.confirmClaudeUsageOverLimit = patch.usageOnLimit === "confirm";
1686
+ if (patch.usageOnLimit === "switch_agent" || patch.usageOnLimit === "wait_reset") {
1687
+ advanced.orchestrationQuotaOnLimit = patch.usageOnLimit;
1688
+ }
1689
+ } else if (typeof patch.confirmClaudeUsageOverLimit === "boolean") {
1663
1690
  advanced.confirmClaudeUsageOverLimit = patch.confirmClaudeUsageOverLimit;
1691
+ if (patch.confirmClaudeUsageOverLimit) advanced.usageOnLimit = "confirm";
1692
+ else if (advanced.usageOnLimit === "confirm") advanced.usageOnLimit = "keep_going";
1664
1693
  }
1665
1694
  if (typeof patch.autoArchiveOnMerge === "boolean") {
1666
1695
  advanced.autoArchiveOnMerge = patch.autoArchiveOnMerge;
@@ -1725,7 +1754,7 @@ function showCostEnabled(settings = loadAppSettings()) {
1725
1754
  return Boolean(settings.advanced.showCost);
1726
1755
  }
1727
1756
  function confirmClaudeUsageOverLimitEnabled(settings = loadAppSettings()) {
1728
- return Boolean(settings.advanced.confirmClaudeUsageOverLimit);
1757
+ return usageOnLimit(settings) === "confirm";
1729
1758
  }
1730
1759
  function autoArchiveOnMergeEnabled(settings = loadAppSettings()) {
1731
1760
  return Boolean(settings.advanced.autoArchiveOnMerge);
@@ -1733,8 +1762,12 @@ function autoArchiveOnMergeEnabled(settings = loadAppSettings()) {
1733
1762
  function autoCleanupOrphansEnabled(settings = loadAppSettings()) {
1734
1763
  return Boolean(settings.advanced.autoCleanupOrphans);
1735
1764
  }
1765
+ function usageOnLimit(settings = loadAppSettings()) {
1766
+ return resolveUsageOnLimit(settings.advanced);
1767
+ }
1736
1768
  function orchestrationQuotaOnLimit(settings = loadAppSettings()) {
1737
- return settings.advanced.orchestrationQuotaOnLimit ?? "switch_agent";
1769
+ const action = usageOnLimit(settings);
1770
+ return action === "wait_reset" ? "wait_reset" : "switch_agent";
1738
1771
  }
1739
1772
  function orchestrationQuotaFallbackAgent(settings = loadAppSettings()) {
1740
1773
  const preferred = settings.advanced.orchestrationQuotaFallbackAgent;
@@ -1863,6 +1896,9 @@ export {
1863
1896
  formatWorkspaceProfileSuffix,
1864
1897
  formatViewerContextDirective,
1865
1898
  formatViewerContextReminder,
1899
+ USAGE_ON_LIMIT_VALUES,
1900
+ isUsageOnLimit,
1901
+ resolveUsageOnLimit,
1866
1902
  ISSUE_SOURCE_LABELS,
1867
1903
  issueSourceLabel,
1868
1904
  HARNESS_ENV_KEYS,
@@ -1929,6 +1965,7 @@ export {
1929
1965
  confirmClaudeUsageOverLimitEnabled,
1930
1966
  autoArchiveOnMergeEnabled,
1931
1967
  autoCleanupOrphansEnabled,
1968
+ usageOnLimit,
1932
1969
  orchestrationQuotaOnLimit,
1933
1970
  orchestrationQuotaFallbackAgent,
1934
1971
  followUpBehavior,
@@ -5,7 +5,7 @@ import {
5
5
  resolveRepoRoot,
6
6
  takenSlugsFromThread,
7
7
  teamSlugFromName
8
- } from "./chunk-DU4ID3DA.js";
8
+ } from "./chunk-STPZQR5B.js";
9
9
  import {
10
10
  ATTACHMENTS_DIR,
11
11
  attachmentsGitignoreBody
@@ -22,13 +22,13 @@ import {
22
22
  resolveThreadDefaults,
23
23
  resolveViewerProfile,
24
24
  resolveViewerProfileForRepo
25
- } from "./chunk-2IQ6W47G.js";
25
+ } from "./chunk-CXFW5LIH.js";
26
26
  import {
27
27
  createEmptyThread,
28
28
  listThreads,
29
29
  updateThread,
30
30
  writeThread
31
- } from "./chunk-KJBYIIJU.js";
31
+ } from "./chunk-DFUES6QU.js";
32
32
  import {
33
33
  appDataDir,
34
34
  globalAgentCwd,
@@ -8,7 +8,7 @@ import {
8
8
  getAbleTimeHost,
9
9
  isAbleTimeConnected,
10
10
  saveAbleTimeConnection
11
- } from "./chunk-HQKGK4KO.js";
11
+ } from "./chunk-ISV5IFH3.js";
12
12
 
13
13
  // src/integrations/abletime-mcp.ts
14
14
  var DEFAULT_ABLETIME_HOST = "https://track.abletime.com";
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-D6JWYJ4P.js";
6
6
  import {
7
7
  listThreads
8
- } from "./chunk-CJFBSQIB.js";
8
+ } from "./chunk-INNLWYXW.js";
9
9
  import {
10
10
  ensureWorktreeSideboardIgnored
11
11
  } from "./chunk-SYFVUF2C.js";
@@ -22,7 +22,7 @@ import {
22
22
  import {
23
23
  getGithubGitAuthMode,
24
24
  getGithubPat
25
- } from "./chunk-HQKGK4KO.js";
25
+ } from "./chunk-ISV5IFH3.js";
26
26
  import {
27
27
  worktreesRoot
28
28
  } from "./chunk-EQNRWDLN.js";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  isOrchestratorThread
3
- } from "./chunk-BLOKJY4U.js";
3
+ } from "./chunk-LJHC62LZ.js";
4
4
  import {
5
5
  codexUnattendedGitConfigArgs,
6
6
  mergeAgentGitAuthEnv,
7
7
  resolveAgentGitAuthEnv,
8
8
  resolveCodexGitWritableRoots
9
- } from "./chunk-DU4ID3DA.js";
9
+ } from "./chunk-STPZQR5B.js";
10
10
  import {
11
11
  applyConnectedTeamToCli,
12
12
  brightsyMcpServerName,
@@ -16,6 +16,9 @@ import {
16
16
  import {
17
17
  loadBrightsyConfig
18
18
  } from "./chunk-AN3THU7F.js";
19
+ import {
20
+ httpFetch
21
+ } from "./chunk-N7WZ6NIN.js";
19
22
  import {
20
23
  applyAgentRunnerHeapEnv,
21
24
  applyNodeLaunch,
@@ -38,7 +41,7 @@ import {
38
41
  loadAppSettings,
39
42
  resolveAgentExecutable,
40
43
  resolveClaudeExecutable
41
- } from "./chunk-2IQ6W47G.js";
44
+ } from "./chunk-CXFW5LIH.js";
42
45
  import {
43
46
  isElectronLikeCommand,
44
47
  unwrapStrippedElectronLaunch
@@ -1934,7 +1937,7 @@ var claudeAdapter = {
1934
1937
  );
1935
1938
  }
1936
1939
  const mode = permissionMode(thread);
1937
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-V2A4YKZ6.js");
1940
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-5AZEEQRU.js");
1938
1941
  const isOrchestrator = isOrchestratorThread2(thread);
1939
1942
  const injectedServers = await buildInjectedMcpServers({
1940
1943
  includeSideboard: true,
@@ -3622,16 +3625,26 @@ function claudeUsageOverLimitWindows(usage) {
3622
3625
  if (!usage) return [];
3623
3626
  return usage.windows.filter(claudeUsageWindowOverLimit);
3624
3627
  }
3625
- function formatClaudeUsageOverLimitConfirm(windows, now = /* @__PURE__ */ new Date()) {
3626
- if (windows.length === 0) return "";
3628
+ function formatOverLimitWindowList(windows, now) {
3627
3629
  const parts = windows.map((w) => {
3628
3630
  const reset = formatClaudeUsageReset(w.resetsAt, now);
3629
3631
  return reset ? `${w.label} (${reset})` : w.label;
3630
3632
  });
3631
- const list = parts.join(", ");
3632
- const verb = windows.length === 1 ? "is" : "are";
3633
+ return {
3634
+ list: parts.join(", "),
3635
+ verb: windows.length === 1 ? "is" : "are"
3636
+ };
3637
+ }
3638
+ function formatClaudeUsageOverLimitConfirm(windows, now = /* @__PURE__ */ new Date()) {
3639
+ if (windows.length === 0) return "";
3640
+ const { list, verb } = formatOverLimitWindowList(windows, now);
3633
3641
  return `Claude Code ${list} ${verb} at or over the plan limit. Send this message anyway?`;
3634
3642
  }
3643
+ function formatClaudeUsageOverLimitWait(windows, now = /* @__PURE__ */ new Date()) {
3644
+ if (windows.length === 0) return "";
3645
+ const { list, verb } = formatOverLimitWindowList(windows, now);
3646
+ return `Claude Code ${list} ${verb} at or over the plan limit. Sending is paused until the window resets.`;
3647
+ }
3635
3648
 
3636
3649
  // src/agents/claude-usage-client.ts
3637
3650
  import { existsSync as existsSync9, readFileSync as readFileSync4 } from "fs";
@@ -3728,7 +3741,7 @@ async function getClaudePlanUsage(opts = {}) {
3728
3741
  cache = { at: now, value: null };
3729
3742
  return null;
3730
3743
  }
3731
- const fetchFn = opts.fetch ?? globalThis.fetch;
3744
+ const fetchFn = opts.fetch ?? httpFetch;
3732
3745
  const userAgent = opts.userAgent ?? await resolveClaudeUserAgent();
3733
3746
  const ac = new AbortController();
3734
3747
  const timer = setTimeout(() => ac.abort(), 8e3);
@@ -4012,6 +4025,28 @@ function allAdapters() {
4012
4025
  }
4013
4026
 
4014
4027
  export {
4028
+ visibleToolRowDetail,
4029
+ toolDetail,
4030
+ toolDescription,
4031
+ isSubagentToolName,
4032
+ isInternalAgentStatusText,
4033
+ isPollWrapperToolName,
4034
+ isShellToolName,
4035
+ toolActivityLine,
4036
+ liveActivitySummary,
4037
+ messagePartParentId,
4038
+ withEventParentId,
4039
+ withEventsParentId,
4040
+ toolFilePath,
4041
+ THINKING_PART_MAX_CHARS,
4042
+ clipThinkingForStore,
4043
+ applyAgentEvent,
4044
+ partsToAssistantText,
4045
+ lastAssistantMessageText,
4046
+ stripBrightsyNdjsonNoise,
4047
+ isBrightsyNdjsonLine,
4048
+ finalizeParts,
4049
+ normalizeParseResult,
4015
4050
  fromInclusiveInputUsage,
4016
4051
  requestOccupancy,
4017
4052
  mergeUsage,
@@ -4038,28 +4073,6 @@ export {
4038
4073
  sanitizeMcpServerName,
4039
4074
  mcpAllowTools,
4040
4075
  mcpAuthWarnings,
4041
- visibleToolRowDetail,
4042
- toolDetail,
4043
- toolDescription,
4044
- isSubagentToolName,
4045
- isInternalAgentStatusText,
4046
- isPollWrapperToolName,
4047
- isShellToolName,
4048
- toolActivityLine,
4049
- liveActivitySummary,
4050
- messagePartParentId,
4051
- withEventParentId,
4052
- withEventsParentId,
4053
- toolFilePath,
4054
- THINKING_PART_MAX_CHARS,
4055
- clipThinkingForStore,
4056
- applyAgentEvent,
4057
- partsToAssistantText,
4058
- lastAssistantMessageText,
4059
- stripBrightsyNdjsonNoise,
4060
- isBrightsyNdjsonLine,
4061
- finalizeParts,
4062
- normalizeParseResult,
4063
4076
  SIDEBOARD_MCP_PROFILE_ENV,
4064
4077
  WORKTREE_MCP_TOOLS,
4065
4078
  WORKTREE_GITHUB_MCP_TOOLS,
@@ -4108,6 +4121,7 @@ export {
4108
4121
  formatClaudeUsageCompact,
4109
4122
  claudeUsageOverLimitWindows,
4110
4123
  formatClaudeUsageOverLimitConfirm,
4124
+ formatClaudeUsageOverLimitWait,
4111
4125
  getClaudePlanUsage,
4112
4126
  getAgentSetupInfo,
4113
4127
  listAgentSetupInfo,
@@ -7,10 +7,10 @@ import {
7
7
  import {
8
8
  getGithubGitAuthMode,
9
9
  getGithubPat
10
- } from "./chunk-2IQ6W47G.js";
10
+ } from "./chunk-CXFW5LIH.js";
11
11
  import {
12
12
  listThreads
13
- } from "./chunk-KJBYIIJU.js";
13
+ } from "./chunk-DFUES6QU.js";
14
14
  import {
15
15
  worktreesRoot
16
16
  } from "./chunk-WFUDY6PC.js";
@@ -9,13 +9,13 @@ import {
9
9
  enrichWorkspacesWithGithub,
10
10
  ensureGlobalCoordinatorCwd,
11
11
  formatWorkspaceInventory
12
- } from "./chunk-S4EEYOSU.js";
13
- import "./chunk-QFABSE3Q.js";
12
+ } from "./chunk-54RSAMBH.js";
13
+ import "./chunk-RPX6VDW7.js";
14
14
  import "./chunk-D6JWYJ4P.js";
15
- import "./chunk-CJFBSQIB.js";
15
+ import "./chunk-INNLWYXW.js";
16
16
  import "./chunk-SYFVUF2C.js";
17
17
  import "./chunk-FNQNJOHY.js";
18
- import "./chunk-HQKGK4KO.js";
18
+ import "./chunk-ISV5IFH3.js";
19
19
  import "./chunk-NSTQ6QKD.js";
20
20
  import "./chunk-KGZBYWZ3.js";
21
21
  import "./chunk-EQNRWDLN.js";
@@ -7,15 +7,15 @@ import {
7
7
  enrichWorkspacesWithGithub,
8
8
  ensureGlobalCoordinatorCwd,
9
9
  formatWorkspaceInventory
10
- } from "./chunk-BLOKJY4U.js";
11
- import "./chunk-DU4ID3DA.js";
10
+ } from "./chunk-LJHC62LZ.js";
11
+ import "./chunk-STPZQR5B.js";
12
12
  import "./chunk-6K64FJDD.js";
13
13
  import "./chunk-QQKDGPUI.js";
14
- import "./chunk-2IQ6W47G.js";
14
+ import "./chunk-CXFW5LIH.js";
15
15
  import "./chunk-4TR3HZFT.js";
16
16
  import "./chunk-WDRMZKVB.js";
17
17
  import "./chunk-JT7R45JB.js";
18
- import "./chunk-KJBYIIJU.js";
18
+ import "./chunk-DFUES6QU.js";
19
19
  import "./chunk-77WWLBCI.js";
20
20
  import "./chunk-WFUDY6PC.js";
21
21
  import "./chunk-UFHNSFAS.js";