@sideboard-ai/core 0.1.326 → 0.1.328

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 (73) hide show
  1. package/dist/{abletime-RYYFGKMU.js → abletime-NW4PJGHN.js} +4 -5
  2. package/dist/{abletime-RDHYSZL2.js → abletime-OW7LTFQD.js} +4 -5
  3. package/dist/{abletime-oauth-OYGS2DAU.js → abletime-oauth-KWQQRHOQ.js} +3 -4
  4. package/dist/{abletime-oauth-QR2QDVMK.js → abletime-oauth-TPR2QDRI.js} +3 -4
  5. package/dist/{abletime-rest-QDPTWNS4.js → abletime-rest-5DCWN3P4.js} +3 -4
  6. package/dist/{abletime-rest-BKYKNPTC.js → abletime-rest-UJ6SXDBN.js} +3 -4
  7. package/dist/agents/claude-runner.cjs +11 -0
  8. package/dist/agents/claude-runner.js +7 -1
  9. package/dist/{agents-QO7GKBYT.js → agents-IYBY3JT5.js} +8 -9
  10. package/dist/{agents-HANWZNI6.js → agents-XWIPONJR.js} +8 -9
  11. package/dist/{app-settings-RXBH7KY4.js → app-settings-A5D364JD.js} +1 -2
  12. package/dist/{app-settings-TUVLZNDE.js → app-settings-SA4HX3ZQ.js} +1 -2
  13. package/dist/{chunk-3Q4XNYHY.js → chunk-2GEUFPQQ.js} +1 -1
  14. package/dist/{chunk-MAW7DIG7.js → chunk-4F7THWIO.js} +2 -2
  15. package/dist/{chunk-K7M7MIWL.js → chunk-4G3W23X3.js} +3 -3
  16. package/dist/{chunk-Q3FHTGIW.js → chunk-5Y2C7Q55.js} +441 -20
  17. package/dist/{chunk-TMCK5TLA.js → chunk-ATQLP22S.js} +1 -1
  18. package/dist/{chunk-PB6HW7SA.js → chunk-CHYUUETG.js} +3 -3
  19. package/dist/{chunk-QPSKQP6E.js → chunk-D446IWPP.js} +48 -3
  20. package/dist/{chunk-C7HUCBX7.js → chunk-DACWFN4O.js} +5 -5
  21. package/dist/{chunk-B244TJWC.js → chunk-ECY7WL6T.js} +2 -2
  22. package/dist/{chunk-D744HOI5.js → chunk-EJRCHCXM.js} +18 -3
  23. package/dist/{chunk-KXRF6RNL.js → chunk-EUIVQAPK.js} +2 -2
  24. package/dist/{chunk-XLVLMQKN.js → chunk-EYDLXVED.js} +40 -25
  25. package/dist/{chunk-75RPUXJS.js → chunk-JKHCADKB.js} +5 -5
  26. package/dist/{chunk-4H5MWZ6J.js → chunk-KLVW3J2B.js} +2 -2
  27. package/dist/{chunk-QG4CYRA3.js → chunk-MO46K6WK.js} +14 -14
  28. package/dist/{chunk-F2PVRF3B.js → chunk-N6ZF3XRP.js} +2 -1
  29. package/dist/chunk-NJV5YEKI.js +194 -0
  30. package/dist/{chunk-BBNWKL4I.js → chunk-NQGLDQYB.js} +8 -8
  31. package/dist/{chunk-YGVGXQA7.js → chunk-Q4UPRQOS.js} +12 -12
  32. package/dist/{chunk-ZUAYA57W.js → chunk-QMLDR63X.js} +2 -2
  33. package/dist/{chunk-KECHK3ZT.js → chunk-R2C45NHT.js} +2 -2
  34. package/dist/{chunk-FWVUGLBG.js → chunk-RDXODLEN.js} +4 -4
  35. package/dist/{chunk-JM2TGOHP.js → chunk-SB5ADEZZ.js} +5 -5
  36. package/dist/{chunk-SO7G6O24.js → chunk-SFXGD5KJ.js} +1 -1
  37. package/dist/{chunk-LRHUBGEM.js → chunk-TUH4ICHQ.js} +1 -1
  38. package/dist/{chunk-WUCAVIIP.js → chunk-UMXBH344.js} +1 -1
  39. package/dist/{chunk-GP3RLZ6A.js → chunk-WD222BVP.js} +109 -491
  40. package/dist/{chunk-46FECFZU.js → chunk-X3XTO45Y.js} +39 -196
  41. package/dist/{chunk-RZVOX2MT.js → chunk-XBBZZHJY.js} +3 -3
  42. package/dist/{chunk-2EOLWHXH.js → chunk-XOMVOBPU.js} +127 -477
  43. package/dist/{chunk-ZSHS46V5.js → chunk-Y6OHM672.js} +476 -20
  44. package/dist/{chunk-YWQF7WAG.js → chunk-ZPBOWO64.js} +2 -2
  45. package/dist/{conductor-4GVTHUUB.js → conductor-G6GH5ZMU.js} +7 -7
  46. package/dist/{conductor-TGWI6ETZ.js → conductor-U5LGJZUJ.js} +6 -7
  47. package/dist/{coordinator-prompt-3E6SIDTM.js → coordinator-prompt-3PJLU3UH.js} +5 -6
  48. package/dist/{coordinator-prompt-WEYJREV6.js → coordinator-prompt-J7O7JB26.js} +5 -6
  49. package/dist/{global-workspace-UIEXAG2B.js → global-workspace-4CTLU2BV.js} +5 -6
  50. package/dist/{global-workspace-FPDZKUPF.js → global-workspace-Y3UDZYJX.js} +5 -6
  51. package/dist/index.cjs +605 -508
  52. package/dist/index.d.cts +23 -11
  53. package/dist/index.d.ts +23 -11
  54. package/dist/index.js +67 -65
  55. package/dist/{linear-6S7MK5YK.js → linear-CXWGH2TW.js} +2 -3
  56. package/dist/{linear-Z2T4KUAQ.js → linear-WLDCJ3AF.js} +2 -3
  57. package/dist/{linear-list-Q4M7AZO2.js → linear-list-52LEDEWO.js} +1 -1
  58. package/dist/{linear-list-A37WLUBO.js → linear-list-FGVN65JU.js} +1 -1
  59. package/dist/mcp/run-stdio.cjs +19762 -19682
  60. package/dist/mcp/run-stdio.js +33 -34
  61. package/dist/{optional-cli-CA4LL322.js → optional-cli-FN4MGB6W.js} +4 -5
  62. package/dist/{optional-cli-AANBL4U5.js → optional-cli-INRVBBBG.js} +3 -4
  63. package/dist/{orchestrator-RQXRZW7Z.js → orchestrator-3F53AZEN.js} +11 -12
  64. package/dist/{orchestrator-7FVDBE7Y.js → orchestrator-YY2JUYKD.js} +12 -12
  65. package/dist/{thread-store-4ZN3DS2W.js → thread-store-4WE24XA2.js} +6 -2
  66. package/dist/{thread-store-IC4BQXDW.js → thread-store-K2ZNGUSM.js} +7 -3
  67. package/dist/{workspaces-LEW4UP56.js → workspaces-MM7CQYR6.js} +5 -6
  68. package/dist/{workspaces-QONNLHNR.js → workspaces-WYCVZ6XH.js} +5 -6
  69. package/dist/{worktree-KFEJAQ2H.js → worktree-JBNEMJ5Z.js} +7 -8
  70. package/dist/{worktree-6GIONDQO.js → worktree-NNVRGPP4.js} +4 -5
  71. package/package.json +1 -1
  72. package/dist/chunk-77WWLBCI.js +0 -50
  73. package/dist/chunk-KGZBYWZ3.js +0 -23
@@ -1,20 +1,28 @@
1
1
  import {
2
2
  sanitizeMcpServerName
3
- } from "./chunk-F2PVRF3B.js";
3
+ } from "./chunk-N6ZF3XRP.js";
4
4
  import {
5
5
  cursorSdkStoreDir
6
6
  } from "./chunk-LG6RJBIY.js";
7
7
  import {
8
- normalizeThinkingEffort
9
- } from "./chunk-77WWLBCI.js";
8
+ caffeinateWhileSchedulesEnabled,
9
+ coerceOrchestratorAgent,
10
+ isOrchestratorCapableAgent,
11
+ normalizeThinkingEffort,
12
+ updateAdvancedSettings
13
+ } from "./chunk-D446IWPP.js";
10
14
  import {
15
+ writePrivateFile
16
+ } from "./chunk-JT7R45JB.js";
17
+ import {
18
+ appDataDir,
11
19
  threadFilePath,
12
20
  threadLockPath,
13
21
  threadsDir
14
22
  } from "./chunk-H4UEFJRI.js";
15
23
 
16
24
  // src/store/thread-store.ts
17
- import { randomUUID } from "crypto";
25
+ import { randomUUID as randomUUID2 } from "crypto";
18
26
 
19
27
  // src/review/review-write-gate.ts
20
28
  var REVIEW_TAB_TITLE = "Review";
@@ -1007,8 +1015,8 @@ function isWorktreeIdentityTitle(title, identities) {
1007
1015
 
1008
1016
  // src/store/thread-store.ts
1009
1017
  import {
1010
- existsSync,
1011
- readFileSync,
1018
+ existsSync as existsSync2,
1019
+ readFileSync as readFileSync2,
1012
1020
  renameSync,
1013
1021
  rmSync,
1014
1022
  statSync,
@@ -1018,7 +1026,435 @@ import {
1018
1026
  } from "fs";
1019
1027
  import { basename } from "path";
1020
1028
  import lockfile from "proper-lockfile";
1021
- function nowIso() {
1029
+
1030
+ // src/store/schedules.ts
1031
+ import { randomUUID } from "crypto";
1032
+ import { existsSync, readFileSync } from "fs";
1033
+ import { join } from "path";
1034
+
1035
+ // src/store/schedule-when.ts
1036
+ import { Cron } from "croner";
1037
+ var WEEKDAY_LABELS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
1038
+ var DURATION_RE = /^(\d+)(s|m|h|d)$/i;
1039
+ var UNIT_MS = {
1040
+ s: 1e3,
1041
+ m: 6e4,
1042
+ h: 36e5,
1043
+ d: 864e5
1044
+ };
1045
+ var DAY_ALIASES = {
1046
+ sun: 0,
1047
+ sunday: 0,
1048
+ mon: 1,
1049
+ monday: 1,
1050
+ tue: 2,
1051
+ tues: 2,
1052
+ tuesday: 2,
1053
+ wed: 3,
1054
+ wednesday: 3,
1055
+ thu: 4,
1056
+ thur: 4,
1057
+ thurs: 4,
1058
+ thursday: 4,
1059
+ fri: 5,
1060
+ friday: 5,
1061
+ sat: 6,
1062
+ saturday: 6
1063
+ };
1064
+ var TIME_RE = /^([01]\d|2[0-3]):([0-5]\d)(?::[0-5]\d)?$/;
1065
+ function parseDurationMs(every) {
1066
+ const m = every.trim().match(DURATION_RE);
1067
+ if (!m) return null;
1068
+ const n = Number.parseInt(m[1], 10);
1069
+ if (!Number.isFinite(n) || n <= 0) return null;
1070
+ const unit = m[2].toLowerCase();
1071
+ return n * UNIT_MS[unit];
1072
+ }
1073
+ function dayIndex(token) {
1074
+ const text = token.trim().toLowerCase();
1075
+ if (/^[0-6]$/.test(text)) return Number(text);
1076
+ return DAY_ALIASES[text];
1077
+ }
1078
+ function normalizeWeekdays(days) {
1079
+ const set = /* @__PURE__ */ new Set();
1080
+ for (const day of days) {
1081
+ if (!Number.isInteger(day) || day < 0 || day > 6) {
1082
+ throw new Error("Days must be 0 (Sunday) through 6 (Saturday)");
1083
+ }
1084
+ set.add(day);
1085
+ }
1086
+ if (set.size === 0) throw new Error("Pick at least one day");
1087
+ return [...set].sort((a, b) => a - b);
1088
+ }
1089
+ function parseWeeklyDays(raw) {
1090
+ const text = raw.trim().toLowerCase();
1091
+ if (!text) throw new Error("Pick at least one day");
1092
+ if (text === "daily" || text === "all" || text === "every day" || text === "everyday") {
1093
+ return [0, 1, 2, 3, 4, 5, 6];
1094
+ }
1095
+ if (text === "weekdays" || text === "weekday") return [1, 2, 3, 4, 5];
1096
+ if (text === "weekends" || text === "weekend") return [0, 6];
1097
+ const days = [];
1098
+ for (const part of text.split(/[\s,]+/).filter(Boolean)) {
1099
+ const range = part.split("-");
1100
+ if (range.length === 2 && range[0] && range[1]) {
1101
+ const start = dayIndex(range[0]);
1102
+ const end = dayIndex(range[1]);
1103
+ if (start === void 0 || end === void 0) {
1104
+ throw new Error(`Unknown day: ${part} (use mon,tue, weekdays, weekends, or daily)`);
1105
+ }
1106
+ if (start <= end) {
1107
+ for (let d = start; d <= end; d++) days.push(d);
1108
+ } else {
1109
+ for (let d = start; d <= 6; d++) days.push(d);
1110
+ for (let d = 0; d <= end; d++) days.push(d);
1111
+ }
1112
+ continue;
1113
+ }
1114
+ const n = dayIndex(part);
1115
+ if (n === void 0) {
1116
+ throw new Error(`Unknown day: ${part} (use mon,tue, weekdays, weekends, or daily)`);
1117
+ }
1118
+ days.push(n);
1119
+ }
1120
+ return normalizeWeekdays(days);
1121
+ }
1122
+ function normalizeWeeklyTime(raw) {
1123
+ const m = raw.trim().match(TIME_RE);
1124
+ if (!m) throw new Error(`Invalid time: ${raw} (use HH:mm, 24-hour)`);
1125
+ return `${m[1]}:${m[2]}`;
1126
+ }
1127
+ function formatWeeklyDays(days) {
1128
+ const key = normalizeWeekdays(days).join(",");
1129
+ if (key === "0,1,2,3,4,5,6") return "daily";
1130
+ if (key === "1,2,3,4,5") return "weekdays";
1131
+ if (key === "0,6") return "weekends";
1132
+ return normalizeWeekdays(days).map((day) => WEEKDAY_LABELS[day]).join(", ");
1133
+ }
1134
+ function weeklyCronExpr(when) {
1135
+ const time = normalizeWeeklyTime(when.time);
1136
+ const [hh, mm] = time.split(":");
1137
+ const days = normalizeWeekdays(when.days);
1138
+ return `${Number(mm)} ${Number(hh)} * * ${days.join(",")}`;
1139
+ }
1140
+ function computeNextRunAt(when, from = /* @__PURE__ */ new Date()) {
1141
+ if (when.kind === "once") {
1142
+ const at = new Date(when.at);
1143
+ if (Number.isNaN(at.getTime())) {
1144
+ throw new Error(`Invalid once-at datetime: ${when.at}`);
1145
+ }
1146
+ return at;
1147
+ }
1148
+ if (when.kind === "every") {
1149
+ const ms = parseDurationMs(when.every);
1150
+ if (!ms) {
1151
+ throw new Error(`Invalid interval: ${when.every} (use 15m, 1h, 6h, 1d)`);
1152
+ }
1153
+ return new Date(from.getTime() + ms);
1154
+ }
1155
+ if (when.kind === "weekly") {
1156
+ return computeNextRunAt(
1157
+ { kind: "cron", expr: weeklyCronExpr(when), tz: when.tz },
1158
+ from
1159
+ );
1160
+ }
1161
+ try {
1162
+ const job = new Cron(when.expr, {
1163
+ timezone: when.tz?.trim() || void 0,
1164
+ paused: true
1165
+ });
1166
+ const next = job.nextRun(from);
1167
+ if (!next) {
1168
+ throw new Error(`Cron expression has no next run: ${when.expr}`);
1169
+ }
1170
+ return next;
1171
+ } catch (err) {
1172
+ const message = err instanceof Error ? err.message : String(err);
1173
+ throw new Error(`Invalid cron: ${message}`);
1174
+ }
1175
+ }
1176
+ function formatScheduleWhen(when) {
1177
+ if (when.kind === "once") return `once at ${when.at}`;
1178
+ if (when.kind === "every") return `every ${when.every}`;
1179
+ if (when.kind === "weekly") {
1180
+ const label = `${formatWeeklyDays(when.days)} at ${normalizeWeeklyTime(when.time)}`;
1181
+ const tz2 = when.tz?.trim();
1182
+ return tz2 ? `${label} (${tz2})` : label;
1183
+ }
1184
+ const tz = when.tz?.trim();
1185
+ return tz ? `cron ${when.expr} (${tz})` : `cron ${when.expr}`;
1186
+ }
1187
+ function normalizeWhen(raw) {
1188
+ if (!raw || typeof raw !== "object") {
1189
+ throw new Error("Schedule is missing `when`");
1190
+ }
1191
+ const rec = raw;
1192
+ const kind = rec.kind;
1193
+ if (kind === "once" && typeof rec.at === "string") {
1194
+ return { kind: "once", at: rec.at };
1195
+ }
1196
+ if (kind === "every" && typeof rec.every === "string") {
1197
+ return { kind: "every", every: rec.every };
1198
+ }
1199
+ if (kind === "cron" && typeof rec.expr === "string") {
1200
+ return {
1201
+ kind: "cron",
1202
+ expr: rec.expr,
1203
+ tz: typeof rec.tz === "string" && rec.tz.trim() ? rec.tz.trim() : void 0
1204
+ };
1205
+ }
1206
+ if (kind === "weekly" && Array.isArray(rec.days) && typeof rec.time === "string") {
1207
+ return {
1208
+ kind: "weekly",
1209
+ days: normalizeWeekdays(rec.days.map((day) => Number(day))),
1210
+ time: normalizeWeeklyTime(rec.time),
1211
+ tz: typeof rec.tz === "string" && rec.tz.trim() ? rec.tz.trim() : void 0
1212
+ };
1213
+ }
1214
+ throw new Error("Schedule `when` must be once, every, weekly, or cron");
1215
+ }
1216
+
1217
+ // src/store/schedules.ts
1218
+ function schedulesPath() {
1219
+ return join(appDataDir(), "schedules.json");
1220
+ }
1221
+ function defaultScheduleName(prompt) {
1222
+ const line = prompt.trim().split(/\r?\n/, 1)[0]?.trim() ?? "";
1223
+ if (!line) return "Untitled automation";
1224
+ return line.length > 60 ? `${line.slice(0, 57).trimEnd()}\u2026` : line;
1225
+ }
1226
+ function resolveScheduleThreadId(raw, env = process.env) {
1227
+ const value = raw?.trim() || "";
1228
+ if (!value) return null;
1229
+ if (value.toLowerCase() === "self") {
1230
+ return env.SIDEBOARD_ORCHESTRATOR_THREAD_ID?.trim() || env.SIDEBOARD_THREAD_ID?.trim() || null;
1231
+ }
1232
+ return value;
1233
+ }
1234
+ function nowIso(d = /* @__PURE__ */ new Date()) {
1235
+ return d.toISOString();
1236
+ }
1237
+ var ATTACHMENT_KINDS = /* @__PURE__ */ new Set([
1238
+ "transcript",
1239
+ "file",
1240
+ "issue",
1241
+ "workspace",
1242
+ "diff-comment",
1243
+ "code-ref"
1244
+ ]);
1245
+ function normalizeOptionalBool(raw) {
1246
+ if (raw === true || raw === false) return raw;
1247
+ return null;
1248
+ }
1249
+ function normalizeAutonomy(raw) {
1250
+ return raw === "default" || raw === "full" ? raw : null;
1251
+ }
1252
+ function normalizeAttachments(raw) {
1253
+ if (!Array.isArray(raw)) return [];
1254
+ const out = [];
1255
+ for (const item of raw) {
1256
+ if (!item || typeof item !== "object") continue;
1257
+ const row = item;
1258
+ if (typeof row.id !== "string" || !row.id.trim()) continue;
1259
+ if (typeof row.name !== "string" || !row.name) continue;
1260
+ if (typeof row.content !== "string") continue;
1261
+ if (!ATTACHMENT_KINDS.has(row.kind)) continue;
1262
+ const next = {
1263
+ id: row.id,
1264
+ name: row.name,
1265
+ kind: row.kind,
1266
+ content: row.content
1267
+ };
1268
+ if (typeof row.path === "string" && row.path) next.path = row.path;
1269
+ if (typeof row.previewDataUrl === "string" && row.previewDataUrl) {
1270
+ next.previewDataUrl = row.previewDataUrl;
1271
+ }
1272
+ out.push(next);
1273
+ }
1274
+ return out;
1275
+ }
1276
+ function normalizeTask(raw) {
1277
+ const when = normalizeWhen(raw.when);
1278
+ const agent = raw.agent && isOrchestratorCapableAgent(raw.agent) ? raw.agent : null;
1279
+ return {
1280
+ id: raw.id,
1281
+ name: typeof raw.name === "string" && raw.name.trim() ? raw.name.trim() : defaultScheduleName(raw.prompt),
1282
+ prompt: String(raw.prompt ?? ""),
1283
+ enabled: Boolean(raw.enabled),
1284
+ when,
1285
+ threadId: raw.threadId?.trim() || null,
1286
+ agent,
1287
+ model: raw.model?.trim() || null,
1288
+ effort: normalizeThinkingEffort(raw.effort),
1289
+ fast: normalizeOptionalBool(raw.fast),
1290
+ planMode: normalizeOptionalBool(raw.planMode),
1291
+ autonomy: normalizeAutonomy(raw.autonomy),
1292
+ attachments: normalizeAttachments(raw.attachments),
1293
+ archiveChat: raw.archiveChat !== false,
1294
+ nextRunAt: raw.nextRunAt,
1295
+ lastRunAt: raw.lastRunAt ?? null,
1296
+ lastThreadId: raw.lastThreadId ?? null,
1297
+ lastError: raw.lastError ?? null,
1298
+ createdBy: raw.createdBy === "mcp" || raw.createdBy === "cli" || raw.createdBy === "ui" ? raw.createdBy : "ui",
1299
+ createdAt: raw.createdAt,
1300
+ updatedAt: raw.updatedAt
1301
+ };
1302
+ }
1303
+ function readAll() {
1304
+ const path = schedulesPath();
1305
+ if (!existsSync(path)) return [];
1306
+ try {
1307
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
1308
+ if (!Array.isArray(parsed)) return [];
1309
+ return parsed.map((row) => {
1310
+ try {
1311
+ return normalizeTask(row);
1312
+ } catch {
1313
+ return null;
1314
+ }
1315
+ }).filter((row) => Boolean(row?.id && row.prompt));
1316
+ } catch {
1317
+ return [];
1318
+ }
1319
+ }
1320
+ function writeAll(rows) {
1321
+ writePrivateFile(schedulesPath(), `${JSON.stringify(rows, null, 2)}
1322
+ `);
1323
+ }
1324
+ function buildTask(input, now) {
1325
+ const prompt = input.prompt.trim();
1326
+ if (!prompt) throw new Error("Schedule prompt is required");
1327
+ const when = normalizeWhen(input.when);
1328
+ const nextRunAt = computeNextRunAt(when, now).toISOString();
1329
+ const ts = nowIso(now);
1330
+ const agent = input.agent ? coerceOrchestratorAgent(input.agent) : null;
1331
+ return {
1332
+ id: randomUUID(),
1333
+ name: input.name?.trim() || defaultScheduleName(prompt),
1334
+ prompt,
1335
+ enabled: input.enabled !== false,
1336
+ when,
1337
+ threadId: input.threadId?.trim() || null,
1338
+ agent,
1339
+ model: input.model?.trim() || null,
1340
+ effort: input.effort != null ? normalizeThinkingEffort(input.effort) : null,
1341
+ fast: normalizeOptionalBool(input.fast),
1342
+ planMode: normalizeOptionalBool(input.planMode),
1343
+ autonomy: normalizeAutonomy(input.autonomy),
1344
+ attachments: normalizeAttachments(input.attachments),
1345
+ archiveChat: input.archiveChat !== false,
1346
+ nextRunAt,
1347
+ lastRunAt: null,
1348
+ lastThreadId: null,
1349
+ lastError: null,
1350
+ createdBy: input.createdBy,
1351
+ createdAt: ts,
1352
+ updatedAt: ts
1353
+ };
1354
+ }
1355
+ function listSchedules() {
1356
+ return readAll().sort((a, b) => a.nextRunAt.localeCompare(b.nextRunAt));
1357
+ }
1358
+ function hasEnabledSchedules() {
1359
+ return listSchedules().some((row) => row.enabled);
1360
+ }
1361
+ function scheduleNeedsCaffeinate(task, now = /* @__PURE__ */ new Date()) {
1362
+ if (!task.enabled) return false;
1363
+ const at = new Date(task.nextRunAt);
1364
+ if (Number.isNaN(at.getTime())) return false;
1365
+ return at.getTime() > now.getTime();
1366
+ }
1367
+ function ensureCaffeinateForFutureSchedule(task) {
1368
+ if (!scheduleNeedsCaffeinate(task)) return;
1369
+ if (caffeinateWhileSchedulesEnabled()) return;
1370
+ updateAdvancedSettings({ caffeinateWhileSchedules: true });
1371
+ }
1372
+ function getSchedule(id) {
1373
+ const key = id.trim();
1374
+ if (!key) return null;
1375
+ return readAll().find(
1376
+ (row) => row.id === key || row.id.startsWith(key) && key.length >= 8
1377
+ ) ?? null;
1378
+ }
1379
+ function createSchedule(input) {
1380
+ const task = buildTask(input, /* @__PURE__ */ new Date());
1381
+ const rows = readAll();
1382
+ rows.push(task);
1383
+ writeAll(rows);
1384
+ ensureCaffeinateForFutureSchedule(task);
1385
+ return task;
1386
+ }
1387
+ function updateSchedule(id, patch) {
1388
+ const rows = readAll();
1389
+ const idx = rows.findIndex((row) => row.id === id || id.length >= 8 && row.id.startsWith(id));
1390
+ if (idx < 0) throw new Error(`Automation not found: ${id}`);
1391
+ const prev = rows[idx];
1392
+ const when = patch.when ? normalizeWhen(patch.when) : prev.when;
1393
+ const prompt = patch.prompt !== void 0 ? patch.prompt.trim() : prev.prompt;
1394
+ if (!prompt) throw new Error("Schedule prompt is required");
1395
+ const whenChanged = patch.when !== void 0;
1396
+ const next = {
1397
+ ...prev,
1398
+ name: patch.name !== void 0 ? patch.name.trim() || defaultScheduleName(prompt) : prev.name,
1399
+ prompt,
1400
+ enabled: patch.enabled ?? prev.enabled,
1401
+ when,
1402
+ threadId: patch.threadId !== void 0 ? patch.threadId?.trim() || null : prev.threadId,
1403
+ agent: patch.agent !== void 0 ? patch.agent ? coerceOrchestratorAgent(patch.agent) : null : prev.agent,
1404
+ model: patch.model !== void 0 ? patch.model?.trim() || null : prev.model,
1405
+ effort: patch.effort !== void 0 ? normalizeThinkingEffort(patch.effort) : prev.effort,
1406
+ fast: patch.fast !== void 0 ? normalizeOptionalBool(patch.fast) : prev.fast,
1407
+ planMode: patch.planMode !== void 0 ? normalizeOptionalBool(patch.planMode) : prev.planMode,
1408
+ autonomy: patch.autonomy !== void 0 ? normalizeAutonomy(patch.autonomy) : prev.autonomy,
1409
+ attachments: patch.attachments !== void 0 ? normalizeAttachments(patch.attachments) : prev.attachments,
1410
+ archiveChat: patch.archiveChat !== void 0 ? patch.archiveChat !== false : prev.archiveChat,
1411
+ nextRunAt: whenChanged ? computeNextRunAt(when).toISOString() : prev.nextRunAt,
1412
+ lastError: whenChanged ? null : prev.lastError,
1413
+ updatedAt: nowIso()
1414
+ };
1415
+ rows[idx] = next;
1416
+ writeAll(rows);
1417
+ ensureCaffeinateForFutureSchedule(next);
1418
+ return next;
1419
+ }
1420
+ function deleteSchedulesForThread(threadId) {
1421
+ const id = threadId.trim();
1422
+ if (!id) return;
1423
+ const rows = readAll();
1424
+ const next = rows.filter((row) => row.threadId !== id);
1425
+ if (next.length === rows.length) return;
1426
+ writeAll(next);
1427
+ }
1428
+ function deleteSchedule(id) {
1429
+ const rows = readAll();
1430
+ const next = rows.filter(
1431
+ (row) => row.id !== id && !(id.length >= 8 && row.id.startsWith(id))
1432
+ );
1433
+ if (next.length === rows.length) throw new Error(`Automation not found: ${id}`);
1434
+ writeAll(next);
1435
+ }
1436
+ function recordScheduleRun(id, result) {
1437
+ const rows = readAll();
1438
+ const idx = rows.findIndex((row) => row.id === id);
1439
+ if (idx < 0) throw new Error(`Automation not found: ${id}`);
1440
+ const prev = rows[idx];
1441
+ const firedAt = result.firedAt ?? /* @__PURE__ */ new Date();
1442
+ const next = {
1443
+ ...prev,
1444
+ enabled: prev.when.kind === "once" ? false : prev.enabled,
1445
+ nextRunAt: prev.when.kind === "once" ? prev.nextRunAt : computeNextRunAt(prev.when, firedAt).toISOString(),
1446
+ lastRunAt: nowIso(firedAt),
1447
+ lastThreadId: result.lastThreadId !== void 0 ? result.lastThreadId : prev.lastThreadId,
1448
+ lastError: result.lastError ?? null,
1449
+ updatedAt: nowIso(firedAt)
1450
+ };
1451
+ rows[idx] = next;
1452
+ writeAll(rows);
1453
+ return next;
1454
+ }
1455
+
1456
+ // src/store/thread-store.ts
1457
+ function nowIso2() {
1022
1458
  return (/* @__PURE__ */ new Date()).toISOString();
1023
1459
  }
1024
1460
  function resolveThreadEffort(raw) {
@@ -1107,9 +1543,9 @@ function normalizeThread(raw) {
1107
1543
  };
1108
1544
  }
1109
1545
  function createEmptyThread(partial) {
1110
- const ts = nowIso();
1546
+ const ts = nowIso2();
1111
1547
  return {
1112
- id: randomUUID(),
1548
+ id: randomUUID2(),
1113
1549
  sessionId: partial.sessionId ?? null,
1114
1550
  autonomy: partial.autonomy ?? "default",
1115
1551
  model: partial.model ?? null,
@@ -1217,7 +1653,7 @@ function readThread(id) {
1217
1653
  const cache = cacheForDir();
1218
1654
  const cached = cache.byId.get(id);
1219
1655
  if (cached && cache.mtimeMs.get(id) === mtimeMs) return cached;
1220
- const raw = readFileSync(path, "utf8");
1656
+ const raw = readFileSync2(path, "utf8");
1221
1657
  const thread = normalizeThread(JSON.parse(raw));
1222
1658
  rememberThread(thread, mtimeMs);
1223
1659
  return thread;
@@ -1226,7 +1662,7 @@ var selfWriteMtimes = /* @__PURE__ */ new Map();
1226
1662
  function writeThread(thread, opts) {
1227
1663
  const path = threadFilePath(idPath(thread.id));
1228
1664
  const tmp = `${path}.${process.pid}.tmp`;
1229
- const next = opts?.touch === false ? { ...thread } : { ...thread, updatedAt: nowIso() };
1665
+ const next = opts?.touch === false ? { ...thread } : { ...thread, updatedAt: nowIso2() };
1230
1666
  writeFileSync(tmp, JSON.stringify(next, null, 2), "utf8");
1231
1667
  renameSync(tmp, path);
1232
1668
  const mtimeMs = fileMtimeMs(path) ?? Date.now();
@@ -1270,30 +1706,29 @@ function listThreads(opts) {
1270
1706
  function deleteThreadRecord(id) {
1271
1707
  forgetThread(id);
1272
1708
  const path = threadFilePath(id);
1273
- if (existsSync(path)) unlinkSync(path);
1274
- const lock = threadLockPath(id);
1275
- if (existsSync(lock)) {
1276
- try {
1277
- unlinkSync(lock);
1278
- } catch {
1279
- }
1709
+ if (existsSync2(path)) unlinkSync(path);
1710
+ try {
1711
+ if (existsSync2(threadLockPath(id))) unlinkSync(threadLockPath(id));
1712
+ } catch {
1280
1713
  }
1281
1714
  try {
1282
1715
  rmSync(cursorSdkStoreDir(id), { recursive: true, force: true });
1283
1716
  } catch {
1284
1717
  }
1718
+ deleteSchedulesForThread(id);
1285
1719
  }
1286
1720
  function updateThread(id, patch) {
1287
1721
  const current = readThread(id);
1288
1722
  if (!current) throw new Error(`Thread not found: ${id}`);
1289
- const next = { ...current, ...patch, id: current.id, updatedAt: nowIso() };
1723
+ const next = { ...current, ...patch, id: current.id, updatedAt: nowIso2() };
1290
1724
  if (next.status === "archived") {
1291
- next.archivedAt = typeof next.archivedAt === "string" && next.archivedAt.trim() || current.archivedAt || nowIso();
1725
+ next.archivedAt = typeof next.archivedAt === "string" && next.archivedAt.trim() || current.archivedAt || nowIso2();
1292
1726
  } else {
1293
1727
  delete next.archivedAt;
1294
1728
  }
1295
1729
  if (!next.ephemeralAutomationId?.trim()) delete next.ephemeralAutomationId;
1296
1730
  writeThread(next);
1731
+ if (patch.status === "archived" && current.status !== "archived") deleteSchedulesForThread(current.id);
1297
1732
  return next;
1298
1733
  }
1299
1734
  function appendMessage(id, message) {
@@ -1339,6 +1774,27 @@ export {
1339
1774
  workspaceRowLabel,
1340
1775
  worktreeIdentityTitles,
1341
1776
  isWorktreeIdentityTitle,
1777
+ WEEKDAY_LABELS,
1778
+ parseDurationMs,
1779
+ normalizeWeekdays,
1780
+ parseWeeklyDays,
1781
+ normalizeWeeklyTime,
1782
+ formatWeeklyDays,
1783
+ weeklyCronExpr,
1784
+ computeNextRunAt,
1785
+ formatScheduleWhen,
1786
+ schedulesPath,
1787
+ defaultScheduleName,
1788
+ resolveScheduleThreadId,
1789
+ listSchedules,
1790
+ hasEnabledSchedules,
1791
+ scheduleNeedsCaffeinate,
1792
+ getSchedule,
1793
+ createSchedule,
1794
+ updateSchedule,
1795
+ deleteSchedulesForThread,
1796
+ deleteSchedule,
1797
+ recordScheduleRun,
1342
1798
  resolveThreadEffort,
1343
1799
  normalizeThread,
1344
1800
  createEmptyThread,
@@ -6,14 +6,14 @@ import {
6
6
  normalizeAbleTimeCredential,
7
7
  normalizeAbleTimeHost,
8
8
  rewriteAbleTimeError
9
- } from "./chunk-JM2TGOHP.js";
9
+ } from "./chunk-SB5ADEZZ.js";
10
10
  import {
11
11
  httpFetch
12
12
  } from "./chunk-2GPQZZLY.js";
13
13
  import {
14
14
  getAbleTimeAccessToken,
15
15
  getAbleTimeHost
16
- } from "./chunk-D744HOI5.js";
16
+ } from "./chunk-EJRCHCXM.js";
17
17
 
18
18
  // src/integrations/abletime-rest.ts
19
19
  var ABLETIME_REST_PREFIX = "/api/public/v2";
@@ -32,19 +32,19 @@ import {
32
32
  tryReservePort,
33
33
  tryReservePorts,
34
34
  worktreeRunPortsPath
35
- } from "./chunk-46FECFZU.js";
35
+ } from "./chunk-X3XTO45Y.js";
36
36
  import "./chunk-OOXRMTU6.js";
37
- import "./chunk-FWVUGLBG.js";
38
- import "./chunk-KECHK3ZT.js";
39
- import "./chunk-ZSHS46V5.js";
37
+ import "./chunk-RDXODLEN.js";
38
+ import "./chunk-R2C45NHT.js";
39
+ import "./chunk-Y6OHM672.js";
40
40
  import "./chunk-QKHEVSB5.js";
41
- import "./chunk-F2PVRF3B.js";
41
+ import "./chunk-NJV5YEKI.js";
42
+ import "./chunk-N6ZF3XRP.js";
42
43
  import "./chunk-OPXEJJBM.js";
43
44
  import "./chunk-6K64FJDD.js";
44
45
  import "./chunk-LG6RJBIY.js";
45
46
  import "./chunk-2TUE6JKQ.js";
46
- import "./chunk-QPSKQP6E.js";
47
- import "./chunk-77WWLBCI.js";
47
+ import "./chunk-D446IWPP.js";
48
48
  import {
49
49
  stripNestedElectronEnv
50
50
  } from "./chunk-4TR3HZFT.js";
@@ -34,23 +34,22 @@ import {
34
34
  tryReservePort,
35
35
  tryReservePorts,
36
36
  worktreeRunPortsPath
37
- } from "./chunk-XLVLMQKN.js";
37
+ } from "./chunk-EYDLXVED.js";
38
38
  import "./chunk-5MXLDDYF.js";
39
- import "./chunk-YGVGXQA7.js";
40
- import "./chunk-75RPUXJS.js";
39
+ import "./chunk-Q4UPRQOS.js";
40
+ import "./chunk-JKHCADKB.js";
41
41
  import "./chunk-N2WW62LF.js";
42
42
  import "./chunk-4YXZOXMT.js";
43
43
  import "./chunk-YBTSZ2SW.js";
44
- import "./chunk-D744HOI5.js";
44
+ import "./chunk-5Y2C7Q55.js";
45
+ import "./chunk-WMZIANPV.js";
46
+ import "./chunk-EJRCHCXM.js";
45
47
  import "./chunk-NSTQ6QKD.js";
46
48
  import {
47
49
  stripNestedElectronEnv
48
50
  } from "./chunk-WWUABK6B.js";
49
51
  import "./chunk-FJZWM2ON.js";
50
52
  import "./chunk-J2LNLI4S.js";
51
- import "./chunk-Q3FHTGIW.js";
52
- import "./chunk-WMZIANPV.js";
53
- import "./chunk-KGZBYWZ3.js";
54
53
  import {
55
54
  hasConductorHook,
56
55
  hasRepoHook,
@@ -7,16 +7,15 @@ import {
7
7
  enrichWorkspacesWithGithub,
8
8
  ensureGlobalCoordinatorCwd,
9
9
  formatWorkspaceInventory
10
- } from "./chunk-FWVUGLBG.js";
11
- import "./chunk-KECHK3ZT.js";
12
- import "./chunk-ZSHS46V5.js";
10
+ } from "./chunk-RDXODLEN.js";
11
+ import "./chunk-R2C45NHT.js";
12
+ import "./chunk-Y6OHM672.js";
13
13
  import "./chunk-QKHEVSB5.js";
14
- import "./chunk-F2PVRF3B.js";
14
+ import "./chunk-N6ZF3XRP.js";
15
15
  import "./chunk-6K64FJDD.js";
16
16
  import "./chunk-LG6RJBIY.js";
17
17
  import "./chunk-2TUE6JKQ.js";
18
- import "./chunk-QPSKQP6E.js";
19
- import "./chunk-77WWLBCI.js";
18
+ import "./chunk-D446IWPP.js";
20
19
  import "./chunk-4TR3HZFT.js";
21
20
  import "./chunk-WDRMZKVB.js";
22
21
  import "./chunk-KI45T4DI.js";
@@ -9,19 +9,18 @@ import {
9
9
  enrichWorkspacesWithGithub,
10
10
  ensureGlobalCoordinatorCwd,
11
11
  formatWorkspaceInventory
12
- } from "./chunk-YGVGXQA7.js";
13
- import "./chunk-75RPUXJS.js";
12
+ } from "./chunk-Q4UPRQOS.js";
13
+ import "./chunk-JKHCADKB.js";
14
14
  import "./chunk-N2WW62LF.js";
15
15
  import "./chunk-4YXZOXMT.js";
16
16
  import "./chunk-YBTSZ2SW.js";
17
- import "./chunk-D744HOI5.js";
17
+ import "./chunk-5Y2C7Q55.js";
18
+ import "./chunk-WMZIANPV.js";
19
+ import "./chunk-EJRCHCXM.js";
18
20
  import "./chunk-NSTQ6QKD.js";
19
21
  import "./chunk-WWUABK6B.js";
20
22
  import "./chunk-FJZWM2ON.js";
21
23
  import "./chunk-J2LNLI4S.js";
22
- import "./chunk-Q3FHTGIW.js";
23
- import "./chunk-WMZIANPV.js";
24
- import "./chunk-KGZBYWZ3.js";
25
24
  import "./chunk-WOU343SI.js";
26
25
  export {
27
26
  COORDINATOR_TOOL_PLAYBOOK,