@sideboard-ai/core 0.1.261 → 0.1.263
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-OQ4PC52L.js → abletime-6AOJI2YZ.js} +4 -4
- package/dist/{abletime-CDGINDXG.js → abletime-U75ZGDIX.js} +5 -5
- package/dist/{abletime-oauth-KX2TDFTE.js → abletime-oauth-LOAHGG4X.js} +3 -3
- package/dist/{abletime-oauth-5A5EOH2A.js → abletime-oauth-TA2YDCYX.js} +4 -4
- package/dist/{abletime-rest-UEHOBLXD.js → abletime-rest-CTA5WV26.js} +4 -4
- package/dist/{abletime-rest-PUGKYTRR.js → abletime-rest-YZPFM6IY.js} +3 -3
- package/dist/agents/claude-runner.cjs +463 -0
- package/dist/agents/claude-runner.d.cts +1 -0
- package/dist/agents/claude-runner.d.ts +1 -0
- package/dist/agents/claude-runner.js +134 -0
- package/dist/agents/cursor-runner.cjs +388 -7
- package/dist/agents/cursor-runner.js +34 -7
- package/dist/{agents-J2P4KNEY.js → agents-3TUMFSMH.js} +10 -9
- package/dist/{agents-IKVUGW5H.js → agents-6FWDRVA2.js} +4 -4
- package/dist/{app-settings-OM7H64YM.js → app-settings-MVZPM6WW.js} +1 -1
- package/dist/{app-settings-VQEUCONM.js → app-settings-RKFFUIFQ.js} +2 -2
- package/dist/{chunk-6PFZ6XO7.js → chunk-2QUQH2SZ.js} +81 -6
- package/dist/{chunk-VIC6TDYT.js → chunk-36FOBJBF.js} +76 -3
- package/dist/{chunk-ABPNIYRS.js → chunk-3H7O27X2.js} +389 -102
- package/dist/{chunk-FSZ7YYFQ.js → chunk-4ALDX5IO.js} +5 -3
- package/dist/{chunk-5OKJDCBK.js → chunk-5PK53SAP.js} +5 -5
- package/dist/{chunk-U3AOJLH3.js → chunk-5ZPT5YAV.js} +8 -6
- package/dist/{chunk-YFTO7U2A.js → chunk-6YOXQVJ7.js} +3 -3
- package/dist/{chunk-J6ONZP74.js → chunk-6YY7XPPL.js} +5 -5
- package/dist/{chunk-WV7KJH2E.js → chunk-A5SAYFJ4.js} +1 -0
- package/dist/{chunk-B6XFBNYM.js → chunk-BOMSJUXW.js} +2 -2
- package/dist/{chunk-S7VDDJ34.js → chunk-CEOTK5GZ.js} +3 -3
- package/dist/{chunk-4F7J6UWD.js → chunk-EK3KVT7I.js} +515 -139
- package/dist/{chunk-HHEKVR6C.js → chunk-F5MFNUAA.js} +40 -2
- package/dist/{chunk-KVQX62XI.js → chunk-K7B25HO4.js} +3 -3
- package/dist/{chunk-JTNY5CK4.js → chunk-L5WGAIL2.js} +46 -46
- package/dist/chunk-NYBFYFK7.js +415 -0
- package/dist/{chunk-GIZQAOHZ.js → chunk-QX6QUZVD.js} +121 -91
- package/dist/{chunk-X2OTZ36G.js → chunk-RKPBIB2U.js} +52 -52
- package/dist/{chunk-W5PWGEKS.js → chunk-T3AYRQJZ.js} +107 -77
- package/dist/{chunk-D554YCHG.js → chunk-YKYEHDMX.js} +2 -2
- package/dist/connected-teams-RU6VATCM.js +1 -1
- package/dist/{coordinator-prompt-VQHQ3RIX.js → coordinator-prompt-HZCQZ6C5.js} +6 -6
- package/dist/{coordinator-prompt-TU6656OK.js → coordinator-prompt-J7DKHOCH.js} +3 -3
- package/dist/{global-workspace-PHF2MOGW.js → global-workspace-6LDUZ2NF.js} +3 -3
- package/dist/{global-workspace-47NZVA44.js → global-workspace-TI26K25J.js} +6 -6
- package/dist/index.cjs +1712 -721
- package/dist/index.d.cts +181 -41
- package/dist/index.d.ts +181 -41
- package/dist/index.js +693 -285
- package/dist/mcp/run-stdio.cjs +10469 -9896
- package/dist/mcp/run-stdio.js +193 -168
- package/dist/{orchestrator-VLTO5JBR.js → orchestrator-4JSG7BWC.js} +5 -5
- package/dist/{orchestrator-OCG4QVA5.js → orchestrator-5YU46YNS.js} +11 -10
- package/dist/{workspaces-I7TWFTJM.js → workspaces-QJ3XIPUJ.js} +6 -6
- package/dist/{workspaces-2XTDS7N2.js → workspaces-WOQHJFRQ.js} +3 -3
- package/dist/{worktree-DDDF3WHV.js → worktree-6U2FA5LO.js} +2 -2
- package/dist/{worktree-YASFE65H.js → worktree-KQA4ON2G.js} +5 -5
- package/package.json +4 -3
- /package/dist/{chunk-LDXSAVWO.js → chunk-GWFVCCJZ.js} +0 -0
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
isOrchestratorThread
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-L5WGAIL2.js";
|
|
6
6
|
import {
|
|
7
7
|
codexUnattendedGitConfigArgs,
|
|
8
8
|
mergeAgentGitAuthEnv,
|
|
9
9
|
resolveAgentGitAuthEnv,
|
|
10
10
|
resolveCodexGitWritableRoots
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-4ALDX5IO.js";
|
|
12
12
|
import {
|
|
13
13
|
applyConnectedTeamToCli,
|
|
14
14
|
brightsyMcpServerName,
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
loadAppSettings,
|
|
38
38
|
resolveAgentExecutable,
|
|
39
39
|
resolveClaudeExecutable
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-36FOBJBF.js";
|
|
41
41
|
import {
|
|
42
42
|
isElectronLikeCommand,
|
|
43
43
|
unwrapStrippedElectronLaunch,
|
|
@@ -803,7 +803,7 @@ var brightsyAdapter = {
|
|
|
803
803
|
};
|
|
804
804
|
|
|
805
805
|
// src/agents/claude.ts
|
|
806
|
-
import { existsSync as
|
|
806
|
+
import { existsSync as existsSync10 } from "fs";
|
|
807
807
|
|
|
808
808
|
// src/agents/claude-mcp.ts
|
|
809
809
|
function sanitizeMcpServerName(name) {
|
|
@@ -825,6 +825,29 @@ function mcpAllowToolsFromNames(names) {
|
|
|
825
825
|
[...names].map((name) => name.trim()).filter(Boolean).map((name) => ({ name, connected: true, needsAuth: false }))
|
|
826
826
|
);
|
|
827
827
|
}
|
|
828
|
+
var BASE_ALLOWED_TOOLS = [
|
|
829
|
+
"Edit",
|
|
830
|
+
"Write",
|
|
831
|
+
"Bash",
|
|
832
|
+
"Read",
|
|
833
|
+
"Glob",
|
|
834
|
+
"Grep",
|
|
835
|
+
"WebFetch",
|
|
836
|
+
"WebSearch",
|
|
837
|
+
"Task",
|
|
838
|
+
"Agent",
|
|
839
|
+
"TaskOutput",
|
|
840
|
+
"TaskStop",
|
|
841
|
+
"EnterWorktree",
|
|
842
|
+
"ExitWorktree",
|
|
843
|
+
"Skill"
|
|
844
|
+
];
|
|
845
|
+
var CLAUDE_PRINT_BG_WAIT_CEILING_MS = 72e5;
|
|
846
|
+
var CLAUDE_CHROME_ALLOWED_TOOLS = [
|
|
847
|
+
"mcp__claude-in-chrome",
|
|
848
|
+
"mcp__claude-in-chrome__*",
|
|
849
|
+
"Skill(claude-in-chrome)"
|
|
850
|
+
];
|
|
828
851
|
|
|
829
852
|
// src/agents/orch-mcp-isolation.ts
|
|
830
853
|
import { existsSync as existsSync7, readFileSync as readFileSync3 } from "fs";
|
|
@@ -844,9 +867,67 @@ import { tmpdir } from "os";
|
|
|
844
867
|
import { dirname as dirname2, join as join4 } from "path";
|
|
845
868
|
import { fileURLToPath } from "url";
|
|
846
869
|
|
|
870
|
+
// src/agent-rpc/protocol.ts
|
|
871
|
+
var AGENT_RPC_PROTOCOL_VERSION = 1;
|
|
872
|
+
var AGENT_RPC_TOKEN_QUERY = "authToken";
|
|
873
|
+
var AGENT_RPC_NATIVE_ENV = "SIDEBOARD_AGENT_RPC_NATIVE";
|
|
874
|
+
var AGENT_RPC_URL_ENV = "SIDEBOARD_AGENT_RPC_URL";
|
|
875
|
+
var AGENT_RPC_TOKEN_ENV = "SIDEBOARD_AGENT_RPC_TOKEN";
|
|
876
|
+
var AGENT_RPC_CWD_ENV = "SIDEBOARD_AGENT_RPC_CWD";
|
|
877
|
+
var AGENT_RPC_CLAUDE_SDK_SERVER = "sideboard_rpc";
|
|
878
|
+
|
|
847
879
|
// src/mcp/profile.ts
|
|
848
880
|
var SIDEBOARD_MCP_PROFILE_ENV = "SIDEBOARD_MCP_PROFILE";
|
|
849
881
|
var SIDEBOARD_THREAD_ID_ENV = "SIDEBOARD_THREAD_ID";
|
|
882
|
+
function agentRpcOwnsPilotTools(env = process.env) {
|
|
883
|
+
return env[AGENT_RPC_NATIVE_ENV]?.trim() === "1";
|
|
884
|
+
}
|
|
885
|
+
function injectedSideboardMcpEnv(opts) {
|
|
886
|
+
const orchId = opts.orchestratorThreadId?.trim();
|
|
887
|
+
const threadId = opts.threadId?.trim() || orchId;
|
|
888
|
+
const env = {
|
|
889
|
+
SIDEBOARD_APP_DATA: appDataDir(),
|
|
890
|
+
[SIDEBOARD_MCP_PROFILE_ENV]: orchId ? "orchestration" : "worktree"
|
|
891
|
+
};
|
|
892
|
+
if (orchId) env.SIDEBOARD_ORCHESTRATOR_THREAD_ID = orchId;
|
|
893
|
+
if (threadId) env[SIDEBOARD_THREAD_ID_ENV] = threadId;
|
|
894
|
+
if (opts.rpcNativeTools) env[AGENT_RPC_NATIVE_ENV] = "1";
|
|
895
|
+
return env;
|
|
896
|
+
}
|
|
897
|
+
var AGENT_RPC_PILOT_MCP_TOOLS = [
|
|
898
|
+
"present_artifact",
|
|
899
|
+
"wait_for_job",
|
|
900
|
+
"stop_job"
|
|
901
|
+
];
|
|
902
|
+
function shouldRegisterMcpWaitForTurn(env = process.env) {
|
|
903
|
+
return !agentRpcOwnsPilotTools(env);
|
|
904
|
+
}
|
|
905
|
+
function worktreeMcpToolNames(env = process.env) {
|
|
906
|
+
if (!agentRpcOwnsPilotTools(env)) return WORKTREE_MCP_TOOLS;
|
|
907
|
+
const omit = new Set(AGENT_RPC_PILOT_MCP_TOOLS);
|
|
908
|
+
return WORKTREE_MCP_TOOLS.filter((name) => !omit.has(name));
|
|
909
|
+
}
|
|
910
|
+
var WORKTREE_MCP_TOOLS = [
|
|
911
|
+
"present_artifact",
|
|
912
|
+
"ask_user",
|
|
913
|
+
"present_plan",
|
|
914
|
+
"present_schema",
|
|
915
|
+
"present_files",
|
|
916
|
+
"wait_for_job",
|
|
917
|
+
"stop_job",
|
|
918
|
+
"list_run_scripts",
|
|
919
|
+
"run_dev_script",
|
|
920
|
+
"stop_dev_script",
|
|
921
|
+
"get_run_log",
|
|
922
|
+
"notify_orchestrator",
|
|
923
|
+
"get_viewer_context",
|
|
924
|
+
"update_viewer_context",
|
|
925
|
+
"list_schedules",
|
|
926
|
+
"create_schedule",
|
|
927
|
+
"update_schedule",
|
|
928
|
+
"delete_schedule",
|
|
929
|
+
"run_schedule"
|
|
930
|
+
];
|
|
850
931
|
function sideboardMcpProfile(env = process.env) {
|
|
851
932
|
return env[SIDEBOARD_MCP_PROFILE_ENV]?.trim().toLowerCase() === "worktree" ? "worktree" : "orchestration";
|
|
852
933
|
}
|
|
@@ -1408,20 +1489,10 @@ async function buildInjectedMcpServers(opts) {
|
|
|
1408
1489
|
const servers = [];
|
|
1409
1490
|
if (opts.includeSideboard) {
|
|
1410
1491
|
const sideboard = await resolveSideboardMcpServer();
|
|
1411
|
-
const orchId = opts.orchestratorThreadId?.trim();
|
|
1412
|
-
const profile = orchId ? "orchestration" : "worktree";
|
|
1413
|
-
const threadId = opts.threadId?.trim() || orchId;
|
|
1414
1492
|
sideboard.env = {
|
|
1415
1493
|
...sideboard.env ?? {},
|
|
1416
|
-
|
|
1417
|
-
[SIDEBOARD_MCP_PROFILE_ENV]: profile
|
|
1494
|
+
...injectedSideboardMcpEnv(opts)
|
|
1418
1495
|
};
|
|
1419
|
-
if (orchId) {
|
|
1420
|
-
sideboard.env.SIDEBOARD_ORCHESTRATOR_THREAD_ID = orchId;
|
|
1421
|
-
}
|
|
1422
|
-
if (threadId) {
|
|
1423
|
-
sideboard.env[SIDEBOARD_THREAD_ID_ENV] = threadId;
|
|
1424
|
-
}
|
|
1425
1496
|
try {
|
|
1426
1497
|
mergeAgentGitAuthEnv(
|
|
1427
1498
|
sideboard.env,
|
|
@@ -1526,7 +1597,7 @@ function stripElectronFromUserMcpEntry(entry) {
|
|
|
1526
1597
|
next.env = cleaned;
|
|
1527
1598
|
return next;
|
|
1528
1599
|
}
|
|
1529
|
-
function
|
|
1600
|
+
function mcpServersRecord(servers, extraServers) {
|
|
1530
1601
|
const mcpServers = {};
|
|
1531
1602
|
for (const s of servers) {
|
|
1532
1603
|
const env = mcpSpawnEnv(s.env);
|
|
@@ -1543,6 +1614,10 @@ function writeMcpServersConfig(servers, extraServers) {
|
|
|
1543
1614
|
mcpServers[name] = stripElectronFromUserMcpEntry(entry);
|
|
1544
1615
|
}
|
|
1545
1616
|
}
|
|
1617
|
+
return mcpServers;
|
|
1618
|
+
}
|
|
1619
|
+
function writeMcpServersConfig(servers, extraServers) {
|
|
1620
|
+
const mcpServers = mcpServersRecord(servers, extraServers);
|
|
1546
1621
|
if (Object.keys(mcpServers).length === 0) return null;
|
|
1547
1622
|
const dir = mkdtempSync(join4(tmpdir(), "sideboard-mcp-"));
|
|
1548
1623
|
const cfgPath = join4(dir, "mcp.json");
|
|
@@ -2524,34 +2599,166 @@ function permissionMode(thread) {
|
|
|
2524
2599
|
};
|
|
2525
2600
|
}
|
|
2526
2601
|
|
|
2527
|
-
// src/
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
"
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2602
|
+
// src/agent-rpc/metadata.ts
|
|
2603
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4, unlinkSync, writeFileSync as writeFileSync4 } from "fs";
|
|
2604
|
+
import { join as join7 } from "path";
|
|
2605
|
+
function agentRuntimeMetadataPath() {
|
|
2606
|
+
return join7(appDataDir(), "agent-runtime.json");
|
|
2607
|
+
}
|
|
2608
|
+
function readAgentRuntimeMetadata() {
|
|
2609
|
+
try {
|
|
2610
|
+
const raw = JSON.parse(readFileSync4(agentRuntimeMetadataPath(), "utf8"));
|
|
2611
|
+
if (!raw || typeof raw !== "object") return null;
|
|
2612
|
+
const rec = raw;
|
|
2613
|
+
if (typeof rec.runtimeId !== "string" || !rec.runtimeId.trim()) return null;
|
|
2614
|
+
if (typeof rec.authToken !== "string" || !rec.authToken.trim()) return null;
|
|
2615
|
+
const pid = Number(rec.pid);
|
|
2616
|
+
if (!Number.isInteger(pid) || pid <= 0) return null;
|
|
2617
|
+
const transports = Array.isArray(rec.transports) ? rec.transports : [];
|
|
2618
|
+
const ws = transports.filter((t) => {
|
|
2619
|
+
if (!t || typeof t !== "object") return false;
|
|
2620
|
+
const row = t;
|
|
2621
|
+
return row.kind === "websocket" && typeof row.url === "string" && Boolean(row.url.trim());
|
|
2622
|
+
});
|
|
2623
|
+
return {
|
|
2624
|
+
runtimeId: rec.runtimeId.trim(),
|
|
2625
|
+
pid,
|
|
2626
|
+
protocolVersion: Number(rec.protocolVersion) || AGENT_RPC_PROTOCOL_VERSION,
|
|
2627
|
+
authToken: rec.authToken,
|
|
2628
|
+
startedAt: Number(rec.startedAt) || 0,
|
|
2629
|
+
transports: ws
|
|
2630
|
+
};
|
|
2631
|
+
} catch {
|
|
2632
|
+
return null;
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
function websocketUrlFromMetadata(meta) {
|
|
2636
|
+
const url = meta?.transports.find((t) => t.kind === "websocket")?.url?.trim();
|
|
2637
|
+
return url || null;
|
|
2638
|
+
}
|
|
2639
|
+
function agentRpcConnectFromMetadata(meta = readAgentRuntimeMetadata()) {
|
|
2640
|
+
if (!agentRuntimeLooksLive(meta)) return null;
|
|
2641
|
+
const url = websocketUrlFromMetadata(meta);
|
|
2642
|
+
const authToken = meta?.authToken;
|
|
2643
|
+
if (!url || !authToken) return null;
|
|
2644
|
+
return { url, authToken };
|
|
2645
|
+
}
|
|
2646
|
+
function pidAlive(pid) {
|
|
2647
|
+
try {
|
|
2648
|
+
process.kill(pid, 0);
|
|
2649
|
+
return true;
|
|
2650
|
+
} catch {
|
|
2651
|
+
return false;
|
|
2652
|
+
}
|
|
2653
|
+
}
|
|
2654
|
+
function agentRuntimeLooksLive(meta = readAgentRuntimeMetadata()) {
|
|
2655
|
+
if (!meta) return false;
|
|
2656
|
+
return pidAlive(meta.pid);
|
|
2657
|
+
}
|
|
2658
|
+
|
|
2659
|
+
// src/agent-rpc/rpc-env.ts
|
|
2660
|
+
function worktreeAgentRpc(isOrchestrator) {
|
|
2661
|
+
return isOrchestrator ? null : agentRpcConnectFromMetadata();
|
|
2662
|
+
}
|
|
2663
|
+
function agentRpcChildEnv(rpc, cwd) {
|
|
2664
|
+
return {
|
|
2665
|
+
[AGENT_RPC_NATIVE_ENV]: "1",
|
|
2666
|
+
[AGENT_RPC_URL_ENV]: rpc.url,
|
|
2667
|
+
[AGENT_RPC_TOKEN_ENV]: rpc.authToken,
|
|
2668
|
+
[AGENT_RPC_CWD_ENV]: cwd
|
|
2669
|
+
};
|
|
2670
|
+
}
|
|
2671
|
+
|
|
2672
|
+
// src/agents/claude-host.ts
|
|
2673
|
+
import { existsSync as existsSync9 } from "fs";
|
|
2674
|
+
import { createRequire as createRequire2 } from "module";
|
|
2675
|
+
import { dirname as dirname4, join as join8 } from "path";
|
|
2676
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2677
|
+
|
|
2678
|
+
// src/agent-rpc/client.ts
|
|
2679
|
+
import { WebSocket } from "ws";
|
|
2680
|
+
|
|
2681
|
+
// src/agent-rpc/pilot-tools.ts
|
|
2682
|
+
var PILOT_TOOL_NAMES = [
|
|
2683
|
+
"present_artifact",
|
|
2684
|
+
"wait_for_job",
|
|
2685
|
+
"stop_job"
|
|
2545
2686
|
];
|
|
2546
|
-
var
|
|
2687
|
+
var PILOT_TOOL_DESCRIPTIONS = {
|
|
2688
|
+
present_artifact: "Show a document or live log in Sideboard\u2019s side column. For html/svg/markdown/react, pass the FULL document and do not also fence that same body in chat. For type=log, pass only NEW lines (same artifact_id appends). Prefer type=log for long-running job output \u2014 do not resend HTML. type=react is a single default-export component (JSX/TSX); only react/react-dom imports.",
|
|
2689
|
+
wait_for_job: "Wait until a detached long job (tests, pack, deploy, connector CLI) finishes. This call stays open for up to ~2 minutes. stillRunning true means the runtime hit the max hold; call wait_for_job again immediately. If the job is hanging, producing no useful output, or doing the wrong thing, call stop_job instead. Do not end the turn or tell the user you will let them know later.",
|
|
2690
|
+
stop_job: "Stop a detached job you started with detached-job.cjs when it is hanging, producing no useful output, buffering forever, or doing the wrong thing (wrong project, infinite watch, huge dump). Do not stop a pack/test/deploy that is clearly making progress."
|
|
2691
|
+
};
|
|
2692
|
+
|
|
2693
|
+
// src/agents/claude-host.ts
|
|
2694
|
+
function claudePilotSdkAllowedTools() {
|
|
2695
|
+
return PILOT_TOOL_NAMES.map(
|
|
2696
|
+
(name) => `mcp__${AGENT_RPC_CLAUDE_SDK_SERVER}__${name}`
|
|
2697
|
+
);
|
|
2698
|
+
}
|
|
2699
|
+
function withClaudePilotRpcTools(allowed) {
|
|
2700
|
+
const omit = new Set(PILOT_TOOL_NAMES.map((name) => `mcp__sideboard__${name}`));
|
|
2701
|
+
return [...allowed.filter((name) => !omit.has(name)), ...claudePilotSdkAllowedTools()];
|
|
2702
|
+
}
|
|
2703
|
+
function entryDir() {
|
|
2704
|
+
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
2705
|
+
if (cjsDir) return cjsDir;
|
|
2706
|
+
try {
|
|
2707
|
+
return dirname4(fileURLToPath2(import.meta.url));
|
|
2708
|
+
} catch {
|
|
2709
|
+
try {
|
|
2710
|
+
const req = createRequire2(process.cwd() + "/");
|
|
2711
|
+
return dirname4(req.resolve("@sideboard-ai/core"));
|
|
2712
|
+
} catch {
|
|
2713
|
+
return process.cwd();
|
|
2714
|
+
}
|
|
2715
|
+
}
|
|
2716
|
+
}
|
|
2717
|
+
function claudeRunnerPath() {
|
|
2718
|
+
const packagedDir = packagedCursorRuntimeDir();
|
|
2719
|
+
if (packagedDir) {
|
|
2720
|
+
const packaged = join8(packagedDir, "core-dist", "agents", "claude-runner.js");
|
|
2721
|
+
if (existsSync9(packaged)) return packaged;
|
|
2722
|
+
}
|
|
2723
|
+
const root = entryDir();
|
|
2724
|
+
const candidates = [
|
|
2725
|
+
join8(root, "agents", "claude-runner.js"),
|
|
2726
|
+
join8(root, "agents", "claude-runner.cjs"),
|
|
2727
|
+
join8(root, "dist", "agents", "claude-runner.js"),
|
|
2728
|
+
join8(root, "dist", "agents", "claude-runner.cjs"),
|
|
2729
|
+
join8(root, "claude-runner.ts"),
|
|
2730
|
+
join8(root, "src", "agents", "claude-runner.ts")
|
|
2731
|
+
];
|
|
2732
|
+
for (const candidate of candidates) {
|
|
2733
|
+
if (existsSync9(candidate)) return candidate;
|
|
2734
|
+
}
|
|
2735
|
+
return candidates[0];
|
|
2736
|
+
}
|
|
2737
|
+
async function buildClaudeRpcTurnCommand(req) {
|
|
2738
|
+
const runner = claudeRunnerPath();
|
|
2739
|
+
const isTs = runner.endsWith(".ts");
|
|
2740
|
+
const launch = applyNodeLaunch(
|
|
2741
|
+
await resolveNodeLaunch(runner),
|
|
2742
|
+
isTs ? ["--import", "tsx", runner] : [runner]
|
|
2743
|
+
);
|
|
2744
|
+
return {
|
|
2745
|
+
file: launch.file,
|
|
2746
|
+
args: launch.args,
|
|
2747
|
+
cwd: req.cwd,
|
|
2748
|
+
stdin: JSON.stringify(req),
|
|
2749
|
+
env: {
|
|
2750
|
+
...launch.env,
|
|
2751
|
+
CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1",
|
|
2752
|
+
CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS: process.env.CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS ?? "7200000",
|
|
2753
|
+
...req.isolateClaudeAiMcp ? { ENABLE_CLAUDEAI_MCP_SERVERS: "false" } : {}
|
|
2754
|
+
}
|
|
2755
|
+
};
|
|
2756
|
+
}
|
|
2757
|
+
|
|
2758
|
+
// src/agents/claude.ts
|
|
2547
2759
|
function isLocalDevAppDataDir(dir = process.env.SIDEBOARD_APP_DATA) {
|
|
2548
2760
|
return /[/\\]\.sideboard[/\\]dev-app-data(?:[/\\]|$)/.test(dir ?? "");
|
|
2549
2761
|
}
|
|
2550
|
-
var CLAUDE_CHROME_ALLOWED_TOOLS = [
|
|
2551
|
-
"mcp__claude-in-chrome",
|
|
2552
|
-
"mcp__claude-in-chrome__*",
|
|
2553
|
-
"Skill(claude-in-chrome)"
|
|
2554
|
-
];
|
|
2555
2762
|
var CLAUDE_PROMPT_ARG_MAX = 2e5;
|
|
2556
2763
|
function usageFromClaude(usage) {
|
|
2557
2764
|
if (!usage) return null;
|
|
@@ -2589,6 +2796,13 @@ function costUsdFromClaudeResult(obj) {
|
|
|
2589
2796
|
}
|
|
2590
2797
|
return void 0;
|
|
2591
2798
|
}
|
|
2799
|
+
function sessionCostUsdFromClaudeResult(obj) {
|
|
2800
|
+
const totalCost = obj.total_cost_usd ?? obj.totalCostUsd;
|
|
2801
|
+
if (totalCost != null && Number.isFinite(Number(totalCost))) {
|
|
2802
|
+
return Number(totalCost);
|
|
2803
|
+
}
|
|
2804
|
+
return void 0;
|
|
2805
|
+
}
|
|
2592
2806
|
function claudeResultErrorDetail(obj) {
|
|
2593
2807
|
const isError = Boolean(obj.is_error) || typeof obj.subtype === "string" && /^error/i.test(obj.subtype);
|
|
2594
2808
|
const fromResult = typeof obj.result === "string" ? obj.result.trim() : "";
|
|
@@ -2921,7 +3135,7 @@ var claudeAdapter = {
|
|
|
2921
3135
|
async detect() {
|
|
2922
3136
|
const claude = resolveClaudeExecutable();
|
|
2923
3137
|
if (claude !== "claude") {
|
|
2924
|
-
if (!
|
|
3138
|
+
if (!existsSync10(claude)) {
|
|
2925
3139
|
return {
|
|
2926
3140
|
agent: "claude",
|
|
2927
3141
|
installed: false,
|
|
@@ -2970,15 +3184,17 @@ var claudeAdapter = {
|
|
|
2970
3184
|
);
|
|
2971
3185
|
}
|
|
2972
3186
|
const mode = permissionMode(thread);
|
|
2973
|
-
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-
|
|
3187
|
+
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-6LDUZ2NF.js");
|
|
2974
3188
|
const isOrchestrator = isOrchestratorThread2(thread);
|
|
3189
|
+
const rpc = worktreeAgentRpc(isOrchestrator);
|
|
2975
3190
|
const injectedServers = await buildInjectedMcpServers({
|
|
2976
3191
|
includeSideboard: true,
|
|
2977
3192
|
includeBrightsy: shouldInjectBrightsyMcp(thread, {
|
|
2978
3193
|
orchestrator: isOrchestrator
|
|
2979
3194
|
}),
|
|
2980
3195
|
orchestratorThreadId: isOrchestrator ? thread.id : null,
|
|
2981
|
-
threadId: thread.id
|
|
3196
|
+
threadId: thread.id,
|
|
3197
|
+
rpcNativeTools: Boolean(rpc)
|
|
2982
3198
|
});
|
|
2983
3199
|
const injectedBrightsyNames = injectedServers.filter((s) => s.name === "brightsy" || s.name.startsWith("brightsy_")).map((s) => s.name);
|
|
2984
3200
|
const chromeOn = claudeChromeEnabled();
|
|
@@ -3006,6 +3222,23 @@ var claudeAdapter = {
|
|
|
3006
3222
|
if (chromeOn) {
|
|
3007
3223
|
allowedTools = [...allowedTools, ...CLAUDE_CHROME_ALLOWED_TOOLS];
|
|
3008
3224
|
}
|
|
3225
|
+
if (rpc) {
|
|
3226
|
+
return buildClaudeRpcTurnCommand({
|
|
3227
|
+
prompt: promptText,
|
|
3228
|
+
cwd: thread.worktreePath,
|
|
3229
|
+
sessionId,
|
|
3230
|
+
model: thread.model,
|
|
3231
|
+
effort: thread.effort ?? (thread.fast ? "low" : "high"),
|
|
3232
|
+
permissionMode: mode.claude,
|
|
3233
|
+
systemPrompt,
|
|
3234
|
+
claudePath: claude,
|
|
3235
|
+
chrome: chromeOn,
|
|
3236
|
+
mcpServers: mcpServersRecord(injectedServers, userMcpEntries),
|
|
3237
|
+
allowedTools: withClaudePilotRpcTools(allowedTools),
|
|
3238
|
+
agentRpc: rpc,
|
|
3239
|
+
isolateClaudeAiMcp: isOrchestrator || isLocalDevAppDataDir()
|
|
3240
|
+
});
|
|
3241
|
+
}
|
|
3009
3242
|
const args = [
|
|
3010
3243
|
"-p",
|
|
3011
3244
|
...useStdin ? [] : [promptText],
|
|
@@ -3140,6 +3373,8 @@ var claudeAdapter = {
|
|
|
3140
3373
|
if (usage) {
|
|
3141
3374
|
const costUsd = costUsdFromClaudeResult(obj);
|
|
3142
3375
|
if (costUsd != null) usage.costUsd = costUsd;
|
|
3376
|
+
const sessionCostUsd = sessionCostUsdFromClaudeResult(obj);
|
|
3377
|
+
if (sessionCostUsd != null) usage.sessionCostUsd = sessionCostUsd;
|
|
3143
3378
|
events.push({ type: "usage", data: usage, scope: "turn" });
|
|
3144
3379
|
}
|
|
3145
3380
|
if (events.length === 0) return null;
|
|
@@ -3210,9 +3445,9 @@ function parseIssuesJson(raw) {
|
|
|
3210
3445
|
}
|
|
3211
3446
|
|
|
3212
3447
|
// src/agents/codex.ts
|
|
3213
|
-
import { existsSync as
|
|
3448
|
+
import { existsSync as existsSync11, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
|
|
3214
3449
|
import { homedir as homedir4 } from "os";
|
|
3215
|
-
import { join as
|
|
3450
|
+
import { join as join9 } from "path";
|
|
3216
3451
|
var CODEX_PROMPT_ARG_MAX = 2e5;
|
|
3217
3452
|
var FALLBACK_CODEX_MODELS = [
|
|
3218
3453
|
{ id: "gpt-5.6-sol", displayName: "GPT-5.6 Sol" },
|
|
@@ -3232,7 +3467,7 @@ async function listCodexModels() {
|
|
|
3232
3467
|
if (codex === "codex") {
|
|
3233
3468
|
const which = await run("which", ["codex"], { reject: false });
|
|
3234
3469
|
if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
|
|
3235
|
-
} else if (!
|
|
3470
|
+
} else if (!existsSync11(codex)) {
|
|
3236
3471
|
return FALLBACK_CODEX_MODELS;
|
|
3237
3472
|
}
|
|
3238
3473
|
const listed = await run(codex, ["debug", "models"], { reject: false });
|
|
@@ -3267,12 +3502,12 @@ function usageFromCodex(usage) {
|
|
|
3267
3502
|
}
|
|
3268
3503
|
function codexConfigHasNetworkAccess() {
|
|
3269
3504
|
const candidates = [
|
|
3270
|
-
|
|
3271
|
-
|
|
3505
|
+
join9(homedir4(), ".codex", "config.toml"),
|
|
3506
|
+
join9(homedir4(), ".config", "codex", "config.toml")
|
|
3272
3507
|
];
|
|
3273
3508
|
for (const path of candidates) {
|
|
3274
|
-
if (!
|
|
3275
|
-
const text =
|
|
3509
|
+
if (!existsSync11(path)) continue;
|
|
3510
|
+
const text = readFileSync5(path, "utf8");
|
|
3276
3511
|
if (/network_access\s*=\s*true/.test(text)) return true;
|
|
3277
3512
|
}
|
|
3278
3513
|
return false;
|
|
@@ -3304,8 +3539,8 @@ function asRecord2(value) {
|
|
|
3304
3539
|
return void 0;
|
|
3305
3540
|
}
|
|
3306
3541
|
function codexLooksAuthenticated() {
|
|
3307
|
-
const authPath =
|
|
3308
|
-
if (!
|
|
3542
|
+
const authPath = join9(homedir4(), ".codex", "auth.json");
|
|
3543
|
+
if (!existsSync11(authPath)) return false;
|
|
3309
3544
|
try {
|
|
3310
3545
|
return statSync2(authPath).size > 2;
|
|
3311
3546
|
} catch {
|
|
@@ -3317,7 +3552,7 @@ var codexAdapter = {
|
|
|
3317
3552
|
async detect() {
|
|
3318
3553
|
const codex = resolveAgentExecutable("codex");
|
|
3319
3554
|
if (codex !== "codex") {
|
|
3320
|
-
if (!
|
|
3555
|
+
if (!existsSync11(codex)) {
|
|
3321
3556
|
return {
|
|
3322
3557
|
agent: "codex",
|
|
3323
3558
|
installed: false,
|
|
@@ -3591,40 +3826,40 @@ var codexAdapter = {
|
|
|
3591
3826
|
};
|
|
3592
3827
|
|
|
3593
3828
|
// src/agents/cursor.ts
|
|
3594
|
-
import { existsSync as
|
|
3595
|
-
import { createRequire as
|
|
3596
|
-
import { dirname as
|
|
3597
|
-
import { fileURLToPath as
|
|
3829
|
+
import { existsSync as existsSync14 } from "fs";
|
|
3830
|
+
import { createRequire as createRequire5 } from "module";
|
|
3831
|
+
import { dirname as dirname7, join as join12 } from "path";
|
|
3832
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
3598
3833
|
|
|
3599
3834
|
// src/agents/cursor-sdk-resolve.ts
|
|
3600
|
-
import { existsSync as
|
|
3601
|
-
import { createRequire as
|
|
3602
|
-
import { basename, dirname as
|
|
3603
|
-
import { fileURLToPath as
|
|
3835
|
+
import { existsSync as existsSync12, readFileSync as readFileSync6 } from "fs";
|
|
3836
|
+
import { createRequire as createRequire3 } from "module";
|
|
3837
|
+
import { basename, dirname as dirname5, join as join10 } from "path";
|
|
3838
|
+
import { fileURLToPath as fileURLToPath3, pathToFileURL } from "url";
|
|
3604
3839
|
var CURSOR_SDK_INSTALL_HINT = "Cursor SDK is not installed. Settings \u2192 Agents \u2192 Cursor \u2192 Install (`npm i -g @cursor/sdk`). Sideboard does not ship the SDK \u2014 update it anytime without a new Sideboard build.";
|
|
3605
3840
|
function thisModuleFile() {
|
|
3606
3841
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
3607
|
-
if (cjsDir) return
|
|
3842
|
+
if (cjsDir) return join10(cjsDir, "cursor-sdk-resolve.js");
|
|
3608
3843
|
try {
|
|
3609
|
-
return
|
|
3844
|
+
return fileURLToPath3(import.meta.url);
|
|
3610
3845
|
} catch {
|
|
3611
|
-
return
|
|
3846
|
+
return join10(process.cwd(), "package.json");
|
|
3612
3847
|
}
|
|
3613
3848
|
}
|
|
3614
3849
|
function packageRootLooksLikeSdk(dir) {
|
|
3615
3850
|
try {
|
|
3616
|
-
const raw =
|
|
3851
|
+
const raw = readFileSync6(join10(dir, "package.json"), "utf8");
|
|
3617
3852
|
const pkg = JSON.parse(raw);
|
|
3618
|
-
return pkg.name === "@cursor/sdk" &&
|
|
3853
|
+
return pkg.name === "@cursor/sdk" && existsSync12(dir);
|
|
3619
3854
|
} catch {
|
|
3620
3855
|
return false;
|
|
3621
3856
|
}
|
|
3622
3857
|
}
|
|
3623
3858
|
function resolvedPackageRoot(fromFile) {
|
|
3624
3859
|
try {
|
|
3625
|
-
const req =
|
|
3860
|
+
const req = createRequire3(fromFile);
|
|
3626
3861
|
const pkgJson = req.resolve("@cursor/sdk/package.json");
|
|
3627
|
-
const root =
|
|
3862
|
+
const root = dirname5(pkgJson);
|
|
3628
3863
|
return packageRootLooksLikeSdk(root) ? root : null;
|
|
3629
3864
|
} catch {
|
|
3630
3865
|
return null;
|
|
@@ -3638,10 +3873,10 @@ function resolveCursorSdkRoot(opts) {
|
|
|
3638
3873
|
}
|
|
3639
3874
|
const globalNm = npmGlobalNodeModules(env);
|
|
3640
3875
|
if (globalNm) {
|
|
3641
|
-
const globalRoot =
|
|
3876
|
+
const globalRoot = join10(globalNm, "@cursor/sdk");
|
|
3642
3877
|
if (packageRootLooksLikeSdk(globalRoot)) return globalRoot;
|
|
3643
3878
|
}
|
|
3644
|
-
const cwdPkg =
|
|
3879
|
+
const cwdPkg = join10(process.cwd(), "package.json");
|
|
3645
3880
|
return resolvedPackageRoot(thisModuleFile()) ?? resolvedPackageRoot(cwdPkg);
|
|
3646
3881
|
}
|
|
3647
3882
|
function isCursorSdkInstalled(opts) {
|
|
@@ -3657,13 +3892,13 @@ function exportTarget(value) {
|
|
|
3657
3892
|
}
|
|
3658
3893
|
function cursorSdkEsmEntry(root) {
|
|
3659
3894
|
try {
|
|
3660
|
-
const pkg = JSON.parse(
|
|
3895
|
+
const pkg = JSON.parse(readFileSync6(join10(root, "package.json"), "utf8"));
|
|
3661
3896
|
const exp = pkg.exports;
|
|
3662
3897
|
const dot = exp && typeof exp === "object" && !Array.isArray(exp) && "." in exp ? exp["."] : exp;
|
|
3663
3898
|
const rel = exportTarget(dot) ?? (typeof pkg.module === "string" ? pkg.module : null);
|
|
3664
3899
|
if (!rel) return null;
|
|
3665
|
-
const entry =
|
|
3666
|
-
return
|
|
3900
|
+
const entry = join10(root, rel);
|
|
3901
|
+
return existsSync12(entry) ? entry : null;
|
|
3667
3902
|
} catch {
|
|
3668
3903
|
return null;
|
|
3669
3904
|
}
|
|
@@ -3679,7 +3914,7 @@ async function importCursorSdk(opts) {
|
|
|
3679
3914
|
try {
|
|
3680
3915
|
let entry = cursorSdkEsmEntry(root);
|
|
3681
3916
|
if (!entry) {
|
|
3682
|
-
const req =
|
|
3917
|
+
const req = createRequire3(join10(root, "package.json"));
|
|
3683
3918
|
entry = req.resolve("@cursor/sdk");
|
|
3684
3919
|
}
|
|
3685
3920
|
return unwrapCursorSdkModule(await import(pathToFileURL(entry).href));
|
|
@@ -3691,8 +3926,8 @@ function cursorSdkPlatformRipgrepPackage() {
|
|
|
3691
3926
|
return `@cursor/sdk-${process.platform}-${process.arch}`;
|
|
3692
3927
|
}
|
|
3693
3928
|
function nodeModulesDirForPackageRoot(packageRoot) {
|
|
3694
|
-
const parent =
|
|
3695
|
-
return basename(parent).startsWith("@") ?
|
|
3929
|
+
const parent = dirname5(packageRoot);
|
|
3930
|
+
return basename(parent).startsWith("@") ? dirname5(parent) : parent;
|
|
3696
3931
|
}
|
|
3697
3932
|
function cursorSdkRipgrepCandidate(opts) {
|
|
3698
3933
|
const root = resolveCursorSdkRoot(opts);
|
|
@@ -3700,10 +3935,10 @@ function cursorSdkRipgrepCandidate(opts) {
|
|
|
3700
3935
|
const nm = nodeModulesDirForPackageRoot(root);
|
|
3701
3936
|
const pkg = cursorSdkPlatformRipgrepPackage();
|
|
3702
3937
|
const bin = process.platform === "win32" ? "rg.exe" : "rg";
|
|
3703
|
-
const sibling =
|
|
3704
|
-
if (
|
|
3705
|
-
const nested =
|
|
3706
|
-
return
|
|
3938
|
+
const sibling = join10(nm, pkg, "bin", bin);
|
|
3939
|
+
if (existsSync12(sibling)) return sibling;
|
|
3940
|
+
const nested = join10(root, "node_modules", pkg, "bin", bin);
|
|
3941
|
+
return existsSync12(nested) ? nested : null;
|
|
3707
3942
|
}
|
|
3708
3943
|
|
|
3709
3944
|
// src/agents/cursor-events.ts
|
|
@@ -3918,9 +4153,9 @@ function parseCursorRunnerLine(line) {
|
|
|
3918
4153
|
}
|
|
3919
4154
|
|
|
3920
4155
|
// src/agents/cursor-ripgrep.ts
|
|
3921
|
-
import { existsSync as
|
|
3922
|
-
import { createRequire as
|
|
3923
|
-
import { dirname as
|
|
4156
|
+
import { existsSync as existsSync13 } from "fs";
|
|
4157
|
+
import { createRequire as createRequire4 } from "module";
|
|
4158
|
+
import { dirname as dirname6, isAbsolute, join as join11, parse, resolve as resolvePath } from "path";
|
|
3924
4159
|
var RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
|
|
3925
4160
|
function rgBinaryName() {
|
|
3926
4161
|
return process.platform === "win32" ? "rg.exe" : "rg";
|
|
@@ -3932,19 +4167,19 @@ function usableRipgrepPath(candidate) {
|
|
|
3932
4167
|
const raw = candidate?.trim();
|
|
3933
4168
|
if (!raw || !isAbsolute(raw)) return null;
|
|
3934
4169
|
const readable = nodeReadableScriptPath(raw);
|
|
3935
|
-
if (!
|
|
4170
|
+
if (!existsSync13(readable) || isAsarPath(readable)) return null;
|
|
3936
4171
|
return readable;
|
|
3937
4172
|
}
|
|
3938
4173
|
function walkForBundledRipgrep(startFile) {
|
|
3939
4174
|
if (!startFile) return null;
|
|
3940
4175
|
const pkg = platformRipgrepPackage();
|
|
3941
4176
|
const name = rgBinaryName();
|
|
3942
|
-
let dir =
|
|
4177
|
+
let dir = dirname6(resolvePath(startFile));
|
|
3943
4178
|
const root = parse(dir).root;
|
|
3944
4179
|
while (dir !== root) {
|
|
3945
|
-
const hit = usableRipgrepPath(
|
|
4180
|
+
const hit = usableRipgrepPath(join11(dir, "node_modules", pkg, "bin", name));
|
|
3946
4181
|
if (hit) return hit;
|
|
3947
|
-
const next =
|
|
4182
|
+
const next = dirname6(dir);
|
|
3948
4183
|
if (next === dir) break;
|
|
3949
4184
|
dir = next;
|
|
3950
4185
|
}
|
|
@@ -3952,9 +4187,9 @@ function walkForBundledRipgrep(startFile) {
|
|
|
3952
4187
|
}
|
|
3953
4188
|
function requireResolveBundledRipgrep(fromFile) {
|
|
3954
4189
|
try {
|
|
3955
|
-
const req =
|
|
4190
|
+
const req = createRequire4(fromFile);
|
|
3956
4191
|
const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
|
|
3957
|
-
return usableRipgrepPath(
|
|
4192
|
+
return usableRipgrepPath(join11(dirname6(pkgJson), "bin", rgBinaryName()));
|
|
3958
4193
|
} catch {
|
|
3959
4194
|
return null;
|
|
3960
4195
|
}
|
|
@@ -4024,15 +4259,15 @@ async function listCursorModels() {
|
|
|
4024
4259
|
return cachedModels?.models ?? FALLBACK_CURSOR_MODELS;
|
|
4025
4260
|
}
|
|
4026
4261
|
}
|
|
4027
|
-
function
|
|
4262
|
+
function entryDir2() {
|
|
4028
4263
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
4029
4264
|
if (cjsDir) return cjsDir;
|
|
4030
4265
|
try {
|
|
4031
|
-
return
|
|
4266
|
+
return dirname7(fileURLToPath4(import.meta.url));
|
|
4032
4267
|
} catch {
|
|
4033
4268
|
try {
|
|
4034
|
-
const req =
|
|
4035
|
-
return
|
|
4269
|
+
const req = createRequire5(process.cwd() + "/");
|
|
4270
|
+
return dirname7(req.resolve("@sideboard-ai/core"));
|
|
4036
4271
|
} catch {
|
|
4037
4272
|
return process.cwd();
|
|
4038
4273
|
}
|
|
@@ -4041,19 +4276,19 @@ function entryDir() {
|
|
|
4041
4276
|
function cursorRunnerPath() {
|
|
4042
4277
|
const packaged = packagedCursorRunnerPath();
|
|
4043
4278
|
if (packaged) return packaged;
|
|
4044
|
-
const root =
|
|
4279
|
+
const root = entryDir2();
|
|
4045
4280
|
const candidates = [
|
|
4046
|
-
|
|
4047
|
-
|
|
4281
|
+
join12(root, "agents", "cursor-runner.js"),
|
|
4282
|
+
join12(root, "agents", "cursor-runner.cjs"),
|
|
4048
4283
|
// If somehow resolved from package root instead of dist/
|
|
4049
|
-
|
|
4050
|
-
|
|
4284
|
+
join12(root, "dist", "agents", "cursor-runner.js"),
|
|
4285
|
+
join12(root, "dist", "agents", "cursor-runner.cjs"),
|
|
4051
4286
|
// Source tree (dev): packages/core/src/agents/cursor-runner.ts
|
|
4052
|
-
|
|
4053
|
-
|
|
4287
|
+
join12(root, "cursor-runner.ts"),
|
|
4288
|
+
join12(root, "src", "agents", "cursor-runner.ts")
|
|
4054
4289
|
];
|
|
4055
4290
|
for (const candidate of candidates) {
|
|
4056
|
-
if (
|
|
4291
|
+
if (existsSync14(candidate)) return candidate;
|
|
4057
4292
|
}
|
|
4058
4293
|
return candidates[0];
|
|
4059
4294
|
}
|
|
@@ -4094,13 +4329,15 @@ var cursorAdapter = {
|
|
|
4094
4329
|
const prompt = flattenTurnInput(dropCachedPrefixOnResume(input, agentId));
|
|
4095
4330
|
const apiKey = resolveCursorApiKey() || void 0;
|
|
4096
4331
|
const isOrchestrator = isOrchestratorThread(thread);
|
|
4332
|
+
const rpc = agentRpcConnectFromMetadata();
|
|
4097
4333
|
const injected = await buildInjectedMcpServers({
|
|
4098
4334
|
includeSideboard: true,
|
|
4099
4335
|
includeBrightsy: shouldInjectBrightsyMcp(thread, {
|
|
4100
4336
|
orchestrator: isOrchestrator
|
|
4101
4337
|
}),
|
|
4102
4338
|
orchestratorThreadId: isOrchestrator ? thread.id : null,
|
|
4103
|
-
threadId: thread.id
|
|
4339
|
+
threadId: thread.id,
|
|
4340
|
+
rpcNativeTools: Boolean(rpc)
|
|
4104
4341
|
});
|
|
4105
4342
|
const mcpServers = toCursorMcpServers(injected);
|
|
4106
4343
|
const req = {
|
|
@@ -4114,6 +4351,8 @@ var cursorAdapter = {
|
|
|
4114
4351
|
planMode: thread.planMode,
|
|
4115
4352
|
apiKey,
|
|
4116
4353
|
...isOrchestrator ? { isolateAmbientMcp: true } : {},
|
|
4354
|
+
...rpc ? { agentRpc: rpc } : {},
|
|
4355
|
+
...isOrchestrator && rpc ? { rpcWaitForTurn: true } : {},
|
|
4117
4356
|
...Object.keys(mcpServers).length > 0 ? { mcpServers } : {}
|
|
4118
4357
|
};
|
|
4119
4358
|
const runner = cursorRunnerPath();
|
|
@@ -4152,7 +4391,155 @@ var cursorAdapter = {
|
|
|
4152
4391
|
};
|
|
4153
4392
|
|
|
4154
4393
|
// src/agents/opencode.ts
|
|
4155
|
-
import { existsSync as
|
|
4394
|
+
import { existsSync as existsSync15 } from "fs";
|
|
4395
|
+
|
|
4396
|
+
// src/agent-rpc/opencode-hook.ts
|
|
4397
|
+
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync5 } from "fs";
|
|
4398
|
+
import { join as join13 } from "path";
|
|
4399
|
+
var OPENCODE_PLUGIN_SOURCE = `import { tool } from "@opencode-ai/plugin"
|
|
4400
|
+
|
|
4401
|
+
const URL = process.env[${JSON.stringify(AGENT_RPC_URL_ENV)}] || ""
|
|
4402
|
+
const TOKEN = process.env[${JSON.stringify(AGENT_RPC_TOKEN_ENV)}] || ""
|
|
4403
|
+
const CWD = process.env[${JSON.stringify(AGENT_RPC_CWD_ENV)}] || ""
|
|
4404
|
+
|
|
4405
|
+
function jsonResult(value) {
|
|
4406
|
+
return JSON.stringify(value)
|
|
4407
|
+
}
|
|
4408
|
+
|
|
4409
|
+
function jsonError(err) {
|
|
4410
|
+
return jsonResult({ ok: false, error: err instanceof Error ? err.message : String(err) })
|
|
4411
|
+
}
|
|
4412
|
+
|
|
4413
|
+
function socketUrl() {
|
|
4414
|
+
const u = new URL(URL)
|
|
4415
|
+
u.searchParams.set(${JSON.stringify(AGENT_RPC_TOKEN_QUERY)}, TOKEN)
|
|
4416
|
+
return u.toString()
|
|
4417
|
+
}
|
|
4418
|
+
|
|
4419
|
+
function call(method, params) {
|
|
4420
|
+
if (!URL || !TOKEN) {
|
|
4421
|
+
return Promise.resolve(jsonError(new Error("Agent RPC runtime is not running")))
|
|
4422
|
+
}
|
|
4423
|
+
return new Promise((resolve) => {
|
|
4424
|
+
let settled = false
|
|
4425
|
+
const done = (value) => {
|
|
4426
|
+
if (settled) return
|
|
4427
|
+
settled = true
|
|
4428
|
+
try { ws.close() } catch {}
|
|
4429
|
+
resolve(value)
|
|
4430
|
+
}
|
|
4431
|
+
const ws = new WebSocket(socketUrl())
|
|
4432
|
+
const id = Date.now()
|
|
4433
|
+
ws.addEventListener("open", () => {
|
|
4434
|
+
ws.send(JSON.stringify({ jsonrpc: "2.0", id, method, params, authToken: TOKEN }))
|
|
4435
|
+
})
|
|
4436
|
+
ws.addEventListener("message", (ev) => {
|
|
4437
|
+
let msg
|
|
4438
|
+
try { msg = JSON.parse(String(ev.data)) } catch { return }
|
|
4439
|
+
if (msg && msg.id === id) {
|
|
4440
|
+
if (msg.error) done(jsonError(new Error(msg.error.message || "Agent RPC error")))
|
|
4441
|
+
else done(jsonResult(msg.result))
|
|
4442
|
+
}
|
|
4443
|
+
})
|
|
4444
|
+
ws.addEventListener("error", () => done(jsonError(new Error("Agent RPC socket error"))))
|
|
4445
|
+
ws.addEventListener("close", () => {
|
|
4446
|
+
if (!settled) done(jsonError(new Error("Agent RPC socket closed")))
|
|
4447
|
+
})
|
|
4448
|
+
})
|
|
4449
|
+
}
|
|
4450
|
+
|
|
4451
|
+
function str(description) {
|
|
4452
|
+
return tool.schema.string().describe(description)
|
|
4453
|
+
}
|
|
4454
|
+
|
|
4455
|
+
function opt(description) {
|
|
4456
|
+
return tool.schema.string().optional().describe(description)
|
|
4457
|
+
}
|
|
4458
|
+
|
|
4459
|
+
export const SideboardRpc = async (ctx) => {
|
|
4460
|
+
const cwd = CWD || ctx.worktree || ctx.directory || ""
|
|
4461
|
+
const job = (method, args) => call(method, { ...args, cwd })
|
|
4462
|
+
return {
|
|
4463
|
+
tool: {
|
|
4464
|
+
present_artifact: tool({
|
|
4465
|
+
description: ${JSON.stringify(PILOT_TOOL_DESCRIPTIONS.present_artifact)},
|
|
4466
|
+
args: {
|
|
4467
|
+
title: str("Short title shown in the artifact pane header"),
|
|
4468
|
+
type: tool.schema.enum(["html", "svg", "markdown", "react", "log"]),
|
|
4469
|
+
content: str("html/svg/markdown/react: full document. log: only the new lines."),
|
|
4470
|
+
artifact_id: opt("Stable id. Required for type=log."),
|
|
4471
|
+
status: tool.schema.enum(["running", "ok", "failed", "idle"]).optional(),
|
|
4472
|
+
phase: opt("Progress phase"),
|
|
4473
|
+
mode: tool.schema.enum(["append", "replace"]).optional(),
|
|
4474
|
+
},
|
|
4475
|
+
async execute(args) {
|
|
4476
|
+
return call("ui.presentArtifact", args)
|
|
4477
|
+
},
|
|
4478
|
+
}),
|
|
4479
|
+
wait_for_job: tool({
|
|
4480
|
+
description: ${JSON.stringify(PILOT_TOOL_DESCRIPTIONS.wait_for_job)},
|
|
4481
|
+
args: {
|
|
4482
|
+
id: str("Detached job id (same kebab-case id passed to detached-job.cjs start)"),
|
|
4483
|
+
},
|
|
4484
|
+
async execute(args) {
|
|
4485
|
+
return job("job.wait", args)
|
|
4486
|
+
},
|
|
4487
|
+
}),
|
|
4488
|
+
stop_job: tool({
|
|
4489
|
+
description: ${JSON.stringify(PILOT_TOOL_DESCRIPTIONS.stop_job)},
|
|
4490
|
+
args: {
|
|
4491
|
+
id: str("Detached job id"),
|
|
4492
|
+
reason: opt("Why the job is being stopped"),
|
|
4493
|
+
},
|
|
4494
|
+
async execute(args) {
|
|
4495
|
+
return job("job.stop", args)
|
|
4496
|
+
},
|
|
4497
|
+
}),
|
|
4498
|
+
},
|
|
4499
|
+
}
|
|
4500
|
+
}
|
|
4501
|
+
`;
|
|
4502
|
+
function writeOpencodeRpcPlugin() {
|
|
4503
|
+
const configDir = join13(appDataDir(), "agent-rpc", "opencode");
|
|
4504
|
+
const pluginDir = join13(configDir, "plugins");
|
|
4505
|
+
mkdirSync3(pluginDir, { recursive: true });
|
|
4506
|
+
const pluginFile = join13(pluginDir, "sideboard-rpc.js");
|
|
4507
|
+
writeFileSync5(pluginFile, OPENCODE_PLUGIN_SOURCE);
|
|
4508
|
+
return { configDir, pluginFile };
|
|
4509
|
+
}
|
|
4510
|
+
|
|
4511
|
+
// src/agent-rpc/opencode-host.ts
|
|
4512
|
+
async function buildOpencodeHostEnv(thread) {
|
|
4513
|
+
const isOrchestrator = isOrchestratorThread(thread);
|
|
4514
|
+
const rpc = worktreeAgentRpc(isOrchestrator);
|
|
4515
|
+
const injected = await buildInjectedMcpServers({
|
|
4516
|
+
includeSideboard: true,
|
|
4517
|
+
includeBrightsy: shouldInjectBrightsyMcp(thread, {
|
|
4518
|
+
orchestrator: isOrchestrator
|
|
4519
|
+
}),
|
|
4520
|
+
orchestratorThreadId: isOrchestrator ? thread.id : null,
|
|
4521
|
+
threadId: thread.id,
|
|
4522
|
+
rpcNativeTools: Boolean(rpc)
|
|
4523
|
+
});
|
|
4524
|
+
const disableNames = isOrchestrator ? userMcpNamesToDisable({
|
|
4525
|
+
injectedNames: injected.map((s) => s.name),
|
|
4526
|
+
names: listUserOpencodeMcpNames()
|
|
4527
|
+
}) : [];
|
|
4528
|
+
const config = injected.length > 0 || disableNames.length > 0 ? JSON.parse(toOpencodeMcpConfigContent(injected, { disableNames })) : {};
|
|
4529
|
+
const env = {};
|
|
4530
|
+
if (rpc) {
|
|
4531
|
+
const { configDir, pluginFile } = writeOpencodeRpcPlugin();
|
|
4532
|
+
env.OPENCODE_CONFIG_DIR = configDir;
|
|
4533
|
+
Object.assign(env, agentRpcChildEnv(rpc, thread.worktreePath));
|
|
4534
|
+
config.plugin = [pluginFile];
|
|
4535
|
+
}
|
|
4536
|
+
if (Object.keys(config).length > 0) {
|
|
4537
|
+
env.OPENCODE_CONFIG_CONTENT = JSON.stringify(config);
|
|
4538
|
+
}
|
|
4539
|
+
return env;
|
|
4540
|
+
}
|
|
4541
|
+
|
|
4542
|
+
// src/agents/opencode.ts
|
|
4156
4543
|
var FALLBACK_OPENCODE_MODELS = [
|
|
4157
4544
|
{ id: "opencode/big-pickle", displayName: "opencode \xB7 big-pickle" },
|
|
4158
4545
|
{
|
|
@@ -4211,7 +4598,7 @@ async function listOpencodeModels() {
|
|
|
4211
4598
|
if (opencode === "opencode") {
|
|
4212
4599
|
const which = await run("which", ["opencode"], { reject: false });
|
|
4213
4600
|
if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
|
|
4214
|
-
} else if (!
|
|
4601
|
+
} else if (!existsSync15(opencode)) {
|
|
4215
4602
|
return FALLBACK_OPENCODE_MODELS;
|
|
4216
4603
|
}
|
|
4217
4604
|
const listed = await run(opencode, ["models"], { reject: false });
|
|
@@ -4246,7 +4633,7 @@ var opencodeAdapter = {
|
|
|
4246
4633
|
async detect() {
|
|
4247
4634
|
const opencode = resolveAgentExecutable("opencode");
|
|
4248
4635
|
if (opencode !== "opencode") {
|
|
4249
|
-
if (!
|
|
4636
|
+
if (!existsSync15(opencode)) {
|
|
4250
4637
|
return {
|
|
4251
4638
|
agent: "opencode",
|
|
4252
4639
|
installed: false,
|
|
@@ -4300,20 +4687,7 @@ var opencodeAdapter = {
|
|
|
4300
4687
|
if (model) {
|
|
4301
4688
|
args.push("--model", model);
|
|
4302
4689
|
}
|
|
4303
|
-
const
|
|
4304
|
-
const injected = await buildInjectedMcpServers({
|
|
4305
|
-
includeSideboard: true,
|
|
4306
|
-
includeBrightsy: shouldInjectBrightsyMcp(thread, {
|
|
4307
|
-
orchestrator: isOrchestrator
|
|
4308
|
-
}),
|
|
4309
|
-
orchestratorThreadId: isOrchestrator ? thread.id : null,
|
|
4310
|
-
threadId: thread.id
|
|
4311
|
-
});
|
|
4312
|
-
const disableNames = isOrchestrator ? userMcpNamesToDisable({
|
|
4313
|
-
injectedNames: injected.map((s) => s.name),
|
|
4314
|
-
names: listUserOpencodeMcpNames()
|
|
4315
|
-
}) : [];
|
|
4316
|
-
const mcpContent = injected.length > 0 || disableNames.length > 0 ? toOpencodeMcpConfigContent(injected, { disableNames }) : null;
|
|
4690
|
+
const hostEnv = await buildOpencodeHostEnv(thread);
|
|
4317
4691
|
return {
|
|
4318
4692
|
file: resolveAgentExecutable("opencode"),
|
|
4319
4693
|
args,
|
|
@@ -4323,7 +4697,7 @@ var opencodeAdapter = {
|
|
|
4323
4697
|
stdin: prompt,
|
|
4324
4698
|
env: {
|
|
4325
4699
|
OPENCODE_PERMISSION: mode.opencodePermission,
|
|
4326
|
-
...
|
|
4700
|
+
...hostEnv
|
|
4327
4701
|
}
|
|
4328
4702
|
};
|
|
4329
4703
|
},
|
|
@@ -4924,9 +5298,9 @@ function formatClaudeUsageOverLimitWait(windows, now = /* @__PURE__ */ new Date(
|
|
|
4924
5298
|
}
|
|
4925
5299
|
|
|
4926
5300
|
// src/agents/claude-usage-client.ts
|
|
4927
|
-
import { existsSync as
|
|
5301
|
+
import { existsSync as existsSync16, readFileSync as readFileSync7 } from "fs";
|
|
4928
5302
|
import { homedir as homedir5 } from "os";
|
|
4929
|
-
import { join as
|
|
5303
|
+
import { join as join14 } from "path";
|
|
4930
5304
|
var CLAUDE_OAUTH_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
|
|
4931
5305
|
var CLAUDE_USAGE_TTL_MS = 9e4;
|
|
4932
5306
|
var CLAUDE_USAGE_ERROR_TTL_MS = 5 * 6e4;
|
|
@@ -4966,14 +5340,14 @@ function accessTokenFromCredentialsJson(raw) {
|
|
|
4966
5340
|
}
|
|
4967
5341
|
}
|
|
4968
5342
|
function claudeCredentialsPath(configDir) {
|
|
4969
|
-
const root = configDir?.trim() || process.env.CLAUDE_CONFIG_DIR?.trim() ||
|
|
4970
|
-
return
|
|
5343
|
+
const root = configDir?.trim() || process.env.CLAUDE_CONFIG_DIR?.trim() || join14(homedir5(), ".claude");
|
|
5344
|
+
return join14(root, ".credentials.json");
|
|
4971
5345
|
}
|
|
4972
5346
|
async function readFileAccessToken(configDir) {
|
|
4973
5347
|
const path = claudeCredentialsPath(configDir);
|
|
4974
|
-
if (!
|
|
5348
|
+
if (!existsSync16(path)) return null;
|
|
4975
5349
|
try {
|
|
4976
|
-
return accessTokenFromCredentialsJson(
|
|
5350
|
+
return accessTokenFromCredentialsJson(readFileSync7(path, "utf8"));
|
|
4977
5351
|
} catch {
|
|
4978
5352
|
return null;
|
|
4979
5353
|
}
|
|
@@ -5086,7 +5460,7 @@ async function getClaudePlanUsage(opts = {}) {
|
|
|
5086
5460
|
}
|
|
5087
5461
|
|
|
5088
5462
|
// src/agents/install.ts
|
|
5089
|
-
import { existsSync as
|
|
5463
|
+
import { existsSync as existsSync17 } from "fs";
|
|
5090
5464
|
var SETUP = {
|
|
5091
5465
|
claude: {
|
|
5092
5466
|
agent: "claude",
|
|
@@ -5267,7 +5641,7 @@ async function installNpmGlobalPackage(opts) {
|
|
|
5267
5641
|
async function resolveExistingCli(agent) {
|
|
5268
5642
|
if (agent === "cursor") return null;
|
|
5269
5643
|
const exe = resolveAgentExecutable(agent);
|
|
5270
|
-
if ((exe.includes("/") || exe.includes("\\")) &&
|
|
5644
|
+
if ((exe.includes("/") || exe.includes("\\")) && existsSync17(exe)) return exe;
|
|
5271
5645
|
enrichPathWithNpmGlobalBin();
|
|
5272
5646
|
return whichOnPath(CLI_BIN[agent]);
|
|
5273
5647
|
}
|
|
@@ -5341,7 +5715,7 @@ async function loginAgent(agent) {
|
|
|
5341
5715
|
};
|
|
5342
5716
|
}
|
|
5343
5717
|
async function loginManagedAccount(accountId) {
|
|
5344
|
-
const { loadAppSettings: loadAppSettings2 } = await import("./app-settings-
|
|
5718
|
+
const { loadAppSettings: loadAppSettings2 } = await import("./app-settings-MVZPM6WW.js");
|
|
5345
5719
|
const { loginEnvPrefix } = await import("./managed-accounts-4BLTJKAN.js");
|
|
5346
5720
|
const account = loadAppSettings2().accounts.accounts.find((a) => a.id === accountId);
|
|
5347
5721
|
if (!account) {
|
|
@@ -5395,16 +5769,6 @@ export {
|
|
|
5395
5769
|
shouldFeedErrorBackToAgent,
|
|
5396
5770
|
formatAgentErrorContinuePrompt,
|
|
5397
5771
|
formatTurnExitError,
|
|
5398
|
-
encodeBrightsyTarget,
|
|
5399
|
-
decodeBrightsyTarget,
|
|
5400
|
-
parseBrightsyCliLine,
|
|
5401
|
-
adjustBrightsyTurnExit,
|
|
5402
|
-
listBrightsyChatTargets,
|
|
5403
|
-
brightsyAdapter,
|
|
5404
|
-
SIDEBOARD_THREAD_ID_ENV,
|
|
5405
|
-
sideboardMcpProfile,
|
|
5406
|
-
packagedMcpDir,
|
|
5407
|
-
applyAgentRunnerHeapEnv,
|
|
5408
5772
|
toolDescription,
|
|
5409
5773
|
isInternalAgentStatusText,
|
|
5410
5774
|
isPollWrapperToolName,
|
|
@@ -5418,6 +5782,18 @@ export {
|
|
|
5418
5782
|
isBrightsyNdjsonLine,
|
|
5419
5783
|
finalizeParts,
|
|
5420
5784
|
normalizeParseResult,
|
|
5785
|
+
encodeBrightsyTarget,
|
|
5786
|
+
decodeBrightsyTarget,
|
|
5787
|
+
parseBrightsyCliLine,
|
|
5788
|
+
adjustBrightsyTurnExit,
|
|
5789
|
+
listBrightsyChatTargets,
|
|
5790
|
+
brightsyAdapter,
|
|
5791
|
+
SIDEBOARD_THREAD_ID_ENV,
|
|
5792
|
+
shouldRegisterMcpWaitForTurn,
|
|
5793
|
+
worktreeMcpToolNames,
|
|
5794
|
+
sideboardMcpProfile,
|
|
5795
|
+
packagedMcpDir,
|
|
5796
|
+
applyAgentRunnerHeapEnv,
|
|
5421
5797
|
PLAN_MODE_INSTRUCTION,
|
|
5422
5798
|
PLAN_MODE_OFF_INSTRUCTION,
|
|
5423
5799
|
planModeTurnInstruction,
|