@sideboard-ai/core 0.1.326 → 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-RYYFGKMU.js → abletime-NW4PJGHN.js} +4 -5
- package/dist/{abletime-RDHYSZL2.js → abletime-OW7LTFQD.js} +4 -5
- package/dist/{abletime-oauth-OYGS2DAU.js → abletime-oauth-KWQQRHOQ.js} +3 -4
- package/dist/{abletime-oauth-QR2QDVMK.js → abletime-oauth-TPR2QDRI.js} +3 -4
- package/dist/{abletime-rest-QDPTWNS4.js → abletime-rest-5DCWN3P4.js} +3 -4
- package/dist/{abletime-rest-BKYKNPTC.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-QO7GKBYT.js → agents-IYBY3JT5.js} +8 -9
- package/dist/{agents-HANWZNI6.js → agents-XWIPONJR.js} +8 -9
- package/dist/{app-settings-RXBH7KY4.js → app-settings-A5D364JD.js} +1 -2
- package/dist/{app-settings-TUVLZNDE.js → app-settings-SA4HX3ZQ.js} +1 -2
- package/dist/{chunk-3Q4XNYHY.js → chunk-2GEUFPQQ.js} +1 -1
- package/dist/{chunk-MAW7DIG7.js → chunk-4F7THWIO.js} +2 -2
- package/dist/{chunk-K7M7MIWL.js → chunk-4G3W23X3.js} +3 -3
- package/dist/{chunk-Q3FHTGIW.js → chunk-5Y2C7Q55.js} +441 -20
- package/dist/{chunk-TMCK5TLA.js → chunk-ATQLP22S.js} +1 -1
- package/dist/{chunk-PB6HW7SA.js → chunk-CHYUUETG.js} +3 -3
- package/dist/{chunk-QPSKQP6E.js → chunk-D446IWPP.js} +48 -3
- package/dist/{chunk-C7HUCBX7.js → chunk-DACWFN4O.js} +5 -5
- package/dist/{chunk-GP3RLZ6A.js → chunk-DEB47BII.js} +51 -487
- package/dist/{chunk-B244TJWC.js → chunk-ECY7WL6T.js} +2 -2
- package/dist/{chunk-D744HOI5.js → chunk-EJRCHCXM.js} +18 -3
- package/dist/{chunk-KXRF6RNL.js → chunk-EUIVQAPK.js} +2 -2
- package/dist/{chunk-46FECFZU.js → chunk-IXWPCOLQ.js} +8 -195
- package/dist/{chunk-75RPUXJS.js → chunk-JKHCADKB.js} +5 -5
- package/dist/{chunk-4H5MWZ6J.js → chunk-KLVW3J2B.js} +2 -2
- package/dist/{chunk-QG4CYRA3.js → chunk-MO46K6WK.js} +14 -14
- package/dist/{chunk-F2PVRF3B.js → chunk-N6ZF3XRP.js} +2 -1
- package/dist/{chunk-BBNWKL4I.js → chunk-NQGLDQYB.js} +8 -8
- package/dist/{chunk-YGVGXQA7.js → chunk-Q4UPRQOS.js} +12 -12
- package/dist/{chunk-ZUAYA57W.js → chunk-QMLDR63X.js} +2 -2
- package/dist/{chunk-KECHK3ZT.js → chunk-R2C45NHT.js} +2 -2
- package/dist/{chunk-FWVUGLBG.js → chunk-RDXODLEN.js} +4 -4
- package/dist/{chunk-XLVLMQKN.js → chunk-RZJ3QJZT.js} +11 -11
- package/dist/{chunk-JM2TGOHP.js → chunk-SB5ADEZZ.js} +5 -5
- package/dist/{chunk-SO7G6O24.js → chunk-SFXGD5KJ.js} +1 -1
- package/dist/{chunk-LRHUBGEM.js → chunk-TUH4ICHQ.js} +1 -1
- package/dist/chunk-ULWPSBAB.js +192 -0
- package/dist/{chunk-WUCAVIIP.js → chunk-UMXBH344.js} +1 -1
- package/dist/{chunk-RZVOX2MT.js → chunk-XBBZZHJY.js} +3 -3
- package/dist/{chunk-ZSHS46V5.js → chunk-Y6OHM672.js} +476 -20
- package/dist/{chunk-2EOLWHXH.js → chunk-YUHZEIVG.js} +69 -473
- package/dist/{chunk-YWQF7WAG.js → chunk-ZPBOWO64.js} +2 -2
- package/dist/{conductor-4GVTHUUB.js → conductor-CP7TW6TN.js} +7 -7
- package/dist/{conductor-TGWI6ETZ.js → conductor-D62Q2XJC.js} +6 -7
- package/dist/{coordinator-prompt-3E6SIDTM.js → coordinator-prompt-3PJLU3UH.js} +5 -6
- package/dist/{coordinator-prompt-WEYJREV6.js → coordinator-prompt-J7O7JB26.js} +5 -6
- package/dist/{global-workspace-UIEXAG2B.js → global-workspace-4CTLU2BV.js} +5 -6
- package/dist/{global-workspace-FPDZKUPF.js → global-workspace-Y3UDZYJX.js} +5 -6
- package/dist/index.cjs +507 -492
- package/dist/index.d.cts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +67 -65
- package/dist/{linear-6S7MK5YK.js → linear-CXWGH2TW.js} +2 -3
- package/dist/{linear-Z2T4KUAQ.js → linear-WLDCJ3AF.js} +2 -3
- package/dist/{linear-list-Q4M7AZO2.js → linear-list-52LEDEWO.js} +1 -1
- package/dist/{linear-list-A37WLUBO.js → linear-list-FGVN65JU.js} +1 -1
- package/dist/mcp/run-stdio.cjs +19654 -19641
- package/dist/mcp/run-stdio.js +33 -34
- package/dist/{optional-cli-CA4LL322.js → optional-cli-FN4MGB6W.js} +4 -5
- package/dist/{optional-cli-AANBL4U5.js → optional-cli-INRVBBBG.js} +3 -4
- package/dist/{orchestrator-7FVDBE7Y.js → orchestrator-EN3ZKD73.js} +12 -12
- package/dist/{orchestrator-RQXRZW7Z.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-LEW4UP56.js → workspaces-MM7CQYR6.js} +5 -6
- package/dist/{workspaces-QONNLHNR.js → workspaces-WYCVZ6XH.js} +5 -6
- package/dist/{worktree-KFEJAQ2H.js → worktree-JBNEMJ5Z.js} +7 -8
- package/dist/{worktree-6GIONDQO.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
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
2
|
sanitizeMcpServerName
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-N6ZF3XRP.js";
|
|
4
4
|
import {
|
|
5
5
|
cursorSdkStoreDir
|
|
6
6
|
} from "./chunk-LG6RJBIY.js";
|
|
7
7
|
import {
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
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 =
|
|
1546
|
+
const ts = nowIso2();
|
|
1111
1547
|
return {
|
|
1112
|
-
id:
|
|
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 =
|
|
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:
|
|
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 (
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
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:
|
|
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 ||
|
|
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,
|