@sideboard-ai/core 0.1.38 → 0.1.41
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 +29 -12
- package/dist/agents/cursor-runner.js +29 -12
- package/dist/{agents-DDW4NBBW.js → agents-T6XHC5OV.js} +1 -1
- package/dist/{chunk-FVGRUZHI.js → chunk-44LYDJFB.js} +2 -2
- package/dist/{chunk-HYRHI3QU.js → chunk-5UIKSPDD.js} +3 -1
- package/dist/{chunk-IS3AGU33.js → chunk-6TZSJMXF.js} +3 -3
- package/dist/{chunk-BEXVE7LX.js → chunk-SX2R2PCE.js} +1 -1
- package/dist/{chunk-PTASB7SJ.js → chunk-UPMGXM4X.js} +1 -1
- package/dist/{chunk-XBEQI5H4.js → chunk-VA2U5EQH.js} +1 -1
- package/dist/{chunk-UKDAGGTU.js → chunk-WD35X6U5.js} +102 -36
- package/dist/{coordinator-prompt-WIYQVMOG.js → coordinator-prompt-FAILHO4J.js} +3 -3
- package/dist/cursor-recover-L5PNQUDT.js +42 -0
- package/dist/{global-workspace-QSRP25HQ.js → global-workspace-4GVWSCEX.js} +4 -4
- package/dist/index.cjs +195 -31
- package/dist/index.d.cts +45 -4
- package/dist/index.d.ts +45 -4
- package/dist/index.js +51 -7
- package/dist/mcp/run-stdio.cjs +143 -29
- package/dist/mcp/run-stdio.js +7 -7
- package/dist/{thread-store-UNPZNIFW.js → thread-store-WPLT3IXM.js} +1 -1
- package/dist/{workspaces-DMYWHVJC.js → workspaces-Z7CSL4O6.js} +5 -5
- package/dist/{worktree-37FBII5A.js → worktree-M3DTPYBW.js} +2 -2
- package/package.json +1 -1
|
@@ -198,18 +198,35 @@ async function main() {
|
|
|
198
198
|
const store = localAgentStore();
|
|
199
199
|
const local = { cwd: req.cwd, store };
|
|
200
200
|
try {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
201
|
+
let agent;
|
|
202
|
+
try {
|
|
203
|
+
agent = req.agentId ? await import_sdk.Agent.resume(req.agentId, {
|
|
204
|
+
apiKey,
|
|
205
|
+
model,
|
|
206
|
+
mode,
|
|
207
|
+
local
|
|
208
|
+
}) : await import_sdk.Agent.create({
|
|
209
|
+
apiKey,
|
|
210
|
+
model,
|
|
211
|
+
mode,
|
|
212
|
+
local,
|
|
213
|
+
name: "Sideboard"
|
|
214
|
+
});
|
|
215
|
+
} catch (err) {
|
|
216
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
217
|
+
if (!req.agentId || !/not found/i.test(message)) throw err;
|
|
218
|
+
emit({
|
|
219
|
+
type: "stderr",
|
|
220
|
+
data: `Cursor agent ${req.agentId} not found \u2014 starting a new session`
|
|
221
|
+
});
|
|
222
|
+
agent = await import_sdk.Agent.create({
|
|
223
|
+
apiKey,
|
|
224
|
+
model,
|
|
225
|
+
mode,
|
|
226
|
+
local,
|
|
227
|
+
name: "Sideboard"
|
|
228
|
+
});
|
|
229
|
+
}
|
|
213
230
|
try {
|
|
214
231
|
emit({ type: "session_id", data: agent.agentId });
|
|
215
232
|
const run = await agent.send(req.prompt);
|
|
@@ -62,18 +62,35 @@ async function main() {
|
|
|
62
62
|
const store = localAgentStore();
|
|
63
63
|
const local = { cwd: req.cwd, store };
|
|
64
64
|
try {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
65
|
+
let agent;
|
|
66
|
+
try {
|
|
67
|
+
agent = req.agentId ? await Agent.resume(req.agentId, {
|
|
68
|
+
apiKey,
|
|
69
|
+
model,
|
|
70
|
+
mode,
|
|
71
|
+
local
|
|
72
|
+
}) : await Agent.create({
|
|
73
|
+
apiKey,
|
|
74
|
+
model,
|
|
75
|
+
mode,
|
|
76
|
+
local,
|
|
77
|
+
name: "Sideboard"
|
|
78
|
+
});
|
|
79
|
+
} catch (err) {
|
|
80
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
81
|
+
if (!req.agentId || !/not found/i.test(message)) throw err;
|
|
82
|
+
emit({
|
|
83
|
+
type: "stderr",
|
|
84
|
+
data: `Cursor agent ${req.agentId} not found \u2014 starting a new session`
|
|
85
|
+
});
|
|
86
|
+
agent = await Agent.create({
|
|
87
|
+
apiKey,
|
|
88
|
+
model,
|
|
89
|
+
mode,
|
|
90
|
+
local,
|
|
91
|
+
name: "Sideboard"
|
|
92
|
+
});
|
|
93
|
+
}
|
|
77
94
|
try {
|
|
78
95
|
emit({ type: "session_id", data: agent.agentId });
|
|
79
96
|
const run = await agent.send(req.prompt);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isGlobalRepoPath
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6TZSJMXF.js";
|
|
4
4
|
import {
|
|
5
5
|
ensureGhPreferOrigin,
|
|
6
6
|
resolveRepoRoot
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-VA2U5EQH.js";
|
|
8
8
|
import {
|
|
9
9
|
appDataDir
|
|
10
10
|
} from "./chunk-M37RITA6.js";
|
|
@@ -26,6 +26,7 @@ function normalizeThread(raw) {
|
|
|
26
26
|
planMode: Boolean(raw.planMode),
|
|
27
27
|
autonomy: raw.autonomy ?? "default",
|
|
28
28
|
lastError: raw.lastError ?? null,
|
|
29
|
+
agentPid: raw.agentPid ?? null,
|
|
29
30
|
attachments: Array.isArray(raw.attachments) ? raw.attachments : [],
|
|
30
31
|
prTitle: raw.prTitle ?? null,
|
|
31
32
|
userSetTitle: Boolean(raw.userSetTitle),
|
|
@@ -61,7 +62,8 @@ function createEmptyThread(partial) {
|
|
|
61
62
|
worktreePath: partial.worktreePath,
|
|
62
63
|
repoPath: partial.repoPath,
|
|
63
64
|
agent: partial.agent,
|
|
64
|
-
lastError: null
|
|
65
|
+
lastError: null,
|
|
66
|
+
agentPid: null
|
|
65
67
|
};
|
|
66
68
|
}
|
|
67
69
|
async function withThreadLock(id, fn) {
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureGlobalCoordinatorCwd
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-UPMGXM4X.js";
|
|
4
4
|
import {
|
|
5
5
|
allocateTeamName,
|
|
6
6
|
takenSlugsFromThread,
|
|
7
7
|
teamSlugFromName
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-VA2U5EQH.js";
|
|
9
9
|
import {
|
|
10
10
|
createEmptyThread,
|
|
11
11
|
listThreads,
|
|
12
12
|
updateThread,
|
|
13
13
|
writeThread
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-5UIKSPDD.js";
|
|
15
15
|
import {
|
|
16
16
|
globalAgentCwd
|
|
17
17
|
} from "./chunk-M37RITA6.js";
|
|
@@ -798,7 +798,7 @@ var claudeAdapter = {
|
|
|
798
798
|
);
|
|
799
799
|
}
|
|
800
800
|
const mode = permissionMode(thread);
|
|
801
|
-
const { isOrchestratorThread } = await import("./global-workspace-
|
|
801
|
+
const { isOrchestratorThread } = await import("./global-workspace-4GVWSCEX.js");
|
|
802
802
|
const isOrchestrator = isOrchestratorThread(thread);
|
|
803
803
|
const injectedServers = await buildInjectedMcpServers({
|
|
804
804
|
includeSideboard: true,
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
ensureWorkspace,
|
|
4
4
|
removeWorkspace,
|
|
5
5
|
syncWorkspacesFromThreads
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-44LYDJFB.js";
|
|
7
7
|
import {
|
|
8
8
|
GLOBAL_WORKSPACE_ID,
|
|
9
9
|
createGlobalChat,
|
|
@@ -13,19 +13,19 @@ import {
|
|
|
13
13
|
isGlobalThread,
|
|
14
14
|
isOrchestratorThread,
|
|
15
15
|
orchestratorSessionPoisonedByBuiltins
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-6TZSJMXF.js";
|
|
17
17
|
import {
|
|
18
18
|
coordinatorSystemPrompt,
|
|
19
19
|
coordinatorTurnReminder,
|
|
20
20
|
enrichWorkspacesWithGithub,
|
|
21
21
|
ensureGlobalCoordinatorCwd
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-UPMGXM4X.js";
|
|
23
23
|
import {
|
|
24
24
|
PLAN_MODE_INSTRUCTION,
|
|
25
25
|
allAdapters,
|
|
26
26
|
getAdapter,
|
|
27
27
|
parseBrightsyCliLine
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-SX2R2PCE.js";
|
|
29
29
|
import {
|
|
30
30
|
fallbackTurnFailDetail,
|
|
31
31
|
formatTurnExitError,
|
|
@@ -71,7 +71,7 @@ import {
|
|
|
71
71
|
takenSlugsFromThread,
|
|
72
72
|
threadDisplayLabel,
|
|
73
73
|
worktreeNameFromPath
|
|
74
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-VA2U5EQH.js";
|
|
75
75
|
import {
|
|
76
76
|
appendMessage,
|
|
77
77
|
createEmptyThread,
|
|
@@ -83,7 +83,7 @@ import {
|
|
|
83
83
|
updateThread,
|
|
84
84
|
withThreadLock,
|
|
85
85
|
writeThread
|
|
86
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-5UIKSPDD.js";
|
|
87
87
|
import {
|
|
88
88
|
loadRepoSettings,
|
|
89
89
|
loadWorkspaceSettings,
|
|
@@ -311,12 +311,20 @@ function diffFromInput(input) {
|
|
|
311
311
|
}
|
|
312
312
|
function parseDiffStat(result) {
|
|
313
313
|
if (!result) return {};
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
if (plus || minus) {
|
|
314
|
+
const paired = result.match(/\+(\d+)\s+-(\d+)/);
|
|
315
|
+
if (paired) {
|
|
317
316
|
return {
|
|
318
|
-
additions:
|
|
319
|
-
deletions:
|
|
317
|
+
additions: Number(paired[1]),
|
|
318
|
+
deletions: Number(paired[2])
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
const verbose = result.match(
|
|
322
|
+
/(\d+)\s+insertions?(?:,\s*(\d+)\s+deletions?)?/i
|
|
323
|
+
);
|
|
324
|
+
if (verbose) {
|
|
325
|
+
return {
|
|
326
|
+
additions: Number(verbose[1]),
|
|
327
|
+
deletions: verbose[2] != null ? Number(verbose[2]) : void 0
|
|
320
328
|
};
|
|
321
329
|
}
|
|
322
330
|
return {};
|
|
@@ -388,8 +396,8 @@ function applyAgentEvent(parts, event) {
|
|
|
388
396
|
...p,
|
|
389
397
|
status: event.isError ? "error" : "done",
|
|
390
398
|
result: event.content,
|
|
391
|
-
additions: fromResult.additions
|
|
392
|
-
deletions: fromResult.deletions
|
|
399
|
+
...fromResult.additions != null ? { additions: fromResult.additions } : {},
|
|
400
|
+
...fromResult.deletions != null ? { deletions: fromResult.deletions } : {}
|
|
393
401
|
};
|
|
394
402
|
});
|
|
395
403
|
return next;
|
|
@@ -451,9 +459,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
451
459
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
452
460
|
);
|
|
453
461
|
}
|
|
454
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
462
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-4GVWSCEX.js");
|
|
455
463
|
if (isGlobalThread2(thread)) {
|
|
456
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
464
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-FAILHO4J.js");
|
|
457
465
|
ensureGlobalCoordinatorCwd2();
|
|
458
466
|
}
|
|
459
467
|
const adapter = getAdapter(thread.agent);
|
|
@@ -2606,7 +2614,7 @@ async function createThread(input, onSetupLine) {
|
|
|
2606
2614
|
return readThread(thread.id) ?? thread;
|
|
2607
2615
|
}
|
|
2608
2616
|
async function listLinearIssues(agent, repoPath) {
|
|
2609
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
2617
|
+
const { getAdapter: getAdapter2 } = await import("./agents-T6XHC5OV.js");
|
|
2610
2618
|
await requireAgent(agent, { requireLinear: true });
|
|
2611
2619
|
const adapter = getAdapter2(agent);
|
|
2612
2620
|
if (!adapter.listLinearIssues) {
|
|
@@ -2826,7 +2834,7 @@ async function adoptThread(input) {
|
|
|
2826
2834
|
messages: input.messages ?? []
|
|
2827
2835
|
});
|
|
2828
2836
|
writeThread(thread);
|
|
2829
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
2837
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-Z7CSL4O6.js");
|
|
2830
2838
|
await ensureWorkspace2(repoPath);
|
|
2831
2839
|
return thread;
|
|
2832
2840
|
}
|
|
@@ -3288,6 +3296,15 @@ async function syncThreadBranchFromGit(threadId) {
|
|
|
3288
3296
|
}
|
|
3289
3297
|
|
|
3290
3298
|
// src/orchestrator/orchestrator.ts
|
|
3299
|
+
function isPidAlive(pid) {
|
|
3300
|
+
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
3301
|
+
try {
|
|
3302
|
+
process.kill(pid, 0);
|
|
3303
|
+
return true;
|
|
3304
|
+
} catch {
|
|
3305
|
+
return false;
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3291
3308
|
var Orchestrator = class {
|
|
3292
3309
|
events = new EventEmitter();
|
|
3293
3310
|
processes = /* @__PURE__ */ new Map();
|
|
@@ -3324,8 +3341,18 @@ var Orchestrator = class {
|
|
|
3324
3341
|
isStaleRunningThread(threadId, status) {
|
|
3325
3342
|
return status === "running" && !this.activeTurns.has(threadId) && !this.startingTurns.has(threadId);
|
|
3326
3343
|
}
|
|
3344
|
+
/**
|
|
3345
|
+
* Cross-process guard: another Sideboard process (MCP stdio) may call reconcile
|
|
3346
|
+
* while the desktop still owns a live agent child. Never reclaim those.
|
|
3347
|
+
*/
|
|
3348
|
+
shouldReclaimRunningThread(thread) {
|
|
3349
|
+
if (!this.isStaleRunningThread(thread.id, thread.status)) return false;
|
|
3350
|
+
const pid = thread.agentPid;
|
|
3351
|
+
if (typeof pid === "number" && pid > 0 && isPidAlive(pid)) return false;
|
|
3352
|
+
return true;
|
|
3353
|
+
}
|
|
3327
3354
|
async reconcile(repoPath, opts) {
|
|
3328
|
-
const reclaimStaleTurns = opts?.reclaimStaleTurns
|
|
3355
|
+
const reclaimStaleTurns = opts?.reclaimStaleTurns === true;
|
|
3329
3356
|
healOrchestrationSoccerTitles();
|
|
3330
3357
|
for (const thread of listThreads({ includeArchived: true })) {
|
|
3331
3358
|
if (thread.status === "archived") continue;
|
|
@@ -3341,7 +3368,7 @@ var Orchestrator = class {
|
|
|
3341
3368
|
if (Object.keys(heal).length) {
|
|
3342
3369
|
updateThread(thread.id, heal);
|
|
3343
3370
|
}
|
|
3344
|
-
if (reclaimStaleTurns && this.
|
|
3371
|
+
if (reclaimStaleTurns && this.shouldReclaimRunningThread(thread)) {
|
|
3345
3372
|
setStatus(thread.id, "stopped", "Process died (reconciled on startup)");
|
|
3346
3373
|
this.emit({ type: "status_changed", threadId: thread.id, status: "stopped" });
|
|
3347
3374
|
}
|
|
@@ -3352,7 +3379,7 @@ var Orchestrator = class {
|
|
|
3352
3379
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
3353
3380
|
continue;
|
|
3354
3381
|
}
|
|
3355
|
-
if (reclaimStaleTurns && this.
|
|
3382
|
+
if (reclaimStaleTurns && this.shouldReclaimRunningThread(thread)) {
|
|
3356
3383
|
setStatus(thread.id, "stopped", "Process died (reconciled on startup)");
|
|
3357
3384
|
this.emit({ type: "status_changed", threadId: thread.id, status: "stopped" });
|
|
3358
3385
|
}
|
|
@@ -3534,6 +3561,11 @@ var Orchestrator = class {
|
|
|
3534
3561
|
await new Promise((r) => setTimeout(r, 100));
|
|
3535
3562
|
continue;
|
|
3536
3563
|
}
|
|
3564
|
+
const livePid = thread.agentPid;
|
|
3565
|
+
if (typeof livePid === "number" && livePid > 0 && isPidAlive(livePid)) {
|
|
3566
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
3567
|
+
continue;
|
|
3568
|
+
}
|
|
3537
3569
|
const prompt = thread.queue[0];
|
|
3538
3570
|
const remaining = thread.queue.slice(1);
|
|
3539
3571
|
updateThread(threadId, { queue: remaining });
|
|
@@ -3677,10 +3709,18 @@ var Orchestrator = class {
|
|
|
3677
3709
|
if (event.type === "stderr" && typeof event.data === "string") {
|
|
3678
3710
|
pushTurnStderr(stderrTail, event.data);
|
|
3679
3711
|
}
|
|
3712
|
+
const live = readThread(threadId);
|
|
3713
|
+
if (live?.lastError?.includes("reconciled on startup") && (this.activeTurns.has(threadId) || this.startingTurns.has(threadId))) {
|
|
3714
|
+
setStatus(threadId, "running");
|
|
3715
|
+
this.emit({ type: "status_changed", threadId, status: "running" });
|
|
3716
|
+
}
|
|
3680
3717
|
}
|
|
3681
3718
|
);
|
|
3682
3719
|
this.activeTurns.set(threadId, handle);
|
|
3683
3720
|
this.startingTurns.delete(threadId);
|
|
3721
|
+
if (typeof handle.pid === "number" && handle.pid > 0) {
|
|
3722
|
+
updateThread(threadId, { agentPid: handle.pid });
|
|
3723
|
+
}
|
|
3684
3724
|
if (this.stoppedTurns.has(threadId)) {
|
|
3685
3725
|
handle.kill();
|
|
3686
3726
|
} else {
|
|
@@ -3700,20 +3740,41 @@ var Orchestrator = class {
|
|
|
3700
3740
|
if (result.sessionId) {
|
|
3701
3741
|
updateThread(threadId, { sessionId: result.sessionId });
|
|
3702
3742
|
}
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3743
|
+
let assistantText = result.assistantText.trim();
|
|
3744
|
+
let parts = result.parts;
|
|
3745
|
+
let usage = result.usage ?? void 0;
|
|
3746
|
+
let exitCode = result.exitCode;
|
|
3747
|
+
if (this.requireThread(threadId).agent === "cursor" && exitCode !== 0 && !assistantText && parts.length === 0) {
|
|
3748
|
+
const sessionId = result.sessionId || this.requireThread(threadId).sessionId || "";
|
|
3749
|
+
if (sessionId) {
|
|
3750
|
+
const { recoverFinishedCursorRun } = await import("./cursor-recover-L5PNQUDT.js");
|
|
3751
|
+
for (let i = 0; i < 8; i++) {
|
|
3752
|
+
const recovered = recoverFinishedCursorRun({
|
|
3753
|
+
agentId: sessionId,
|
|
3754
|
+
startedAfterMs: turnStartedAt - 5e3
|
|
3755
|
+
});
|
|
3756
|
+
if (recovered?.result) {
|
|
3757
|
+
assistantText = recovered.result;
|
|
3758
|
+
exitCode = 0;
|
|
3759
|
+
break;
|
|
3760
|
+
}
|
|
3761
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
3762
|
+
}
|
|
3763
|
+
}
|
|
3764
|
+
}
|
|
3765
|
+
const failureOnlyMessage = exitCode !== 0 && looksLikeAgentFailureMessage(assistantText) && !parts.some((p) => p.type === "tool" || p.type === "thinking");
|
|
3766
|
+
if (!failureOnlyMessage && (assistantText || parts.length > 0)) {
|
|
3706
3767
|
appendMessage(threadId, {
|
|
3707
3768
|
role: "agent",
|
|
3708
3769
|
text: assistantText,
|
|
3709
|
-
parts:
|
|
3770
|
+
parts: parts.length > 0 ? parts : void 0,
|
|
3710
3771
|
durationMs: Math.max(0, Date.now() - turnStartedAt),
|
|
3711
|
-
usage
|
|
3772
|
+
usage,
|
|
3712
3773
|
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
3713
3774
|
});
|
|
3714
3775
|
}
|
|
3715
3776
|
const afterTurn = this.requireThread(threadId);
|
|
3716
|
-
if (afterTurn.planMode && afterTurn.agent === "claude" &&
|
|
3777
|
+
if (afterTurn.planMode && afterTurn.agent === "claude" && parts.some(
|
|
3717
3778
|
(p) => p.type === "tool" && /exitplanmode/i.test(p.name)
|
|
3718
3779
|
)) {
|
|
3719
3780
|
updateThread(threadId, { sessionId: null });
|
|
@@ -3722,22 +3783,22 @@ var Orchestrator = class {
|
|
|
3722
3783
|
if (this.stoppedTurns.has(threadId)) {
|
|
3723
3784
|
setStatus(threadId, "stopped");
|
|
3724
3785
|
this.emit({ type: "status_changed", threadId, status: "stopped" });
|
|
3725
|
-
this.emit({ type: "turn_finished", threadId, exitCode
|
|
3786
|
+
this.emit({ type: "turn_finished", threadId, exitCode });
|
|
3726
3787
|
} else {
|
|
3727
3788
|
const lastStderr = summarizeTurnStderr(stderrTail);
|
|
3728
|
-
const detail = lastStderr || (
|
|
3729
|
-
const failDetail = formatTurnExitError(
|
|
3789
|
+
const detail = lastStderr || (exitCode !== 0 ? fallbackTurnFailDetail(assistantText) : "");
|
|
3790
|
+
const failDetail = formatTurnExitError(exitCode, detail);
|
|
3730
3791
|
setStatus(
|
|
3731
3792
|
threadId,
|
|
3732
|
-
|
|
3733
|
-
|
|
3793
|
+
exitCode === 0 ? "idle" : "error",
|
|
3794
|
+
exitCode === 0 ? null : failDetail
|
|
3734
3795
|
);
|
|
3735
3796
|
this.emit({
|
|
3736
3797
|
type: "status_changed",
|
|
3737
3798
|
threadId,
|
|
3738
|
-
status:
|
|
3799
|
+
status: exitCode === 0 ? "idle" : "error"
|
|
3739
3800
|
});
|
|
3740
|
-
this.emit({ type: "turn_finished", threadId, exitCode
|
|
3801
|
+
this.emit({ type: "turn_finished", threadId, exitCode });
|
|
3741
3802
|
}
|
|
3742
3803
|
} catch (err) {
|
|
3743
3804
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -3758,6 +3819,10 @@ var Orchestrator = class {
|
|
|
3758
3819
|
this.processes.delete(`${threadId}:agent`);
|
|
3759
3820
|
this.stoppedTurns.delete(threadId);
|
|
3760
3821
|
this.runningCount = Math.max(0, this.runningCount - 1);
|
|
3822
|
+
try {
|
|
3823
|
+
updateThread(threadId, { agentPid: null });
|
|
3824
|
+
} catch {
|
|
3825
|
+
}
|
|
3761
3826
|
}
|
|
3762
3827
|
}
|
|
3763
3828
|
/**
|
|
@@ -4331,7 +4396,7 @@ var Orchestrator = class {
|
|
|
4331
4396
|
return setStatus(thread.id, "idle");
|
|
4332
4397
|
}
|
|
4333
4398
|
if (!existsSync11(thread.worktreePath)) {
|
|
4334
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
4399
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-M3DTPYBW.js");
|
|
4335
4400
|
const { execa: execa6 } = await import("execa");
|
|
4336
4401
|
const slug = thread.worktreePath.split("/").pop();
|
|
4337
4402
|
const dest = thread.worktreePath;
|
|
@@ -4414,7 +4479,7 @@ async function startOrchestration(opts) {
|
|
|
4414
4479
|
sourceRef: "default",
|
|
4415
4480
|
...createOpts
|
|
4416
4481
|
}).catch(async () => {
|
|
4417
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
4482
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-M3DTPYBW.js");
|
|
4418
4483
|
const repo = await resolveRepoRoot2(repoPath);
|
|
4419
4484
|
const def = await resolveDefaultBranch2(repo);
|
|
4420
4485
|
return createThread({
|
|
@@ -4424,7 +4489,7 @@ async function startOrchestration(opts) {
|
|
|
4424
4489
|
repoPath: repo
|
|
4425
4490
|
});
|
|
4426
4491
|
});
|
|
4427
|
-
const { updateThread: upd } = await import("./thread-store-
|
|
4492
|
+
const { updateThread: upd } = await import("./thread-store-WPLT3IXM.js");
|
|
4428
4493
|
const updated = upd(thread.id, {
|
|
4429
4494
|
sourceType: "orchestration",
|
|
4430
4495
|
sourceRef: goal
|
|
@@ -5107,6 +5172,7 @@ export {
|
|
|
5107
5172
|
worktreeCleanupSettings,
|
|
5108
5173
|
applyThreadIntoMain,
|
|
5109
5174
|
cloneRepoIntoSideboard,
|
|
5175
|
+
isPidAlive,
|
|
5110
5176
|
Orchestrator,
|
|
5111
5177
|
getOrchestrator,
|
|
5112
5178
|
startOrchestration,
|
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
enrichWorkspacesWithGithub,
|
|
7
7
|
ensureGlobalCoordinatorCwd,
|
|
8
8
|
formatWorkspaceInventory
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-UPMGXM4X.js";
|
|
10
|
+
import "./chunk-VA2U5EQH.js";
|
|
11
|
+
import "./chunk-5UIKSPDD.js";
|
|
12
12
|
import "./chunk-M37RITA6.js";
|
|
13
13
|
import "./chunk-AJ6ROGD7.js";
|
|
14
14
|
export {
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {
|
|
2
|
+
appDataDir
|
|
3
|
+
} from "./chunk-M37RITA6.js";
|
|
4
|
+
|
|
5
|
+
// src/agents/cursor-recover.ts
|
|
6
|
+
import { existsSync, readFileSync } from "fs";
|
|
7
|
+
import { join } from "path";
|
|
8
|
+
function recoverFinishedCursorRun(opts) {
|
|
9
|
+
const agentId = opts.agentId.trim();
|
|
10
|
+
if (!agentId) return null;
|
|
11
|
+
const runsPath = join(appDataDir(), "cursor-sdk-store", "runs.ndjson");
|
|
12
|
+
if (!existsSync(runsPath)) return null;
|
|
13
|
+
try {
|
|
14
|
+
const lines = readFileSync(runsPath, "utf8").split("\n");
|
|
15
|
+
let best = null;
|
|
16
|
+
for (const line of lines) {
|
|
17
|
+
const trimmed = line.trim();
|
|
18
|
+
if (!trimmed) continue;
|
|
19
|
+
let row;
|
|
20
|
+
try {
|
|
21
|
+
row = JSON.parse(trimmed);
|
|
22
|
+
} catch {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (row.agentId !== agentId) continue;
|
|
26
|
+
if (row.status !== "finished") continue;
|
|
27
|
+
if (typeof row.result !== "string" || !row.result.trim()) continue;
|
|
28
|
+
const endedAt = typeof row.endedAt === "number" ? row.endedAt : 0;
|
|
29
|
+
const createdAt = typeof row.createdAt === "number" ? row.createdAt : 0;
|
|
30
|
+
if (createdAt < opts.startedAfterMs && endedAt < opts.startedAfterMs) continue;
|
|
31
|
+
if (!best || endedAt >= best.endedAt) {
|
|
32
|
+
best = { runId: row.runId || "", result: row.result.trim(), endedAt };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return best;
|
|
36
|
+
} catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
recoverFinishedCursorRun
|
|
42
|
+
};
|
|
@@ -11,10 +11,10 @@ import {
|
|
|
11
11
|
orchestrationTitleNeedsSoccerNickname,
|
|
12
12
|
orchestratorSessionPoisonedByBuiltins,
|
|
13
13
|
takenTeamSlugsForOrchestration
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
14
|
+
} from "./chunk-6TZSJMXF.js";
|
|
15
|
+
import "./chunk-UPMGXM4X.js";
|
|
16
|
+
import "./chunk-VA2U5EQH.js";
|
|
17
|
+
import "./chunk-5UIKSPDD.js";
|
|
18
18
|
import {
|
|
19
19
|
globalAgentCwd
|
|
20
20
|
} from "./chunk-M37RITA6.js";
|