@sideboard-ai/core 0.1.325 → 0.1.327
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.
- package/dist/{abletime-M7STTMZT.js → abletime-NW4PJGHN.js} +4 -5
- package/dist/{abletime-VL234MCP.js → abletime-OW7LTFQD.js} +4 -5
- package/dist/{abletime-oauth-LMMGMAPA.js → abletime-oauth-KWQQRHOQ.js} +3 -4
- package/dist/{abletime-oauth-P4ZFBEAL.js → abletime-oauth-TPR2QDRI.js} +3 -4
- package/dist/{abletime-rest-DLV7EIWS.js → abletime-rest-5DCWN3P4.js} +3 -4
- package/dist/{abletime-rest-GOI7HELR.js → abletime-rest-UJ6SXDBN.js} +3 -4
- package/dist/agents/claude-runner.cjs +11 -0
- package/dist/agents/claude-runner.js +7 -1
- package/dist/agents/cursor-runner.cjs +1 -1
- package/dist/agents/cursor-runner.js +1 -1
- package/dist/{agents-MBIEAETM.js → agents-IYBY3JT5.js} +9 -10
- package/dist/{agents-LDRM3BTY.js → agents-XWIPONJR.js} +8 -9
- package/dist/{app-settings-UQHUNOLV.js → app-settings-A5D364JD.js} +1 -2
- package/dist/{app-settings-E7DMMEKC.js → app-settings-SA4HX3ZQ.js} +1 -2
- package/dist/{chunk-BOFYI6LC.js → chunk-2GEUFPQQ.js} +1 -1
- package/dist/{chunk-F65JMKUR.js → chunk-4F7THWIO.js} +2 -2
- package/dist/{chunk-A76MKMSF.js → chunk-4G3W23X3.js} +3 -3
- package/dist/{chunk-Q3FHTGIW.js → chunk-5Y2C7Q55.js} +441 -20
- package/dist/{chunk-PPTJMBUY.js → chunk-ATQLP22S.js} +1 -1
- package/dist/{chunk-NWGINMEA.js → chunk-CHYUUETG.js} +3 -3
- package/dist/{chunk-RZJTGBXY.js → chunk-D446IWPP.js} +50 -4
- package/dist/{chunk-ZEUMWHOH.js → chunk-DACWFN4O.js} +5 -5
- package/dist/{chunk-SACHHTBJ.js → chunk-DEB47BII.js} +52 -488
- package/dist/{chunk-2UP3XD2D.js → chunk-ECY7WL6T.js} +2 -2
- package/dist/{chunk-CI4M54LS.js → chunk-EJRCHCXM.js} +21 -4
- package/dist/{chunk-H36GKGU2.js → chunk-EUIVQAPK.js} +2 -2
- package/dist/{chunk-WYEST76H.js → chunk-IXWPCOLQ.js} +19 -203
- package/dist/{chunk-EO6ZFLG6.js → chunk-JKHCADKB.js} +5 -5
- package/dist/{chunk-SK6NYGPD.js → chunk-KLVW3J2B.js} +2 -2
- package/dist/{chunk-HG6KS7OT.js → chunk-MO46K6WK.js} +22 -18
- package/dist/{chunk-F2PVRF3B.js → chunk-N6ZF3XRP.js} +2 -1
- package/dist/{chunk-MFMDZAA6.js → chunk-NQGLDQYB.js} +16 -12
- package/dist/{chunk-U5WO6MEB.js → chunk-NURZOXGN.js} +1 -1
- package/dist/{chunk-ZHDXLDLA.js → chunk-Q4UPRQOS.js} +12 -12
- package/dist/{chunk-SQQBU7Z6.js → chunk-QMLDR63X.js} +2 -2
- package/dist/{chunk-BTF3ATST.js → chunk-R2C45NHT.js} +2 -2
- package/dist/{chunk-APKUI4BP.js → chunk-RDXODLEN.js} +4 -4
- package/dist/{chunk-7G27TB4M.js → chunk-RZJ3QJZT.js} +18 -14
- package/dist/{chunk-AQEKPJWU.js → chunk-SB5ADEZZ.js} +5 -5
- package/dist/{chunk-7LUOLYFM.js → chunk-SFXGD5KJ.js} +1 -1
- package/dist/{chunk-EZR6W4B3.js → chunk-TUH4ICHQ.js} +1 -1
- package/dist/chunk-ULWPSBAB.js +192 -0
- package/dist/{chunk-MBT6WDAB.js → chunk-UMXBH344.js} +1 -1
- package/dist/{chunk-SS6CYGLF.js → chunk-XBBZZHJY.js} +3 -3
- package/dist/{chunk-ZSHS46V5.js → chunk-Y6OHM672.js} +476 -20
- package/dist/{chunk-GNLKBS3U.js → chunk-YUHZEIVG.js} +69 -473
- package/dist/{chunk-VAFQS4D2.js → chunk-ZPBOWO64.js} +2 -2
- package/dist/{conductor-KB7L7NQN.js → conductor-CP7TW6TN.js} +7 -7
- package/dist/{conductor-D4KFZF54.js → conductor-D62Q2XJC.js} +6 -7
- package/dist/{coordinator-prompt-OBXEC63K.js → coordinator-prompt-3PJLU3UH.js} +5 -6
- package/dist/{coordinator-prompt-SUO4FRY3.js → coordinator-prompt-J7O7JB26.js} +5 -6
- package/dist/{global-workspace-Z2SURNHA.js → global-workspace-4CTLU2BV.js} +5 -6
- package/dist/{global-workspace-UHU2FXTY.js → global-workspace-Y3UDZYJX.js} +5 -6
- package/dist/index.cjs +527 -506
- package/dist/index.d.cts +16 -10
- package/dist/index.d.ts +16 -10
- package/dist/index.js +68 -66
- package/dist/{linear-SIHEBU3X.js → linear-CXWGH2TW.js} +2 -3
- package/dist/{linear-HFUOUJ5H.js → linear-WLDCJ3AF.js} +2 -3
- package/dist/{linear-list-JFV3EES6.js → linear-list-52LEDEWO.js} +1 -1
- package/dist/{linear-list-63I7QUC6.js → linear-list-FGVN65JU.js} +1 -1
- package/dist/mcp/run-stdio.cjs +19655 -19635
- package/dist/mcp/run-stdio.js +33 -34
- package/dist/{optional-cli-ULDP3O5S.js → optional-cli-FN4MGB6W.js} +4 -5
- package/dist/{optional-cli-U2GUA2X6.js → optional-cli-INRVBBBG.js} +3 -4
- package/dist/{orchestrator-3H4KNGPN.js → orchestrator-EN3ZKD73.js} +13 -13
- package/dist/{orchestrator-6ROMEWBP.js → orchestrator-W4TZBBDO.js} +11 -12
- package/dist/{thread-store-4ZN3DS2W.js → thread-store-4WE24XA2.js} +6 -2
- package/dist/{thread-store-IC4BQXDW.js → thread-store-K2ZNGUSM.js} +7 -3
- package/dist/{workspaces-MG5JHRKW.js → workspaces-MM7CQYR6.js} +5 -6
- package/dist/{workspaces-QJNKEGEM.js → workspaces-WYCVZ6XH.js} +5 -6
- package/dist/{worktree-MYJYUHZM.js → worktree-JBNEMJ5Z.js} +7 -8
- package/dist/{worktree-KSJPTHGZ.js → worktree-NNVRGPP4.js} +4 -5
- package/package.json +1 -1
- package/dist/chunk-77WWLBCI.js +0 -50
- package/dist/chunk-KGZBYWZ3.js +0 -23
package/dist/index.cjs
CHANGED
|
@@ -133,7 +133,8 @@ var init_claude_mcp = __esm({
|
|
|
133
133
|
"TaskStop",
|
|
134
134
|
"EnterWorktree",
|
|
135
135
|
"ExitWorktree",
|
|
136
|
-
"Skill"
|
|
136
|
+
"Skill",
|
|
137
|
+
"AskUserQuestion"
|
|
137
138
|
];
|
|
138
139
|
CLAUDE_PRINT_BG_WAIT_CEILING_MS = 72e5;
|
|
139
140
|
CLAUDE_CHROME_ALLOWED_TOOLS = [
|
|
@@ -1796,10 +1797,11 @@ function applyTurnUsage(current, incoming, scope = "request") {
|
|
|
1796
1797
|
...incoming.sessionCostUsd != null ? { sessionCostUsd: incoming.sessionCostUsd } : {}
|
|
1797
1798
|
};
|
|
1798
1799
|
}
|
|
1800
|
+
const explicit = incoming.lastRequestTokens != null && incoming.lastRequestTokens > 0 ? incoming.lastRequestTokens : void 0;
|
|
1799
1801
|
return {
|
|
1800
1802
|
...incoming,
|
|
1801
1803
|
costUsd: incoming.costUsd ?? current?.costUsd,
|
|
1802
|
-
lastRequestTokens: current?.lastRequestTokens ??
|
|
1804
|
+
lastRequestTokens: current?.lastRequestTokens ?? explicit,
|
|
1803
1805
|
...incoming.sessionCostUsd == null && current?.sessionCostUsd != null ? { sessionCostUsd: current.sessionCostUsd } : {}
|
|
1804
1806
|
};
|
|
1805
1807
|
}
|
|
@@ -5184,6 +5186,449 @@ var init_cursor_store = __esm({
|
|
|
5184
5186
|
}
|
|
5185
5187
|
});
|
|
5186
5188
|
|
|
5189
|
+
// src/store/schedule-when.ts
|
|
5190
|
+
function parseDurationMs(every) {
|
|
5191
|
+
const m = every.trim().match(DURATION_RE);
|
|
5192
|
+
if (!m) return null;
|
|
5193
|
+
const n = Number.parseInt(m[1], 10);
|
|
5194
|
+
if (!Number.isFinite(n) || n <= 0) return null;
|
|
5195
|
+
const unit = m[2].toLowerCase();
|
|
5196
|
+
return n * UNIT_MS[unit];
|
|
5197
|
+
}
|
|
5198
|
+
function dayIndex(token) {
|
|
5199
|
+
const text7 = token.trim().toLowerCase();
|
|
5200
|
+
if (/^[0-6]$/.test(text7)) return Number(text7);
|
|
5201
|
+
return DAY_ALIASES[text7];
|
|
5202
|
+
}
|
|
5203
|
+
function normalizeWeekdays(days) {
|
|
5204
|
+
const set = /* @__PURE__ */ new Set();
|
|
5205
|
+
for (const day of days) {
|
|
5206
|
+
if (!Number.isInteger(day) || day < 0 || day > 6) {
|
|
5207
|
+
throw new Error("Days must be 0 (Sunday) through 6 (Saturday)");
|
|
5208
|
+
}
|
|
5209
|
+
set.add(day);
|
|
5210
|
+
}
|
|
5211
|
+
if (set.size === 0) throw new Error("Pick at least one day");
|
|
5212
|
+
return [...set].sort((a, b) => a - b);
|
|
5213
|
+
}
|
|
5214
|
+
function parseWeeklyDays(raw) {
|
|
5215
|
+
const text7 = raw.trim().toLowerCase();
|
|
5216
|
+
if (!text7) throw new Error("Pick at least one day");
|
|
5217
|
+
if (text7 === "daily" || text7 === "all" || text7 === "every day" || text7 === "everyday") {
|
|
5218
|
+
return [0, 1, 2, 3, 4, 5, 6];
|
|
5219
|
+
}
|
|
5220
|
+
if (text7 === "weekdays" || text7 === "weekday") return [1, 2, 3, 4, 5];
|
|
5221
|
+
if (text7 === "weekends" || text7 === "weekend") return [0, 6];
|
|
5222
|
+
const days = [];
|
|
5223
|
+
for (const part of text7.split(/[\s,]+/).filter(Boolean)) {
|
|
5224
|
+
const range = part.split("-");
|
|
5225
|
+
if (range.length === 2 && range[0] && range[1]) {
|
|
5226
|
+
const start = dayIndex(range[0]);
|
|
5227
|
+
const end = dayIndex(range[1]);
|
|
5228
|
+
if (start === void 0 || end === void 0) {
|
|
5229
|
+
throw new Error(`Unknown day: ${part} (use mon,tue, weekdays, weekends, or daily)`);
|
|
5230
|
+
}
|
|
5231
|
+
if (start <= end) {
|
|
5232
|
+
for (let d = start; d <= end; d++) days.push(d);
|
|
5233
|
+
} else {
|
|
5234
|
+
for (let d = start; d <= 6; d++) days.push(d);
|
|
5235
|
+
for (let d = 0; d <= end; d++) days.push(d);
|
|
5236
|
+
}
|
|
5237
|
+
continue;
|
|
5238
|
+
}
|
|
5239
|
+
const n = dayIndex(part);
|
|
5240
|
+
if (n === void 0) {
|
|
5241
|
+
throw new Error(`Unknown day: ${part} (use mon,tue, weekdays, weekends, or daily)`);
|
|
5242
|
+
}
|
|
5243
|
+
days.push(n);
|
|
5244
|
+
}
|
|
5245
|
+
return normalizeWeekdays(days);
|
|
5246
|
+
}
|
|
5247
|
+
function normalizeWeeklyTime(raw) {
|
|
5248
|
+
const m = raw.trim().match(TIME_RE);
|
|
5249
|
+
if (!m) throw new Error(`Invalid time: ${raw} (use HH:mm, 24-hour)`);
|
|
5250
|
+
return `${m[1]}:${m[2]}`;
|
|
5251
|
+
}
|
|
5252
|
+
function formatWeeklyDays(days) {
|
|
5253
|
+
const key = normalizeWeekdays(days).join(",");
|
|
5254
|
+
if (key === "0,1,2,3,4,5,6") return "daily";
|
|
5255
|
+
if (key === "1,2,3,4,5") return "weekdays";
|
|
5256
|
+
if (key === "0,6") return "weekends";
|
|
5257
|
+
return normalizeWeekdays(days).map((day) => WEEKDAY_LABELS[day]).join(", ");
|
|
5258
|
+
}
|
|
5259
|
+
function weeklyCronExpr(when) {
|
|
5260
|
+
const time = normalizeWeeklyTime(when.time);
|
|
5261
|
+
const [hh, mm] = time.split(":");
|
|
5262
|
+
const days = normalizeWeekdays(when.days);
|
|
5263
|
+
return `${Number(mm)} ${Number(hh)} * * ${days.join(",")}`;
|
|
5264
|
+
}
|
|
5265
|
+
function computeNextRunAt(when, from = /* @__PURE__ */ new Date()) {
|
|
5266
|
+
if (when.kind === "once") {
|
|
5267
|
+
const at = new Date(when.at);
|
|
5268
|
+
if (Number.isNaN(at.getTime())) {
|
|
5269
|
+
throw new Error(`Invalid once-at datetime: ${when.at}`);
|
|
5270
|
+
}
|
|
5271
|
+
return at;
|
|
5272
|
+
}
|
|
5273
|
+
if (when.kind === "every") {
|
|
5274
|
+
const ms = parseDurationMs(when.every);
|
|
5275
|
+
if (!ms) {
|
|
5276
|
+
throw new Error(`Invalid interval: ${when.every} (use 15m, 1h, 6h, 1d)`);
|
|
5277
|
+
}
|
|
5278
|
+
return new Date(from.getTime() + ms);
|
|
5279
|
+
}
|
|
5280
|
+
if (when.kind === "weekly") {
|
|
5281
|
+
return computeNextRunAt(
|
|
5282
|
+
{ kind: "cron", expr: weeklyCronExpr(when), tz: when.tz },
|
|
5283
|
+
from
|
|
5284
|
+
);
|
|
5285
|
+
}
|
|
5286
|
+
try {
|
|
5287
|
+
const job = new import_croner.Cron(when.expr, {
|
|
5288
|
+
timezone: when.tz?.trim() || void 0,
|
|
5289
|
+
paused: true
|
|
5290
|
+
});
|
|
5291
|
+
const next = job.nextRun(from);
|
|
5292
|
+
if (!next) {
|
|
5293
|
+
throw new Error(`Cron expression has no next run: ${when.expr}`);
|
|
5294
|
+
}
|
|
5295
|
+
return next;
|
|
5296
|
+
} catch (err) {
|
|
5297
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
5298
|
+
throw new Error(`Invalid cron: ${message}`);
|
|
5299
|
+
}
|
|
5300
|
+
}
|
|
5301
|
+
function formatScheduleWhen(when) {
|
|
5302
|
+
if (when.kind === "once") return `once at ${when.at}`;
|
|
5303
|
+
if (when.kind === "every") return `every ${when.every}`;
|
|
5304
|
+
if (when.kind === "weekly") {
|
|
5305
|
+
const label = `${formatWeeklyDays(when.days)} at ${normalizeWeeklyTime(when.time)}`;
|
|
5306
|
+
const tz2 = when.tz?.trim();
|
|
5307
|
+
return tz2 ? `${label} (${tz2})` : label;
|
|
5308
|
+
}
|
|
5309
|
+
const tz = when.tz?.trim();
|
|
5310
|
+
return tz ? `cron ${when.expr} (${tz})` : `cron ${when.expr}`;
|
|
5311
|
+
}
|
|
5312
|
+
function normalizeWhen(raw) {
|
|
5313
|
+
if (!raw || typeof raw !== "object") {
|
|
5314
|
+
throw new Error("Schedule is missing `when`");
|
|
5315
|
+
}
|
|
5316
|
+
const rec = raw;
|
|
5317
|
+
const kind = rec.kind;
|
|
5318
|
+
if (kind === "once" && typeof rec.at === "string") {
|
|
5319
|
+
return { kind: "once", at: rec.at };
|
|
5320
|
+
}
|
|
5321
|
+
if (kind === "every" && typeof rec.every === "string") {
|
|
5322
|
+
return { kind: "every", every: rec.every };
|
|
5323
|
+
}
|
|
5324
|
+
if (kind === "cron" && typeof rec.expr === "string") {
|
|
5325
|
+
return {
|
|
5326
|
+
kind: "cron",
|
|
5327
|
+
expr: rec.expr,
|
|
5328
|
+
tz: typeof rec.tz === "string" && rec.tz.trim() ? rec.tz.trim() : void 0
|
|
5329
|
+
};
|
|
5330
|
+
}
|
|
5331
|
+
if (kind === "weekly" && Array.isArray(rec.days) && typeof rec.time === "string") {
|
|
5332
|
+
return {
|
|
5333
|
+
kind: "weekly",
|
|
5334
|
+
days: normalizeWeekdays(rec.days.map((day) => Number(day))),
|
|
5335
|
+
time: normalizeWeeklyTime(rec.time),
|
|
5336
|
+
tz: typeof rec.tz === "string" && rec.tz.trim() ? rec.tz.trim() : void 0
|
|
5337
|
+
};
|
|
5338
|
+
}
|
|
5339
|
+
throw new Error("Schedule `when` must be once, every, weekly, or cron");
|
|
5340
|
+
}
|
|
5341
|
+
var import_croner, WEEKDAY_LABELS, DURATION_RE, UNIT_MS, DAY_ALIASES, TIME_RE;
|
|
5342
|
+
var init_schedule_when = __esm({
|
|
5343
|
+
"src/store/schedule-when.ts"() {
|
|
5344
|
+
"use strict";
|
|
5345
|
+
import_croner = require("croner");
|
|
5346
|
+
WEEKDAY_LABELS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
5347
|
+
DURATION_RE = /^(\d+)(s|m|h|d)$/i;
|
|
5348
|
+
UNIT_MS = {
|
|
5349
|
+
s: 1e3,
|
|
5350
|
+
m: 6e4,
|
|
5351
|
+
h: 36e5,
|
|
5352
|
+
d: 864e5
|
|
5353
|
+
};
|
|
5354
|
+
DAY_ALIASES = {
|
|
5355
|
+
sun: 0,
|
|
5356
|
+
sunday: 0,
|
|
5357
|
+
mon: 1,
|
|
5358
|
+
monday: 1,
|
|
5359
|
+
tue: 2,
|
|
5360
|
+
tues: 2,
|
|
5361
|
+
tuesday: 2,
|
|
5362
|
+
wed: 3,
|
|
5363
|
+
wednesday: 3,
|
|
5364
|
+
thu: 4,
|
|
5365
|
+
thur: 4,
|
|
5366
|
+
thurs: 4,
|
|
5367
|
+
thursday: 4,
|
|
5368
|
+
fri: 5,
|
|
5369
|
+
friday: 5,
|
|
5370
|
+
sat: 6,
|
|
5371
|
+
saturday: 6
|
|
5372
|
+
};
|
|
5373
|
+
TIME_RE = /^([01]\d|2[0-3]):([0-5]\d)(?::[0-5]\d)?$/;
|
|
5374
|
+
}
|
|
5375
|
+
});
|
|
5376
|
+
|
|
5377
|
+
// src/store/schedules.ts
|
|
5378
|
+
function schedulesPath() {
|
|
5379
|
+
return (0, import_node_path15.join)(appDataDir(), "schedules.json");
|
|
5380
|
+
}
|
|
5381
|
+
function defaultScheduleName(prompt) {
|
|
5382
|
+
const line = prompt.trim().split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
5383
|
+
if (!line) return "Untitled automation";
|
|
5384
|
+
return line.length > 60 ? `${line.slice(0, 57).trimEnd()}\u2026` : line;
|
|
5385
|
+
}
|
|
5386
|
+
function resolveScheduleThreadId(raw, env = process.env) {
|
|
5387
|
+
const value = raw?.trim() || "";
|
|
5388
|
+
if (!value) return null;
|
|
5389
|
+
if (value.toLowerCase() === "self") {
|
|
5390
|
+
return env.SIDEBOARD_ORCHESTRATOR_THREAD_ID?.trim() || env.SIDEBOARD_THREAD_ID?.trim() || null;
|
|
5391
|
+
}
|
|
5392
|
+
return value;
|
|
5393
|
+
}
|
|
5394
|
+
function nowIso(d = /* @__PURE__ */ new Date()) {
|
|
5395
|
+
return d.toISOString();
|
|
5396
|
+
}
|
|
5397
|
+
function normalizeOptionalBool(raw) {
|
|
5398
|
+
if (raw === true || raw === false) return raw;
|
|
5399
|
+
return null;
|
|
5400
|
+
}
|
|
5401
|
+
function normalizeAutonomy2(raw) {
|
|
5402
|
+
return raw === "default" || raw === "full" ? raw : null;
|
|
5403
|
+
}
|
|
5404
|
+
function normalizeAttachments(raw) {
|
|
5405
|
+
if (!Array.isArray(raw)) return [];
|
|
5406
|
+
const out = [];
|
|
5407
|
+
for (const item of raw) {
|
|
5408
|
+
if (!item || typeof item !== "object") continue;
|
|
5409
|
+
const row2 = item;
|
|
5410
|
+
if (typeof row2.id !== "string" || !row2.id.trim()) continue;
|
|
5411
|
+
if (typeof row2.name !== "string" || !row2.name) continue;
|
|
5412
|
+
if (typeof row2.content !== "string") continue;
|
|
5413
|
+
if (!ATTACHMENT_KINDS.has(row2.kind)) continue;
|
|
5414
|
+
const next = {
|
|
5415
|
+
id: row2.id,
|
|
5416
|
+
name: row2.name,
|
|
5417
|
+
kind: row2.kind,
|
|
5418
|
+
content: row2.content
|
|
5419
|
+
};
|
|
5420
|
+
if (typeof row2.path === "string" && row2.path) next.path = row2.path;
|
|
5421
|
+
if (typeof row2.previewDataUrl === "string" && row2.previewDataUrl) {
|
|
5422
|
+
next.previewDataUrl = row2.previewDataUrl;
|
|
5423
|
+
}
|
|
5424
|
+
out.push(next);
|
|
5425
|
+
}
|
|
5426
|
+
return out;
|
|
5427
|
+
}
|
|
5428
|
+
function normalizeTask(raw) {
|
|
5429
|
+
const when = normalizeWhen(raw.when);
|
|
5430
|
+
const agent = raw.agent && isOrchestratorCapableAgent(raw.agent) ? raw.agent : null;
|
|
5431
|
+
return {
|
|
5432
|
+
id: raw.id,
|
|
5433
|
+
name: typeof raw.name === "string" && raw.name.trim() ? raw.name.trim() : defaultScheduleName(raw.prompt),
|
|
5434
|
+
prompt: String(raw.prompt ?? ""),
|
|
5435
|
+
enabled: Boolean(raw.enabled),
|
|
5436
|
+
when,
|
|
5437
|
+
threadId: raw.threadId?.trim() || null,
|
|
5438
|
+
agent,
|
|
5439
|
+
model: raw.model?.trim() || null,
|
|
5440
|
+
effort: normalizeThinkingEffort(raw.effort),
|
|
5441
|
+
fast: normalizeOptionalBool(raw.fast),
|
|
5442
|
+
planMode: normalizeOptionalBool(raw.planMode),
|
|
5443
|
+
autonomy: normalizeAutonomy2(raw.autonomy),
|
|
5444
|
+
attachments: normalizeAttachments(raw.attachments),
|
|
5445
|
+
archiveChat: raw.archiveChat !== false,
|
|
5446
|
+
nextRunAt: raw.nextRunAt,
|
|
5447
|
+
lastRunAt: raw.lastRunAt ?? null,
|
|
5448
|
+
lastThreadId: raw.lastThreadId ?? null,
|
|
5449
|
+
lastError: raw.lastError ?? null,
|
|
5450
|
+
createdBy: raw.createdBy === "mcp" || raw.createdBy === "cli" || raw.createdBy === "ui" ? raw.createdBy : "ui",
|
|
5451
|
+
createdAt: raw.createdAt,
|
|
5452
|
+
updatedAt: raw.updatedAt
|
|
5453
|
+
};
|
|
5454
|
+
}
|
|
5455
|
+
function readAll() {
|
|
5456
|
+
const path2 = schedulesPath();
|
|
5457
|
+
if (!(0, import_node_fs12.existsSync)(path2)) return [];
|
|
5458
|
+
try {
|
|
5459
|
+
const parsed = JSON.parse((0, import_node_fs12.readFileSync)(path2, "utf8"));
|
|
5460
|
+
if (!Array.isArray(parsed)) return [];
|
|
5461
|
+
return parsed.map((row2) => {
|
|
5462
|
+
try {
|
|
5463
|
+
return normalizeTask(row2);
|
|
5464
|
+
} catch {
|
|
5465
|
+
return null;
|
|
5466
|
+
}
|
|
5467
|
+
}).filter((row2) => Boolean(row2?.id && row2.prompt));
|
|
5468
|
+
} catch {
|
|
5469
|
+
return [];
|
|
5470
|
+
}
|
|
5471
|
+
}
|
|
5472
|
+
function writeAll(rows) {
|
|
5473
|
+
writePrivateFile(schedulesPath(), `${JSON.stringify(rows, null, 2)}
|
|
5474
|
+
`);
|
|
5475
|
+
}
|
|
5476
|
+
function buildTask(input, now) {
|
|
5477
|
+
const prompt = input.prompt.trim();
|
|
5478
|
+
if (!prompt) throw new Error("Schedule prompt is required");
|
|
5479
|
+
const when = normalizeWhen(input.when);
|
|
5480
|
+
const nextRunAt = computeNextRunAt(when, now).toISOString();
|
|
5481
|
+
const ts = nowIso(now);
|
|
5482
|
+
const agent = input.agent ? coerceOrchestratorAgent(input.agent) : null;
|
|
5483
|
+
return {
|
|
5484
|
+
id: (0, import_node_crypto5.randomUUID)(),
|
|
5485
|
+
name: input.name?.trim() || defaultScheduleName(prompt),
|
|
5486
|
+
prompt,
|
|
5487
|
+
enabled: input.enabled !== false,
|
|
5488
|
+
when,
|
|
5489
|
+
threadId: input.threadId?.trim() || null,
|
|
5490
|
+
agent,
|
|
5491
|
+
model: input.model?.trim() || null,
|
|
5492
|
+
effort: input.effort != null ? normalizeThinkingEffort(input.effort) : null,
|
|
5493
|
+
fast: normalizeOptionalBool(input.fast),
|
|
5494
|
+
planMode: normalizeOptionalBool(input.planMode),
|
|
5495
|
+
autonomy: normalizeAutonomy2(input.autonomy),
|
|
5496
|
+
attachments: normalizeAttachments(input.attachments),
|
|
5497
|
+
archiveChat: input.archiveChat !== false,
|
|
5498
|
+
nextRunAt,
|
|
5499
|
+
lastRunAt: null,
|
|
5500
|
+
lastThreadId: null,
|
|
5501
|
+
lastError: null,
|
|
5502
|
+
createdBy: input.createdBy,
|
|
5503
|
+
createdAt: ts,
|
|
5504
|
+
updatedAt: ts
|
|
5505
|
+
};
|
|
5506
|
+
}
|
|
5507
|
+
function listSchedules() {
|
|
5508
|
+
return readAll().sort((a, b) => a.nextRunAt.localeCompare(b.nextRunAt));
|
|
5509
|
+
}
|
|
5510
|
+
function hasEnabledSchedules() {
|
|
5511
|
+
return listSchedules().some((row2) => row2.enabled);
|
|
5512
|
+
}
|
|
5513
|
+
function scheduleNeedsCaffeinate(task, now = /* @__PURE__ */ new Date()) {
|
|
5514
|
+
if (!task.enabled) return false;
|
|
5515
|
+
const at = new Date(task.nextRunAt);
|
|
5516
|
+
if (Number.isNaN(at.getTime())) return false;
|
|
5517
|
+
return at.getTime() > now.getTime();
|
|
5518
|
+
}
|
|
5519
|
+
function ensureCaffeinateForFutureSchedule(task) {
|
|
5520
|
+
if (!scheduleNeedsCaffeinate(task)) return;
|
|
5521
|
+
if (caffeinateWhileSchedulesEnabled()) return;
|
|
5522
|
+
updateAdvancedSettings({ caffeinateWhileSchedules: true });
|
|
5523
|
+
}
|
|
5524
|
+
function getSchedule(id) {
|
|
5525
|
+
const key = id.trim();
|
|
5526
|
+
if (!key) return null;
|
|
5527
|
+
return readAll().find(
|
|
5528
|
+
(row2) => row2.id === key || row2.id.startsWith(key) && key.length >= 8
|
|
5529
|
+
) ?? null;
|
|
5530
|
+
}
|
|
5531
|
+
function createSchedule(input) {
|
|
5532
|
+
const task = buildTask(input, /* @__PURE__ */ new Date());
|
|
5533
|
+
const rows = readAll();
|
|
5534
|
+
rows.push(task);
|
|
5535
|
+
writeAll(rows);
|
|
5536
|
+
ensureCaffeinateForFutureSchedule(task);
|
|
5537
|
+
return task;
|
|
5538
|
+
}
|
|
5539
|
+
function updateSchedule(id, patch) {
|
|
5540
|
+
const rows = readAll();
|
|
5541
|
+
const idx = rows.findIndex((row2) => row2.id === id || id.length >= 8 && row2.id.startsWith(id));
|
|
5542
|
+
if (idx < 0) throw new Error(`Automation not found: ${id}`);
|
|
5543
|
+
const prev = rows[idx];
|
|
5544
|
+
const when = patch.when ? normalizeWhen(patch.when) : prev.when;
|
|
5545
|
+
const prompt = patch.prompt !== void 0 ? patch.prompt.trim() : prev.prompt;
|
|
5546
|
+
if (!prompt) throw new Error("Schedule prompt is required");
|
|
5547
|
+
const whenChanged = patch.when !== void 0;
|
|
5548
|
+
const next = {
|
|
5549
|
+
...prev,
|
|
5550
|
+
name: patch.name !== void 0 ? patch.name.trim() || defaultScheduleName(prompt) : prev.name,
|
|
5551
|
+
prompt,
|
|
5552
|
+
enabled: patch.enabled ?? prev.enabled,
|
|
5553
|
+
when,
|
|
5554
|
+
threadId: patch.threadId !== void 0 ? patch.threadId?.trim() || null : prev.threadId,
|
|
5555
|
+
agent: patch.agent !== void 0 ? patch.agent ? coerceOrchestratorAgent(patch.agent) : null : prev.agent,
|
|
5556
|
+
model: patch.model !== void 0 ? patch.model?.trim() || null : prev.model,
|
|
5557
|
+
effort: patch.effort !== void 0 ? normalizeThinkingEffort(patch.effort) : prev.effort,
|
|
5558
|
+
fast: patch.fast !== void 0 ? normalizeOptionalBool(patch.fast) : prev.fast,
|
|
5559
|
+
planMode: patch.planMode !== void 0 ? normalizeOptionalBool(patch.planMode) : prev.planMode,
|
|
5560
|
+
autonomy: patch.autonomy !== void 0 ? normalizeAutonomy2(patch.autonomy) : prev.autonomy,
|
|
5561
|
+
attachments: patch.attachments !== void 0 ? normalizeAttachments(patch.attachments) : prev.attachments,
|
|
5562
|
+
archiveChat: patch.archiveChat !== void 0 ? patch.archiveChat !== false : prev.archiveChat,
|
|
5563
|
+
nextRunAt: whenChanged ? computeNextRunAt(when).toISOString() : prev.nextRunAt,
|
|
5564
|
+
lastError: whenChanged ? null : prev.lastError,
|
|
5565
|
+
updatedAt: nowIso()
|
|
5566
|
+
};
|
|
5567
|
+
rows[idx] = next;
|
|
5568
|
+
writeAll(rows);
|
|
5569
|
+
ensureCaffeinateForFutureSchedule(next);
|
|
5570
|
+
return next;
|
|
5571
|
+
}
|
|
5572
|
+
function deleteSchedulesForThread(threadId) {
|
|
5573
|
+
const id = threadId.trim();
|
|
5574
|
+
if (!id) return;
|
|
5575
|
+
const rows = readAll();
|
|
5576
|
+
const next = rows.filter((row2) => row2.threadId !== id);
|
|
5577
|
+
if (next.length === rows.length) return;
|
|
5578
|
+
writeAll(next);
|
|
5579
|
+
}
|
|
5580
|
+
function deleteSchedule(id) {
|
|
5581
|
+
const rows = readAll();
|
|
5582
|
+
const next = rows.filter(
|
|
5583
|
+
(row2) => row2.id !== id && !(id.length >= 8 && row2.id.startsWith(id))
|
|
5584
|
+
);
|
|
5585
|
+
if (next.length === rows.length) throw new Error(`Automation not found: ${id}`);
|
|
5586
|
+
writeAll(next);
|
|
5587
|
+
}
|
|
5588
|
+
function recordScheduleRun(id, result) {
|
|
5589
|
+
const rows = readAll();
|
|
5590
|
+
const idx = rows.findIndex((row2) => row2.id === id);
|
|
5591
|
+
if (idx < 0) throw new Error(`Automation not found: ${id}`);
|
|
5592
|
+
const prev = rows[idx];
|
|
5593
|
+
const firedAt = result.firedAt ?? /* @__PURE__ */ new Date();
|
|
5594
|
+
const next = {
|
|
5595
|
+
...prev,
|
|
5596
|
+
enabled: prev.when.kind === "once" ? false : prev.enabled,
|
|
5597
|
+
nextRunAt: prev.when.kind === "once" ? prev.nextRunAt : computeNextRunAt(prev.when, firedAt).toISOString(),
|
|
5598
|
+
lastRunAt: nowIso(firedAt),
|
|
5599
|
+
lastThreadId: result.lastThreadId !== void 0 ? result.lastThreadId : prev.lastThreadId,
|
|
5600
|
+
lastError: result.lastError ?? null,
|
|
5601
|
+
updatedAt: nowIso(firedAt)
|
|
5602
|
+
};
|
|
5603
|
+
rows[idx] = next;
|
|
5604
|
+
writeAll(rows);
|
|
5605
|
+
return next;
|
|
5606
|
+
}
|
|
5607
|
+
var import_node_crypto5, import_node_fs12, import_node_path15, ATTACHMENT_KINDS;
|
|
5608
|
+
var init_schedules = __esm({
|
|
5609
|
+
"src/store/schedules.ts"() {
|
|
5610
|
+
"use strict";
|
|
5611
|
+
import_node_crypto5 = require("crypto");
|
|
5612
|
+
import_node_fs12 = require("fs");
|
|
5613
|
+
import_node_path15 = require("path");
|
|
5614
|
+
init_schedule_when();
|
|
5615
|
+
init_orchestrator_capable();
|
|
5616
|
+
init_thinking_effort();
|
|
5617
|
+
init_paths();
|
|
5618
|
+
init_private_file();
|
|
5619
|
+
init_app_settings();
|
|
5620
|
+
init_schedule_when();
|
|
5621
|
+
ATTACHMENT_KINDS = /* @__PURE__ */ new Set([
|
|
5622
|
+
"transcript",
|
|
5623
|
+
"file",
|
|
5624
|
+
"issue",
|
|
5625
|
+
"workspace",
|
|
5626
|
+
"diff-comment",
|
|
5627
|
+
"code-ref"
|
|
5628
|
+
]);
|
|
5629
|
+
}
|
|
5630
|
+
});
|
|
5631
|
+
|
|
5187
5632
|
// src/store/thread-store.ts
|
|
5188
5633
|
var thread_store_exports = {};
|
|
5189
5634
|
__export(thread_store_exports, {
|
|
@@ -5204,7 +5649,7 @@ __export(thread_store_exports, {
|
|
|
5204
5649
|
withThreadLock: () => withThreadLock,
|
|
5205
5650
|
writeThread: () => writeThread
|
|
5206
5651
|
});
|
|
5207
|
-
function
|
|
5652
|
+
function nowIso2() {
|
|
5208
5653
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
5209
5654
|
}
|
|
5210
5655
|
function resolveThreadEffort(raw) {
|
|
@@ -5293,9 +5738,9 @@ function normalizeThread(raw) {
|
|
|
5293
5738
|
};
|
|
5294
5739
|
}
|
|
5295
5740
|
function createEmptyThread(partial) {
|
|
5296
|
-
const ts =
|
|
5741
|
+
const ts = nowIso2();
|
|
5297
5742
|
return {
|
|
5298
|
-
id: (0,
|
|
5743
|
+
id: (0, import_node_crypto6.randomUUID)(),
|
|
5299
5744
|
sessionId: partial.sessionId ?? null,
|
|
5300
5745
|
autonomy: partial.autonomy ?? "default",
|
|
5301
5746
|
model: partial.model ?? null,
|
|
@@ -5348,7 +5793,7 @@ function createEmptyThread(partial) {
|
|
|
5348
5793
|
}
|
|
5349
5794
|
async function withThreadLock(id, fn) {
|
|
5350
5795
|
const lockPath = threadLockPath(id);
|
|
5351
|
-
(0,
|
|
5796
|
+
(0, import_node_fs13.writeFileSync)(lockPath, "", { flag: "a" });
|
|
5352
5797
|
let release;
|
|
5353
5798
|
try {
|
|
5354
5799
|
release = await import_proper_lockfile.default.lock(lockPath, {
|
|
@@ -5369,7 +5814,7 @@ function cacheForDir() {
|
|
|
5369
5814
|
}
|
|
5370
5815
|
function fileMtimeMs(path2) {
|
|
5371
5816
|
try {
|
|
5372
|
-
return (0,
|
|
5817
|
+
return (0, import_node_fs13.statSync)(path2).mtimeMs;
|
|
5373
5818
|
} catch {
|
|
5374
5819
|
return null;
|
|
5375
5820
|
}
|
|
@@ -5402,7 +5847,7 @@ function readThread(id) {
|
|
|
5402
5847
|
const cache2 = cacheForDir();
|
|
5403
5848
|
const cached2 = cache2.byId.get(id);
|
|
5404
5849
|
if (cached2 && cache2.mtimeMs.get(id) === mtimeMs) return cached2;
|
|
5405
|
-
const raw = (0,
|
|
5850
|
+
const raw = (0, import_node_fs13.readFileSync)(path2, "utf8");
|
|
5406
5851
|
const thread = normalizeThread(JSON.parse(raw));
|
|
5407
5852
|
rememberThread(thread, mtimeMs);
|
|
5408
5853
|
return thread;
|
|
@@ -5410,9 +5855,9 @@ function readThread(id) {
|
|
|
5410
5855
|
function writeThread(thread, opts) {
|
|
5411
5856
|
const path2 = threadFilePath(idPath(thread.id));
|
|
5412
5857
|
const tmp = `${path2}.${process.pid}.tmp`;
|
|
5413
|
-
const next = opts?.touch === false ? { ...thread } : { ...thread, updatedAt:
|
|
5414
|
-
(0,
|
|
5415
|
-
(0,
|
|
5858
|
+
const next = opts?.touch === false ? { ...thread } : { ...thread, updatedAt: nowIso2() };
|
|
5859
|
+
(0, import_node_fs13.writeFileSync)(tmp, JSON.stringify(next, null, 2), "utf8");
|
|
5860
|
+
(0, import_node_fs13.renameSync)(tmp, path2);
|
|
5416
5861
|
const mtimeMs = fileMtimeMs(path2) ?? Date.now();
|
|
5417
5862
|
rememberThread(next, mtimeMs);
|
|
5418
5863
|
selfWriteMtimes.set(thread.id, mtimeMs);
|
|
@@ -5426,12 +5871,12 @@ function idPath(id) {
|
|
|
5426
5871
|
return id;
|
|
5427
5872
|
}
|
|
5428
5873
|
function isThreadRecordFile(nameOrPath) {
|
|
5429
|
-
const name = (0,
|
|
5874
|
+
const name = (0, import_node_path16.basename)(nameOrPath);
|
|
5430
5875
|
return name.endsWith(".json") && !name.endsWith(".live.json") && !name.endsWith(".setup.log.json");
|
|
5431
5876
|
}
|
|
5432
5877
|
function listThreads(opts) {
|
|
5433
5878
|
const cache2 = cacheForDir();
|
|
5434
|
-
const files = (0,
|
|
5879
|
+
const files = (0, import_node_fs13.readdirSync)(threadsDir()).filter(isThreadRecordFile);
|
|
5435
5880
|
const seen = /* @__PURE__ */ new Set();
|
|
5436
5881
|
for (const f of files) {
|
|
5437
5882
|
const id = f.replace(/\.json$/, "");
|
|
@@ -5454,30 +5899,29 @@ function listThreads(opts) {
|
|
|
5454
5899
|
function deleteThreadRecord(id) {
|
|
5455
5900
|
forgetThread(id);
|
|
5456
5901
|
const path2 = threadFilePath(id);
|
|
5457
|
-
if ((0,
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
(0, import_node_fs12.unlinkSync)(lock);
|
|
5462
|
-
} catch {
|
|
5463
|
-
}
|
|
5902
|
+
if ((0, import_node_fs13.existsSync)(path2)) (0, import_node_fs13.unlinkSync)(path2);
|
|
5903
|
+
try {
|
|
5904
|
+
if ((0, import_node_fs13.existsSync)(threadLockPath(id))) (0, import_node_fs13.unlinkSync)(threadLockPath(id));
|
|
5905
|
+
} catch {
|
|
5464
5906
|
}
|
|
5465
5907
|
try {
|
|
5466
|
-
(0,
|
|
5908
|
+
(0, import_node_fs13.rmSync)(cursorSdkStoreDir(id), { recursive: true, force: true });
|
|
5467
5909
|
} catch {
|
|
5468
5910
|
}
|
|
5911
|
+
deleteSchedulesForThread(id);
|
|
5469
5912
|
}
|
|
5470
5913
|
function updateThread(id, patch) {
|
|
5471
5914
|
const current = readThread(id);
|
|
5472
5915
|
if (!current) throw new Error(`Thread not found: ${id}`);
|
|
5473
|
-
const next = { ...current, ...patch, id: current.id, updatedAt:
|
|
5916
|
+
const next = { ...current, ...patch, id: current.id, updatedAt: nowIso2() };
|
|
5474
5917
|
if (next.status === "archived") {
|
|
5475
|
-
next.archivedAt = typeof next.archivedAt === "string" && next.archivedAt.trim() || current.archivedAt ||
|
|
5918
|
+
next.archivedAt = typeof next.archivedAt === "string" && next.archivedAt.trim() || current.archivedAt || nowIso2();
|
|
5476
5919
|
} else {
|
|
5477
5920
|
delete next.archivedAt;
|
|
5478
5921
|
}
|
|
5479
5922
|
if (!next.ephemeralAutomationId?.trim()) delete next.ephemeralAutomationId;
|
|
5480
5923
|
writeThread(next);
|
|
5924
|
+
if (patch.status === "archived" && current.status !== "archived") deleteSchedulesForThread(current.id);
|
|
5481
5925
|
return next;
|
|
5482
5926
|
}
|
|
5483
5927
|
function appendMessage(id, message) {
|
|
@@ -5494,19 +5938,20 @@ function findThreadByRef(ref) {
|
|
|
5494
5938
|
(t) => t.id === ref || t.id.startsWith(ref) || t.branchName === ref || t.title === ref
|
|
5495
5939
|
) ?? null;
|
|
5496
5940
|
}
|
|
5497
|
-
var
|
|
5941
|
+
var import_node_crypto6, import_node_fs13, import_node_path16, import_proper_lockfile, listCache, selfWriteMtimes;
|
|
5498
5942
|
var init_thread_store = __esm({
|
|
5499
5943
|
"src/store/thread-store.ts"() {
|
|
5500
5944
|
"use strict";
|
|
5501
|
-
|
|
5945
|
+
import_node_crypto6 = require("crypto");
|
|
5502
5946
|
init_worktree_labels();
|
|
5503
|
-
|
|
5504
|
-
|
|
5947
|
+
import_node_fs13 = require("fs");
|
|
5948
|
+
import_node_path16 = require("path");
|
|
5505
5949
|
import_proper_lockfile = __toESM(require("proper-lockfile"), 1);
|
|
5506
5950
|
init_thinking_effort();
|
|
5507
5951
|
init_claude_mcp();
|
|
5508
5952
|
init_cursor_store();
|
|
5509
5953
|
init_paths();
|
|
5954
|
+
init_schedules();
|
|
5510
5955
|
listCache = null;
|
|
5511
5956
|
selfWriteMtimes = /* @__PURE__ */ new Map();
|
|
5512
5957
|
}
|
|
@@ -8037,11 +8482,11 @@ function materialize(mem) {
|
|
|
8037
8482
|
};
|
|
8038
8483
|
}
|
|
8039
8484
|
function setupLogPath(threadId) {
|
|
8040
|
-
return (0,
|
|
8485
|
+
return (0, import_node_path17.join)(threadsDir(), `${threadId}.setup.log.json`);
|
|
8041
8486
|
}
|
|
8042
8487
|
function setupLogKeyForWorktree(worktreePath) {
|
|
8043
8488
|
const norm = normalizeWorktreePath(worktreePath);
|
|
8044
|
-
return `wt-${(0,
|
|
8489
|
+
return `wt-${(0, import_node_crypto7.createHash)("sha1").update(norm).digest("hex").slice(0, 16)}`;
|
|
8045
8490
|
}
|
|
8046
8491
|
function emptySetupLog() {
|
|
8047
8492
|
return { ...EMPTY };
|
|
@@ -8063,7 +8508,7 @@ function persistNow(threadId) {
|
|
|
8063
8508
|
const mem = memory.get(threadId);
|
|
8064
8509
|
if (!mem) return;
|
|
8065
8510
|
try {
|
|
8066
|
-
(0,
|
|
8511
|
+
(0, import_node_fs14.writeFileSync)(
|
|
8067
8512
|
setupLogPath(threadId),
|
|
8068
8513
|
`${JSON.stringify(materialize(mem))}
|
|
8069
8514
|
`,
|
|
@@ -8084,9 +8529,9 @@ function schedulePersist(threadId) {
|
|
|
8084
8529
|
}
|
|
8085
8530
|
function loadFromDisk(threadId) {
|
|
8086
8531
|
const path2 = setupLogPath(threadId);
|
|
8087
|
-
if (!(0,
|
|
8532
|
+
if (!(0, import_node_fs14.existsSync)(path2)) return null;
|
|
8088
8533
|
try {
|
|
8089
|
-
const raw = JSON.parse((0,
|
|
8534
|
+
const raw = JSON.parse((0, import_node_fs14.readFileSync)(path2, "utf8"));
|
|
8090
8535
|
return {
|
|
8091
8536
|
output: typeof raw.output === "string" ? raw.output : "",
|
|
8092
8537
|
running: Boolean(raw.running),
|
|
@@ -8142,13 +8587,13 @@ function finishSetupLog(threadId, exitCode, source) {
|
|
|
8142
8587
|
persistNow(threadId);
|
|
8143
8588
|
return materialize(mem);
|
|
8144
8589
|
}
|
|
8145
|
-
var
|
|
8590
|
+
var import_node_crypto7, import_node_fs14, import_node_path17, EMPTY, MAX_SETUP_LOG_CHARS, memory, persistTimers, PERSIST_DEBOUNCE_MS;
|
|
8146
8591
|
var init_setup_log = __esm({
|
|
8147
8592
|
"src/store/setup-log.ts"() {
|
|
8148
8593
|
"use strict";
|
|
8149
|
-
|
|
8150
|
-
|
|
8151
|
-
|
|
8594
|
+
import_node_crypto7 = require("crypto");
|
|
8595
|
+
import_node_fs14 = require("fs");
|
|
8596
|
+
import_node_path17 = require("path");
|
|
8152
8597
|
init_worktree_labels();
|
|
8153
8598
|
init_paths();
|
|
8154
8599
|
EMPTY = {
|
|
@@ -8193,11 +8638,11 @@ function safeScriptToken(scriptName) {
|
|
|
8193
8638
|
return token || "dev";
|
|
8194
8639
|
}
|
|
8195
8640
|
function runLogPath(key) {
|
|
8196
|
-
return (0,
|
|
8641
|
+
return (0, import_node_path18.join)(threadsDir(), `${key}.run.log.json`);
|
|
8197
8642
|
}
|
|
8198
8643
|
function runLogKeyForWorktree(worktreePath, scriptName) {
|
|
8199
8644
|
const norm = normalizeWorktreePath(worktreePath);
|
|
8200
|
-
const hash = (0,
|
|
8645
|
+
const hash = (0, import_node_crypto8.createHash)("sha1").update(norm).digest("hex").slice(0, 16);
|
|
8201
8646
|
return `wt-${hash}-run-${safeScriptToken(scriptName)}`;
|
|
8202
8647
|
}
|
|
8203
8648
|
function emptyRunLog() {
|
|
@@ -8221,7 +8666,7 @@ function persistNow2(key) {
|
|
|
8221
8666
|
const mem = memory2.get(key);
|
|
8222
8667
|
if (!mem) return;
|
|
8223
8668
|
try {
|
|
8224
|
-
(0,
|
|
8669
|
+
(0, import_node_fs15.writeFileSync)(runLogPath(key), `${JSON.stringify(materialize2(mem))}
|
|
8225
8670
|
`, "utf8");
|
|
8226
8671
|
} catch {
|
|
8227
8672
|
}
|
|
@@ -8238,9 +8683,9 @@ function schedulePersist2(key) {
|
|
|
8238
8683
|
}
|
|
8239
8684
|
function loadFromDisk2(key) {
|
|
8240
8685
|
const path2 = runLogPath(key);
|
|
8241
|
-
if (!(0,
|
|
8686
|
+
if (!(0, import_node_fs15.existsSync)(path2)) return null;
|
|
8242
8687
|
try {
|
|
8243
|
-
const raw = JSON.parse((0,
|
|
8688
|
+
const raw = JSON.parse((0, import_node_fs15.readFileSync)(path2, "utf8"));
|
|
8244
8689
|
return {
|
|
8245
8690
|
output: typeof raw.output === "string" ? raw.output : "",
|
|
8246
8691
|
running: Boolean(raw.running),
|
|
@@ -8298,13 +8743,13 @@ function finishRunLog(key, exitCode) {
|
|
|
8298
8743
|
function flushRunLog(key) {
|
|
8299
8744
|
persistNow2(key);
|
|
8300
8745
|
}
|
|
8301
|
-
var
|
|
8746
|
+
var import_node_crypto8, import_node_fs15, import_node_path18, EMPTY2, MAX_RUN_LOG_CHARS, DEFAULT_RUN_LOG_TAIL_CHARS, memory2, persistTimers2, PERSIST_DEBOUNCE_MS2;
|
|
8302
8747
|
var init_run_log = __esm({
|
|
8303
8748
|
"src/store/run-log.ts"() {
|
|
8304
8749
|
"use strict";
|
|
8305
|
-
|
|
8306
|
-
|
|
8307
|
-
|
|
8750
|
+
import_node_crypto8 = require("crypto");
|
|
8751
|
+
import_node_fs15 = require("fs");
|
|
8752
|
+
import_node_path18 = require("path");
|
|
8308
8753
|
init_worktree_labels();
|
|
8309
8754
|
init_setup_log();
|
|
8310
8755
|
init_paths();
|
|
@@ -8322,441 +8767,6 @@ var init_run_log = __esm({
|
|
|
8322
8767
|
}
|
|
8323
8768
|
});
|
|
8324
8769
|
|
|
8325
|
-
// src/store/schedule-when.ts
|
|
8326
|
-
function parseDurationMs(every) {
|
|
8327
|
-
const m = every.trim().match(DURATION_RE);
|
|
8328
|
-
if (!m) return null;
|
|
8329
|
-
const n = Number.parseInt(m[1], 10);
|
|
8330
|
-
if (!Number.isFinite(n) || n <= 0) return null;
|
|
8331
|
-
const unit = m[2].toLowerCase();
|
|
8332
|
-
return n * UNIT_MS[unit];
|
|
8333
|
-
}
|
|
8334
|
-
function dayIndex(token) {
|
|
8335
|
-
const text7 = token.trim().toLowerCase();
|
|
8336
|
-
if (/^[0-6]$/.test(text7)) return Number(text7);
|
|
8337
|
-
return DAY_ALIASES[text7];
|
|
8338
|
-
}
|
|
8339
|
-
function normalizeWeekdays(days) {
|
|
8340
|
-
const set = /* @__PURE__ */ new Set();
|
|
8341
|
-
for (const day of days) {
|
|
8342
|
-
if (!Number.isInteger(day) || day < 0 || day > 6) {
|
|
8343
|
-
throw new Error("Days must be 0 (Sunday) through 6 (Saturday)");
|
|
8344
|
-
}
|
|
8345
|
-
set.add(day);
|
|
8346
|
-
}
|
|
8347
|
-
if (set.size === 0) throw new Error("Pick at least one day");
|
|
8348
|
-
return [...set].sort((a, b) => a - b);
|
|
8349
|
-
}
|
|
8350
|
-
function parseWeeklyDays(raw) {
|
|
8351
|
-
const text7 = raw.trim().toLowerCase();
|
|
8352
|
-
if (!text7) throw new Error("Pick at least one day");
|
|
8353
|
-
if (text7 === "daily" || text7 === "all" || text7 === "every day" || text7 === "everyday") {
|
|
8354
|
-
return [0, 1, 2, 3, 4, 5, 6];
|
|
8355
|
-
}
|
|
8356
|
-
if (text7 === "weekdays" || text7 === "weekday") return [1, 2, 3, 4, 5];
|
|
8357
|
-
if (text7 === "weekends" || text7 === "weekend") return [0, 6];
|
|
8358
|
-
const days = [];
|
|
8359
|
-
for (const part of text7.split(/[\s,]+/).filter(Boolean)) {
|
|
8360
|
-
const range = part.split("-");
|
|
8361
|
-
if (range.length === 2 && range[0] && range[1]) {
|
|
8362
|
-
const start = dayIndex(range[0]);
|
|
8363
|
-
const end = dayIndex(range[1]);
|
|
8364
|
-
if (start === void 0 || end === void 0) {
|
|
8365
|
-
throw new Error(`Unknown day: ${part} (use mon,tue, weekdays, weekends, or daily)`);
|
|
8366
|
-
}
|
|
8367
|
-
if (start <= end) {
|
|
8368
|
-
for (let d = start; d <= end; d++) days.push(d);
|
|
8369
|
-
} else {
|
|
8370
|
-
for (let d = start; d <= 6; d++) days.push(d);
|
|
8371
|
-
for (let d = 0; d <= end; d++) days.push(d);
|
|
8372
|
-
}
|
|
8373
|
-
continue;
|
|
8374
|
-
}
|
|
8375
|
-
const n = dayIndex(part);
|
|
8376
|
-
if (n === void 0) {
|
|
8377
|
-
throw new Error(`Unknown day: ${part} (use mon,tue, weekdays, weekends, or daily)`);
|
|
8378
|
-
}
|
|
8379
|
-
days.push(n);
|
|
8380
|
-
}
|
|
8381
|
-
return normalizeWeekdays(days);
|
|
8382
|
-
}
|
|
8383
|
-
function normalizeWeeklyTime(raw) {
|
|
8384
|
-
const m = raw.trim().match(TIME_RE);
|
|
8385
|
-
if (!m) throw new Error(`Invalid time: ${raw} (use HH:mm, 24-hour)`);
|
|
8386
|
-
return `${m[1]}:${m[2]}`;
|
|
8387
|
-
}
|
|
8388
|
-
function formatWeeklyDays(days) {
|
|
8389
|
-
const key = normalizeWeekdays(days).join(",");
|
|
8390
|
-
if (key === "0,1,2,3,4,5,6") return "daily";
|
|
8391
|
-
if (key === "1,2,3,4,5") return "weekdays";
|
|
8392
|
-
if (key === "0,6") return "weekends";
|
|
8393
|
-
return normalizeWeekdays(days).map((day) => WEEKDAY_LABELS[day]).join(", ");
|
|
8394
|
-
}
|
|
8395
|
-
function weeklyCronExpr(when) {
|
|
8396
|
-
const time = normalizeWeeklyTime(when.time);
|
|
8397
|
-
const [hh, mm] = time.split(":");
|
|
8398
|
-
const days = normalizeWeekdays(when.days);
|
|
8399
|
-
return `${Number(mm)} ${Number(hh)} * * ${days.join(",")}`;
|
|
8400
|
-
}
|
|
8401
|
-
function computeNextRunAt(when, from = /* @__PURE__ */ new Date()) {
|
|
8402
|
-
if (when.kind === "once") {
|
|
8403
|
-
const at = new Date(when.at);
|
|
8404
|
-
if (Number.isNaN(at.getTime())) {
|
|
8405
|
-
throw new Error(`Invalid once-at datetime: ${when.at}`);
|
|
8406
|
-
}
|
|
8407
|
-
return at;
|
|
8408
|
-
}
|
|
8409
|
-
if (when.kind === "every") {
|
|
8410
|
-
const ms = parseDurationMs(when.every);
|
|
8411
|
-
if (!ms) {
|
|
8412
|
-
throw new Error(`Invalid interval: ${when.every} (use 15m, 1h, 6h, 1d)`);
|
|
8413
|
-
}
|
|
8414
|
-
return new Date(from.getTime() + ms);
|
|
8415
|
-
}
|
|
8416
|
-
if (when.kind === "weekly") {
|
|
8417
|
-
return computeNextRunAt(
|
|
8418
|
-
{ kind: "cron", expr: weeklyCronExpr(when), tz: when.tz },
|
|
8419
|
-
from
|
|
8420
|
-
);
|
|
8421
|
-
}
|
|
8422
|
-
try {
|
|
8423
|
-
const job = new import_croner.Cron(when.expr, {
|
|
8424
|
-
timezone: when.tz?.trim() || void 0,
|
|
8425
|
-
paused: true
|
|
8426
|
-
});
|
|
8427
|
-
const next = job.nextRun(from);
|
|
8428
|
-
if (!next) {
|
|
8429
|
-
throw new Error(`Cron expression has no next run: ${when.expr}`);
|
|
8430
|
-
}
|
|
8431
|
-
return next;
|
|
8432
|
-
} catch (err) {
|
|
8433
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
8434
|
-
throw new Error(`Invalid cron: ${message}`);
|
|
8435
|
-
}
|
|
8436
|
-
}
|
|
8437
|
-
function formatScheduleWhen(when) {
|
|
8438
|
-
if (when.kind === "once") return `once at ${when.at}`;
|
|
8439
|
-
if (when.kind === "every") return `every ${when.every}`;
|
|
8440
|
-
if (when.kind === "weekly") {
|
|
8441
|
-
const label = `${formatWeeklyDays(when.days)} at ${normalizeWeeklyTime(when.time)}`;
|
|
8442
|
-
const tz2 = when.tz?.trim();
|
|
8443
|
-
return tz2 ? `${label} (${tz2})` : label;
|
|
8444
|
-
}
|
|
8445
|
-
const tz = when.tz?.trim();
|
|
8446
|
-
return tz ? `cron ${when.expr} (${tz})` : `cron ${when.expr}`;
|
|
8447
|
-
}
|
|
8448
|
-
function normalizeWhen(raw) {
|
|
8449
|
-
if (!raw || typeof raw !== "object") {
|
|
8450
|
-
throw new Error("Schedule is missing `when`");
|
|
8451
|
-
}
|
|
8452
|
-
const rec = raw;
|
|
8453
|
-
const kind = rec.kind;
|
|
8454
|
-
if (kind === "once" && typeof rec.at === "string") {
|
|
8455
|
-
return { kind: "once", at: rec.at };
|
|
8456
|
-
}
|
|
8457
|
-
if (kind === "every" && typeof rec.every === "string") {
|
|
8458
|
-
return { kind: "every", every: rec.every };
|
|
8459
|
-
}
|
|
8460
|
-
if (kind === "cron" && typeof rec.expr === "string") {
|
|
8461
|
-
return {
|
|
8462
|
-
kind: "cron",
|
|
8463
|
-
expr: rec.expr,
|
|
8464
|
-
tz: typeof rec.tz === "string" && rec.tz.trim() ? rec.tz.trim() : void 0
|
|
8465
|
-
};
|
|
8466
|
-
}
|
|
8467
|
-
if (kind === "weekly" && Array.isArray(rec.days) && typeof rec.time === "string") {
|
|
8468
|
-
return {
|
|
8469
|
-
kind: "weekly",
|
|
8470
|
-
days: normalizeWeekdays(rec.days.map((day) => Number(day))),
|
|
8471
|
-
time: normalizeWeeklyTime(rec.time),
|
|
8472
|
-
tz: typeof rec.tz === "string" && rec.tz.trim() ? rec.tz.trim() : void 0
|
|
8473
|
-
};
|
|
8474
|
-
}
|
|
8475
|
-
throw new Error("Schedule `when` must be once, every, weekly, or cron");
|
|
8476
|
-
}
|
|
8477
|
-
var import_croner, WEEKDAY_LABELS, DURATION_RE, UNIT_MS, DAY_ALIASES, TIME_RE;
|
|
8478
|
-
var init_schedule_when = __esm({
|
|
8479
|
-
"src/store/schedule-when.ts"() {
|
|
8480
|
-
"use strict";
|
|
8481
|
-
import_croner = require("croner");
|
|
8482
|
-
WEEKDAY_LABELS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
8483
|
-
DURATION_RE = /^(\d+)(s|m|h|d)$/i;
|
|
8484
|
-
UNIT_MS = {
|
|
8485
|
-
s: 1e3,
|
|
8486
|
-
m: 6e4,
|
|
8487
|
-
h: 36e5,
|
|
8488
|
-
d: 864e5
|
|
8489
|
-
};
|
|
8490
|
-
DAY_ALIASES = {
|
|
8491
|
-
sun: 0,
|
|
8492
|
-
sunday: 0,
|
|
8493
|
-
mon: 1,
|
|
8494
|
-
monday: 1,
|
|
8495
|
-
tue: 2,
|
|
8496
|
-
tues: 2,
|
|
8497
|
-
tuesday: 2,
|
|
8498
|
-
wed: 3,
|
|
8499
|
-
wednesday: 3,
|
|
8500
|
-
thu: 4,
|
|
8501
|
-
thur: 4,
|
|
8502
|
-
thurs: 4,
|
|
8503
|
-
thursday: 4,
|
|
8504
|
-
fri: 5,
|
|
8505
|
-
friday: 5,
|
|
8506
|
-
sat: 6,
|
|
8507
|
-
saturday: 6
|
|
8508
|
-
};
|
|
8509
|
-
TIME_RE = /^([01]\d|2[0-3]):([0-5]\d)(?::[0-5]\d)?$/;
|
|
8510
|
-
}
|
|
8511
|
-
});
|
|
8512
|
-
|
|
8513
|
-
// src/store/schedules.ts
|
|
8514
|
-
function schedulesPath() {
|
|
8515
|
-
return (0, import_node_path18.join)(appDataDir(), "schedules.json");
|
|
8516
|
-
}
|
|
8517
|
-
function defaultScheduleName(prompt) {
|
|
8518
|
-
const line = prompt.trim().split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
8519
|
-
if (!line) return "Untitled automation";
|
|
8520
|
-
return line.length > 60 ? `${line.slice(0, 57).trimEnd()}\u2026` : line;
|
|
8521
|
-
}
|
|
8522
|
-
function resolveScheduleThreadId(raw, env = process.env) {
|
|
8523
|
-
const value = raw?.trim() || "";
|
|
8524
|
-
if (!value) return null;
|
|
8525
|
-
if (value.toLowerCase() === "self") {
|
|
8526
|
-
return env.SIDEBOARD_ORCHESTRATOR_THREAD_ID?.trim() || env.SIDEBOARD_THREAD_ID?.trim() || null;
|
|
8527
|
-
}
|
|
8528
|
-
return value;
|
|
8529
|
-
}
|
|
8530
|
-
function nowIso2(d = /* @__PURE__ */ new Date()) {
|
|
8531
|
-
return d.toISOString();
|
|
8532
|
-
}
|
|
8533
|
-
function normalizeOptionalBool(raw) {
|
|
8534
|
-
if (raw === true || raw === false) return raw;
|
|
8535
|
-
return null;
|
|
8536
|
-
}
|
|
8537
|
-
function normalizeAutonomy2(raw) {
|
|
8538
|
-
return raw === "default" || raw === "full" ? raw : null;
|
|
8539
|
-
}
|
|
8540
|
-
function normalizeAttachments(raw) {
|
|
8541
|
-
if (!Array.isArray(raw)) return [];
|
|
8542
|
-
const out = [];
|
|
8543
|
-
for (const item of raw) {
|
|
8544
|
-
if (!item || typeof item !== "object") continue;
|
|
8545
|
-
const row2 = item;
|
|
8546
|
-
if (typeof row2.id !== "string" || !row2.id.trim()) continue;
|
|
8547
|
-
if (typeof row2.name !== "string" || !row2.name) continue;
|
|
8548
|
-
if (typeof row2.content !== "string") continue;
|
|
8549
|
-
if (!ATTACHMENT_KINDS.has(row2.kind)) continue;
|
|
8550
|
-
const next = {
|
|
8551
|
-
id: row2.id,
|
|
8552
|
-
name: row2.name,
|
|
8553
|
-
kind: row2.kind,
|
|
8554
|
-
content: row2.content
|
|
8555
|
-
};
|
|
8556
|
-
if (typeof row2.path === "string" && row2.path) next.path = row2.path;
|
|
8557
|
-
if (typeof row2.previewDataUrl === "string" && row2.previewDataUrl) {
|
|
8558
|
-
next.previewDataUrl = row2.previewDataUrl;
|
|
8559
|
-
}
|
|
8560
|
-
out.push(next);
|
|
8561
|
-
}
|
|
8562
|
-
return out;
|
|
8563
|
-
}
|
|
8564
|
-
function normalizeTask(raw) {
|
|
8565
|
-
const when = normalizeWhen(raw.when);
|
|
8566
|
-
const agent = raw.agent && isOrchestratorCapableAgent(raw.agent) ? raw.agent : null;
|
|
8567
|
-
return {
|
|
8568
|
-
id: raw.id,
|
|
8569
|
-
name: typeof raw.name === "string" && raw.name.trim() ? raw.name.trim() : defaultScheduleName(raw.prompt),
|
|
8570
|
-
prompt: String(raw.prompt ?? ""),
|
|
8571
|
-
enabled: Boolean(raw.enabled),
|
|
8572
|
-
when,
|
|
8573
|
-
threadId: raw.threadId?.trim() || null,
|
|
8574
|
-
agent,
|
|
8575
|
-
model: raw.model?.trim() || null,
|
|
8576
|
-
effort: normalizeThinkingEffort(raw.effort),
|
|
8577
|
-
fast: normalizeOptionalBool(raw.fast),
|
|
8578
|
-
planMode: normalizeOptionalBool(raw.planMode),
|
|
8579
|
-
autonomy: normalizeAutonomy2(raw.autonomy),
|
|
8580
|
-
attachments: normalizeAttachments(raw.attachments),
|
|
8581
|
-
archiveChat: raw.archiveChat !== false,
|
|
8582
|
-
nextRunAt: raw.nextRunAt,
|
|
8583
|
-
lastRunAt: raw.lastRunAt ?? null,
|
|
8584
|
-
lastThreadId: raw.lastThreadId ?? null,
|
|
8585
|
-
lastError: raw.lastError ?? null,
|
|
8586
|
-
createdBy: raw.createdBy === "mcp" || raw.createdBy === "cli" || raw.createdBy === "ui" ? raw.createdBy : "ui",
|
|
8587
|
-
createdAt: raw.createdAt,
|
|
8588
|
-
updatedAt: raw.updatedAt
|
|
8589
|
-
};
|
|
8590
|
-
}
|
|
8591
|
-
function readAll() {
|
|
8592
|
-
const path2 = schedulesPath();
|
|
8593
|
-
if (!(0, import_node_fs15.existsSync)(path2)) return [];
|
|
8594
|
-
try {
|
|
8595
|
-
const parsed = JSON.parse((0, import_node_fs15.readFileSync)(path2, "utf8"));
|
|
8596
|
-
if (!Array.isArray(parsed)) return [];
|
|
8597
|
-
return parsed.map((row2) => {
|
|
8598
|
-
try {
|
|
8599
|
-
return normalizeTask(row2);
|
|
8600
|
-
} catch {
|
|
8601
|
-
return null;
|
|
8602
|
-
}
|
|
8603
|
-
}).filter((row2) => Boolean(row2?.id && row2.prompt));
|
|
8604
|
-
} catch {
|
|
8605
|
-
return [];
|
|
8606
|
-
}
|
|
8607
|
-
}
|
|
8608
|
-
function writeAll(rows) {
|
|
8609
|
-
writePrivateFile(schedulesPath(), `${JSON.stringify(rows, null, 2)}
|
|
8610
|
-
`);
|
|
8611
|
-
}
|
|
8612
|
-
function buildTask(input, now) {
|
|
8613
|
-
const prompt = input.prompt.trim();
|
|
8614
|
-
if (!prompt) throw new Error("Schedule prompt is required");
|
|
8615
|
-
const when = normalizeWhen(input.when);
|
|
8616
|
-
const nextRunAt = computeNextRunAt(when, now).toISOString();
|
|
8617
|
-
const ts = nowIso2(now);
|
|
8618
|
-
const agent = input.agent ? coerceOrchestratorAgent(input.agent) : null;
|
|
8619
|
-
return {
|
|
8620
|
-
id: (0, import_node_crypto8.randomUUID)(),
|
|
8621
|
-
name: input.name?.trim() || defaultScheduleName(prompt),
|
|
8622
|
-
prompt,
|
|
8623
|
-
enabled: input.enabled !== false,
|
|
8624
|
-
when,
|
|
8625
|
-
threadId: input.threadId?.trim() || null,
|
|
8626
|
-
agent,
|
|
8627
|
-
model: input.model?.trim() || null,
|
|
8628
|
-
effort: input.effort != null ? normalizeThinkingEffort(input.effort) : null,
|
|
8629
|
-
fast: normalizeOptionalBool(input.fast),
|
|
8630
|
-
planMode: normalizeOptionalBool(input.planMode),
|
|
8631
|
-
autonomy: normalizeAutonomy2(input.autonomy),
|
|
8632
|
-
attachments: normalizeAttachments(input.attachments),
|
|
8633
|
-
archiveChat: input.archiveChat !== false,
|
|
8634
|
-
nextRunAt,
|
|
8635
|
-
lastRunAt: null,
|
|
8636
|
-
lastThreadId: null,
|
|
8637
|
-
lastError: null,
|
|
8638
|
-
createdBy: input.createdBy,
|
|
8639
|
-
createdAt: ts,
|
|
8640
|
-
updatedAt: ts
|
|
8641
|
-
};
|
|
8642
|
-
}
|
|
8643
|
-
function listSchedules() {
|
|
8644
|
-
return readAll().sort((a, b) => a.nextRunAt.localeCompare(b.nextRunAt));
|
|
8645
|
-
}
|
|
8646
|
-
function hasEnabledSchedules() {
|
|
8647
|
-
return listSchedules().some((row2) => row2.enabled);
|
|
8648
|
-
}
|
|
8649
|
-
function scheduleNeedsCaffeinate(task, now = /* @__PURE__ */ new Date()) {
|
|
8650
|
-
if (!task.enabled) return false;
|
|
8651
|
-
const at = new Date(task.nextRunAt);
|
|
8652
|
-
if (Number.isNaN(at.getTime())) return false;
|
|
8653
|
-
return at.getTime() > now.getTime();
|
|
8654
|
-
}
|
|
8655
|
-
function ensureCaffeinateForFutureSchedule(task) {
|
|
8656
|
-
if (!scheduleNeedsCaffeinate(task)) return;
|
|
8657
|
-
if (caffeinateWhileSchedulesEnabled()) return;
|
|
8658
|
-
updateAdvancedSettings({ caffeinateWhileSchedules: true });
|
|
8659
|
-
}
|
|
8660
|
-
function getSchedule(id) {
|
|
8661
|
-
const key = id.trim();
|
|
8662
|
-
if (!key) return null;
|
|
8663
|
-
return readAll().find(
|
|
8664
|
-
(row2) => row2.id === key || row2.id.startsWith(key) && key.length >= 8
|
|
8665
|
-
) ?? null;
|
|
8666
|
-
}
|
|
8667
|
-
function createSchedule(input) {
|
|
8668
|
-
const task = buildTask(input, /* @__PURE__ */ new Date());
|
|
8669
|
-
const rows = readAll();
|
|
8670
|
-
rows.push(task);
|
|
8671
|
-
writeAll(rows);
|
|
8672
|
-
ensureCaffeinateForFutureSchedule(task);
|
|
8673
|
-
return task;
|
|
8674
|
-
}
|
|
8675
|
-
function updateSchedule(id, patch) {
|
|
8676
|
-
const rows = readAll();
|
|
8677
|
-
const idx = rows.findIndex((row2) => row2.id === id || id.length >= 8 && row2.id.startsWith(id));
|
|
8678
|
-
if (idx < 0) throw new Error(`Automation not found: ${id}`);
|
|
8679
|
-
const prev = rows[idx];
|
|
8680
|
-
const when = patch.when ? normalizeWhen(patch.when) : prev.when;
|
|
8681
|
-
const prompt = patch.prompt !== void 0 ? patch.prompt.trim() : prev.prompt;
|
|
8682
|
-
if (!prompt) throw new Error("Schedule prompt is required");
|
|
8683
|
-
const whenChanged = patch.when !== void 0;
|
|
8684
|
-
const next = {
|
|
8685
|
-
...prev,
|
|
8686
|
-
name: patch.name !== void 0 ? patch.name.trim() || defaultScheduleName(prompt) : prev.name,
|
|
8687
|
-
prompt,
|
|
8688
|
-
enabled: patch.enabled ?? prev.enabled,
|
|
8689
|
-
when,
|
|
8690
|
-
threadId: patch.threadId !== void 0 ? patch.threadId?.trim() || null : prev.threadId,
|
|
8691
|
-
agent: patch.agent !== void 0 ? patch.agent ? coerceOrchestratorAgent(patch.agent) : null : prev.agent,
|
|
8692
|
-
model: patch.model !== void 0 ? patch.model?.trim() || null : prev.model,
|
|
8693
|
-
effort: patch.effort !== void 0 ? normalizeThinkingEffort(patch.effort) : prev.effort,
|
|
8694
|
-
fast: patch.fast !== void 0 ? normalizeOptionalBool(patch.fast) : prev.fast,
|
|
8695
|
-
planMode: patch.planMode !== void 0 ? normalizeOptionalBool(patch.planMode) : prev.planMode,
|
|
8696
|
-
autonomy: patch.autonomy !== void 0 ? normalizeAutonomy2(patch.autonomy) : prev.autonomy,
|
|
8697
|
-
attachments: patch.attachments !== void 0 ? normalizeAttachments(patch.attachments) : prev.attachments,
|
|
8698
|
-
archiveChat: patch.archiveChat !== void 0 ? patch.archiveChat !== false : prev.archiveChat,
|
|
8699
|
-
nextRunAt: whenChanged ? computeNextRunAt(when).toISOString() : prev.nextRunAt,
|
|
8700
|
-
lastError: whenChanged ? null : prev.lastError,
|
|
8701
|
-
updatedAt: nowIso2()
|
|
8702
|
-
};
|
|
8703
|
-
rows[idx] = next;
|
|
8704
|
-
writeAll(rows);
|
|
8705
|
-
ensureCaffeinateForFutureSchedule(next);
|
|
8706
|
-
return next;
|
|
8707
|
-
}
|
|
8708
|
-
function deleteSchedule(id) {
|
|
8709
|
-
const rows = readAll();
|
|
8710
|
-
const next = rows.filter(
|
|
8711
|
-
(row2) => row2.id !== id && !(id.length >= 8 && row2.id.startsWith(id))
|
|
8712
|
-
);
|
|
8713
|
-
if (next.length === rows.length) throw new Error(`Automation not found: ${id}`);
|
|
8714
|
-
writeAll(next);
|
|
8715
|
-
}
|
|
8716
|
-
function recordScheduleRun(id, result) {
|
|
8717
|
-
const rows = readAll();
|
|
8718
|
-
const idx = rows.findIndex((row2) => row2.id === id);
|
|
8719
|
-
if (idx < 0) throw new Error(`Automation not found: ${id}`);
|
|
8720
|
-
const prev = rows[idx];
|
|
8721
|
-
const firedAt = result.firedAt ?? /* @__PURE__ */ new Date();
|
|
8722
|
-
const next = {
|
|
8723
|
-
...prev,
|
|
8724
|
-
enabled: prev.when.kind === "once" ? false : prev.enabled,
|
|
8725
|
-
nextRunAt: prev.when.kind === "once" ? prev.nextRunAt : computeNextRunAt(prev.when, firedAt).toISOString(),
|
|
8726
|
-
lastRunAt: nowIso2(firedAt),
|
|
8727
|
-
lastThreadId: result.lastThreadId !== void 0 ? result.lastThreadId : prev.lastThreadId,
|
|
8728
|
-
lastError: result.lastError ?? null,
|
|
8729
|
-
updatedAt: nowIso2(firedAt)
|
|
8730
|
-
};
|
|
8731
|
-
rows[idx] = next;
|
|
8732
|
-
writeAll(rows);
|
|
8733
|
-
return next;
|
|
8734
|
-
}
|
|
8735
|
-
var import_node_crypto8, import_node_fs15, import_node_path18, ATTACHMENT_KINDS;
|
|
8736
|
-
var init_schedules = __esm({
|
|
8737
|
-
"src/store/schedules.ts"() {
|
|
8738
|
-
"use strict";
|
|
8739
|
-
import_node_crypto8 = require("crypto");
|
|
8740
|
-
import_node_fs15 = require("fs");
|
|
8741
|
-
import_node_path18 = require("path");
|
|
8742
|
-
init_schedule_when();
|
|
8743
|
-
init_orchestrator_capable();
|
|
8744
|
-
init_thinking_effort();
|
|
8745
|
-
init_paths();
|
|
8746
|
-
init_private_file();
|
|
8747
|
-
init_app_settings();
|
|
8748
|
-
init_schedule_when();
|
|
8749
|
-
ATTACHMENT_KINDS = /* @__PURE__ */ new Set([
|
|
8750
|
-
"transcript",
|
|
8751
|
-
"file",
|
|
8752
|
-
"issue",
|
|
8753
|
-
"workspace",
|
|
8754
|
-
"diff-comment",
|
|
8755
|
-
"code-ref"
|
|
8756
|
-
]);
|
|
8757
|
-
}
|
|
8758
|
-
});
|
|
8759
|
-
|
|
8760
8770
|
// src/store/desktop-host.ts
|
|
8761
8771
|
function desktopHostPidPath() {
|
|
8762
8772
|
return (0, import_node_path19.join)(appDataDir(), "desktop-host.pid");
|
|
@@ -13152,7 +13162,7 @@ var init_coordinator_prompt = __esm({
|
|
|
13152
13162
|
"- 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_projects (this cwd is not a project). update_viewer_context requires confirmed=true after ask_user. Never write context unprompted.",
|
|
13153
13163
|
"- list_env / set_env / delete_env \u2014 Settings \u2192 Environment. scope=project requires repoPath from list_projects and stores the key under that project prefix (the project name, uppercased, plus _). APPLE_ID for sideboard is SIDEBOARD_APPLE_ID. scope=account is shared by every project and is not prefixed. list_env returns names only.",
|
|
13154
13164
|
"- set_caffeinate \u2014 keep this Mac awake across turns (macOS caffeinate). Turn on for phone remote / 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.",
|
|
13155
|
-
"- list_schedules / create_schedule / update_schedule / delete_schedule / run_schedule \u2014 automations that send a prompt to a chat (chatId or self) or start a new Global chat (omit chatId). One-shot `at`, interval `every` (15m/1h/6h/1d), clock time `time` + `days` (07:30 and weekdays, or mon,wed), or 5-field `cron`. Recurring jobs without chatId open a new chat each run and archive it when that run finishes unless archiveChat is false (leave the chat open to keep talking). History keeps the last 5 archived runs for that automation. Worktree agents have the same tools (`chatId=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 automations are enabled (or call set_caffeinate). The desktop lists them in the sidebar after Board.",
|
|
13165
|
+
"- list_schedules / create_schedule / update_schedule / delete_schedule / run_schedule \u2014 automations that send a prompt to a chat (chatId or self) or start a new Global chat (omit chatId). A job bound to a chat is removed when that chat is archived. Omit chatId only for a Global automation that should outlive the chat. One-shot `at`, interval `every` (15m/1h/6h/1d), clock time `time` + `days` (07:30 and weekdays, or mon,wed), or 5-field `cron`. Recurring jobs without chatId open a new chat each run and archive it when that run finishes unless archiveChat is false (leave the chat open to keep talking). History keeps the last 5 archived runs for that automation. Worktree agents have the same tools (`chatId=self` continues that coding chat and is removed when that chat is archived). 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 automations are enabled (or call set_caffeinate). The desktop lists them in the sidebar after Board.",
|
|
13156
13166
|
"Projects:",
|
|
13157
13167
|
"- add_project / remove_project \u2014 register or unregister a git repo",
|
|
13158
13168
|
"Workspaces and chats:",
|
|
@@ -19535,13 +19545,16 @@ async function listCodexModels() {
|
|
|
19535
19545
|
return cachedCodexModels?.models ?? FALLBACK_CODEX_MODELS;
|
|
19536
19546
|
}
|
|
19537
19547
|
}
|
|
19538
|
-
function usageFromCodex(usage) {
|
|
19548
|
+
function usageFromCodex(usage, asContext = false) {
|
|
19539
19549
|
if (!usage) return null;
|
|
19540
|
-
|
|
19550
|
+
const mapped = fromInclusiveInputUsage({
|
|
19541
19551
|
inputTokens: Number(usage.input_tokens ?? 0),
|
|
19542
19552
|
outputTokens: Number(usage.output_tokens ?? 0),
|
|
19543
19553
|
cachedInputTokens: Number(usage.cached_input_tokens ?? 0)
|
|
19544
19554
|
});
|
|
19555
|
+
if (!mapped || !asContext) return mapped;
|
|
19556
|
+
const occ = requestOccupancy(mapped);
|
|
19557
|
+
return occ > 0 ? { ...mapped, lastRequestTokens: occ } : mapped;
|
|
19545
19558
|
}
|
|
19546
19559
|
function codexHomeDir() {
|
|
19547
19560
|
return process.env.CODEX_HOME?.trim() || (0, import_node_path45.join)((0, import_node_os17.homedir)(), ".codex");
|
|
@@ -19837,7 +19850,7 @@ var init_codex = __esm({
|
|
|
19837
19850
|
}
|
|
19838
19851
|
if (type === "turn.completed" || type === "turn_completed") {
|
|
19839
19852
|
const payload = obj;
|
|
19840
|
-
const usage = usageFromCodex(payload.last_token_usage
|
|
19853
|
+
const usage = payload.last_token_usage ? usageFromCodex(payload.last_token_usage, true) : usageFromCodex(payload.usage);
|
|
19841
19854
|
return usage ? { type: "usage", data: usage, scope: "turn" } : null;
|
|
19842
19855
|
}
|
|
19843
19856
|
if (typeof obj.content === "string" && obj.content.trim()) {
|
|
@@ -20175,7 +20188,7 @@ function cursorSdkMessageToEvents(msg) {
|
|
|
20175
20188
|
}
|
|
20176
20189
|
if (msg.type === "usage") {
|
|
20177
20190
|
const usage = usageFromCursor(msg.usage);
|
|
20178
|
-
if (usage) return [{ type: "usage", data: usage, scope: "
|
|
20191
|
+
if (usage) return [{ type: "usage", data: usage, scope: "turn" }];
|
|
20179
20192
|
}
|
|
20180
20193
|
if (msg.type === "status" && msg.status === "ERROR") {
|
|
20181
20194
|
const rawMessage = msg.message;
|
|
@@ -22812,13 +22825,12 @@ function estimateOccupancyTokens(messages) {
|
|
|
22812
22825
|
function threadHasCompactedContext(messages) {
|
|
22813
22826
|
return messages.some((m) => m.role === "summary");
|
|
22814
22827
|
}
|
|
22815
|
-
function forwardOccupancyTokens(messages, usage, windowTokens = 1e6) {
|
|
22828
|
+
function forwardOccupancyTokens(messages, usage, windowTokens = 1e6, opts) {
|
|
22816
22829
|
const estimated = estimateOccupancyTokens(messages);
|
|
22830
|
+
if (opts?.trustProviderOccupancy === false) return estimated;
|
|
22817
22831
|
if (threadHasCompactedContext(messages) && estimated > 0) return estimated;
|
|
22818
|
-
|
|
22819
|
-
|
|
22820
|
-
if (last > 0 && last <= windowTokens) return last;
|
|
22821
|
-
}
|
|
22832
|
+
const explicit = usage?.lastRequestTokens;
|
|
22833
|
+
if (explicit != null && explicit > 0 && explicit <= windowTokens) return explicit;
|
|
22822
22834
|
return estimated;
|
|
22823
22835
|
}
|
|
22824
22836
|
function forwardContextUsage(usage, messages) {
|
|
@@ -23212,11 +23224,15 @@ function applyCompaction(messages, summaryText, thresholds = {}) {
|
|
|
23212
23224
|
return [summary, ...recent];
|
|
23213
23225
|
}
|
|
23214
23226
|
function lastRequestOccupancy(thread) {
|
|
23227
|
+
if (thread.agent === "cursor") return estimateOccupancyTokens(thread.messages);
|
|
23215
23228
|
for (let i = thread.messages.length - 1; i >= 0; i--) {
|
|
23216
23229
|
const usage = thread.messages[i]?.usage;
|
|
23217
|
-
if (usage)
|
|
23230
|
+
if (!usage) continue;
|
|
23231
|
+
const n = usage.lastRequestTokens;
|
|
23232
|
+
if (n != null && n > 0) return n;
|
|
23233
|
+
if (thread.agent === "codex") return estimateOccupancyTokens(thread.messages);
|
|
23218
23234
|
}
|
|
23219
|
-
return 0;
|
|
23235
|
+
return thread.agent === "codex" ? estimateOccupancyTokens(thread.messages) : 0;
|
|
23220
23236
|
}
|
|
23221
23237
|
function shouldResetSessionForOccupancy(thread, occupancyTokens = SESSION_RESET_OCCUPANCY_TOKENS) {
|
|
23222
23238
|
return lastRequestOccupancy(thread) >= occupancyTokens;
|
|
@@ -23235,7 +23251,7 @@ async function maybeCompactContext(thread, thresholds = {}, summarize2 = summari
|
|
|
23235
23251
|
});
|
|
23236
23252
|
let messages = applyCompaction(thread.messages, summary, thresholds);
|
|
23237
23253
|
const compactedMessages = appendCompactedMessages(thread.compactedMessages, older);
|
|
23238
|
-
const resetSession = shouldResetSessionForOccupancy(
|
|
23254
|
+
const resetSession = shouldResetSessionForOccupancy(thread);
|
|
23239
23255
|
if (resetSession) {
|
|
23240
23256
|
messages = applyForwardOccupancy(messages);
|
|
23241
23257
|
}
|
|
@@ -23260,7 +23276,6 @@ var init_context_compact = __esm({
|
|
|
23260
23276
|
"use strict";
|
|
23261
23277
|
init_message_parts();
|
|
23262
23278
|
init_error_detail();
|
|
23263
|
-
init_usage();
|
|
23264
23279
|
init_context_estimate();
|
|
23265
23280
|
init_summarize();
|
|
23266
23281
|
init_context_estimate();
|
|
@@ -31367,7 +31382,7 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
31367
31382
|
lines.push(formatDevAccessHint(opts?.activeRuns));
|
|
31368
31383
|
lines.push("");
|
|
31369
31384
|
lines.push(
|
|
31370
|
-
"Automations (sidebar, after Board): `create_schedule` / `list_schedules` (`at` / `every` / `cron` / `time`+`days`). `archiveChat=false` keeps the new chat. `chatId=self`
|
|
31385
|
+
"Automations (sidebar, after Board): `create_schedule` / `list_schedules` (`at` / `every` / `cron` / `time`+`days`). `archiveChat=false` keeps the new chat. `chatId=self` is removed when this chat is archived. Fires only while Sideboard.app is running. A future job turns on Settings \u2192 Advanced \u2192 Caffeinate while automations are enabled."
|
|
31371
31386
|
);
|
|
31372
31387
|
lines.push(
|
|
31373
31388
|
"`set_workspace_tags` labels this checkout (omit ref; replace, add, or remove). Not another checkout."
|
|
@@ -31387,7 +31402,7 @@ function connectedOrchestratorTurnReminder(thread, find) {
|
|
|
31387
31402
|
return formatConnectedOrchestratorReminder(connectedOrchestrator(thread, find));
|
|
31388
31403
|
}
|
|
31389
31404
|
function formatWorktreeReminder() {
|
|
31390
|
-
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, or time + days such as weekdays at 07:30; archiveChat=false leaves the new chat open; chatId=self
|
|
31405
|
+
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, or time + days such as weekdays at 07:30; archiveChat=false leaves the new chat open; chatId=self ends with the chat). set_workspace_tags updates labels on this workspace (omit ref).";
|
|
31391
31406
|
}
|
|
31392
31407
|
function formatClaudeSubagentReminder() {
|
|
31393
31408
|
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.';
|
|
@@ -35445,7 +35460,15 @@ async function fireSchedule(id) {
|
|
|
35445
35460
|
const deps = fireHooks ?? await defaultDeps();
|
|
35446
35461
|
const prompt = formatScheduledPrompt(schedule.name, schedule.prompt);
|
|
35447
35462
|
const target = schedule.threadId ? deps.findThread(schedule.threadId) : null;
|
|
35448
|
-
if (
|
|
35463
|
+
if (schedule.threadId && (!target || target.status === "archived")) {
|
|
35464
|
+
deleteSchedule(schedule.id);
|
|
35465
|
+
return {
|
|
35466
|
+
...schedule,
|
|
35467
|
+
enabled: false,
|
|
35468
|
+
lastError: "Removed because its chat is archived or gone."
|
|
35469
|
+
};
|
|
35470
|
+
}
|
|
35471
|
+
if (target) {
|
|
35449
35472
|
const sent = await deps.send(target.id, prompt, {
|
|
35450
35473
|
attachments: schedule.attachments,
|
|
35451
35474
|
options: scheduleSendOptions(schedule)
|
|
@@ -35455,8 +35478,7 @@ async function fireSchedule(id) {
|
|
|
35455
35478
|
lastError: null
|
|
35456
35479
|
});
|
|
35457
35480
|
}
|
|
35458
|
-
const
|
|
35459
|
-
const archiveFresh = schedule.archiveChat !== false && !pinReplacement;
|
|
35481
|
+
const archiveFresh = schedule.archiveChat !== false;
|
|
35460
35482
|
const created = await deps.startOrchestration({
|
|
35461
35483
|
goal: prompt,
|
|
35462
35484
|
agent: pickAgent(schedule),
|
|
@@ -35469,9 +35491,6 @@ async function fireSchedule(id) {
|
|
|
35469
35491
|
...archiveFresh ? { ephemeralAutomationId: schedule.id } : {},
|
|
35470
35492
|
ephemeralTitle: schedule.name
|
|
35471
35493
|
});
|
|
35472
|
-
if (pinReplacement) {
|
|
35473
|
-
updateSchedule(schedule.id, { threadId: created.id });
|
|
35474
|
-
}
|
|
35475
35494
|
return recordScheduleRun(schedule.id, {
|
|
35476
35495
|
lastThreadId: created.id,
|
|
35477
35496
|
lastError: null
|
|
@@ -35888,6 +35907,7 @@ __export(index_exports, {
|
|
|
35888
35907
|
defaultScheduleName: () => defaultScheduleName,
|
|
35889
35908
|
deleteBranchOnPurgeEnabled: () => deleteBranchOnPurgeEnabled,
|
|
35890
35909
|
deleteSchedule: () => deleteSchedule,
|
|
35910
|
+
deleteSchedulesForThread: () => deleteSchedulesForThread,
|
|
35891
35911
|
deleteThreadRecord: () => deleteThreadRecord,
|
|
35892
35912
|
deriveTaskState: () => deriveTaskState,
|
|
35893
35913
|
desktopHostPidPath: () => desktopHostPidPath,
|
|
@@ -45355,7 +45375,7 @@ function whenFromUpdate(id, args) {
|
|
|
45355
45375
|
}
|
|
45356
45376
|
function createdHint(schedule) {
|
|
45357
45377
|
const awake = scheduleNeedsCaffeinate(schedule) ? " Caffeinate while automations are enabled is now on so the Mac can stay awake until this job is due." : "";
|
|
45358
|
-
const fresh = schedule.threadId ? "" : schedule.archiveChat === false ? " This job leaves the new chat open so you can keep talking." : " A new Global chat is archived when the run finishes (History keeps the last 5 runs). Pass archiveChat=false to leave it open.";
|
|
45378
|
+
const fresh = schedule.threadId ? " This job is removed when that chat is archived." : schedule.archiveChat === false ? " This job leaves the new chat open so you can keep talking." : " A new Global chat is archived when the run finishes (History keeps the last 5 runs). Pass archiveChat=false to leave it open.";
|
|
45359
45379
|
return `Fires while Sideboard.app is running.${fresh}${awake}`;
|
|
45360
45380
|
}
|
|
45361
45381
|
function registerScheduleTools(server) {
|
|
@@ -45373,7 +45393,7 @@ function registerScheduleTools(server) {
|
|
|
45373
45393
|
);
|
|
45374
45394
|
server.tool(
|
|
45375
45395
|
"create_schedule",
|
|
45376
|
-
"Create a local automation that, when due, sends a prompt to an existing chat (chatId) or starts a new Global orchestration chat (omit chatId). Pass chatId=self to continue this chat.
|
|
45396
|
+
"Create a local automation that, when due, sends a prompt to an existing chat (chatId) or starts a new Global orchestration chat (omit chatId). Pass chatId=self to continue this chat. A job bound to a chat is removed when that chat is archived or gone; it does not start a new Global chat. Omit chatId only for a Global automation that should outlive this chat. Exactly one of at (ISO datetime), every (15m/1h/6h/1d), time (HH:mm, with days such as weekdays or mon,wed), or cron (5-field). Recurring jobs without chatId open a new Global chat each run and archive it when that run finishes unless archiveChat is false (leave the chat open to keep talking, for example a morning start-my-day run). History keeps the last 5 archived runs for that automation. Creating or enabling a future job turns on Settings \u2192 Advanced \u2192 Caffeinate while automations are enabled so the Mac stays awake until due. Sideboard.app must be running for the job to fire.",
|
|
45377
45397
|
{
|
|
45378
45398
|
prompt: import_zod10.z.string().describe("User message / goal queued when the automation fires"),
|
|
45379
45399
|
name: import_zod10.z.string().optional(),
|
|
@@ -45387,7 +45407,7 @@ function registerScheduleTools(server) {
|
|
|
45387
45407
|
"Archive a new Global chat when the run finishes. Default true. Pass false to leave the chat open."
|
|
45388
45408
|
),
|
|
45389
45409
|
chatId: import_zod10.z.string().optional().describe(
|
|
45390
|
-
'Existing chat id
|
|
45410
|
+
'Existing chat id, or "self" for this chat. That job is removed when the chat is archived. Omit only for a Global automation that should outlive this chat.'
|
|
45391
45411
|
),
|
|
45392
45412
|
threadId: import_zod10.z.string().optional().describe("Legacy alias for chatId."),
|
|
45393
45413
|
agent: import_zod10.z.enum(["claude", "cursor", "codex", "opencode"]).optional().describe("Agent for a new Global chat (omit for Account default)"),
|
|
@@ -45439,7 +45459,7 @@ function registerScheduleTools(server) {
|
|
|
45439
45459
|
tz: import_zod10.z.string().optional(),
|
|
45440
45460
|
archiveChat: import_zod10.z.boolean().optional().describe("Archive a new Global chat when the run finishes. False leaves it open."),
|
|
45441
45461
|
chatId: import_zod10.z.string().optional().describe(
|
|
45442
|
-
'Existing chat
|
|
45462
|
+
'Existing chat, "self", or empty string for a Global chat each run. A bound job is removed when that chat is archived.'
|
|
45443
45463
|
),
|
|
45444
45464
|
threadId: import_zod10.z.string().optional().describe("Legacy alias for chatId."),
|
|
45445
45465
|
agent: import_zod10.z.enum(["claude", "cursor", "codex", "opencode"]).optional(),
|
|
@@ -50033,6 +50053,7 @@ async function pollSlackOutboundWatches(opts) {
|
|
|
50033
50053
|
defaultScheduleName,
|
|
50034
50054
|
deleteBranchOnPurgeEnabled,
|
|
50035
50055
|
deleteSchedule,
|
|
50056
|
+
deleteSchedulesForThread,
|
|
50036
50057
|
deleteThreadRecord,
|
|
50037
50058
|
deriveTaskState,
|
|
50038
50059
|
desktopHostPidPath,
|