@sideboard-ai/core 0.1.252 → 0.1.253

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 (27) hide show
  1. package/dist/{agents-B66CNEPB.js → agents-6HDC7UA7.js} +3 -3
  2. package/dist/{agents-C7T4US6D.js → agents-RKZ2NBIV.js} +3 -3
  3. package/dist/{chunk-AQQWP2TL.js → chunk-46KDLP6T.js} +37 -25
  4. package/dist/{chunk-4DGYMF7H.js → chunk-6ZYSXLXK.js} +16 -4
  5. package/dist/{chunk-FKGVQKRX.js → chunk-GZRS5QVL.js} +38 -26
  6. package/dist/{chunk-6IP4FWMK.js → chunk-IAS7Q2YF.js} +2 -2
  7. package/dist/{chunk-SJ3IUYG2.js → chunk-JUYD2YUC.js} +2 -2
  8. package/dist/{chunk-BHPGORIY.js → chunk-MLB5CFUP.js} +22 -5
  9. package/dist/{chunk-NYXDZCMP.js → chunk-PLMMPA6A.js} +18 -2
  10. package/dist/{chunk-PV4KCI2S.js → chunk-WVNQML4W.js} +18 -2
  11. package/dist/{coordinator-prompt-A2JJ5X7B.js → coordinator-prompt-JKW7YZOC.js} +2 -2
  12. package/dist/{coordinator-prompt-BX2R5EMW.js → coordinator-prompt-YSIC6YFC.js} +2 -2
  13. package/dist/{global-workspace-PUJEGSOB.js → global-workspace-3Q57XYG4.js} +2 -2
  14. package/dist/{global-workspace-JJRPZNTY.js → global-workspace-DMR5JB7T.js} +2 -2
  15. package/dist/index.cjs +657 -606
  16. package/dist/index.d.cts +14 -9
  17. package/dist/index.d.ts +14 -9
  18. package/dist/index.js +22 -14
  19. package/dist/mcp/run-stdio.cjs +73 -29
  20. package/dist/mcp/run-stdio.js +21 -14
  21. package/dist/{orchestrator-O3V4UH73.js → orchestrator-PJCQSVLY.js} +4 -4
  22. package/dist/{orchestrator-O3TVI7SN.js → orchestrator-W6DUFWVE.js} +4 -4
  23. package/dist/{workspaces-V3PZRTY5.js → workspaces-6A3ASHHI.js} +2 -2
  24. package/dist/{workspaces-FUOZIR3V.js → workspaces-PS3IO4VJ.js} +2 -2
  25. package/dist/{worktree-UK62JCYF.js → worktree-7WTVHFGF.js} +1 -1
  26. package/dist/{worktree-4DNK2CK6.js → worktree-DLSVHUF6.js} +1 -1
  27. package/package.json +1 -1
@@ -6886,6 +6886,7 @@ function parsePrDetailsView(view) {
6886
6886
  const author = view.author ?? {};
6887
6887
  const comments = Array.isArray(view.comments) ? view.comments : [];
6888
6888
  const reviews = Array.isArray(view.reviews) ? view.reviews : [];
6889
+ const commits = Array.isArray(view.commits) ? view.commits : [];
6889
6890
  const requested = {
6890
6891
  ids: reviewerIdentities(view.reviewRequests),
6891
6892
  users: humanReviewerLogins(view.reviewRequests),
@@ -6906,8 +6907,22 @@ function parsePrDetailsView(view) {
6906
6907
  additions: Number(view.additions ?? 0),
6907
6908
  deletions: Number(view.deletions ?? 0),
6908
6909
  changedFiles: Number(view.changedFiles ?? 0),
6909
- // Commits live in Changes; omit from GraphQL to save rate-limit points.
6910
- commits: [],
6910
+ commits: commits.map((c) => {
6911
+ const row = c;
6912
+ const authors = Array.isArray(row.authors) ? row.authors.map((a) => {
6913
+ const actor = a;
6914
+ return {
6915
+ login: actor.login?.trim() || actor.name?.trim() || "unknown",
6916
+ name: actor.name ?? null
6917
+ };
6918
+ }) : [];
6919
+ return {
6920
+ oid: String(row.oid ?? ""),
6921
+ messageHeadline: String(row.messageHeadline ?? ""),
6922
+ committedDate: String(row.committedDate ?? ""),
6923
+ authors
6924
+ };
6925
+ }),
6911
6926
  comments: comments.map((c) => {
6912
6927
  const row = c;
6913
6928
  const a = row.author ?? {};
@@ -7718,6 +7733,7 @@ var init_worktree = __esm({
7718
7733
  "additions",
7719
7734
  "deletions",
7720
7735
  "changedFiles",
7736
+ "commits",
7721
7737
  "comments",
7722
7738
  "reviews",
7723
7739
  "assignees",
@@ -8399,7 +8415,7 @@ var init_coordinator_prompt = __esm({
8399
8415
  "- ask_user \u2014 composer multiple-choice only when blocked on a concrete choice (approach fork, which API, Save this context / Do not save). Never for hellos, check-ins, invented \u201Cwhat should we do?\u201D menus, or after a review \u2014 reply in chat. Explain options first, description on every option, then wait.",
8400
8416
  "- get_viewer_context / update_viewer_context \u2014 read or replace Settings \u2192 Agents (account) and Settings \u2192 Projects (per-repo) context. You can update a project: pass scope=project and repoPath from list_workspaces (this cwd is not a project). update_viewer_context requires confirmed=true after ask_user. Never write context unprompted.",
8401
8417
  "- set_caffeinate \u2014 keep this Mac awake across turns (macOS caffeinate). Turn on for Slack / away-from-keyboard work, overnight schedules, or when the user will be away. Turn OFF when they say they are done, wrapping up, going to sleep, or no longer need the machine awake. Closing this chat also releases it.",
8402
- "- list_schedules / create_schedule / update_schedule / delete_schedule / run_schedule \u2014 local jobs that send a prompt to an orchestration chat (threadId or self) or start a new Global chat (omit threadId). One-shot `at`, interval `every` (15m/1h/6h/1d), or 5-field `cron`. Recurring jobs without threadId open a new chat each run. Jobs fire only while Sideboard.app is running; sleep skips until wake. Overnight/unattended runs: ask the user to enable Settings \u2192 Advanced \u2192 Caffeinate while schedules are enabled, or call set_caffeinate.",
8418
+ "- list_schedules / create_schedule / update_schedule / delete_schedule / run_schedule \u2014 local jobs that send a prompt to a chat (threadId or self) or start a new Global chat (omit threadId). One-shot `at`, interval `every` (15m/1h/6h/1d), or 5-field `cron`. Recurring jobs without threadId open a new chat each run. Worktree agents have the same tools (`threadId=self` continues that coding chat). Jobs fire only while Sideboard.app is running; sleep skips until wake. Creating or enabling a future job turns on Settings \u2192 Advanced \u2192 Caffeinate while schedules are enabled (or call set_caffeinate).",
8403
8419
  "Workspaces:",
8404
8420
  "- add_workspace / remove_workspace \u2014 register or unregister a git repo",
8405
8421
  "Worktree threads (chats):",
@@ -10152,7 +10168,12 @@ var init_injected_mcp = __esm({
10152
10168
  "mcp__sideboard__get_run_log",
10153
10169
  "mcp__sideboard__notify_orchestrator",
10154
10170
  "mcp__sideboard__get_viewer_context",
10155
- "mcp__sideboard__update_viewer_context"
10171
+ "mcp__sideboard__update_viewer_context",
10172
+ "mcp__sideboard__list_schedules",
10173
+ "mcp__sideboard__create_schedule",
10174
+ "mcp__sideboard__update_schedule",
10175
+ "mcp__sideboard__delete_schedule",
10176
+ "mcp__sideboard__run_schedule"
10156
10177
  ];
10157
10178
  SIDEBOARD_GITHUB_MCP_ALLOWED_TOOLS = ["mcp__sideboard__github_*"];
10158
10179
  SIDEBOARD_LINEAR_MCP_ALLOWED_TOOLS = ["mcp__sideboard__linear_*"];
@@ -10467,6 +10488,13 @@ function toolDescription(name, input) {
10467
10488
  return str2(input?.name) ? `Read ${str2(input?.name)} log` : "Read Dev log";
10468
10489
  }
10469
10490
  if (/notify_orchestrator$/i.test(name)) return "Notify orchestrator";
10491
+ if (/list_schedules$/i.test(name)) return "List schedules";
10492
+ if (/create_schedule$/i.test(name)) {
10493
+ return str2(input?.name) ? `Schedule ${str2(input?.name)}` : "Create schedule";
10494
+ }
10495
+ if (/update_schedule$/i.test(name)) return "Update schedule";
10496
+ if (/delete_schedule$/i.test(name)) return "Delete schedule";
10497
+ if (/run_schedule$/i.test(name)) return "Run schedule";
10470
10498
  if (isSkillToolName(name)) {
10471
10499
  const cmd = skillCommandFromInput(input);
10472
10500
  return cmd ? `Using /${cmd}` : "Using skill";
@@ -21405,11 +21433,15 @@ function formatWorktreeDirective(thread, opts) {
21405
21433
  lines.push("");
21406
21434
  lines.push(formatDevAccessHint(opts?.activeRuns));
21407
21435
  lines.push("");
21436
+ lines.push(
21437
+ "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."
21438
+ );
21439
+ lines.push("");
21408
21440
  lines.push(formatProcessGuideDirective({ worktreePath: thread.worktreePath }));
21409
21441
  return lines.join("\n");
21410
21442
  }
21411
21443
  function formatWorktreeReminder() {
21412
- 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.";
21444
+ 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).";
21413
21445
  }
21414
21446
  function mentionsPrGoal(prompt) {
21415
21447
  return PR_GOAL_RE.test(prompt);
@@ -22036,7 +22068,7 @@ function resolveScheduleThreadId(raw, env = process.env) {
22036
22068
  const value = raw?.trim() || "";
22037
22069
  if (!value) return null;
22038
22070
  if (value.toLowerCase() === "self") {
22039
- return env.SIDEBOARD_ORCHESTRATOR_THREAD_ID?.trim() || null;
22071
+ return env.SIDEBOARD_ORCHESTRATOR_THREAD_ID?.trim() || env.SIDEBOARD_THREAD_ID?.trim() || null;
22040
22072
  }
22041
22073
  return value;
22042
22074
  }
@@ -22164,6 +22196,17 @@ function buildTask(input, now) {
22164
22196
  function listSchedules() {
22165
22197
  return readAll2().sort((a, b) => a.nextRunAt.localeCompare(b.nextRunAt));
22166
22198
  }
22199
+ function scheduleNeedsCaffeinate(task, now = /* @__PURE__ */ new Date()) {
22200
+ if (!task.enabled) return false;
22201
+ const at = new Date(task.nextRunAt);
22202
+ if (Number.isNaN(at.getTime())) return false;
22203
+ return at.getTime() > now.getTime();
22204
+ }
22205
+ function ensureCaffeinateForFutureSchedule(task) {
22206
+ if (!scheduleNeedsCaffeinate(task)) return;
22207
+ if (caffeinateWhileSchedulesEnabled()) return;
22208
+ updateAdvancedSettings({ caffeinateWhileSchedules: true });
22209
+ }
22167
22210
  function getSchedule(id) {
22168
22211
  const key = id.trim();
22169
22212
  if (!key) return null;
@@ -22176,6 +22219,7 @@ function createSchedule(input) {
22176
22219
  const rows = readAll2();
22177
22220
  rows.push(task);
22178
22221
  writeAll2(rows);
22222
+ ensureCaffeinateForFutureSchedule(task);
22179
22223
  return task;
22180
22224
  }
22181
22225
  function updateSchedule(id, patch) {
@@ -22202,6 +22246,7 @@ function updateSchedule(id, patch) {
22202
22246
  };
22203
22247
  rows[idx] = next;
22204
22248
  writeAll2(rows);
22249
+ ensureCaffeinateForFutureSchedule(next);
22205
22250
  return next;
22206
22251
  }
22207
22252
  function deleteSchedule(id) {
@@ -22242,6 +22287,7 @@ var init_schedules = __esm({
22242
22287
  init_orchestrator_capable();
22243
22288
  init_paths();
22244
22289
  init_private_file();
22290
+ init_app_settings();
22245
22291
  DURATION_RE = /^(\d+)(s|m|h|d)$/i;
22246
22292
  UNIT_MS = {
22247
22293
  s: 1e3,
@@ -22278,19 +22324,9 @@ async function fireSchedule(id) {
22278
22324
  try {
22279
22325
  const deps = fireHooks ?? await defaultDeps();
22280
22326
  const prompt = formatScheduledPrompt(schedule.name, schedule.prompt);
22281
- if (schedule.threadId) {
22282
- const thread = deps.findThread(schedule.threadId);
22283
- if (!thread || thread.status === "archived") {
22284
- return recordScheduleRun(schedule.id, {
22285
- lastError: thread ? `Orchestration chat ${schedule.threadId} is archived` : `Orchestration chat not found: ${schedule.threadId}`
22286
- });
22287
- }
22288
- if (!isOrchestratorThread(thread)) {
22289
- return recordScheduleRun(schedule.id, {
22290
- lastError: `Thread ${schedule.threadId} is not an orchestration chat`
22291
- });
22292
- }
22293
- const sent = await deps.send(thread.id, prompt);
22327
+ const target = schedule.threadId ? deps.findThread(schedule.threadId) : null;
22328
+ if (target && target.status !== "archived") {
22329
+ const sent = await deps.send(target.id, prompt);
22294
22330
  return recordScheduleRun(schedule.id, {
22295
22331
  lastThreadId: sent.id,
22296
22332
  lastError: null
@@ -22301,6 +22337,9 @@ async function fireSchedule(id) {
22301
22337
  agent: pickAgent(schedule),
22302
22338
  model: schedule.model
22303
22339
  });
22340
+ if (schedule.threadId && schedule.when.kind !== "once") {
22341
+ updateSchedule(schedule.id, { threadId: created.id });
22342
+ }
22304
22343
  return recordScheduleRun(schedule.id, {
22305
22344
  lastThreadId: created.id,
22306
22345
  lastError: null
@@ -22369,7 +22408,6 @@ var init_schedule_runner = __esm({
22369
22408
  init_app_settings();
22370
22409
  init_schedules();
22371
22410
  init_thread_store();
22372
- init_global_workspace();
22373
22411
  SET_TIMEOUT_MAX = 2147483647;
22374
22412
  fireHooks = null;
22375
22413
  timers = /* @__PURE__ */ new Map();
@@ -29113,7 +29151,7 @@ function parseWhen(args) {
29113
29151
  function registerScheduleTools(server) {
29114
29152
  server.tool(
29115
29153
  "list_schedules",
29116
- "List local Sideboard schedules that trigger orchestration agents. Jobs fire only while Sideboard.app is running on this Mac (sleep skips until wake).",
29154
+ "List local Sideboard schedules that trigger a chat when due. Jobs fire only while Sideboard.app is running on this Mac (sleep skips until wake).",
29117
29155
  {},
29118
29156
  async () => {
29119
29157
  try {
@@ -29125,7 +29163,7 @@ function registerScheduleTools(server) {
29125
29163
  );
29126
29164
  server.tool(
29127
29165
  "create_schedule",
29128
- "Create a local schedule that, when due, sends a prompt to an orchestration chat (threadId) or starts a new Global orchestration chat (omit threadId). Pass threadId=self to continue this coordinator. Exactly one of at (ISO datetime), every (15m/1h/6h/1d), or cron (5-field). Recurring jobs without threadId open a new chat each run. Overnight/unattended runs need Settings \u2192 Advanced \u2192 Caffeinate while schedules are enabled, or set_caffeinate. Sideboard.app must be running for the job to fire.",
29166
+ "Create a local schedule that, when due, sends a prompt to an existing chat (threadId) or starts a new Global orchestration chat (omit threadId). Pass threadId=self to continue this chat. If that chat is missing or archived when the job fires, Sideboard starts a new Global chat (recurring jobs then continue that chat). Exactly one of at (ISO datetime), every (15m/1h/6h/1d), or cron (5-field). Recurring jobs without threadId open a new Global chat each run. Creating or enabling a future job turns on Settings \u2192 Advanced \u2192 Caffeinate while schedules are enabled so the Mac stays awake until due. Sideboard.app must be running for the job to fire.",
29129
29167
  {
29130
29168
  prompt: import_zod8.z.string().describe("User message / goal queued when the schedule fires"),
29131
29169
  name: import_zod8.z.string().optional(),
@@ -29134,7 +29172,7 @@ function registerScheduleTools(server) {
29134
29172
  cron: import_zod8.z.string().optional().describe("5-field cron expression"),
29135
29173
  tz: import_zod8.z.string().optional().describe("IANA timezone for cron (default: system)"),
29136
29174
  threadId: import_zod8.z.string().optional().describe(
29137
- 'Existing orchestration chat id, or "self" for this coordinator. Omit to create a new Global chat on fire.'
29175
+ 'Existing chat id (orchestration or worktree), or "self" for this chat. Omit to create a new Global chat on fire.'
29138
29176
  ),
29139
29177
  agent: import_zod8.z.enum(["claude", "cursor", "codex", "opencode"]).optional().describe("Agent for a new Global chat (omit for Account default)"),
29140
29178
  model: import_zod8.z.string().optional()
@@ -29145,7 +29183,9 @@ function registerScheduleTools(server) {
29145
29183
  const threadId = resolveScheduleThreadId(args.threadId);
29146
29184
  if (args.threadId?.trim().toLowerCase() === "self" && !threadId) {
29147
29185
  return fail5(
29148
- new Error("threadId=self requires this turn to be an orchestration chat")
29186
+ new Error(
29187
+ "threadId=self needs this chat id (SIDEBOARD_THREAD_ID or SIDEBOARD_ORCHESTRATOR_THREAD_ID)"
29188
+ )
29149
29189
  );
29150
29190
  }
29151
29191
  const schedule = createSchedule({
@@ -29159,7 +29199,7 @@ function registerScheduleTools(server) {
29159
29199
  });
29160
29200
  return text6({
29161
29201
  schedule,
29162
- hint: "Fires while Sideboard.app is running. Recurring jobs without threadId create a new orchestration chat each run. Overnight runs need Settings \u2192 Advanced \u2192 Caffeinate while schedules are enabled, or set_caffeinate."
29202
+ hint: scheduleNeedsCaffeinate(schedule) ? "Fires while Sideboard.app is running. Recurring jobs without threadId create a new orchestration chat each run. Caffeinate while schedules are enabled is now on so the Mac can stay awake until this job is due." : "Fires while Sideboard.app is running. Recurring jobs without threadId create a new orchestration chat each run."
29163
29203
  });
29164
29204
  } catch (err) {
29165
29205
  return fail5(err);
@@ -29177,7 +29217,9 @@ function registerScheduleTools(server) {
29177
29217
  every: import_zod8.z.string().optional(),
29178
29218
  cron: import_zod8.z.string().optional(),
29179
29219
  tz: import_zod8.z.string().optional(),
29180
- threadId: import_zod8.z.string().optional().describe('Existing orchestration chat, "self", or empty string to create a new chat each run'),
29220
+ threadId: import_zod8.z.string().optional().describe(
29221
+ 'Existing chat (orchestration or worktree), "self", or empty string to create a new Global chat each run'
29222
+ ),
29181
29223
  agent: import_zod8.z.enum(["claude", "cursor", "codex", "opencode"]).optional(),
29182
29224
  model: import_zod8.z.string().optional(),
29183
29225
  enabled: import_zod8.z.boolean().optional()
@@ -29196,7 +29238,9 @@ function registerScheduleTools(server) {
29196
29238
  threadId = resolveScheduleThreadId(args.threadId);
29197
29239
  if (args.threadId.trim().toLowerCase() === "self" && !threadId) {
29198
29240
  return fail5(
29199
- new Error("threadId=self requires this turn to be an orchestration chat")
29241
+ new Error(
29242
+ "threadId=self needs this chat id (SIDEBOARD_THREAD_ID or SIDEBOARD_ORCHESTRATOR_THREAD_ID)"
29243
+ )
29200
29244
  );
29201
29245
  }
29202
29246
  }
@@ -29230,7 +29274,7 @@ function registerScheduleTools(server) {
29230
29274
  );
29231
29275
  server.tool(
29232
29276
  "run_schedule",
29233
- "Fire a schedule now (does not wait for nextRunAt). Queues the prompt or starts a new Global chat. If Sideboard.app is running, the desktop drains the turn.",
29277
+ "Fire a schedule now (does not wait for nextRunAt). Queues the prompt on the target chat or starts a new Global chat. If Sideboard.app is running, the desktop drains the turn.",
29234
29278
  { id: import_zod8.z.string() },
29235
29279
  async ({ id }) => {
29236
29280
  try {
@@ -30170,10 +30214,10 @@ async function startMcpServer() {
30170
30214
  }
30171
30215
  );
30172
30216
  }
30217
+ registerScheduleTools(server);
30173
30218
  if (!worktreeProfile) {
30174
30219
  registerSlackTools(server);
30175
30220
  registerConnectedIssueVendorTools(server);
30176
- registerScheduleTools(server);
30177
30221
  const { getCaffeinateHold: getCaffeinateHold2, setCaffeinateHold: setCaffeinateHold2 } = await Promise.resolve().then(() => (init_caffeinate_hold(), caffeinate_hold_exports));
30178
30222
  const { resolveNewThreadOptions: resolveNewThreadOptions2, resolveThreadDefaults: resolveThreadDefaults2 } = await Promise.resolve().then(() => (init_app_settings(), app_settings_exports));
30179
30223
  const accountDefaults = resolveThreadDefaults2();
@@ -43,13 +43,14 @@ import {
43
43
  readTurnLive,
44
44
  resolveOrchChildFollowUp,
45
45
  resolveScheduleThreadId,
46
+ scheduleNeedsCaffeinate,
46
47
  sliceRunLogOutput,
47
48
  stopDetachedJob,
48
49
  syncBoardPins,
49
50
  threadsSharingWorktree,
50
51
  updateSchedule,
51
52
  waitForDetachedJob
52
- } from "../chunk-AQQWP2TL.js";
53
+ } from "../chunk-46KDLP6T.js";
53
54
  import {
54
55
  PRESENT_PLAN_REQUIRES_PLAN_MODE,
55
56
  PRESENT_PLAN_TOOL_DESCRIPTION,
@@ -66,13 +67,13 @@ import {
66
67
  materializeSystemCaBundle,
67
68
  sideboardMcpProfile,
68
69
  trustSystemCertificates
69
- } from "../chunk-4DGYMF7H.js";
70
+ } from "../chunk-6ZYSXLXK.js";
70
71
  import {
71
72
  GLOBAL_WORKSPACE_ID,
72
73
  isCloudCoordinatorThread,
73
74
  isOrchestratorThread,
74
75
  listWorkspaces
75
- } from "../chunk-6IP4FWMK.js";
76
+ } from "../chunk-IAS7Q2YF.js";
76
77
  import "../chunk-XAISOBBG.js";
77
78
  import "../chunk-P2BSMNHB.js";
78
79
  import "../chunk-XIEDFRBP.js";
@@ -90,7 +91,7 @@ import {
90
91
  resolveListPrsOptions,
91
92
  resolveRepoRoot,
92
93
  warmGithubAgentAuth
93
- } from "../chunk-PV4KCI2S.js";
94
+ } from "../chunk-WVNQML4W.js";
94
95
  import "../chunk-D6JWYJ4P.js";
95
96
  import {
96
97
  appendMessage,
@@ -2367,7 +2368,7 @@ async function continueSourceThread(threadId, prompt) {
2367
2368
  await continueOnReply(threadId, prompt);
2368
2369
  return;
2369
2370
  }
2370
- const { getOrchestrator: getOrchestrator2 } = await import("../orchestrator-O3TVI7SN.js");
2371
+ const { getOrchestrator: getOrchestrator2 } = await import("../orchestrator-W6DUFWVE.js");
2371
2372
  await getOrchestrator2().send(threadId, prompt);
2372
2373
  } catch {
2373
2374
  }
@@ -3912,7 +3913,7 @@ function parseWhen(args) {
3912
3913
  function registerScheduleTools(server) {
3913
3914
  server.tool(
3914
3915
  "list_schedules",
3915
- "List local Sideboard schedules that trigger orchestration agents. Jobs fire only while Sideboard.app is running on this Mac (sleep skips until wake).",
3916
+ "List local Sideboard schedules that trigger a chat when due. Jobs fire only while Sideboard.app is running on this Mac (sleep skips until wake).",
3916
3917
  {},
3917
3918
  async () => {
3918
3919
  try {
@@ -3924,7 +3925,7 @@ function registerScheduleTools(server) {
3924
3925
  );
3925
3926
  server.tool(
3926
3927
  "create_schedule",
3927
- "Create a local schedule that, when due, sends a prompt to an orchestration chat (threadId) or starts a new Global orchestration chat (omit threadId). Pass threadId=self to continue this coordinator. Exactly one of at (ISO datetime), every (15m/1h/6h/1d), or cron (5-field). Recurring jobs without threadId open a new chat each run. Overnight/unattended runs need Settings \u2192 Advanced \u2192 Caffeinate while schedules are enabled, or set_caffeinate. Sideboard.app must be running for the job to fire.",
3928
+ "Create a local schedule that, when due, sends a prompt to an existing chat (threadId) or starts a new Global orchestration chat (omit threadId). Pass threadId=self to continue this chat. If that chat is missing or archived when the job fires, Sideboard starts a new Global chat (recurring jobs then continue that chat). Exactly one of at (ISO datetime), every (15m/1h/6h/1d), or cron (5-field). Recurring jobs without threadId open a new Global chat each run. Creating or enabling a future job turns on Settings \u2192 Advanced \u2192 Caffeinate while schedules are enabled so the Mac stays awake until due. Sideboard.app must be running for the job to fire.",
3928
3929
  {
3929
3930
  prompt: z8.string().describe("User message / goal queued when the schedule fires"),
3930
3931
  name: z8.string().optional(),
@@ -3933,7 +3934,7 @@ function registerScheduleTools(server) {
3933
3934
  cron: z8.string().optional().describe("5-field cron expression"),
3934
3935
  tz: z8.string().optional().describe("IANA timezone for cron (default: system)"),
3935
3936
  threadId: z8.string().optional().describe(
3936
- 'Existing orchestration chat id, or "self" for this coordinator. Omit to create a new Global chat on fire.'
3937
+ 'Existing chat id (orchestration or worktree), or "self" for this chat. Omit to create a new Global chat on fire.'
3937
3938
  ),
3938
3939
  agent: z8.enum(["claude", "cursor", "codex", "opencode"]).optional().describe("Agent for a new Global chat (omit for Account default)"),
3939
3940
  model: z8.string().optional()
@@ -3944,7 +3945,9 @@ function registerScheduleTools(server) {
3944
3945
  const threadId = resolveScheduleThreadId(args.threadId);
3945
3946
  if (args.threadId?.trim().toLowerCase() === "self" && !threadId) {
3946
3947
  return fail5(
3947
- new Error("threadId=self requires this turn to be an orchestration chat")
3948
+ new Error(
3949
+ "threadId=self needs this chat id (SIDEBOARD_THREAD_ID or SIDEBOARD_ORCHESTRATOR_THREAD_ID)"
3950
+ )
3948
3951
  );
3949
3952
  }
3950
3953
  const schedule = createSchedule({
@@ -3958,7 +3961,7 @@ function registerScheduleTools(server) {
3958
3961
  });
3959
3962
  return text6({
3960
3963
  schedule,
3961
- hint: "Fires while Sideboard.app is running. Recurring jobs without threadId create a new orchestration chat each run. Overnight runs need Settings \u2192 Advanced \u2192 Caffeinate while schedules are enabled, or set_caffeinate."
3964
+ hint: scheduleNeedsCaffeinate(schedule) ? "Fires while Sideboard.app is running. Recurring jobs without threadId create a new orchestration chat each run. Caffeinate while schedules are enabled is now on so the Mac can stay awake until this job is due." : "Fires while Sideboard.app is running. Recurring jobs without threadId create a new orchestration chat each run."
3962
3965
  });
3963
3966
  } catch (err) {
3964
3967
  return fail5(err);
@@ -3976,7 +3979,9 @@ function registerScheduleTools(server) {
3976
3979
  every: z8.string().optional(),
3977
3980
  cron: z8.string().optional(),
3978
3981
  tz: z8.string().optional(),
3979
- threadId: z8.string().optional().describe('Existing orchestration chat, "self", or empty string to create a new chat each run'),
3982
+ threadId: z8.string().optional().describe(
3983
+ 'Existing chat (orchestration or worktree), "self", or empty string to create a new Global chat each run'
3984
+ ),
3980
3985
  agent: z8.enum(["claude", "cursor", "codex", "opencode"]).optional(),
3981
3986
  model: z8.string().optional(),
3982
3987
  enabled: z8.boolean().optional()
@@ -3995,7 +4000,9 @@ function registerScheduleTools(server) {
3995
4000
  threadId = resolveScheduleThreadId(args.threadId);
3996
4001
  if (args.threadId.trim().toLowerCase() === "self" && !threadId) {
3997
4002
  return fail5(
3998
- new Error("threadId=self requires this turn to be an orchestration chat")
4003
+ new Error(
4004
+ "threadId=self needs this chat id (SIDEBOARD_THREAD_ID or SIDEBOARD_ORCHESTRATOR_THREAD_ID)"
4005
+ )
3999
4006
  );
4000
4007
  }
4001
4008
  }
@@ -4029,7 +4036,7 @@ function registerScheduleTools(server) {
4029
4036
  );
4030
4037
  server.tool(
4031
4038
  "run_schedule",
4032
- "Fire a schedule now (does not wait for nextRunAt). Queues the prompt or starts a new Global chat. If Sideboard.app is running, the desktop drains the turn.",
4039
+ "Fire a schedule now (does not wait for nextRunAt). Queues the prompt on the target chat or starts a new Global chat. If Sideboard.app is running, the desktop drains the turn.",
4033
4040
  { id: z8.string() },
4034
4041
  async ({ id }) => {
4035
4042
  try {
@@ -4954,10 +4961,10 @@ async function startMcpServer() {
4954
4961
  }
4955
4962
  );
4956
4963
  }
4964
+ registerScheduleTools(server);
4957
4965
  if (!worktreeProfile) {
4958
4966
  registerSlackTools(server);
4959
4967
  registerConnectedIssueVendorTools(server);
4960
- registerScheduleTools(server);
4961
4968
  const { getCaffeinateHold, setCaffeinateHold } = await import("../caffeinate-hold-UAGLSGMM.js");
4962
4969
  const { resolveNewThreadOptions, resolveThreadDefaults } = await import("../app-settings-CLARFJUX.js");
4963
4970
  const accountDefaults = resolveThreadDefaults();
@@ -9,11 +9,11 @@ import {
9
9
  resolveSendFollowUp,
10
10
  startOrchestration,
11
11
  waitForPidExit
12
- } from "./chunk-FKGVQKRX.js";
12
+ } from "./chunk-GZRS5QVL.js";
13
13
  import "./chunk-PGPSIEMW.js";
14
- import "./chunk-BHPGORIY.js";
15
- import "./chunk-SJ3IUYG2.js";
16
- import "./chunk-NYXDZCMP.js";
14
+ import "./chunk-MLB5CFUP.js";
15
+ import "./chunk-JUYD2YUC.js";
16
+ import "./chunk-PLMMPA6A.js";
17
17
  import "./chunk-6K64FJDD.js";
18
18
  import "./chunk-2P4XKWV2.js";
19
19
  import "./chunk-5F4YFGHL.js";
@@ -11,15 +11,15 @@ import {
11
11
  resolveSendFollowUp,
12
12
  startOrchestration,
13
13
  waitForPidExit
14
- } from "./chunk-AQQWP2TL.js";
14
+ } from "./chunk-46KDLP6T.js";
15
15
  import "./chunk-WDDUIGFK.js";
16
16
  import "./chunk-QN5DL2QO.js";
17
- import "./chunk-4DGYMF7H.js";
18
- import "./chunk-6IP4FWMK.js";
17
+ import "./chunk-6ZYSXLXK.js";
18
+ import "./chunk-IAS7Q2YF.js";
19
19
  import "./chunk-XAISOBBG.js";
20
20
  import "./chunk-P2BSMNHB.js";
21
21
  import "./chunk-VKQGAWHY.js";
22
- import "./chunk-PV4KCI2S.js";
22
+ import "./chunk-WVNQML4W.js";
23
23
  import "./chunk-D6JWYJ4P.js";
24
24
  import "./chunk-RJC2MKXN.js";
25
25
  import "./chunk-H547WSSZ.js";
@@ -7,8 +7,8 @@ import {
7
7
  primaryCheckoutFromLinkedWorktree,
8
8
  removeWorkspace,
9
9
  syncWorkspacesFromThreads
10
- } from "./chunk-6IP4FWMK.js";
11
- import "./chunk-PV4KCI2S.js";
10
+ } from "./chunk-IAS7Q2YF.js";
11
+ import "./chunk-WVNQML4W.js";
12
12
  import "./chunk-D6JWYJ4P.js";
13
13
  import "./chunk-RJC2MKXN.js";
14
14
  import "./chunk-H547WSSZ.js";
@@ -5,8 +5,8 @@ import {
5
5
  primaryCheckoutFromLinkedWorktree,
6
6
  removeWorkspace,
7
7
  syncWorkspacesFromThreads
8
- } from "./chunk-SJ3IUYG2.js";
9
- import "./chunk-NYXDZCMP.js";
8
+ } from "./chunk-JUYD2YUC.js";
9
+ import "./chunk-PLMMPA6A.js";
10
10
  import "./chunk-6K64FJDD.js";
11
11
  import "./chunk-2P4XKWV2.js";
12
12
  import "./chunk-KJM3E3NF.js";
@@ -61,7 +61,7 @@ import {
61
61
  worktreeDisplayLabelForGroup,
62
62
  worktreeNameFromPath,
63
63
  worktreeSlugForTicket
64
- } from "./chunk-PV4KCI2S.js";
64
+ } from "./chunk-WVNQML4W.js";
65
65
  import "./chunk-D6JWYJ4P.js";
66
66
  import "./chunk-RJC2MKXN.js";
67
67
  import "./chunk-H547WSSZ.js";
@@ -59,7 +59,7 @@ import {
59
59
  worktreeDisplayLabelForGroup,
60
60
  worktreeNameFromPath,
61
61
  worktreeSlugForTicket
62
- } from "./chunk-NYXDZCMP.js";
62
+ } from "./chunk-PLMMPA6A.js";
63
63
  import "./chunk-6K64FJDD.js";
64
64
  import "./chunk-2P4XKWV2.js";
65
65
  import "./chunk-KJM3E3NF.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sideboard-ai/core",
3
- "version": "0.1.252",
3
+ "version": "0.1.253",
4
4
  "description": "Sideboard core — orchestration, agents, git worktrees, MCP server",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",