@sideboard-ai/core 0.1.292 → 0.1.293
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/agents/cursor-runner.cjs +329 -36
- package/dist/agents/cursor-runner.js +318 -17
- package/dist/{agents-4BBCKITL.js → agents-SITR5V6F.js} +3 -3
- package/dist/{agents-XAKSP653.js → agents-WT72O5A3.js} +3 -3
- package/dist/{chunk-2IXKTAIT.js → chunk-2VGLZIU6.js} +37 -13
- package/dist/{chunk-GBAACE3C.js → chunk-4YXXLWDI.js} +3 -3
- package/dist/{chunk-4VXWLY3L.js → chunk-IP5WSADC.js} +9 -9
- package/dist/{chunk-QOUTSISS.js → chunk-LSHGJI4S.js} +10 -10
- package/dist/{chunk-O4324MXE.js → chunk-PO3PDNMV.js} +1 -1
- package/dist/{chunk-LUQ7MIVD.js → chunk-RPCKGO3J.js} +3 -3
- package/dist/{chunk-5HPMKLJ7.js → chunk-UO5C2L2G.js} +37 -13
- package/dist/{chunk-G74TSBJ3.js → chunk-WRDKJRWF.js} +3 -3
- package/dist/{chunk-VNCPRMIK.js → chunk-XZW3BXZW.js} +3 -3
- package/dist/{chunk-V3BSO2O6.js → chunk-ZRQWV3MS.js} +1 -1
- package/dist/{conductor-UFJXJPTF.js → conductor-MAYZSFL6.js} +3 -3
- package/dist/{conductor-5MNGC25D.js → conductor-P7XPGYF4.js} +3 -3
- package/dist/{coordinator-prompt-5Q66Y5KW.js → coordinator-prompt-NAM5JHLT.js} +2 -2
- package/dist/{coordinator-prompt-BYPEW6DE.js → coordinator-prompt-OZFKNCM3.js} +2 -2
- package/dist/{global-workspace-BTH2YGDZ.js → global-workspace-CTFQDG7G.js} +2 -2
- package/dist/{global-workspace-YKOYXSB2.js → global-workspace-UGR6FQXI.js} +2 -2
- package/dist/index.cjs +47 -13
- package/dist/index.d.cts +10 -4
- package/dist/index.d.ts +10 -4
- package/dist/index.js +17 -7
- package/dist/mcp/run-stdio.cjs +37 -13
- package/dist/mcp/run-stdio.js +5 -5
- package/dist/{orchestrator-EQSK2RMI.js → orchestrator-4QVF6CE2.js} +5 -5
- package/dist/{orchestrator-GSOW3RPA.js → orchestrator-BOGVTCWI.js} +5 -5
- package/dist/{workspaces-ELO2YVTU.js → workspaces-QNKFBA63.js} +2 -2
- package/dist/{workspaces-RFD6I4FM.js → workspaces-YNZXVBSF.js} +2 -2
- package/dist/{worktree-ADVQ6X6C.js → worktree-EMCWDPZJ.js} +1 -1
- package/dist/{worktree-TN7DZDJZ.js → worktree-ERRH4TAG.js} +1 -1
- package/package.json +1 -1
|
@@ -35,9 +35,291 @@ import {
|
|
|
35
35
|
import "../chunk-EHT2DRT4.js";
|
|
36
36
|
|
|
37
37
|
// src/agents/cursor-runner.ts
|
|
38
|
-
import { mkdirSync } from "fs";
|
|
38
|
+
import { mkdirSync as mkdirSync2 } from "fs";
|
|
39
39
|
import { createInterface } from "readline";
|
|
40
40
|
|
|
41
|
+
// src/agents/cursor-catalog.ts
|
|
42
|
+
import {
|
|
43
|
+
existsSync,
|
|
44
|
+
mkdirSync,
|
|
45
|
+
readdirSync,
|
|
46
|
+
readFileSync,
|
|
47
|
+
renameSync,
|
|
48
|
+
unlinkSync,
|
|
49
|
+
writeFileSync
|
|
50
|
+
} from "fs";
|
|
51
|
+
import { basename, dirname, join } from "path";
|
|
52
|
+
import lockfile from "proper-lockfile";
|
|
53
|
+
var CATALOG_FILES = ["agents.ndjson", "runs.ndjson", "run_events.ndjson", "checkpoints.ndjson"];
|
|
54
|
+
var INTERRUPTED_TMP = /^\.(agents|runs|run_events|checkpoints)\.ndjson\.[0-9a-f]{16}\.tmp$/;
|
|
55
|
+
async function acquireCursorCatalogLock(storeDir) {
|
|
56
|
+
mkdirSync(storeDir, { recursive: true });
|
|
57
|
+
const lockPath = join(storeDir, ".catalog.lock");
|
|
58
|
+
writeFileSync(lockPath, "", { flag: "a" });
|
|
59
|
+
try {
|
|
60
|
+
return await lockfile.lock(lockPath, {
|
|
61
|
+
retries: { retries: 40, minTimeout: 50, maxTimeout: 500 },
|
|
62
|
+
stale: 5e3,
|
|
63
|
+
update: 2e3
|
|
64
|
+
});
|
|
65
|
+
} catch {
|
|
66
|
+
return async () => {
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
var heldCatalogRelease;
|
|
71
|
+
function publishRepair(repair, note) {
|
|
72
|
+
for (const line of repair.notes) note(line);
|
|
73
|
+
}
|
|
74
|
+
async function openCursorCatalogTurn(storeDir, note) {
|
|
75
|
+
mkdirSync(storeDir, { recursive: true });
|
|
76
|
+
heldCatalogRelease = await acquireCursorCatalogLock(storeDir);
|
|
77
|
+
publishRepair(repairCursorLocalCatalog(storeDir), note);
|
|
78
|
+
}
|
|
79
|
+
function repairCursorCatalogForResume(storeDir, note) {
|
|
80
|
+
const repair = repairCursorLocalCatalog(storeDir);
|
|
81
|
+
publishRepair(repair, note);
|
|
82
|
+
return repair.repaired;
|
|
83
|
+
}
|
|
84
|
+
async function closeCursorCatalogTurn() {
|
|
85
|
+
const release = heldCatalogRelease;
|
|
86
|
+
heldCatalogRelease = void 0;
|
|
87
|
+
if (release) await release().catch(() => void 0);
|
|
88
|
+
}
|
|
89
|
+
function repairCursorLocalCatalog(storeDir) {
|
|
90
|
+
if (!existsSync(storeDir)) return { repaired: false, notes: [] };
|
|
91
|
+
const notes = [];
|
|
92
|
+
let repaired = false;
|
|
93
|
+
const loaded = /* @__PURE__ */ new Map();
|
|
94
|
+
for (const file of CATALOG_FILES) {
|
|
95
|
+
loaded.set(file, loadCatalogFile(storeDir, file));
|
|
96
|
+
}
|
|
97
|
+
const checkpoints = mergeByKey(
|
|
98
|
+
loaded.get("checkpoints.ndjson").main,
|
|
99
|
+
loaded.get("checkpoints.ndjson").tmpRows,
|
|
100
|
+
(row) => checkpointKey(row),
|
|
101
|
+
(main2) => main2
|
|
102
|
+
);
|
|
103
|
+
const blobs = checkpointBlobs(checkpoints.rows);
|
|
104
|
+
const agents = mergeByKey(
|
|
105
|
+
loaded.get("agents.ndjson").main,
|
|
106
|
+
loaded.get("agents.ndjson").tmpRows,
|
|
107
|
+
(row) => typeof row.agentId === "string" ? row.agentId : null,
|
|
108
|
+
(main2, extra) => preferAgent(main2, extra, blobs)
|
|
109
|
+
);
|
|
110
|
+
const runs = mergeByKey(
|
|
111
|
+
loaded.get("runs.ndjson").main,
|
|
112
|
+
loaded.get("runs.ndjson").tmpRows,
|
|
113
|
+
(row) => runKey(row),
|
|
114
|
+
(main2, extra) => num(extra.updatedAt) >= num(main2.updatedAt) ? extra : main2
|
|
115
|
+
);
|
|
116
|
+
const events = mergeByKey(
|
|
117
|
+
loaded.get("run_events.ndjson").main,
|
|
118
|
+
loaded.get("run_events.ndjson").tmpRows,
|
|
119
|
+
(row) => eventKey(row),
|
|
120
|
+
(main2) => main2
|
|
121
|
+
);
|
|
122
|
+
const merged = {
|
|
123
|
+
"checkpoints.ndjson": checkpoints.rows,
|
|
124
|
+
"agents.ndjson": agents.rows,
|
|
125
|
+
"runs.ndjson": runs.rows,
|
|
126
|
+
"run_events.ndjson": events.rows
|
|
127
|
+
};
|
|
128
|
+
for (const agent of merged["agents.ndjson"]) {
|
|
129
|
+
if (restoreAgentCheckpoint(agent, merged["runs.ndjson"], blobs, notes)) repaired = true;
|
|
130
|
+
if (clearMissingActiveRun(agent, merged["runs.ndjson"], notes)) repaired = true;
|
|
131
|
+
}
|
|
132
|
+
for (const file of CATALOG_FILES) {
|
|
133
|
+
const prior = loaded.get(file);
|
|
134
|
+
const next = merged[file];
|
|
135
|
+
const recovered = countNewKeys(prior.main, next, keyFor(file));
|
|
136
|
+
if (recovered > 0) {
|
|
137
|
+
notes.push(`Cursor catalog recovered ${recovered} ${file} row(s) from an interrupted write`);
|
|
138
|
+
repaired = true;
|
|
139
|
+
}
|
|
140
|
+
if (!sameRows(prior.main, next)) {
|
|
141
|
+
writeCatalogFile(join(storeDir, file), next);
|
|
142
|
+
repaired = true;
|
|
143
|
+
}
|
|
144
|
+
for (const tmp of prior.tmps) {
|
|
145
|
+
try {
|
|
146
|
+
unlinkSync(tmp);
|
|
147
|
+
} catch {
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return { repaired, notes };
|
|
152
|
+
}
|
|
153
|
+
function loadCatalogFile(storeDir, file) {
|
|
154
|
+
const tmps = interruptedTmps(storeDir, file);
|
|
155
|
+
return {
|
|
156
|
+
main: readRows(join(storeDir, file)),
|
|
157
|
+
tmps,
|
|
158
|
+
tmpRows: tmps.flatMap((tmp) => readRows(tmp))
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function keyFor(file) {
|
|
162
|
+
if (file === "checkpoints.ndjson") return checkpointKey;
|
|
163
|
+
if (file === "agents.ndjson") return (row) => typeof row.agentId === "string" ? row.agentId : null;
|
|
164
|
+
if (file === "runs.ndjson") return runKey;
|
|
165
|
+
return eventKey;
|
|
166
|
+
}
|
|
167
|
+
function countNewKeys(main2, next, keyOf) {
|
|
168
|
+
const had = new Set(main2.map(keyOf).filter((key) => Boolean(key)));
|
|
169
|
+
let n = 0;
|
|
170
|
+
for (const row of next) {
|
|
171
|
+
const key = keyOf(row);
|
|
172
|
+
if (key && !had.has(key)) n += 1;
|
|
173
|
+
}
|
|
174
|
+
return n;
|
|
175
|
+
}
|
|
176
|
+
function interruptedTmps(storeDir, file) {
|
|
177
|
+
let names = [];
|
|
178
|
+
try {
|
|
179
|
+
names = readdirSync(storeDir);
|
|
180
|
+
} catch {
|
|
181
|
+
return [];
|
|
182
|
+
}
|
|
183
|
+
const prefix = `.${file}.`;
|
|
184
|
+
return names.filter((name) => name.startsWith(prefix) && INTERRUPTED_TMP.test(name)).map((name) => join(storeDir, name));
|
|
185
|
+
}
|
|
186
|
+
function readRows(file) {
|
|
187
|
+
if (!existsSync(file)) return [];
|
|
188
|
+
let raw = "";
|
|
189
|
+
try {
|
|
190
|
+
raw = readFileSync(file, "utf8");
|
|
191
|
+
} catch {
|
|
192
|
+
return [];
|
|
193
|
+
}
|
|
194
|
+
const rows = [];
|
|
195
|
+
for (const line of raw.split("\n")) {
|
|
196
|
+
const trimmed = line.trim();
|
|
197
|
+
if (!trimmed) continue;
|
|
198
|
+
try {
|
|
199
|
+
const parsed = JSON.parse(trimmed);
|
|
200
|
+
if (isRow(parsed)) rows.push(parsed);
|
|
201
|
+
} catch {
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return rows;
|
|
205
|
+
}
|
|
206
|
+
function writeCatalogFile(file, rows) {
|
|
207
|
+
if (rows.length === 0 && !existsSync(file)) return;
|
|
208
|
+
const body = rows.map((row) => JSON.stringify(row)).join("\n");
|
|
209
|
+
const dir = dirname(file);
|
|
210
|
+
mkdirSync(dir, { recursive: true });
|
|
211
|
+
const tmp = join(dir, `.${basename(file)}.repair.tmp`);
|
|
212
|
+
writeFileSync(tmp, body);
|
|
213
|
+
renameSync(tmp, file);
|
|
214
|
+
}
|
|
215
|
+
function mergeByKey(main2, extra, keyOf, prefer) {
|
|
216
|
+
const out = [];
|
|
217
|
+
const index = /* @__PURE__ */ new Map();
|
|
218
|
+
for (const row of main2) {
|
|
219
|
+
const key = keyOf(row);
|
|
220
|
+
if (!key || index.has(key)) continue;
|
|
221
|
+
index.set(key, out.length);
|
|
222
|
+
out.push(structuredClone(row));
|
|
223
|
+
}
|
|
224
|
+
for (const row of extra) {
|
|
225
|
+
const key = keyOf(row);
|
|
226
|
+
if (!key) continue;
|
|
227
|
+
const at = index.get(key);
|
|
228
|
+
if (at == null) {
|
|
229
|
+
index.set(key, out.length);
|
|
230
|
+
out.push(structuredClone(row));
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
out[at] = structuredClone(prefer(out[at], row));
|
|
234
|
+
}
|
|
235
|
+
return { rows: out };
|
|
236
|
+
}
|
|
237
|
+
function restoreAgentCheckpoint(agent, runs, blobs, notes) {
|
|
238
|
+
const agentId = typeof agent.agentId === "string" ? agent.agentId : "";
|
|
239
|
+
const current = rootBlobId(agent.latestCheckpoint);
|
|
240
|
+
if (!agentId || !current || blobs.has(`${agentId}\0${current}`)) return false;
|
|
241
|
+
const fallback = fallbackCheckpoint(runs, agentId, blobs);
|
|
242
|
+
const fallbackId = rootBlobId(fallback);
|
|
243
|
+
if (!fallback || !fallbackId) return false;
|
|
244
|
+
agent.latestCheckpoint = fallback;
|
|
245
|
+
agent.updatedAt = Date.now();
|
|
246
|
+
notes.push(
|
|
247
|
+
`Cursor catalog restored agent ${agentId} to checkpoint ${fallbackId} (root blob ${current} was missing)`
|
|
248
|
+
);
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
function clearMissingActiveRun(agent, runs, notes) {
|
|
252
|
+
const agentId = typeof agent.agentId === "string" ? agent.agentId : "";
|
|
253
|
+
const active = typeof agent.activeRunId === "string" ? agent.activeRunId : "";
|
|
254
|
+
if (!agentId || !active) return false;
|
|
255
|
+
const live = runs.some((run) => run.agentId === agentId && run.runId === active);
|
|
256
|
+
if (live) return false;
|
|
257
|
+
agent.activeRunId = null;
|
|
258
|
+
if (agent.status === "running") agent.status = "idle";
|
|
259
|
+
notes.push(`Cursor catalog cleared missing run ${active} on agent ${agentId}`);
|
|
260
|
+
return true;
|
|
261
|
+
}
|
|
262
|
+
function fallbackCheckpoint(runs, agentId, blobs) {
|
|
263
|
+
const mine = runs.filter((run) => run.agentId === agentId).slice().sort((a, b) => num(b.updatedAt) - num(a.updatedAt));
|
|
264
|
+
for (const run of mine) {
|
|
265
|
+
for (const field of ["latestCheckpointRef", "startCheckpointRef"]) {
|
|
266
|
+
const ref = run[field];
|
|
267
|
+
const id = rootBlobId(ref);
|
|
268
|
+
if (id && blobs.has(`${agentId}\0${id}`) && isRow(ref)) return ref;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
function preferAgent(main2, extra, blobs) {
|
|
274
|
+
const mainOk = checkpointPresent(main2, blobs);
|
|
275
|
+
const extraOk = checkpointPresent(extra, blobs);
|
|
276
|
+
if (mainOk && !extraOk) return main2;
|
|
277
|
+
if (extraOk && !mainOk) return extra;
|
|
278
|
+
return num(extra.updatedAt) >= num(main2.updatedAt) ? extra : main2;
|
|
279
|
+
}
|
|
280
|
+
function checkpointPresent(agent, blobs) {
|
|
281
|
+
const agentId = typeof agent.agentId === "string" ? agent.agentId : "";
|
|
282
|
+
const id = rootBlobId(agent.latestCheckpoint);
|
|
283
|
+
if (!id) return true;
|
|
284
|
+
return blobs.has(`${agentId}\0${id}`);
|
|
285
|
+
}
|
|
286
|
+
function checkpointBlobs(rows) {
|
|
287
|
+
const ids = /* @__PURE__ */ new Set();
|
|
288
|
+
for (const row of rows) {
|
|
289
|
+
if (typeof row.agentId !== "string" || typeof row.blobId !== "string") continue;
|
|
290
|
+
if (typeof row.dataBase64 !== "string" || !row.dataBase64) continue;
|
|
291
|
+
ids.add(`${row.agentId}\0${row.blobId}`);
|
|
292
|
+
}
|
|
293
|
+
return ids;
|
|
294
|
+
}
|
|
295
|
+
function checkpointKey(row) {
|
|
296
|
+
if (typeof row.agentId !== "string" || typeof row.blobId !== "string") return null;
|
|
297
|
+
return `${row.agentId}\0${row.blobId}`;
|
|
298
|
+
}
|
|
299
|
+
function runKey(row) {
|
|
300
|
+
if (typeof row.agentId !== "string" || typeof row.runId !== "string") return null;
|
|
301
|
+
return `${row.agentId}\0${row.runId}`;
|
|
302
|
+
}
|
|
303
|
+
function eventKey(row) {
|
|
304
|
+
if (typeof row.runId !== "string") return null;
|
|
305
|
+
if (typeof row.seq === "number") return `${row.runId}\0${row.seq}`;
|
|
306
|
+
if (typeof row.offset === "string") return `${row.runId}\0${row.offset}`;
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
309
|
+
function rootBlobId(ref) {
|
|
310
|
+
if (!isRow(ref) || typeof ref.rootBlobId !== "string" || !ref.rootBlobId) return null;
|
|
311
|
+
return ref.rootBlobId;
|
|
312
|
+
}
|
|
313
|
+
function num(value) {
|
|
314
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
315
|
+
}
|
|
316
|
+
function sameRows(a, b) {
|
|
317
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
318
|
+
}
|
|
319
|
+
function isRow(value) {
|
|
320
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
321
|
+
}
|
|
322
|
+
|
|
41
323
|
// src/agents/cursor-session.ts
|
|
42
324
|
function cursorErrorMessage(err) {
|
|
43
325
|
if (err instanceof Error) return err.message.trim();
|
|
@@ -146,7 +428,7 @@ async function* iterateUntilIdle(iterable, idleMs, onIdle, activity) {
|
|
|
146
428
|
}
|
|
147
429
|
|
|
148
430
|
// src/agents/sliced-file-read.ts
|
|
149
|
-
import { readFileSync, realpathSync, statSync } from "fs";
|
|
431
|
+
import { readFileSync as readFileSync2, realpathSync, statSync } from "fs";
|
|
150
432
|
import { isAbsolute, relative, resolve, sep } from "path";
|
|
151
433
|
var SLICED_READ_DEFAULT_LIMIT = 200;
|
|
152
434
|
var SLICED_READ_MAX_LINE_CHARS = 2e3;
|
|
@@ -221,7 +503,7 @@ function executeSlicedFileRead(cwd, args) {
|
|
|
221
503
|
try {
|
|
222
504
|
const st = statSync(abs);
|
|
223
505
|
if (!st.isFile()) return `Error: not a file: ${rawPath}`;
|
|
224
|
-
buf =
|
|
506
|
+
buf = readFileSync2(abs);
|
|
225
507
|
} catch (err) {
|
|
226
508
|
return `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
227
509
|
}
|
|
@@ -306,7 +588,7 @@ function emit(event) {
|
|
|
306
588
|
}
|
|
307
589
|
function localAgentStore(Store, threadId) {
|
|
308
590
|
const root = cursorSdkStoreDir(threadId);
|
|
309
|
-
|
|
591
|
+
mkdirSync2(root, { recursive: true });
|
|
310
592
|
return new Store(root);
|
|
311
593
|
}
|
|
312
594
|
async function cancelStaleRuns(Agent, agentId, opts) {
|
|
@@ -396,6 +678,9 @@ async function main() {
|
|
|
396
678
|
fast: Boolean(req.fast)
|
|
397
679
|
});
|
|
398
680
|
const mode = req.planMode ? "plan" : "agent";
|
|
681
|
+
const storeRoot = cursorSdkStoreDir(req.threadId);
|
|
682
|
+
const note = (line) => emit({ type: "stderr", data: line });
|
|
683
|
+
await openCursorCatalogTurn(storeRoot, note);
|
|
399
684
|
const store = localAgentStore(JsonlLocalAgentStore, req.threadId);
|
|
400
685
|
const isolateSources = [];
|
|
401
686
|
let onRpcProgress = () => {
|
|
@@ -444,20 +729,22 @@ async function main() {
|
|
|
444
729
|
async function createAgent() {
|
|
445
730
|
return retryTransport(() => Agent.create(createOpts));
|
|
446
731
|
}
|
|
732
|
+
function resumeAgent(agentId) {
|
|
733
|
+
const { name: _name, ...opts } = createOpts;
|
|
734
|
+
return retryTransport(() => Agent.resume(agentId, opts));
|
|
735
|
+
}
|
|
447
736
|
async function openAgent() {
|
|
448
737
|
try {
|
|
449
|
-
return req.agentId ? await
|
|
450
|
-
() => Agent.resume(req.agentId, {
|
|
451
|
-
apiKey,
|
|
452
|
-
model,
|
|
453
|
-
mode,
|
|
454
|
-
local,
|
|
455
|
-
disallowedTools: ["read"],
|
|
456
|
-
...mcpServers ? { mcpServers } : {}
|
|
457
|
-
})
|
|
458
|
-
) : await createAgent();
|
|
738
|
+
return req.agentId ? await resumeAgent(req.agentId) : await createAgent();
|
|
459
739
|
} catch (err) {
|
|
460
740
|
if (!isUnresumableCursorSession(err)) throw err;
|
|
741
|
+
if (repairCursorCatalogForResume(storeRoot, note) && req.agentId) {
|
|
742
|
+
try {
|
|
743
|
+
return await resumeAgent(req.agentId);
|
|
744
|
+
} catch (err2) {
|
|
745
|
+
if (!isUnresumableCursorSession(err2)) throw err2;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
461
748
|
emit({
|
|
462
749
|
type: "stderr",
|
|
463
750
|
data: cursorSessionRecoveryMessage(err, req.agentId)
|
|
@@ -511,7 +798,9 @@ async function main() {
|
|
|
511
798
|
new Promise((resolve2) => {
|
|
512
799
|
setTimeout(resolve2, 2e3);
|
|
513
800
|
})
|
|
514
|
-
]).finally(() =>
|
|
801
|
+
]).finally(() => {
|
|
802
|
+
void closeCursorCatalogTurn().finally(() => process.exit(1));
|
|
803
|
+
});
|
|
515
804
|
};
|
|
516
805
|
process.once("SIGTERM", onSignal);
|
|
517
806
|
process.once("SIGINT", onSignal);
|
|
@@ -609,11 +898,21 @@ async function main() {
|
|
|
609
898
|
return await runTurn(agent);
|
|
610
899
|
}
|
|
611
900
|
if (!isUnresumableCursorSession(err)) throw err;
|
|
901
|
+
const agentId = agent.agentId;
|
|
902
|
+
await agent[Symbol.asyncDispose]().catch(() => void 0);
|
|
903
|
+
const repaired = repairCursorCatalogForResume(storeRoot, note);
|
|
904
|
+
if (repaired) {
|
|
905
|
+
try {
|
|
906
|
+
agent = await resumeAgent(agentId);
|
|
907
|
+
return await runTurn(agent);
|
|
908
|
+
} catch (err2) {
|
|
909
|
+
if (!isUnresumableCursorSession(err2)) throw err2;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
612
912
|
emit({
|
|
613
913
|
type: "stderr",
|
|
614
|
-
data: cursorSessionRecoveryMessage(err,
|
|
914
|
+
data: cursorSessionRecoveryMessage(err, agentId)
|
|
615
915
|
});
|
|
616
|
-
await agent[Symbol.asyncDispose]().catch(() => void 0);
|
|
617
916
|
agent = await createAgent();
|
|
618
917
|
return await runTurn(agent);
|
|
619
918
|
}
|
|
@@ -631,6 +930,8 @@ async function main() {
|
|
|
631
930
|
const message = err instanceof Error ? err.message : String(err);
|
|
632
931
|
emit({ type: "stderr", data: message });
|
|
633
932
|
return 1;
|
|
933
|
+
} finally {
|
|
934
|
+
await closeCursorCatalogTurn();
|
|
634
935
|
}
|
|
635
936
|
}
|
|
636
937
|
main().then(
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
planModeTurnInstruction,
|
|
38
38
|
resolveCursorModelId,
|
|
39
39
|
resolveQuotaFallbackAgent
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-XZW3BXZW.js";
|
|
41
41
|
import "./chunk-VGNLMGBK.js";
|
|
42
42
|
import "./chunk-YSLCWCMJ.js";
|
|
43
43
|
import {
|
|
@@ -52,8 +52,8 @@ import {
|
|
|
52
52
|
resolveLoginCommand,
|
|
53
53
|
whichOnPath
|
|
54
54
|
} from "./chunk-NXXQFLNQ.js";
|
|
55
|
-
import "./chunk-
|
|
56
|
-
import "./chunk-
|
|
55
|
+
import "./chunk-ZRQWV3MS.js";
|
|
56
|
+
import "./chunk-2VGLZIU6.js";
|
|
57
57
|
import "./chunk-QB5MDOHL.js";
|
|
58
58
|
import "./chunk-2P4XKWV2.js";
|
|
59
59
|
import "./chunk-33KDPEK4.js";
|
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
resolveCursorSdkRoot,
|
|
47
47
|
resolveQuotaFallbackAgent,
|
|
48
48
|
turnCostUsdFromCursorUsage
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-RPCKGO3J.js";
|
|
50
50
|
import {
|
|
51
51
|
getAgentSetupInfo,
|
|
52
52
|
installAgent,
|
|
@@ -63,8 +63,8 @@ import "./chunk-7IAMHN2N.js";
|
|
|
63
63
|
import "./chunk-PXMLMBMI.js";
|
|
64
64
|
import "./chunk-2GPQZZLY.js";
|
|
65
65
|
import "./chunk-AFLNFGGB.js";
|
|
66
|
-
import "./chunk-
|
|
67
|
-
import "./chunk-
|
|
66
|
+
import "./chunk-PO3PDNMV.js";
|
|
67
|
+
import "./chunk-UO5C2L2G.js";
|
|
68
68
|
import "./chunk-N2WW62LF.js";
|
|
69
69
|
import "./chunk-DD67JWTN.js";
|
|
70
70
|
import {
|
|
@@ -2021,15 +2021,8 @@ async function fetchOriginForWorktree(repoPath, sourceRef, opts) {
|
|
|
2021
2021
|
async function fastForwardMainCheckoutIfSafe(repoPath, opts) {
|
|
2022
2022
|
try {
|
|
2023
2023
|
const branch = opts?.branch?.trim() || await resolveDefaultBranch(repoPath, { network: false });
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
});
|
|
2027
|
-
const current = head.stdout.trim();
|
|
2028
|
-
if (head.exitCode !== 0 || !current || current === "HEAD" || current !== branch) {
|
|
2029
|
-
return { updated: false, reason: "not-on-default" };
|
|
2030
|
-
}
|
|
2031
|
-
if (await isDirty(repoPath)) {
|
|
2032
|
-
return { updated: false, reason: "dirty" };
|
|
2024
|
+
if (!branch || branch === "HEAD" || branch.includes("..")) {
|
|
2025
|
+
return { updated: false, reason: "ff-failed" };
|
|
2033
2026
|
}
|
|
2034
2027
|
const remote = `origin/${branch}`;
|
|
2035
2028
|
const remoteOk = await git(["rev-parse", "--verify", remote], repoPath, {
|
|
@@ -2038,8 +2031,27 @@ async function fastForwardMainCheckoutIfSafe(repoPath, opts) {
|
|
|
2038
2031
|
if (remoteOk.exitCode !== 0) {
|
|
2039
2032
|
return { updated: false, reason: "no-origin-tip" };
|
|
2040
2033
|
}
|
|
2034
|
+
const worktrees = await listWorktrees(repoPath);
|
|
2035
|
+
if (worktrees.length === 0) {
|
|
2036
|
+
return { updated: false, reason: "ff-failed" };
|
|
2037
|
+
}
|
|
2038
|
+
const checkout = worktrees.find((entry) => entry.branch === branch) ?? null;
|
|
2039
|
+
const localRef = `refs/heads/${branch}`;
|
|
2040
|
+
const localOk = await git(["rev-parse", "--verify", localRef], repoPath, {
|
|
2041
|
+
reject: false
|
|
2042
|
+
});
|
|
2043
|
+
if (localOk.exitCode !== 0) {
|
|
2044
|
+
if (checkout) return { updated: false, reason: "ff-failed" };
|
|
2045
|
+
const created = await git(["branch", "--track", branch, remote], repoPath, {
|
|
2046
|
+
reject: false
|
|
2047
|
+
});
|
|
2048
|
+
if (created.exitCode !== 0) {
|
|
2049
|
+
return { updated: false, reason: "ff-failed" };
|
|
2050
|
+
}
|
|
2051
|
+
return { updated: true, reason: "updated" };
|
|
2052
|
+
}
|
|
2041
2053
|
const ancestor = await git(
|
|
2042
|
-
["merge-base", "--is-ancestor",
|
|
2054
|
+
["merge-base", "--is-ancestor", localRef, remote],
|
|
2043
2055
|
repoPath,
|
|
2044
2056
|
{ reject: false }
|
|
2045
2057
|
);
|
|
@@ -2047,7 +2059,7 @@ async function fastForwardMainCheckoutIfSafe(repoPath, opts) {
|
|
|
2047
2059
|
return { updated: false, reason: "diverged" };
|
|
2048
2060
|
}
|
|
2049
2061
|
const behind = await git(
|
|
2050
|
-
["rev-list", "--count",
|
|
2062
|
+
["rev-list", "--count", `${localRef}..${remote}`],
|
|
2051
2063
|
repoPath,
|
|
2052
2064
|
{ reject: false }
|
|
2053
2065
|
);
|
|
@@ -2055,10 +2067,22 @@ async function fastForwardMainCheckoutIfSafe(repoPath, opts) {
|
|
|
2055
2067
|
if (behind.exitCode !== 0 || !Number.isFinite(n) || n <= 0) {
|
|
2056
2068
|
return { updated: false, reason: "already-current" };
|
|
2057
2069
|
}
|
|
2058
|
-
|
|
2070
|
+
if (checkout) {
|
|
2071
|
+
if (await isDirty(checkout.path)) {
|
|
2072
|
+
return { updated: false, reason: "dirty" };
|
|
2073
|
+
}
|
|
2074
|
+
const ff = await git(["merge", "--ff-only", remote], checkout.path, {
|
|
2075
|
+
reject: false
|
|
2076
|
+
});
|
|
2077
|
+
if (ff.exitCode !== 0) {
|
|
2078
|
+
return { updated: false, reason: "ff-failed" };
|
|
2079
|
+
}
|
|
2080
|
+
return { updated: true, reason: "updated" };
|
|
2081
|
+
}
|
|
2082
|
+
const moved = await git(["branch", "-f", branch, remote], repoPath, {
|
|
2059
2083
|
reject: false
|
|
2060
2084
|
});
|
|
2061
|
-
if (
|
|
2085
|
+
if (moved.exitCode !== 0) {
|
|
2062
2086
|
return { updated: false, reason: "ff-failed" };
|
|
2063
2087
|
}
|
|
2064
2088
|
return { updated: true, reason: "updated" };
|
|
@@ -8,11 +8,11 @@ import {
|
|
|
8
8
|
isGlobalThread,
|
|
9
9
|
isOrchestratorThread,
|
|
10
10
|
isSlackCoordinatorThread
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-ZRQWV3MS.js";
|
|
12
12
|
import {
|
|
13
13
|
mergeAgentGitAuthEnv,
|
|
14
14
|
resolveAgentGitAuthEnv
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-2VGLZIU6.js";
|
|
16
16
|
import {
|
|
17
17
|
allocateTeamName,
|
|
18
18
|
createEmptyThread,
|
|
@@ -1776,7 +1776,7 @@ var PORT_RANGE_SIZE = 10;
|
|
|
1776
1776
|
var RECLAIM_RETRY_DELAY_MS = 40;
|
|
1777
1777
|
var RECLAIM_TRIES = 8;
|
|
1778
1778
|
async function killReclaimable(ports, worktreePath, signal) {
|
|
1779
|
-
const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-
|
|
1779
|
+
const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-MAYZSFL6.js");
|
|
1780
1780
|
if (worktreePath) killStaleWorktreeListeners2(ports, worktreePath, signal);
|
|
1781
1781
|
else killListenersOnPorts2(ports);
|
|
1782
1782
|
}
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
parseSessionQuotaResetAt,
|
|
28
28
|
planModeTurnInstruction,
|
|
29
29
|
resolveQuotaFallbackAgent
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-RPCKGO3J.js";
|
|
31
31
|
import {
|
|
32
32
|
REVIEW_TAB_TITLE,
|
|
33
33
|
applyWorktreePkgCacheEnv,
|
|
@@ -66,7 +66,7 @@ import {
|
|
|
66
66
|
worktreeDevProcessKey,
|
|
67
67
|
worktreeRunProcessKey,
|
|
68
68
|
worktreeSetupProcessKey
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-WRDKJRWF.js";
|
|
70
70
|
import {
|
|
71
71
|
applyAgentEvent,
|
|
72
72
|
clipAgentEventForPaint,
|
|
@@ -118,7 +118,7 @@ import {
|
|
|
118
118
|
stageAbsolutePathsAsAttachments,
|
|
119
119
|
stageBuffersAsAttachments,
|
|
120
120
|
syncWorkspacesFromThreads
|
|
121
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-PO3PDNMV.js";
|
|
122
122
|
import {
|
|
123
123
|
addPrStackLayer,
|
|
124
124
|
allocateTeamSlug,
|
|
@@ -160,7 +160,7 @@ import {
|
|
|
160
160
|
resolveRepoRoot,
|
|
161
161
|
switchWorktreeBranch,
|
|
162
162
|
withRepoGitLock
|
|
163
|
-
} from "./chunk-
|
|
163
|
+
} from "./chunk-UO5C2L2G.js";
|
|
164
164
|
import {
|
|
165
165
|
clearStaleIndexLocks,
|
|
166
166
|
enrichPathWithNpmGlobalBin,
|
|
@@ -503,9 +503,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
503
503
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
504
504
|
);
|
|
505
505
|
}
|
|
506
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
506
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-CTFQDG7G.js");
|
|
507
507
|
if (isGlobalThread2(thread)) {
|
|
508
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
508
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-OZFKNCM3.js");
|
|
509
509
|
ensureGlobalCoordinatorCwd2(
|
|
510
510
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
511
511
|
);
|
|
@@ -3119,7 +3119,7 @@ async function adoptThread(input) {
|
|
|
3119
3119
|
messages: input.messages ?? []
|
|
3120
3120
|
});
|
|
3121
3121
|
writeThread(thread);
|
|
3122
|
-
const { addWorkspace: addWorkspace2 } = await import("./workspaces-
|
|
3122
|
+
const { addWorkspace: addWorkspace2 } = await import("./workspaces-QNKFBA63.js");
|
|
3123
3123
|
await addWorkspace2(repoPath);
|
|
3124
3124
|
const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-5N2KTYIT.js");
|
|
3125
3125
|
await ensureWorktreeSideboardIgnored(input.worktreePath);
|
|
@@ -5994,7 +5994,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
5994
5994
|
${prompt}`;
|
|
5995
5995
|
}
|
|
5996
5996
|
async function defaultDeps() {
|
|
5997
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
5997
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-4QVF6CE2.js");
|
|
5998
5998
|
const orch = getOrchestrator2();
|
|
5999
5999
|
return {
|
|
6000
6000
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -8866,7 +8866,7 @@ async function startOrchestration(opts) {
|
|
|
8866
8866
|
sourceRef: "default",
|
|
8867
8867
|
...createOpts
|
|
8868
8868
|
}).catch(async () => {
|
|
8869
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
8869
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-EMCWDPZJ.js");
|
|
8870
8870
|
const repo = await resolveRepoRoot2(repoPath);
|
|
8871
8871
|
const def = await resolveDefaultBranch2(repo);
|
|
8872
8872
|
return orch.createThread({
|