@sideboard-ai/core 0.1.319 → 0.1.320

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/{abletime-L3ODNTBT.js → abletime-CRRLEYTE.js} +4 -4
  2. package/dist/{abletime-DVYO4IVS.js → abletime-ICW6Q2AB.js} +4 -4
  3. package/dist/{abletime-oauth-2VWQCXGT.js → abletime-oauth-P3KPPJE4.js} +3 -3
  4. package/dist/{abletime-oauth-6DTX7LB7.js → abletime-oauth-Q76XBSPG.js} +3 -3
  5. package/dist/{abletime-rest-PYQM234B.js → abletime-rest-DNFAYYLP.js} +3 -3
  6. package/dist/{abletime-rest-7NICZYOC.js → abletime-rest-DQ3PNKXP.js} +3 -3
  7. package/dist/{agents-KABJUDPI.js → agents-CJZYJOWP.js} +7 -7
  8. package/dist/{agents-2AR7I6B6.js → agents-F2E2HACB.js} +7 -7
  9. package/dist/{app-settings-CZVFMOI5.js → app-settings-KMPVI2B7.js} +1 -1
  10. package/dist/{app-settings-V6YPYY57.js → app-settings-P3H4SEIK.js} +1 -1
  11. package/dist/{chunk-YEIHCSZS.js → chunk-4GZC6DDH.js} +2 -0
  12. package/dist/{chunk-5OM7UCTQ.js → chunk-56M6VEXI.js} +3 -3
  13. package/dist/{chunk-ZM43NTJJ.js → chunk-5OQONGHO.js} +5 -5
  14. package/dist/{chunk-A6C67DY5.js → chunk-5S3YP5KH.js} +4 -4
  15. package/dist/{chunk-QPLQXWND.js → chunk-72PUPPV2.js} +3 -3
  16. package/dist/{chunk-OO3R6CS2.js → chunk-B7UL36WH.js} +214 -37
  17. package/dist/{chunk-WLZHRNE6.js → chunk-BTIXTH4N.js} +3 -3
  18. package/dist/{chunk-AESO2KJS.js → chunk-CB5Z5C3J.js} +2 -2
  19. package/dist/{chunk-AUJ4XB6H.js → chunk-DFUXW2IT.js} +2 -2
  20. package/dist/{chunk-ST2UQBJT.js → chunk-DJZRDTZY.js} +6 -6
  21. package/dist/{chunk-TUJFCJJU.js → chunk-EDXTP2VR.js} +2 -2
  22. package/dist/{chunk-I5TESHDN.js → chunk-EQ52JR3Q.js} +5 -5
  23. package/dist/{chunk-FDXHNROD.js → chunk-EQ5JY3MJ.js} +2 -2
  24. package/dist/{chunk-E52SQENB.js → chunk-FZKAAAEB.js} +3 -1
  25. package/dist/{chunk-JD7CC6SW.js → chunk-HHPTGIKS.js} +2 -2
  26. package/dist/{chunk-U2N32EA6.js → chunk-IDPFLXRY.js} +215 -38
  27. package/dist/{chunk-GCHSJCCX.js → chunk-IFU4W4C4.js} +3 -1
  28. package/dist/{chunk-IAPO7ZFG.js → chunk-LLIEU2ZB.js} +5 -5
  29. package/dist/{chunk-MBYGWNLQ.js → chunk-OAFBHCSM.js} +1 -1
  30. package/dist/{chunk-NRSC4N5X.js → chunk-P74GXA5V.js} +6 -6
  31. package/dist/{chunk-A46CIARU.js → chunk-PNLGWAYE.js} +2 -2
  32. package/dist/{chunk-53OCOGND.js → chunk-QGY3UNNL.js} +2 -2
  33. package/dist/{chunk-7Q327QF2.js → chunk-QIC2JXHW.js} +5 -5
  34. package/dist/{chunk-YALFZKSC.js → chunk-RHJPP26T.js} +11 -11
  35. package/dist/{chunk-AZ4GEEGL.js → chunk-UK2KESBN.js} +2 -2
  36. package/dist/{chunk-LXBZQP2Q.js → chunk-V76MQ7MH.js} +5 -5
  37. package/dist/{chunk-HOLB6ZFZ.js → chunk-XMHMVEIY.js} +2 -0
  38. package/dist/{chunk-GH7UMULC.js → chunk-ZYZBCLJR.js} +6 -6
  39. package/dist/{conductor-MG2RAQNT.js → conductor-FPFY6Z5S.js} +6 -6
  40. package/dist/{conductor-NIUBJLTS.js → conductor-JA5W3L7C.js} +6 -6
  41. package/dist/{coordinator-prompt-3CT3D5UM.js → coordinator-prompt-M75TAN43.js} +4 -4
  42. package/dist/{coordinator-prompt-X74F3JIC.js → coordinator-prompt-NUC2ZXMJ.js} +4 -4
  43. package/dist/{global-workspace-BUWMRNW5.js → global-workspace-5A4H34AF.js} +4 -4
  44. package/dist/{global-workspace-FTNJEML3.js → global-workspace-SCLQUNUI.js} +4 -4
  45. package/dist/index.cjs +589 -402
  46. package/dist/index.d.cts +29 -4
  47. package/dist/index.d.ts +29 -4
  48. package/dist/index.js +28 -28
  49. package/dist/mcp/run-stdio.cjs +219 -32
  50. package/dist/mcp/run-stdio.js +23 -23
  51. package/dist/{optional-cli-EMSZBYDE.js → optional-cli-2V3SLME5.js} +3 -3
  52. package/dist/{optional-cli-6GGESWGE.js → optional-cli-MRNQKVIR.js} +4 -4
  53. package/dist/{orchestrator-H3DSZ5RM.js → orchestrator-7BDZ5GWD.js} +10 -10
  54. package/dist/{orchestrator-NCA4LSCC.js → orchestrator-NPFWU3XU.js} +10 -10
  55. package/dist/{thread-store-PLNIWFZ4.js → thread-store-JWHVXLDX.js} +1 -1
  56. package/dist/{thread-store-7BBA63KV.js → thread-store-QHYN2ZMQ.js} +1 -1
  57. package/dist/{workspaces-2V5UYPYC.js → workspaces-5QA3YM4L.js} +4 -4
  58. package/dist/{workspaces-MGKEAYNM.js → workspaces-KWMBOTQD.js} +4 -4
  59. package/dist/{worktree-THAXW5U7.js → worktree-7EATHVYQ.js} +3 -3
  60. package/dist/{worktree-XJKLDYOL.js → worktree-O6BANO2I.js} +3 -3
  61. package/package.json +1 -1
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  loadAppSettings,
6
6
  saveAppSettings
7
- } from "./chunk-E52SQENB.js";
7
+ } from "./chunk-FZKAAAEB.js";
8
8
 
9
9
  // src/integrations/optional-services.ts
10
10
  var OPTIONAL_SERVICE_IDS = ["vercel", "supabase", "posthog", "sentry"];
@@ -273,7 +273,7 @@ async function connectedCliPresence(integrations) {
273
273
  const ids = connectedOptionalServices(integrations).filter((spec) => spec.cli).map((spec) => spec.id);
274
274
  if (ids.length === 0) return void 0;
275
275
  try {
276
- const { optionalCliPresence } = await import("./optional-cli-6GGESWGE.js");
276
+ const { optionalCliPresence } = await import("./optional-cli-MRNQKVIR.js");
277
277
  return await optionalCliPresence(ids);
278
278
  } catch {
279
279
  return void 0;
@@ -876,7 +876,9 @@ function planHistoryRetention(archived, thresholds = {}) {
876
876
  if (archivedUpdatedMs(thread) < cutoff) expiredIds.add(thread.id);
877
877
  }
878
878
  }
879
- const remaining = oldestFirst.filter((t) => !expiredIds.has(t.id));
879
+ const remaining = oldestFirst.filter(
880
+ (t) => !expiredIds.has(t.id) && !t.ephemeralAutomationId?.trim()
881
+ );
880
882
  const overflow = remaining.length > maxCount ? remaining.slice(0, remaining.length - maxCount) : [];
881
883
  const stripIds = [];
882
884
  const purgeIds = [...expiredIds];
@@ -6,14 +6,14 @@ import {
6
6
  normalizeAbleTimeCredential,
7
7
  normalizeAbleTimeHost,
8
8
  rewriteAbleTimeError
9
- } from "./chunk-ZM43NTJJ.js";
9
+ } from "./chunk-5OQONGHO.js";
10
10
  import {
11
11
  httpFetch
12
12
  } from "./chunk-2GPQZZLY.js";
13
13
  import {
14
14
  getAbleTimeAccessToken,
15
15
  getAbleTimeHost
16
- } from "./chunk-GCHSJCCX.js";
16
+ } from "./chunk-IFU4W4C4.js";
17
17
 
18
18
  // src/integrations/abletime-rest.ts
19
19
  var ABLETIME_REST_PREFIX = "/api/public/v2";
@@ -14,7 +14,7 @@ import {
14
14
  parseSessionQuotaResetAt,
15
15
  planModeTurnInstruction,
16
16
  resolveQuotaFallbackAgent
17
- } from "./chunk-IAPO7ZFG.js";
17
+ } from "./chunk-LLIEU2ZB.js";
18
18
  import {
19
19
  applyWorktreePkgCacheEnv,
20
20
  askBlockStillWaiting,
@@ -52,7 +52,7 @@ import {
52
52
  worktreeDevProcessKey,
53
53
  worktreeRunProcessKey,
54
54
  worktreeSetupProcessKey
55
- } from "./chunk-ST2UQBJT.js";
55
+ } from "./chunk-DJZRDTZY.js";
56
56
  import {
57
57
  applyAgentEvent,
58
58
  clipAgentEventForPaint,
@@ -67,14 +67,14 @@ import {
67
67
  partsToAssistantText,
68
68
  stripBrightsyNdjsonNoise,
69
69
  toolDescription
70
- } from "./chunk-7Q327QF2.js";
70
+ } from "./chunk-QIC2JXHW.js";
71
71
  import {
72
72
  titleFromPrompt
73
73
  } from "./chunk-7H655NEW.js";
74
74
  import {
75
75
  formatOptionalServicesDirectiveForTurn,
76
76
  formatOptionalServicesReminderForTurn
77
- } from "./chunk-FDXHNROD.js";
77
+ } from "./chunk-EQ5JY3MJ.js";
78
78
  import {
79
79
  SLACK_REPLY_FORMATTING,
80
80
  addWorkspace,
@@ -99,7 +99,7 @@ import {
99
99
  stageAbsolutePathsAsAttachments,
100
100
  stageBuffersAsAttachments,
101
101
  syncWorkspacesFromThreads
102
- } from "./chunk-YALFZKSC.js";
102
+ } from "./chunk-RHJPP26T.js";
103
103
  import {
104
104
  addPrStackLayer,
105
105
  allocateTeamSlug,
@@ -143,7 +143,7 @@ import {
143
143
  resolveRepoRoot,
144
144
  switchWorktreeBranch,
145
145
  withRepoGitLock
146
- } from "./chunk-TUJFCJJU.js";
146
+ } from "./chunk-EDXTP2VR.js";
147
147
  import {
148
148
  REVIEW_TAB_TITLE,
149
149
  agentNicknameFromWorktreePath,
@@ -171,7 +171,7 @@ import {
171
171
  worktreeNameFromPath,
172
172
  worktreeSlugForTicket,
173
173
  writeThread
174
- } from "./chunk-YEIHCSZS.js";
174
+ } from "./chunk-4GZC6DDH.js";
175
175
  import {
176
176
  mcpServerIdForPermission,
177
177
  mcpServerPermissionUpdate
@@ -239,7 +239,10 @@ import {
239
239
  usageOnLimit,
240
240
  withTurnScopedCost,
241
241
  writeViewerContext
242
- } from "./chunk-E52SQENB.js";
242
+ } from "./chunk-FZKAAAEB.js";
243
+ import {
244
+ normalizeThinkingEffort
245
+ } from "./chunk-77WWLBCI.js";
243
246
  import {
244
247
  examplePrefixedBranch,
245
248
  sanitizeGitBranchPrefix
@@ -461,9 +464,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
461
464
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
462
465
  );
463
466
  }
464
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-FTNJEML3.js");
467
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-SCLQUNUI.js");
465
468
  if (isGlobalThread2(thread)) {
466
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-X74F3JIC.js");
469
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-NUC2ZXMJ.js");
467
470
  ensureGlobalCoordinatorCwd2(
468
471
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
469
472
  );
@@ -2074,6 +2077,71 @@ function claimSteerRequest(threadId) {
2074
2077
  });
2075
2078
  }
2076
2079
 
2080
+ // src/orchestrator/ephemeral-automation.ts
2081
+ function ephemeralRunReadyToArchive(thread) {
2082
+ if (!thread.ephemeralAutomationId?.trim()) return false;
2083
+ if (thread.status !== "idle" && thread.status !== "error") return false;
2084
+ if (thread.queue.length > 0) return false;
2085
+ if (thread.agentBlock?.reason?.trim()) return false;
2086
+ if (thread.quotaResumeAt) return false;
2087
+ return true;
2088
+ }
2089
+ function markEphemeralAutomation(threadId, opts) {
2090
+ const id = opts.ephemeralAutomationId?.trim();
2091
+ const current = readThread(threadId);
2092
+ if (!current) throw new Error(`Thread not found: ${threadId}`);
2093
+ if (!id) return current;
2094
+ const title = opts.ephemeralTitle?.trim();
2095
+ return updateThread(threadId, {
2096
+ ephemeralAutomationId: id,
2097
+ ...title ? { title, userSetTitle: true } : {}
2098
+ });
2099
+ }
2100
+ async function archiveEphemeralAutomationIfReady(threadId, archive) {
2101
+ const keep = await withThreadLock(threadId, async () => {
2102
+ const thread = readThread(threadId);
2103
+ if (!thread || !ephemeralRunReadyToArchive(thread)) return null;
2104
+ const automationId = thread.ephemeralAutomationId?.trim();
2105
+ if (!automationId) return null;
2106
+ await archive(thread.id);
2107
+ return {
2108
+ automationId,
2109
+ keepId: archivedContinuationId(automationId, threadId) ?? threadId
2110
+ };
2111
+ });
2112
+ if (keep) forgetOlderEphemeralRuns(keep.automationId, keep.keepId);
2113
+ }
2114
+ function archivedContinuationId(automationId, sourceId) {
2115
+ for (const thread of listThreads({ includeArchived: true })) {
2116
+ if (thread.id === sourceId || thread.status !== "archived") continue;
2117
+ if (thread.ephemeralAutomationId !== automationId) continue;
2118
+ if (thread.quotaContinuedFromId !== sourceId) continue;
2119
+ return thread.id;
2120
+ }
2121
+ return null;
2122
+ }
2123
+ function clearEphemeralAutomation(threadId) {
2124
+ const thread = readThread(threadId);
2125
+ if (!thread?.ephemeralAutomationId?.trim()) return;
2126
+ updateThread(threadId, { ephemeralAutomationId: void 0 });
2127
+ }
2128
+ function forgetOlderEphemeralRuns(automationId, keepId) {
2129
+ const id = automationId.trim();
2130
+ if (!id || !keepId) return [];
2131
+ const removed = [];
2132
+ for (const thread of listThreads({ includeArchived: true })) {
2133
+ if (thread.id === keepId) continue;
2134
+ if (thread.status !== "archived") continue;
2135
+ if (thread.ephemeralAutomationId !== id) continue;
2136
+ try {
2137
+ deleteThreadRecord(thread.id);
2138
+ removed.push(thread.id);
2139
+ } catch {
2140
+ }
2141
+ }
2142
+ return removed;
2143
+ }
2144
+
2077
2145
  // src/threads/agent-purpose-title.ts
2078
2146
  function agentPurposeStamp(input) {
2079
2147
  if (input.autoContinue) return null;
@@ -2930,7 +2998,7 @@ async function createThread(input, _onSetupLine) {
2930
2998
  });
2931
2999
  await requireAgent(resolved.agent);
2932
3000
  if (input.cowboy) {
2933
- const { cowboyModeEnabled } = await import("./app-settings-V6YPYY57.js");
3001
+ const { cowboyModeEnabled } = await import("./app-settings-P3H4SEIK.js");
2934
3002
  if (!cowboyModeEnabled()) {
2935
3003
  throw new Error(
2936
3004
  "Cowboy mode is off. Enable it in Settings \u2192 Advanced."
@@ -2989,7 +3057,7 @@ async function createThread(input, _onSetupLine) {
2989
3057
  let sourceIsFork = false;
2990
3058
  if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
2991
3059
  if (isAbleTimeConnected() && getIssueSource() === "abletime") {
2992
- const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-DVYO4IVS.js");
3060
+ const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-ICW6Q2AB.js");
2993
3061
  const task = await ensureAbleTimeTask({
2994
3062
  title: title?.trim() || "Untitled work",
2995
3063
  description: input.prompt?.trim() || void 0
@@ -3100,7 +3168,7 @@ async function createThread(input, _onSetupLine) {
3100
3168
  return readThread(thread.id) ?? thread;
3101
3169
  }
3102
3170
  async function listLinearIssues(agent, repoPath) {
3103
- const { getAdapter: getAdapter2 } = await import("./agents-2AR7I6B6.js");
3171
+ const { getAdapter: getAdapter2 } = await import("./agents-F2E2HACB.js");
3104
3172
  await requireAgent(agent, { requireLinear: true });
3105
3173
  const adapter = getAdapter2(agent);
3106
3174
  if (!adapter.listLinearIssues) {
@@ -3760,17 +3828,23 @@ async function isolateQuotaFailover(run) {
3760
3828
  }
3761
3829
  }
3762
3830
  function createQuotaFailoverChat(from, fallbackAgent, limitText, opts) {
3831
+ const ephemeralAutomationId = from.ephemeralAutomationId?.trim();
3832
+ const ephemeralTitle = ephemeralAutomationId ? from.title.trim() : "";
3763
3833
  const handoff = buildQuotaHandoffAttachment(from, limitText, fallbackAgent);
3764
3834
  const tab = createChatTab({
3765
3835
  fromThreadId: from.id,
3766
3836
  agent: fallbackAgent,
3767
3837
  model: null,
3768
3838
  attachments: [handoff],
3839
+ ...ephemeralTitle ? { title: ephemeralTitle } : {},
3769
3840
  ...opts && "accountId" in opts ? { accountId: opts.accountId } : {}
3770
3841
  });
3771
3842
  const patch = {
3772
3843
  quotaContinuedFromId: from.id,
3773
- sourceRef: from.sourceRef
3844
+ sourceRef: from.sourceRef,
3845
+ // The original drain archives as idle. This sibling has to carry the one-off
3846
+ // so it archives when the continued turn finishes and History keeps it.
3847
+ ...ephemeralAutomationId ? { ephemeralAutomationId } : {}
3774
3848
  };
3775
3849
  if (isOrchestratorThread(from)) {
3776
3850
  patch.parentThreadId = from.id;
@@ -3877,7 +3951,7 @@ async function adoptThread(input) {
3877
3951
  messages: input.messages ?? []
3878
3952
  });
3879
3953
  writeThread(thread);
3880
- const { addWorkspace: addWorkspace2 } = await import("./workspaces-MGKEAYNM.js");
3954
+ const { addWorkspace: addWorkspace2 } = await import("./workspaces-KWMBOTQD.js");
3881
3955
  await addWorkspace2(repoPath);
3882
3956
  const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-RXZPTCNH.js");
3883
3957
  await ensureWorktreeSideboardIgnored(input.worktreePath);
@@ -6072,7 +6146,7 @@ function formatWorktreeDirective(thread, opts) {
6072
6146
  lines.push(formatDevAccessHint(opts?.activeRuns));
6073
6147
  lines.push("");
6074
6148
  lines.push(
6075
- "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."
6149
+ "Automations (sidebar, after Board): `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 automations are enabled."
6076
6150
  );
6077
6151
  lines.push(
6078
6152
  "`set_workspace_tags` labels this checkout (omit ref; replace, add, or remove). Not another checkout."
@@ -6092,7 +6166,7 @@ function connectedOrchestratorTurnReminder(thread, find) {
6092
6166
  return formatConnectedOrchestratorReminder(connectedOrchestrator(thread, find));
6093
6167
  }
6094
6168
  function formatWorktreeReminder() {
6095
- 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). set_workspace_tags updates labels on this workspace (omit ref).";
6169
+ 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. Automations: create_schedule (at / every / cron; chatId=self for this chat). set_workspace_tags updates labels on this workspace (omit ref).";
6096
6170
  }
6097
6171
  function formatClaudeSubagentReminder() {
6098
6172
  return 'Claude subagents: if Task/Agent workers will edit files, write a short plan in this chat and continue in the same turn. Do not ask the user whether to isolate, and do not set worktree.bgIsolation to none. One writer may edit this workspace. Every other writer is an Agent with isolation "worktree" and a disjoint file list (read-only explore agents may overlap). While those agents run, leave their files alone. Merge each returned branch into this workspace, then remove the temporary worktree. You stay in this cwd. If Claude says another write-capable agent is in this directory, or that writes to the shared checkout are blocked, re-spawn that agent with isolation "worktree" or make the edit yourself. That note is another worker in this chat, or a worker Claude still has marked running. Do not mention it to the user.';
@@ -6732,7 +6806,7 @@ function parseDurationMs(every) {
6732
6806
  }
6733
6807
  function defaultScheduleName(prompt) {
6734
6808
  const line = prompt.trim().split(/\r?\n/, 1)[0]?.trim() ?? "";
6735
- if (!line) return "Untitled schedule";
6809
+ if (!line) return "Untitled automation";
6736
6810
  return line.length > 60 ? `${line.slice(0, 57).trimEnd()}\u2026` : line;
6737
6811
  }
6738
6812
  function resolveScheduleThreadId(raw, env = process.env) {
@@ -6803,6 +6877,45 @@ function normalizeWhen(raw) {
6803
6877
  }
6804
6878
  throw new Error("Schedule `when` must be once, every, or cron");
6805
6879
  }
6880
+ var ATTACHMENT_KINDS = /* @__PURE__ */ new Set([
6881
+ "transcript",
6882
+ "file",
6883
+ "issue",
6884
+ "workspace",
6885
+ "diff-comment",
6886
+ "code-ref"
6887
+ ]);
6888
+ function normalizeOptionalBool(raw) {
6889
+ if (raw === true || raw === false) return raw;
6890
+ return null;
6891
+ }
6892
+ function normalizeAutonomy(raw) {
6893
+ return raw === "default" || raw === "full" ? raw : null;
6894
+ }
6895
+ function normalizeAttachments(raw) {
6896
+ if (!Array.isArray(raw)) return [];
6897
+ const out = [];
6898
+ for (const item of raw) {
6899
+ if (!item || typeof item !== "object") continue;
6900
+ const row = item;
6901
+ if (typeof row.id !== "string" || !row.id.trim()) continue;
6902
+ if (typeof row.name !== "string" || !row.name) continue;
6903
+ if (typeof row.content !== "string") continue;
6904
+ if (!ATTACHMENT_KINDS.has(row.kind)) continue;
6905
+ const next = {
6906
+ id: row.id,
6907
+ name: row.name,
6908
+ kind: row.kind,
6909
+ content: row.content
6910
+ };
6911
+ if (typeof row.path === "string" && row.path) next.path = row.path;
6912
+ if (typeof row.previewDataUrl === "string" && row.previewDataUrl) {
6913
+ next.previewDataUrl = row.previewDataUrl;
6914
+ }
6915
+ out.push(next);
6916
+ }
6917
+ return out;
6918
+ }
6806
6919
  function normalizeTask(raw) {
6807
6920
  const when = normalizeWhen(raw.when);
6808
6921
  const agent = raw.agent && isOrchestratorCapableAgent(raw.agent) ? raw.agent : null;
@@ -6815,6 +6928,11 @@ function normalizeTask(raw) {
6815
6928
  threadId: raw.threadId?.trim() || null,
6816
6929
  agent,
6817
6930
  model: raw.model?.trim() || null,
6931
+ effort: normalizeThinkingEffort(raw.effort),
6932
+ fast: normalizeOptionalBool(raw.fast),
6933
+ planMode: normalizeOptionalBool(raw.planMode),
6934
+ autonomy: normalizeAutonomy(raw.autonomy),
6935
+ attachments: normalizeAttachments(raw.attachments),
6818
6936
  nextRunAt: raw.nextRunAt,
6819
6937
  lastRunAt: raw.lastRunAt ?? null,
6820
6938
  lastThreadId: raw.lastThreadId ?? null,
@@ -6861,6 +6979,11 @@ function buildTask(input, now) {
6861
6979
  threadId: input.threadId?.trim() || null,
6862
6980
  agent,
6863
6981
  model: input.model?.trim() || null,
6982
+ effort: input.effort != null ? normalizeThinkingEffort(input.effort) : null,
6983
+ fast: normalizeOptionalBool(input.fast),
6984
+ planMode: normalizeOptionalBool(input.planMode),
6985
+ autonomy: normalizeAutonomy(input.autonomy),
6986
+ attachments: normalizeAttachments(input.attachments),
6864
6987
  nextRunAt,
6865
6988
  lastRunAt: null,
6866
6989
  lastThreadId: null,
@@ -6905,7 +7028,7 @@ function createSchedule(input) {
6905
7028
  function updateSchedule(id, patch) {
6906
7029
  const rows = readAll();
6907
7030
  const idx = rows.findIndex((row) => row.id === id || id.length >= 8 && row.id.startsWith(id));
6908
- if (idx < 0) throw new Error(`Schedule not found: ${id}`);
7031
+ if (idx < 0) throw new Error(`Automation not found: ${id}`);
6909
7032
  const prev = rows[idx];
6910
7033
  const when = patch.when ? normalizeWhen(patch.when) : prev.when;
6911
7034
  const prompt = patch.prompt !== void 0 ? patch.prompt.trim() : prev.prompt;
@@ -6920,6 +7043,11 @@ function updateSchedule(id, patch) {
6920
7043
  threadId: patch.threadId !== void 0 ? patch.threadId?.trim() || null : prev.threadId,
6921
7044
  agent: patch.agent !== void 0 ? patch.agent ? coerceOrchestratorAgent(patch.agent) : null : prev.agent,
6922
7045
  model: patch.model !== void 0 ? patch.model?.trim() || null : prev.model,
7046
+ effort: patch.effort !== void 0 ? normalizeThinkingEffort(patch.effort) : prev.effort,
7047
+ fast: patch.fast !== void 0 ? normalizeOptionalBool(patch.fast) : prev.fast,
7048
+ planMode: patch.planMode !== void 0 ? normalizeOptionalBool(patch.planMode) : prev.planMode,
7049
+ autonomy: patch.autonomy !== void 0 ? normalizeAutonomy(patch.autonomy) : prev.autonomy,
7050
+ attachments: patch.attachments !== void 0 ? normalizeAttachments(patch.attachments) : prev.attachments,
6923
7051
  nextRunAt: whenChanged ? computeNextRunAt(when).toISOString() : prev.nextRunAt,
6924
7052
  lastError: whenChanged ? null : prev.lastError,
6925
7053
  updatedAt: nowIso()
@@ -6934,13 +7062,13 @@ function deleteSchedule(id) {
6934
7062
  const next = rows.filter(
6935
7063
  (row) => row.id !== id && !(id.length >= 8 && row.id.startsWith(id))
6936
7064
  );
6937
- if (next.length === rows.length) throw new Error(`Schedule not found: ${id}`);
7065
+ if (next.length === rows.length) throw new Error(`Automation not found: ${id}`);
6938
7066
  writeAll(next);
6939
7067
  }
6940
7068
  function recordScheduleRun(id, result) {
6941
7069
  const rows = readAll();
6942
7070
  const idx = rows.findIndex((row) => row.id === id);
6943
- if (idx < 0) throw new Error(`Schedule not found: ${id}`);
7071
+ if (idx < 0) throw new Error(`Automation not found: ${id}`);
6944
7072
  const prev = rows[idx];
6945
7073
  const firedAt = result.firedAt ?? /* @__PURE__ */ new Date();
6946
7074
  const next = {
@@ -6967,21 +7095,56 @@ function formatScheduledPrompt(name, prompt) {
6967
7095
  ${prompt}`;
6968
7096
  }
6969
7097
  async function defaultDeps() {
6970
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-NCA4LSCC.js");
7098
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-NPFWU3XU.js");
6971
7099
  const orch = getOrchestrator2();
6972
7100
  return {
6973
7101
  findThread: (id) => findThreadByRef(id),
6974
- send: (id, prompt) => orch.send(id, prompt),
7102
+ send: async (id, prompt, opts) => {
7103
+ if (opts?.options && Object.keys(opts.options).length > 0) {
7104
+ try {
7105
+ orch.setThreadOptions(id, opts.options);
7106
+ } catch {
7107
+ const rest = scheduleOptionsAfterRefusedAgentSwitch(opts.options);
7108
+ if (Object.keys(rest).length > 0) {
7109
+ try {
7110
+ orch.setThreadOptions(id, rest);
7111
+ } catch {
7112
+ }
7113
+ }
7114
+ }
7115
+ }
7116
+ const thread = findThreadByRef(id);
7117
+ const attachments = thread ? persistPendingFileAttachments(thread.worktreePath, opts?.attachments ?? []) : opts?.attachments ?? [];
7118
+ return orch.send(id, prompt, { attachments });
7119
+ },
6975
7120
  startOrchestration: (opts) => startOrchestration2(opts)
6976
7121
  };
6977
7122
  }
7123
+ function scheduleOptionsAfterRefusedAgentSwitch(options) {
7124
+ const { agent: _agent, model: _model, ...rest } = options;
7125
+ return rest;
7126
+ }
7127
+ function scheduleSendOptions(schedule) {
7128
+ const patch = {};
7129
+ if (schedule.agent) {
7130
+ patch.agent = schedule.agent;
7131
+ patch.model = schedule.model;
7132
+ } else if (schedule.model) {
7133
+ patch.model = schedule.model;
7134
+ }
7135
+ if (schedule.effort) patch.effort = schedule.effort;
7136
+ if (schedule.fast != null) patch.fast = schedule.fast;
7137
+ if (schedule.planMode != null) patch.planMode = schedule.planMode;
7138
+ if (schedule.autonomy) patch.autonomy = schedule.autonomy;
7139
+ return Object.keys(patch).length > 0 ? patch : void 0;
7140
+ }
6978
7141
  function pickAgent(schedule) {
6979
7142
  if (schedule.agent) return schedule.agent;
6980
7143
  return coerceOrchestratorAgent(resolveOrchestratorDefaults().agent);
6981
7144
  }
6982
7145
  async function fireSchedule(id) {
6983
7146
  const schedule = getSchedule(id);
6984
- if (!schedule) throw new Error(`Schedule not found: ${id}`);
7147
+ if (!schedule) throw new Error(`Automation not found: ${id}`);
6985
7148
  if (firing.has(schedule.id)) return schedule;
6986
7149
  firing.add(schedule.id);
6987
7150
  try {
@@ -6989,18 +7152,28 @@ async function fireSchedule(id) {
6989
7152
  const prompt = formatScheduledPrompt(schedule.name, schedule.prompt);
6990
7153
  const target = schedule.threadId ? deps.findThread(schedule.threadId) : null;
6991
7154
  if (target && target.status !== "archived") {
6992
- const sent = await deps.send(target.id, prompt);
7155
+ const sent = await deps.send(target.id, prompt, {
7156
+ attachments: schedule.attachments,
7157
+ options: scheduleSendOptions(schedule)
7158
+ });
6993
7159
  return recordScheduleRun(schedule.id, {
6994
7160
  lastThreadId: sent.id,
6995
7161
  lastError: null
6996
7162
  });
6997
7163
  }
7164
+ const pinReplacement = Boolean(schedule.threadId) && schedule.when.kind !== "once";
6998
7165
  const created = await deps.startOrchestration({
6999
7166
  goal: prompt,
7000
7167
  agent: pickAgent(schedule),
7001
- model: schedule.model
7168
+ model: schedule.model,
7169
+ ...schedule.effort ? { effort: schedule.effort } : {},
7170
+ ...schedule.fast != null ? { fast: schedule.fast } : {},
7171
+ ...schedule.planMode != null ? { planMode: schedule.planMode } : {},
7172
+ ...schedule.autonomy ? { autonomy: schedule.autonomy } : {},
7173
+ attachments: schedule.attachments,
7174
+ ...pinReplacement ? {} : { ephemeralAutomationId: schedule.id, ephemeralTitle: schedule.name }
7002
7175
  });
7003
- if (schedule.threadId && schedule.when.kind !== "once") {
7176
+ if (pinReplacement) {
7004
7177
  updateSchedule(schedule.id, { threadId: created.id });
7005
7178
  }
7006
7179
  return recordScheduleRun(schedule.id, {
@@ -7288,7 +7461,7 @@ var Orchestrator = class {
7288
7461
  orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
7289
7462
  });
7290
7463
  }
7291
- const { autoCleanupOrphansEnabled } = await import("./app-settings-V6YPYY57.js");
7464
+ const { autoCleanupOrphansEnabled } = await import("./app-settings-P3H4SEIK.js");
7292
7465
  if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
7293
7466
  await cleanupOrphanWorktrees({ repoPaths });
7294
7467
  }
@@ -7682,7 +7855,7 @@ var Orchestrator = class {
7682
7855
  }
7683
7856
  await setup;
7684
7857
  if (skipSetup) return;
7685
- const { autoRunAfterSetupEnabled } = await import("./app-settings-V6YPYY57.js");
7858
+ const { autoRunAfterSetupEnabled } = await import("./app-settings-P3H4SEIK.js");
7686
7859
  if (autoRunAfterSetupEnabled()) {
7687
7860
  try {
7688
7861
  await this.startDev(threadId);
@@ -7891,6 +8064,7 @@ var Orchestrator = class {
7891
8064
  } finally {
7892
8065
  this.draining.delete(threadId);
7893
8066
  }
8067
+ await archiveEphemeralAutomationIfReady(threadId, (id) => this.archive(id));
7894
8068
  }
7895
8069
  async runTurn(threadId, prompt) {
7896
8070
  const existing = readThread(threadId);
@@ -8058,7 +8232,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
8058
8232
  }
8059
8233
  const isBrightsy = fresh.agent === "brightsy";
8060
8234
  const isOrchestration = isOrchestratorThread(fresh);
8061
- const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-V6YPYY57.js");
8235
+ const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-P3H4SEIK.js");
8062
8236
  const gitAuthMode = getGithubGitAuthMode();
8063
8237
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
8064
8238
  githubSlug: await withTimeout(
@@ -9386,7 +9560,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
9386
9560
  if (Object.keys(patch).length === 0) continue;
9387
9561
  updateThread(t.id, patch);
9388
9562
  }
9389
- const { autoArchiveOnMergeEnabled } = await import("./app-settings-V6YPYY57.js");
9563
+ const { autoArchiveOnMergeEnabled } = await import("./app-settings-P3H4SEIK.js");
9390
9564
  const latest = this.requireThread(thread.id);
9391
9565
  if (!shouldAutoArchiveOnPrMerge({
9392
9566
  previousPrState: prevState || null,
@@ -9710,7 +9884,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
9710
9884
  await runArchiveScript(thread.repoPath, thread.worktreePath);
9711
9885
  } catch {
9712
9886
  }
9713
- const { deleteBranchOnPurgeEnabled } = await import("./app-settings-V6YPYY57.js");
9887
+ const { deleteBranchOnPurgeEnabled } = await import("./app-settings-P3H4SEIK.js");
9714
9888
  const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
9715
9889
  await removeWorktree(thread.repoPath, thread.worktreePath, {
9716
9890
  deleteBranch: deleteBranch ? thread.branchName : void 0
@@ -9724,6 +9898,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
9724
9898
  if (thread.status !== "archived") {
9725
9899
  throw new Error("Thread is not archived");
9726
9900
  }
9901
+ clearEphemeralAutomation(thread.id);
9727
9902
  if (isGlobalThread(thread)) {
9728
9903
  const { globalAgentCwd } = await import("./paths-PHWEVXD5.js");
9729
9904
  updateThread(thread.id, { worktreePath: globalAgentCwd() });
@@ -9823,10 +9998,11 @@ async function startOrchestration(opts) {
9823
9998
  planMode: opts.planMode,
9824
9999
  attachments: opts.attachments
9825
10000
  });
10001
+ const ready2 = markEphemeralAutomation(thread2.id, opts);
9826
10002
  if (goal) {
9827
- return orch.send(thread2.id, goal);
10003
+ return orch.send(ready2.id, goal);
9828
10004
  }
9829
- return thread2;
10005
+ return ready2;
9830
10006
  }
9831
10007
  const { titleFromPrompt: titleFromPrompt2 } = await import("./title-Z7WAJN57.js");
9832
10008
  const title = titleFromPrompt2(goal) || "Orchestration";
@@ -9846,7 +10022,7 @@ async function startOrchestration(opts) {
9846
10022
  sourceRef: "default",
9847
10023
  ...createOpts
9848
10024
  }).catch(async () => {
9849
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-THAXW5U7.js");
10025
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-7EATHVYQ.js");
9850
10026
  const repo = await resolveRepoRoot2(repoPath);
9851
10027
  const def = await resolveDefaultBranch2(repo);
9852
10028
  return orch.createThread({
@@ -9856,15 +10032,16 @@ async function startOrchestration(opts) {
9856
10032
  repoPath: repo
9857
10033
  });
9858
10034
  });
9859
- const { updateThread: upd } = await import("./thread-store-7BBA63KV.js");
10035
+ const { updateThread: upd } = await import("./thread-store-QHYN2ZMQ.js");
9860
10036
  const updated = upd(thread.id, {
9861
10037
  sourceType: "orchestration",
9862
10038
  sourceRef: goal
9863
10039
  });
10040
+ const ready = markEphemeralAutomation(updated.id, opts);
9864
10041
  if (goal) {
9865
- return orch.send(updated.id, goal);
10042
+ return orch.send(ready.id, goal);
9866
10043
  }
9867
- return updated;
10044
+ return ready;
9868
10045
  }
9869
10046
 
9870
10047
  export {
@@ -661,7 +661,9 @@ function planHistoryRetention(archived, thresholds = {}) {
661
661
  if (archivedUpdatedMs(thread) < cutoff) expiredIds.add(thread.id);
662
662
  }
663
663
  }
664
- const remaining = oldestFirst.filter((t) => !expiredIds.has(t.id));
664
+ const remaining = oldestFirst.filter(
665
+ (t) => !expiredIds.has(t.id) && !t.ephemeralAutomationId?.trim()
666
+ );
665
667
  const overflow = remaining.length > maxCount ? remaining.slice(0, remaining.length - maxCount) : [];
666
668
  const stripIds = [];
667
669
  const purgeIds = [...expiredIds];
@@ -9,16 +9,16 @@ import {
9
9
  looksLikeSkillBody,
10
10
  skillCommandFromBody,
11
11
  withEventParentId
12
- } from "./chunk-7Q327QF2.js";
12
+ } from "./chunk-QIC2JXHW.js";
13
13
  import {
14
14
  isOrchestratorThread
15
- } from "./chunk-YALFZKSC.js";
15
+ } from "./chunk-RHJPP26T.js";
16
16
  import {
17
17
  codexUnattendedGitConfigArgs,
18
18
  mergeAgentGitAuthEnv,
19
19
  resolveAgentGitAuthEnv,
20
20
  resolveCodexGitWritableRoots
21
- } from "./chunk-TUJFCJJU.js";
21
+ } from "./chunk-EDXTP2VR.js";
22
22
  import {
23
23
  loadBrightsyConfig
24
24
  } from "./chunk-RSA47QYR.js";
@@ -76,7 +76,7 @@ import {
76
76
  loadAppSettings,
77
77
  resolveAgentExecutable,
78
78
  resolveClaudeExecutable
79
- } from "./chunk-E52SQENB.js";
79
+ } from "./chunk-FZKAAAEB.js";
80
80
  import {
81
81
  isElectronLikeCommand,
82
82
  unwrapStrippedElectronLaunch
@@ -2609,7 +2609,7 @@ var claudeAdapter = {
2609
2609
  );
2610
2610
  }
2611
2611
  const mode = permissionMode(thread);
2612
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-FTNJEML3.js");
2612
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-SCLQUNUI.js");
2613
2613
  const isOrchestrator = isOrchestratorThread2(thread);
2614
2614
  const rpc = worktreeAgentRpc(isOrchestrator);
2615
2615
  const injectedServers = await buildInjectedMcpServers({
@@ -125,7 +125,7 @@ async function connectedCliPresence(integrations) {
125
125
  const ids = connectedOptionalServices(integrations).filter((spec) => spec.cli).map((spec) => spec.id);
126
126
  if (ids.length === 0) return void 0;
127
127
  try {
128
- const { optionalCliPresence } = await import("./optional-cli-EMSZBYDE.js");
128
+ const { optionalCliPresence } = await import("./optional-cli-2V3SLME5.js");
129
129
  return await optionalCliPresence(ids);
130
130
  } catch {
131
131
  return void 0;