@sideboard-ai/core 0.1.39 → 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-2YFQNL3O.js → chunk-WD35X6U5.js} +87 -29
- 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 +130 -22
- package/dist/index.d.cts +18 -4
- package/dist/index.d.ts +18 -4
- package/dist/index.js +9 -7
- package/dist/mcp/run-stdio.cjs +128 -22
- 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
package/dist/mcp/run-stdio.cjs
CHANGED
|
@@ -443,6 +443,7 @@ function normalizeThread(raw) {
|
|
|
443
443
|
planMode: Boolean(raw.planMode),
|
|
444
444
|
autonomy: raw.autonomy ?? "default",
|
|
445
445
|
lastError: raw.lastError ?? null,
|
|
446
|
+
agentPid: raw.agentPid ?? null,
|
|
446
447
|
attachments: Array.isArray(raw.attachments) ? raw.attachments : [],
|
|
447
448
|
prTitle: raw.prTitle ?? null,
|
|
448
449
|
userSetTitle: Boolean(raw.userSetTitle),
|
|
@@ -478,7 +479,8 @@ function createEmptyThread(partial) {
|
|
|
478
479
|
worktreePath: partial.worktreePath,
|
|
479
480
|
repoPath: partial.repoPath,
|
|
480
481
|
agent: partial.agent,
|
|
481
|
-
lastError: null
|
|
482
|
+
lastError: null,
|
|
483
|
+
agentPid: null
|
|
482
484
|
};
|
|
483
485
|
}
|
|
484
486
|
async function withThreadLock(id, fn) {
|
|
@@ -5615,15 +5617,62 @@ var init_workspaces = __esm({
|
|
|
5615
5617
|
}
|
|
5616
5618
|
});
|
|
5617
5619
|
|
|
5620
|
+
// src/agents/cursor-recover.ts
|
|
5621
|
+
var cursor_recover_exports = {};
|
|
5622
|
+
__export(cursor_recover_exports, {
|
|
5623
|
+
recoverFinishedCursorRun: () => recoverFinishedCursorRun
|
|
5624
|
+
});
|
|
5625
|
+
function recoverFinishedCursorRun(opts) {
|
|
5626
|
+
const agentId = opts.agentId.trim();
|
|
5627
|
+
if (!agentId) return null;
|
|
5628
|
+
const runsPath = (0, import_node_path23.join)(appDataDir(), "cursor-sdk-store", "runs.ndjson");
|
|
5629
|
+
if (!(0, import_node_fs24.existsSync)(runsPath)) return null;
|
|
5630
|
+
try {
|
|
5631
|
+
const lines = (0, import_node_fs24.readFileSync)(runsPath, "utf8").split("\n");
|
|
5632
|
+
let best = null;
|
|
5633
|
+
for (const line of lines) {
|
|
5634
|
+
const trimmed = line.trim();
|
|
5635
|
+
if (!trimmed) continue;
|
|
5636
|
+
let row;
|
|
5637
|
+
try {
|
|
5638
|
+
row = JSON.parse(trimmed);
|
|
5639
|
+
} catch {
|
|
5640
|
+
continue;
|
|
5641
|
+
}
|
|
5642
|
+
if (row.agentId !== agentId) continue;
|
|
5643
|
+
if (row.status !== "finished") continue;
|
|
5644
|
+
if (typeof row.result !== "string" || !row.result.trim()) continue;
|
|
5645
|
+
const endedAt = typeof row.endedAt === "number" ? row.endedAt : 0;
|
|
5646
|
+
const createdAt = typeof row.createdAt === "number" ? row.createdAt : 0;
|
|
5647
|
+
if (createdAt < opts.startedAfterMs && endedAt < opts.startedAfterMs) continue;
|
|
5648
|
+
if (!best || endedAt >= best.endedAt) {
|
|
5649
|
+
best = { runId: row.runId || "", result: row.result.trim(), endedAt };
|
|
5650
|
+
}
|
|
5651
|
+
}
|
|
5652
|
+
return best;
|
|
5653
|
+
} catch {
|
|
5654
|
+
return null;
|
|
5655
|
+
}
|
|
5656
|
+
}
|
|
5657
|
+
var import_node_fs24, import_node_path23;
|
|
5658
|
+
var init_cursor_recover = __esm({
|
|
5659
|
+
"src/agents/cursor-recover.ts"() {
|
|
5660
|
+
"use strict";
|
|
5661
|
+
import_node_fs24 = require("fs");
|
|
5662
|
+
import_node_path23 = require("path");
|
|
5663
|
+
init_paths();
|
|
5664
|
+
}
|
|
5665
|
+
});
|
|
5666
|
+
|
|
5618
5667
|
// src/mcp/server.ts
|
|
5619
5668
|
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
5620
5669
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
5621
5670
|
var import_zod = require("zod");
|
|
5622
|
-
var
|
|
5671
|
+
var import_node_path24 = require("path");
|
|
5623
5672
|
|
|
5624
5673
|
// src/orchestrator/orchestrator.ts
|
|
5625
5674
|
var import_node_events = require("events");
|
|
5626
|
-
var
|
|
5675
|
+
var import_node_fs25 = require("fs");
|
|
5627
5676
|
init_error_detail();
|
|
5628
5677
|
|
|
5629
5678
|
// src/agents/spawn.ts
|
|
@@ -8677,6 +8726,15 @@ async function syncThreadBranchFromGit(threadId) {
|
|
|
8677
8726
|
init_workspaces();
|
|
8678
8727
|
init_global_workspace();
|
|
8679
8728
|
init_coordinator_prompt();
|
|
8729
|
+
function isPidAlive(pid) {
|
|
8730
|
+
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
8731
|
+
try {
|
|
8732
|
+
process.kill(pid, 0);
|
|
8733
|
+
return true;
|
|
8734
|
+
} catch {
|
|
8735
|
+
return false;
|
|
8736
|
+
}
|
|
8737
|
+
}
|
|
8680
8738
|
var Orchestrator = class {
|
|
8681
8739
|
events = new import_node_events.EventEmitter();
|
|
8682
8740
|
processes = /* @__PURE__ */ new Map();
|
|
@@ -8713,8 +8771,18 @@ var Orchestrator = class {
|
|
|
8713
8771
|
isStaleRunningThread(threadId, status) {
|
|
8714
8772
|
return status === "running" && !this.activeTurns.has(threadId) && !this.startingTurns.has(threadId);
|
|
8715
8773
|
}
|
|
8774
|
+
/**
|
|
8775
|
+
* Cross-process guard: another Sideboard process (MCP stdio) may call reconcile
|
|
8776
|
+
* while the desktop still owns a live agent child. Never reclaim those.
|
|
8777
|
+
*/
|
|
8778
|
+
shouldReclaimRunningThread(thread) {
|
|
8779
|
+
if (!this.isStaleRunningThread(thread.id, thread.status)) return false;
|
|
8780
|
+
const pid = thread.agentPid;
|
|
8781
|
+
if (typeof pid === "number" && pid > 0 && isPidAlive(pid)) return false;
|
|
8782
|
+
return true;
|
|
8783
|
+
}
|
|
8716
8784
|
async reconcile(repoPath, opts) {
|
|
8717
|
-
const reclaimStaleTurns = opts?.reclaimStaleTurns
|
|
8785
|
+
const reclaimStaleTurns = opts?.reclaimStaleTurns === true;
|
|
8718
8786
|
healOrchestrationSoccerTitles();
|
|
8719
8787
|
for (const thread of listThreads({ includeArchived: true })) {
|
|
8720
8788
|
if (thread.status === "archived") continue;
|
|
@@ -8730,18 +8798,18 @@ var Orchestrator = class {
|
|
|
8730
8798
|
if (Object.keys(heal).length) {
|
|
8731
8799
|
updateThread(thread.id, heal);
|
|
8732
8800
|
}
|
|
8733
|
-
if (reclaimStaleTurns && this.
|
|
8801
|
+
if (reclaimStaleTurns && this.shouldReclaimRunningThread(thread)) {
|
|
8734
8802
|
setStatus(thread.id, "stopped", "Process died (reconciled on startup)");
|
|
8735
8803
|
this.emit({ type: "status_changed", threadId: thread.id, status: "stopped" });
|
|
8736
8804
|
}
|
|
8737
8805
|
continue;
|
|
8738
8806
|
}
|
|
8739
|
-
if (!(0,
|
|
8807
|
+
if (!(0, import_node_fs25.existsSync)(thread.worktreePath)) {
|
|
8740
8808
|
setStatus(thread.id, "broken", "Worktree missing on disk");
|
|
8741
8809
|
this.emit({ type: "status_changed", threadId: thread.id, status: "broken" });
|
|
8742
8810
|
continue;
|
|
8743
8811
|
}
|
|
8744
|
-
if (reclaimStaleTurns && this.
|
|
8812
|
+
if (reclaimStaleTurns && this.shouldReclaimRunningThread(thread)) {
|
|
8745
8813
|
setStatus(thread.id, "stopped", "Process died (reconciled on startup)");
|
|
8746
8814
|
this.emit({ type: "status_changed", threadId: thread.id, status: "stopped" });
|
|
8747
8815
|
}
|
|
@@ -8923,6 +8991,11 @@ var Orchestrator = class {
|
|
|
8923
8991
|
await new Promise((r) => setTimeout(r, 100));
|
|
8924
8992
|
continue;
|
|
8925
8993
|
}
|
|
8994
|
+
const livePid = thread.agentPid;
|
|
8995
|
+
if (typeof livePid === "number" && livePid > 0 && isPidAlive(livePid)) {
|
|
8996
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
8997
|
+
continue;
|
|
8998
|
+
}
|
|
8926
8999
|
const prompt = thread.queue[0];
|
|
8927
9000
|
const remaining = thread.queue.slice(1);
|
|
8928
9001
|
updateThread(threadId, { queue: remaining });
|
|
@@ -9066,10 +9139,18 @@ var Orchestrator = class {
|
|
|
9066
9139
|
if (event.type === "stderr" && typeof event.data === "string") {
|
|
9067
9140
|
pushTurnStderr(stderrTail, event.data);
|
|
9068
9141
|
}
|
|
9142
|
+
const live = readThread(threadId);
|
|
9143
|
+
if (live?.lastError?.includes("reconciled on startup") && (this.activeTurns.has(threadId) || this.startingTurns.has(threadId))) {
|
|
9144
|
+
setStatus(threadId, "running");
|
|
9145
|
+
this.emit({ type: "status_changed", threadId, status: "running" });
|
|
9146
|
+
}
|
|
9069
9147
|
}
|
|
9070
9148
|
);
|
|
9071
9149
|
this.activeTurns.set(threadId, handle);
|
|
9072
9150
|
this.startingTurns.delete(threadId);
|
|
9151
|
+
if (typeof handle.pid === "number" && handle.pid > 0) {
|
|
9152
|
+
updateThread(threadId, { agentPid: handle.pid });
|
|
9153
|
+
}
|
|
9073
9154
|
if (this.stoppedTurns.has(threadId)) {
|
|
9074
9155
|
handle.kill();
|
|
9075
9156
|
} else {
|
|
@@ -9089,20 +9170,41 @@ var Orchestrator = class {
|
|
|
9089
9170
|
if (result.sessionId) {
|
|
9090
9171
|
updateThread(threadId, { sessionId: result.sessionId });
|
|
9091
9172
|
}
|
|
9092
|
-
|
|
9093
|
-
|
|
9094
|
-
|
|
9173
|
+
let assistantText = result.assistantText.trim();
|
|
9174
|
+
let parts = result.parts;
|
|
9175
|
+
let usage = result.usage ?? void 0;
|
|
9176
|
+
let exitCode = result.exitCode;
|
|
9177
|
+
if (this.requireThread(threadId).agent === "cursor" && exitCode !== 0 && !assistantText && parts.length === 0) {
|
|
9178
|
+
const sessionId = result.sessionId || this.requireThread(threadId).sessionId || "";
|
|
9179
|
+
if (sessionId) {
|
|
9180
|
+
const { recoverFinishedCursorRun: recoverFinishedCursorRun2 } = await Promise.resolve().then(() => (init_cursor_recover(), cursor_recover_exports));
|
|
9181
|
+
for (let i = 0; i < 8; i++) {
|
|
9182
|
+
const recovered = recoverFinishedCursorRun2({
|
|
9183
|
+
agentId: sessionId,
|
|
9184
|
+
startedAfterMs: turnStartedAt - 5e3
|
|
9185
|
+
});
|
|
9186
|
+
if (recovered?.result) {
|
|
9187
|
+
assistantText = recovered.result;
|
|
9188
|
+
exitCode = 0;
|
|
9189
|
+
break;
|
|
9190
|
+
}
|
|
9191
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
9192
|
+
}
|
|
9193
|
+
}
|
|
9194
|
+
}
|
|
9195
|
+
const failureOnlyMessage = exitCode !== 0 && looksLikeAgentFailureMessage(assistantText) && !parts.some((p) => p.type === "tool" || p.type === "thinking");
|
|
9196
|
+
if (!failureOnlyMessage && (assistantText || parts.length > 0)) {
|
|
9095
9197
|
appendMessage(threadId, {
|
|
9096
9198
|
role: "agent",
|
|
9097
9199
|
text: assistantText,
|
|
9098
|
-
parts:
|
|
9200
|
+
parts: parts.length > 0 ? parts : void 0,
|
|
9099
9201
|
durationMs: Math.max(0, Date.now() - turnStartedAt),
|
|
9100
|
-
usage
|
|
9202
|
+
usage,
|
|
9101
9203
|
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
9102
9204
|
});
|
|
9103
9205
|
}
|
|
9104
9206
|
const afterTurn = this.requireThread(threadId);
|
|
9105
|
-
if (afterTurn.planMode && afterTurn.agent === "claude" &&
|
|
9207
|
+
if (afterTurn.planMode && afterTurn.agent === "claude" && parts.some(
|
|
9106
9208
|
(p) => p.type === "tool" && /exitplanmode/i.test(p.name)
|
|
9107
9209
|
)) {
|
|
9108
9210
|
updateThread(threadId, { sessionId: null });
|
|
@@ -9111,22 +9213,22 @@ var Orchestrator = class {
|
|
|
9111
9213
|
if (this.stoppedTurns.has(threadId)) {
|
|
9112
9214
|
setStatus(threadId, "stopped");
|
|
9113
9215
|
this.emit({ type: "status_changed", threadId, status: "stopped" });
|
|
9114
|
-
this.emit({ type: "turn_finished", threadId, exitCode
|
|
9216
|
+
this.emit({ type: "turn_finished", threadId, exitCode });
|
|
9115
9217
|
} else {
|
|
9116
9218
|
const lastStderr = summarizeTurnStderr(stderrTail);
|
|
9117
|
-
const detail = lastStderr || (
|
|
9118
|
-
const failDetail = formatTurnExitError(
|
|
9219
|
+
const detail = lastStderr || (exitCode !== 0 ? fallbackTurnFailDetail(assistantText) : "");
|
|
9220
|
+
const failDetail = formatTurnExitError(exitCode, detail);
|
|
9119
9221
|
setStatus(
|
|
9120
9222
|
threadId,
|
|
9121
|
-
|
|
9122
|
-
|
|
9223
|
+
exitCode === 0 ? "idle" : "error",
|
|
9224
|
+
exitCode === 0 ? null : failDetail
|
|
9123
9225
|
);
|
|
9124
9226
|
this.emit({
|
|
9125
9227
|
type: "status_changed",
|
|
9126
9228
|
threadId,
|
|
9127
|
-
status:
|
|
9229
|
+
status: exitCode === 0 ? "idle" : "error"
|
|
9128
9230
|
});
|
|
9129
|
-
this.emit({ type: "turn_finished", threadId, exitCode
|
|
9231
|
+
this.emit({ type: "turn_finished", threadId, exitCode });
|
|
9130
9232
|
}
|
|
9131
9233
|
} catch (err) {
|
|
9132
9234
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -9147,6 +9249,10 @@ var Orchestrator = class {
|
|
|
9147
9249
|
this.processes.delete(`${threadId}:agent`);
|
|
9148
9250
|
this.stoppedTurns.delete(threadId);
|
|
9149
9251
|
this.runningCount = Math.max(0, this.runningCount - 1);
|
|
9252
|
+
try {
|
|
9253
|
+
updateThread(threadId, { agentPid: null });
|
|
9254
|
+
} catch {
|
|
9255
|
+
}
|
|
9150
9256
|
}
|
|
9151
9257
|
}
|
|
9152
9258
|
/**
|
|
@@ -9719,7 +9825,7 @@ var Orchestrator = class {
|
|
|
9719
9825
|
updateThread(thread.id, { worktreePath: globalAgentCwd2() });
|
|
9720
9826
|
return setStatus(thread.id, "idle");
|
|
9721
9827
|
}
|
|
9722
|
-
if (!(0,
|
|
9828
|
+
if (!(0, import_node_fs25.existsSync)(thread.worktreePath)) {
|
|
9723
9829
|
const { createThreadWorktree: createThreadWorktree2 } = await Promise.resolve().then(() => (init_worktree(), worktree_exports));
|
|
9724
9830
|
const { execa: execa7 } = await import("execa");
|
|
9725
9831
|
const slug = thread.worktreePath.split("/").pop();
|
|
@@ -9937,7 +10043,7 @@ async function startMcpServer() {
|
|
|
9937
10043
|
async () => {
|
|
9938
10044
|
const threads = orch.getThreads(true);
|
|
9939
10045
|
const lines = threads.map((t) => {
|
|
9940
|
-
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0,
|
|
10046
|
+
const repo = t.repoPath === GLOBAL_WORKSPACE_ID ? "Orchestration" : (0, import_node_path24.basename)(t.repoPath) || t.repoPath;
|
|
9941
10047
|
return `${t.id.slice(0, 8)} ${t.status.padEnd(9)} ${t.agent.padEnd(8)} ${repo} ${t.sourceType}:${t.sourceRef} ${t.title} sideboard://thread/${t.id}${t.devPort ? ` http://localhost:${t.devPort}` : ""}`;
|
|
9942
10048
|
});
|
|
9943
10049
|
return {
|
package/dist/mcp/run-stdio.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
startMcpServer
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-WD35X6U5.js";
|
|
5
|
+
import "../chunk-44LYDJFB.js";
|
|
6
|
+
import "../chunk-6TZSJMXF.js";
|
|
7
|
+
import "../chunk-UPMGXM4X.js";
|
|
8
|
+
import "../chunk-SX2R2PCE.js";
|
|
9
9
|
import "../chunk-ILQK4P5R.js";
|
|
10
10
|
import "../chunk-PU27NUO4.js";
|
|
11
11
|
import "../chunk-YZ23S32T.js";
|
|
12
|
-
import "../chunk-
|
|
13
|
-
import "../chunk-
|
|
12
|
+
import "../chunk-VA2U5EQH.js";
|
|
13
|
+
import "../chunk-5UIKSPDD.js";
|
|
14
14
|
import "../chunk-M37RITA6.js";
|
|
15
15
|
import "../chunk-AJ6ROGD7.js";
|
|
16
16
|
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
listWorkspaces,
|
|
5
5
|
removeWorkspace,
|
|
6
6
|
syncWorkspacesFromThreads
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-44LYDJFB.js";
|
|
8
|
+
import "./chunk-6TZSJMXF.js";
|
|
9
|
+
import "./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 {
|
|
@@ -41,8 +41,8 @@ import {
|
|
|
41
41
|
worktreeDisplayLabel,
|
|
42
42
|
worktreeDisplayLabelForGroup,
|
|
43
43
|
worktreeNameFromPath
|
|
44
|
-
} from "./chunk-
|
|
45
|
-
import "./chunk-
|
|
44
|
+
} from "./chunk-VA2U5EQH.js";
|
|
45
|
+
import "./chunk-5UIKSPDD.js";
|
|
46
46
|
import "./chunk-M37RITA6.js";
|
|
47
47
|
import "./chunk-AJ6ROGD7.js";
|
|
48
48
|
export {
|