@sideboard-ai/core 0.1.324 → 0.1.326
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-CU2UPMJF.js → abletime-RDHYSZL2.js} +5 -4
- package/dist/{abletime-5ZY3ZUUO.js → abletime-RYYFGKMU.js} +6 -5
- package/dist/{abletime-oauth-7EOSBEFM.js → abletime-oauth-OYGS2DAU.js} +3 -3
- package/dist/{abletime-oauth-4TTCR3CT.js → abletime-oauth-QR2QDVMK.js} +3 -3
- package/dist/{abletime-rest-KOKE7V4B.js → abletime-rest-BKYKNPTC.js} +3 -3
- package/dist/{abletime-rest-3TG4G7LW.js → abletime-rest-QDPTWNS4.js} +3 -3
- package/dist/agents/claude-runner.cjs +59 -22
- package/dist/agents/claude-runner.js +39 -16
- package/dist/agents/cursor-runner.cjs +97 -32
- package/dist/agents/cursor-runner.js +74 -24
- package/dist/{agents-YK65UDLT.js → agents-HANWZNI6.js} +9 -8
- package/dist/{agents-LUSTCMDN.js → agents-QO7GKBYT.js} +12 -11
- package/dist/{app-settings-XIF4EC4K.js → app-settings-RXBH7KY4.js} +1 -1
- package/dist/{app-settings-I5HM5RMP.js → app-settings-TUVLZNDE.js} +1 -1
- package/dist/{chunk-7MQSYPAY.js → chunk-2EOLWHXH.js} +206 -188
- package/dist/{chunk-QOS4465Y.js → chunk-3Q4XNYHY.js} +1 -1
- package/dist/{chunk-RR4WCGNB.js → chunk-46FECFZU.js} +18 -15
- package/dist/{chunk-5GDJSFCT.js → chunk-4H5MWZ6J.js} +2 -2
- package/dist/{chunk-EQ52JR3Q.js → chunk-5MXLDDYF.js} +1 -1
- package/dist/{chunk-NCHOTN3C.js → chunk-5YCKATG6.js} +4 -3
- package/dist/{chunk-ROOZDDFA.js → chunk-75RPUXJS.js} +7 -8
- package/dist/{chunk-INBUV7HY.js → chunk-B244TJWC.js} +2 -2
- package/dist/{chunk-JH5SMVM5.js → chunk-BBNWKL4I.js} +268 -235
- package/dist/{chunk-ODH3XHMI.js → chunk-C7HUCBX7.js} +5 -5
- package/dist/{chunk-OIHRC2ZJ.js → chunk-D744HOI5.js} +25 -3
- package/dist/chunk-DBKHL7NC.js +214 -0
- package/dist/chunk-F6GE7V3Q.js +216 -0
- package/dist/{chunk-JE3JLHMO.js → chunk-FWVUGLBG.js} +3 -3
- package/dist/{chunk-DF5BM5OY.js → chunk-GP3RLZ6A.js} +207 -186
- package/dist/{chunk-FR3SAYUL.js → chunk-JM2TGOHP.js} +5 -5
- package/dist/{chunk-Y3WREIPQ.js → chunk-K7M7MIWL.js} +12 -210
- package/dist/{chunk-FUFNMUNR.js → chunk-KECHK3ZT.js} +7 -8
- package/dist/{chunk-EKU7FQVG.js → chunk-KXRF6RNL.js} +2 -2
- package/dist/chunk-LRHUBGEM.js +1259 -0
- package/dist/{chunk-MZIZTSR2.js → chunk-MAW7DIG7.js} +2 -2
- package/dist/{chunk-ZHGMRBSC.js → chunk-NURZOXGN.js} +4 -4
- package/dist/{chunk-QIC2JXHW.js → chunk-OOXRMTU6.js} +1 -1
- package/dist/{chunk-5XNT6BCG.js → chunk-OPXEJJBM.js} +1 -1
- package/dist/chunk-OYRN356W.js +80 -0
- package/dist/{chunk-7PVT73H6.js → chunk-PB6HW7SA.js} +12 -210
- package/dist/{chunk-B4CDSSRN.js → chunk-Q3FHTGIW.js} +2 -0
- package/dist/{chunk-7D5QIU3N.js → chunk-QG4CYRA3.js} +301 -268
- package/dist/{chunk-EJ66LEKH.js → chunk-QPSKQP6E.js} +24 -3
- package/dist/{chunk-Q3YJZPQI.js → chunk-RZVOX2MT.js} +3 -3
- package/dist/chunk-SO7G6O24.js +1445 -0
- package/dist/{chunk-YDUHLWI5.js → chunk-SUZOPJZC.js} +21 -7
- package/dist/chunk-TMCK5TLA.js +25 -0
- package/dist/chunk-W3ZLE4PO.js +77 -0
- package/dist/chunk-WUCAVIIP.js +28 -0
- package/dist/{chunk-BYUCNIXK.js → chunk-XLVLMQKN.js} +13 -9
- package/dist/{chunk-ZIRQZUZY.js → chunk-YGVGXQA7.js} +3 -3
- package/dist/{chunk-NXUN4U5P.js → chunk-YWQF7WAG.js} +2 -2
- package/dist/{chunk-IFWGG2M2.js → chunk-ZSHS46V5.js} +2 -0
- package/dist/{chunk-74OPNF7U.js → chunk-ZUAYA57W.js} +2 -2
- package/dist/{conductor-SPZOTC7W.js → conductor-4GVTHUUB.js} +7 -7
- package/dist/{conductor-JFABMXDA.js → conductor-TGWI6ETZ.js} +6 -6
- package/dist/{coordinator-prompt-K66RGNWK.js → coordinator-prompt-3E6SIDTM.js} +4 -4
- package/dist/{coordinator-prompt-Z6UFHFDH.js → coordinator-prompt-WEYJREV6.js} +4 -4
- package/dist/{cursor-recover-TEBFKAZ4.js → cursor-recover-7F46PAJ5.js} +1 -1
- package/dist/{cursor-recover-OWPQUHFH.js → cursor-recover-BDIAZIE3.js} +1 -1
- package/dist/{global-workspace-A6UO6PJV.js → global-workspace-FPDZKUPF.js} +4 -4
- package/dist/{global-workspace-RHEO55B4.js → global-workspace-UIEXAG2B.js} +4 -4
- package/dist/index.cjs +21094 -20840
- package/dist/index.d.cts +36 -17
- package/dist/index.d.ts +36 -17
- package/dist/index.js +343 -1678
- package/dist/linear-6S7MK5YK.js +69 -0
- package/dist/linear-Z2T4KUAQ.js +67 -0
- package/dist/linear-list-A37WLUBO.js +6 -0
- package/dist/linear-list-Q4M7AZO2.js +8 -0
- package/dist/mcp/run-stdio.cjs +15903 -15640
- package/dist/mcp/run-stdio.js +67 -1247
- package/dist/{optional-cli-RMMS5L6F.js → optional-cli-AANBL4U5.js} +3 -3
- package/dist/{optional-cli-Y3Z3GIPZ.js → optional-cli-CA4LL322.js} +4 -4
- package/dist/{orchestrator-7VTAUY24.js → orchestrator-7FVDBE7Y.js} +15 -13
- package/dist/{orchestrator-2O6OJQLX.js → orchestrator-RQXRZW7Z.js} +14 -12
- package/dist/{thread-store-3F7GR64A.js → thread-store-4ZN3DS2W.js} +1 -1
- package/dist/{thread-store-JRSL4HQY.js → thread-store-IC4BQXDW.js} +1 -1
- package/dist/{workspaces-NRKEXOYR.js → workspaces-LEW4UP56.js} +4 -4
- package/dist/{workspaces-42E6AGXD.js → workspaces-QONNLHNR.js} +4 -4
- package/dist/{worktree-ZDA2UJ7C.js → worktree-6GIONDQO.js} +3 -3
- package/dist/{worktree-4NGXCCUO.js → worktree-KFEJAQ2H.js} +3 -3
- package/package.json +1 -1
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
applyConnectedTeamToCli,
|
|
5
|
-
brightsyMcpServerName,
|
|
6
|
-
ensureCliTeamTracked,
|
|
7
|
-
ensureConnectedBrightsyTeamTokens
|
|
8
|
-
} from "./chunk-6U6QRUHY.js";
|
|
9
|
-
import {
|
|
10
|
-
loadBrightsyConfig
|
|
11
|
-
} from "./chunk-E63AM3PW.js";
|
|
12
|
-
import {
|
|
13
|
-
httpFetch
|
|
14
|
-
} from "./chunk-2GPQZZLY.js";
|
|
15
3
|
import {
|
|
16
4
|
extractJsonErrorMessage,
|
|
17
5
|
formatUnknownDetail,
|
|
@@ -21,16 +9,31 @@ import {
|
|
|
21
9
|
looksLikeSkillBody,
|
|
22
10
|
skillCommandFromBody,
|
|
23
11
|
withEventParentId
|
|
24
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-5MXLDDYF.js";
|
|
25
13
|
import {
|
|
26
14
|
isOrchestratorThread
|
|
27
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-YGVGXQA7.js";
|
|
28
16
|
import {
|
|
29
17
|
codexUnattendedGitConfigArgs,
|
|
30
18
|
mergeAgentGitAuthEnv,
|
|
31
19
|
resolveAgentGitAuthEnv,
|
|
32
20
|
resolveCodexGitWritableRoots
|
|
33
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-75RPUXJS.js";
|
|
22
|
+
import {
|
|
23
|
+
applyConnectedTeamToCli,
|
|
24
|
+
brightsyMcpServerName,
|
|
25
|
+
ensureCliTeamTracked,
|
|
26
|
+
ensureConnectedBrightsyTeamTokens
|
|
27
|
+
} from "./chunk-6U6QRUHY.js";
|
|
28
|
+
import {
|
|
29
|
+
loadBrightsyConfig
|
|
30
|
+
} from "./chunk-E63AM3PW.js";
|
|
31
|
+
import {
|
|
32
|
+
httpFetch
|
|
33
|
+
} from "./chunk-2GPQZZLY.js";
|
|
34
|
+
import {
|
|
35
|
+
listAssignedLinearIssues
|
|
36
|
+
} from "./chunk-WUCAVIIP.js";
|
|
34
37
|
import {
|
|
35
38
|
githubAgentAuthReady,
|
|
36
39
|
npmGlobalNodeModules,
|
|
@@ -43,9 +46,10 @@ import {
|
|
|
43
46
|
isLinearConnected,
|
|
44
47
|
isPosthogConnected,
|
|
45
48
|
loadAppSettings,
|
|
49
|
+
requestOccupancy,
|
|
46
50
|
resolveAgentExecutable,
|
|
47
51
|
resolveClaudeExecutable
|
|
48
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-D744HOI5.js";
|
|
49
53
|
import {
|
|
50
54
|
isElectronLikeCommand,
|
|
51
55
|
unwrapStrippedElectronLaunch,
|
|
@@ -57,7 +61,7 @@ import {
|
|
|
57
61
|
CLAUDE_POSTHOG_CONNECTOR_ALLOWED_TOOLS,
|
|
58
62
|
CLAUDE_PRINT_BG_WAIT_CEILING_MS,
|
|
59
63
|
mcpAllowToolsFromNames
|
|
60
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-Q3FHTGIW.js";
|
|
61
65
|
import {
|
|
62
66
|
appDataDir
|
|
63
67
|
} from "./chunk-WOU343SI.js";
|
|
@@ -448,6 +452,7 @@ var brightsyAdapter = {
|
|
|
448
452
|
|
|
449
453
|
// src/agents/claude.ts
|
|
450
454
|
import { existsSync as existsSync11 } from "fs";
|
|
455
|
+
import { dirname as dirname5 } from "path";
|
|
451
456
|
|
|
452
457
|
// src/agents/claude-mcp-status.ts
|
|
453
458
|
var SIDEBOARD_CONNECTOR_SERVICES = [
|
|
@@ -564,7 +569,7 @@ function isNotableMcpInitStatus(server, sideboardOk, coverage) {
|
|
|
564
569
|
|
|
565
570
|
// src/mcp-ui/host.ts
|
|
566
571
|
import { createHash } from "crypto";
|
|
567
|
-
import { homedir as
|
|
572
|
+
import { homedir as homedir6 } from "os";
|
|
568
573
|
|
|
569
574
|
// src/agents/orch-mcp-isolation.ts
|
|
570
575
|
import { existsSync as existsSync8, readFileSync as readFileSync4 } from "fs";
|
|
@@ -921,20 +926,20 @@ function readJson(path) {
|
|
|
921
926
|
}
|
|
922
927
|
|
|
923
928
|
// src/agents/orch-mcp-isolation.ts
|
|
924
|
-
import { homedir as
|
|
925
|
-
import { join as
|
|
929
|
+
import { homedir as homedir5 } from "os";
|
|
930
|
+
import { join as join8 } from "path";
|
|
926
931
|
import { parse as parseToml } from "smol-toml";
|
|
927
932
|
|
|
928
933
|
// src/agents/user-mcp-config.ts
|
|
929
|
-
import { existsSync as existsSync7, mkdirSync as
|
|
930
|
-
import { homedir as
|
|
931
|
-
import { dirname as dirname3, join as
|
|
934
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
935
|
+
import { homedir as homedir4 } from "os";
|
|
936
|
+
import { dirname as dirname3, join as join7 } from "path";
|
|
932
937
|
|
|
933
938
|
// src/agents/injected-mcp.ts
|
|
934
|
-
import { existsSync as existsSync6, mkdtempSync, writeFileSync as
|
|
939
|
+
import { existsSync as existsSync6, mkdtempSync, writeFileSync as writeFileSync3 } from "fs";
|
|
935
940
|
import { createRequire } from "module";
|
|
936
941
|
import { tmpdir } from "os";
|
|
937
|
-
import { dirname as dirname2, join as
|
|
942
|
+
import { dirname as dirname2, join as join6 } from "path";
|
|
938
943
|
import { fileURLToPath } from "url";
|
|
939
944
|
|
|
940
945
|
// src/agent-rpc/protocol.ts
|
|
@@ -1401,6 +1406,44 @@ async function resolveNodeLaunch(scriptPath) {
|
|
|
1401
1406
|
};
|
|
1402
1407
|
}
|
|
1403
1408
|
|
|
1409
|
+
// src/agents/codex-mcp-profile.ts
|
|
1410
|
+
import { randomBytes } from "crypto";
|
|
1411
|
+
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
1412
|
+
import { homedir as homedir3 } from "os";
|
|
1413
|
+
import { join as join5 } from "path";
|
|
1414
|
+
function isCodexSecretEnvKey(key) {
|
|
1415
|
+
return /token|secret|password|credential|oauth|api_key|_key$/i.test(key);
|
|
1416
|
+
}
|
|
1417
|
+
function tomlBasicString(value) {
|
|
1418
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r")}"`;
|
|
1419
|
+
}
|
|
1420
|
+
function secretEnv(env) {
|
|
1421
|
+
if (!env) return void 0;
|
|
1422
|
+
const out = { ...env };
|
|
1423
|
+
delete out.ELECTRON_RUN_AS_NODE;
|
|
1424
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
1425
|
+
}
|
|
1426
|
+
function writeCodexMcpSecretProfile(servers) {
|
|
1427
|
+
const blocks = [];
|
|
1428
|
+
for (const s of servers) {
|
|
1429
|
+
const env = secretEnv(s.env);
|
|
1430
|
+
if (!env) continue;
|
|
1431
|
+
const secrets = Object.entries(env).filter(([key]) => isCodexSecretEnvKey(key));
|
|
1432
|
+
if (secrets.length === 0) continue;
|
|
1433
|
+
const lines = [`[mcp_servers.${s.name}.env]`];
|
|
1434
|
+
for (const [key, value] of secrets) lines.push(`${key} = ${tomlBasicString(value)}`);
|
|
1435
|
+
blocks.push(lines.join("\n"));
|
|
1436
|
+
}
|
|
1437
|
+
if (blocks.length === 0) return null;
|
|
1438
|
+
const home = process.env.CODEX_HOME?.trim() || join5(homedir3(), ".codex");
|
|
1439
|
+
mkdirSync2(home, { recursive: true, mode: 448 });
|
|
1440
|
+
const profile = `sideboard-${randomBytes(8).toString("hex")}`;
|
|
1441
|
+
const file = join5(home, `${profile}.config.toml`);
|
|
1442
|
+
writeFileSync2(file, `${blocks.join("\n\n")}
|
|
1443
|
+
`, { mode: 384 });
|
|
1444
|
+
return { profile, file };
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1404
1447
|
// src/agents/injected-mcp.ts
|
|
1405
1448
|
var SIDEBOARD_MCP_ALLOWED_TOOLS = [
|
|
1406
1449
|
"mcp__sideboard",
|
|
@@ -1536,7 +1579,7 @@ function corePackageDir() {
|
|
|
1536
1579
|
} catch {
|
|
1537
1580
|
}
|
|
1538
1581
|
try {
|
|
1539
|
-
const req = createRequire(
|
|
1582
|
+
const req = createRequire(join6(process.cwd(), "package.json"));
|
|
1540
1583
|
return dirname2(req.resolve("@sideboard-ai/core"));
|
|
1541
1584
|
} catch {
|
|
1542
1585
|
return process.cwd();
|
|
@@ -1550,13 +1593,13 @@ function findSideboardMcpJsEntry() {
|
|
|
1550
1593
|
let dir = corePackageDir();
|
|
1551
1594
|
for (let i = 0; i < 10; i++) {
|
|
1552
1595
|
const candidates = [
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1596
|
+
join6(dir, "mcp/run-stdio.js"),
|
|
1597
|
+
join6(dir, "mcp/run-stdio.cjs"),
|
|
1598
|
+
join6(dir, "dist/mcp/run-stdio.js"),
|
|
1599
|
+
join6(dir, "dist/mcp/run-stdio.cjs"),
|
|
1600
|
+
join6(dir, "packages/core/dist/mcp/run-stdio.js"),
|
|
1601
|
+
join6(dir, "packages/cli/dist/index.js"),
|
|
1602
|
+
join6(dir, "cli/dist/index.js")
|
|
1560
1603
|
];
|
|
1561
1604
|
for (const p of candidates) {
|
|
1562
1605
|
if (existsSync6(p) && !isAsarPath(p)) return p;
|
|
@@ -1664,6 +1707,7 @@ function toCodexMcpConfigArgs(servers) {
|
|
|
1664
1707
|
const env = mcpSpawnEnv(s.env);
|
|
1665
1708
|
if (env) {
|
|
1666
1709
|
for (const [key, value] of Object.entries(env)) {
|
|
1710
|
+
if (isCodexSecretEnvKey(key)) continue;
|
|
1667
1711
|
args.push("-c", `${prefix}.env.${key}=${JSON.stringify(value)}`);
|
|
1668
1712
|
}
|
|
1669
1713
|
}
|
|
@@ -1722,15 +1766,15 @@ function mcpServersRecord(servers, extraServers) {
|
|
|
1722
1766
|
function writeMcpServersConfig(servers, extraServers) {
|
|
1723
1767
|
const mcpServers = mcpServersRecord(servers, extraServers);
|
|
1724
1768
|
if (Object.keys(mcpServers).length === 0) return null;
|
|
1725
|
-
const dir = mkdtempSync(
|
|
1726
|
-
const cfgPath =
|
|
1727
|
-
|
|
1769
|
+
const dir = mkdtempSync(join6(tmpdir(), "sideboard-mcp-"));
|
|
1770
|
+
const cfgPath = join6(dir, "mcp.json");
|
|
1771
|
+
writeFileSync3(cfgPath, JSON.stringify({ mcpServers }, null, 2), { mode: 384 });
|
|
1728
1772
|
return cfgPath;
|
|
1729
1773
|
}
|
|
1730
1774
|
|
|
1731
1775
|
// src/agents/user-mcp-config.ts
|
|
1732
1776
|
function userClaudeMcpConfigPath() {
|
|
1733
|
-
return
|
|
1777
|
+
return join7(homedir4(), ".claude.json");
|
|
1734
1778
|
}
|
|
1735
1779
|
|
|
1736
1780
|
// src/agents/orch-mcp-isolation.ts
|
|
@@ -1767,13 +1811,19 @@ function readText(path) {
|
|
|
1767
1811
|
return "";
|
|
1768
1812
|
}
|
|
1769
1813
|
}
|
|
1770
|
-
function userCodexConfigPaths(home =
|
|
1771
|
-
|
|
1814
|
+
function userCodexConfigPaths(home = homedir5()) {
|
|
1815
|
+
const paths = [
|
|
1816
|
+
join8(home, ".codex", "config.toml"),
|
|
1817
|
+
join8(home, ".config", "codex", "config.toml")
|
|
1818
|
+
];
|
|
1819
|
+
const codexHome = process.env.CODEX_HOME?.trim();
|
|
1820
|
+
if (codexHome) paths.unshift(join8(codexHome, "config.toml"));
|
|
1821
|
+
return paths;
|
|
1772
1822
|
}
|
|
1773
|
-
function userOpencodeConfigPaths(home =
|
|
1823
|
+
function userOpencodeConfigPaths(home = homedir5()) {
|
|
1774
1824
|
return [
|
|
1775
|
-
|
|
1776
|
-
|
|
1825
|
+
join8(home, ".config", "opencode", "opencode.json"),
|
|
1826
|
+
join8(home, ".config", "opencode", "opencode.jsonc")
|
|
1777
1827
|
];
|
|
1778
1828
|
}
|
|
1779
1829
|
function userMcpNamesToDisable(opts) {
|
|
@@ -1792,7 +1842,7 @@ function userMcpNamesToDisable(opts) {
|
|
|
1792
1842
|
}
|
|
1793
1843
|
return out;
|
|
1794
1844
|
}
|
|
1795
|
-
function listUserCodexMcpNames(home =
|
|
1845
|
+
function listUserCodexMcpNames(home = homedir5()) {
|
|
1796
1846
|
const names = [];
|
|
1797
1847
|
for (const path of userCodexConfigPaths(home)) {
|
|
1798
1848
|
if (!existsSync8(path)) continue;
|
|
@@ -1800,7 +1850,7 @@ function listUserCodexMcpNames(home = homedir4()) {
|
|
|
1800
1850
|
}
|
|
1801
1851
|
return names;
|
|
1802
1852
|
}
|
|
1803
|
-
function listUserOpencodeMcpNames(home =
|
|
1853
|
+
function listUserOpencodeMcpNames(home = homedir5()) {
|
|
1804
1854
|
const names = [];
|
|
1805
1855
|
for (const path of userOpencodeConfigPaths(home)) {
|
|
1806
1856
|
if (!existsSync8(path)) continue;
|
|
@@ -1808,12 +1858,12 @@ function listUserOpencodeMcpNames(home = homedir4()) {
|
|
|
1808
1858
|
}
|
|
1809
1859
|
return names;
|
|
1810
1860
|
}
|
|
1811
|
-
function userClaudeMcpConfigObject(home =
|
|
1812
|
-
const claudePath = home ===
|
|
1861
|
+
function userClaudeMcpConfigObject(home = homedir5()) {
|
|
1862
|
+
const claudePath = home === homedir5() ? userClaudeMcpConfigPath() : join8(home, ".claude.json");
|
|
1813
1863
|
if (!existsSync8(claudePath)) return {};
|
|
1814
1864
|
return asObject(asObject(readJsonObject(claudePath)).mcpServers);
|
|
1815
1865
|
}
|
|
1816
|
-
function listUserClaudeMcpServerEntries(home =
|
|
1866
|
+
function listUserClaudeMcpServerEntries(home = homedir5(), projectDirs) {
|
|
1817
1867
|
const out = {};
|
|
1818
1868
|
for (const [name, entry] of Object.entries(
|
|
1819
1869
|
listEnabledClaudePluginMcpServers({ home, projectDirs })
|
|
@@ -1851,7 +1901,7 @@ function toCodexUnattendedAppsArgs() {
|
|
|
1851
1901
|
}
|
|
1852
1902
|
|
|
1853
1903
|
// src/mcp-ui/proxy-http.ts
|
|
1854
|
-
import { randomBytes, randomUUID } from "crypto";
|
|
1904
|
+
import { randomBytes as randomBytes2, randomUUID } from "crypto";
|
|
1855
1905
|
import { createServer } from "http";
|
|
1856
1906
|
import { Server as Server2 } from "@modelcontextprotocol/sdk/server/index.js";
|
|
1857
1907
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
@@ -1948,7 +1998,7 @@ function listedTool(tool) {
|
|
|
1948
1998
|
|
|
1949
1999
|
// src/mcp-ui/proxy-http.ts
|
|
1950
2000
|
async function listenMcpUiProxy(opts) {
|
|
1951
|
-
const token =
|
|
2001
|
+
const token = randomBytes2(24).toString("hex");
|
|
1952
2002
|
const transports = /* @__PURE__ */ new Map();
|
|
1953
2003
|
const httpServer = createServer((req, res) => {
|
|
1954
2004
|
void handle(req, res);
|
|
@@ -2321,7 +2371,7 @@ var singleton;
|
|
|
2321
2371
|
function getMcpUiHost() {
|
|
2322
2372
|
if (!singleton) {
|
|
2323
2373
|
singleton = new McpUiHost({
|
|
2324
|
-
entries: (projectDirs) => listUserClaudeMcpServerEntries(
|
|
2374
|
+
entries: (projectDirs) => listUserClaudeMcpServerEntries(homedir6(), projectDirs)
|
|
2325
2375
|
});
|
|
2326
2376
|
}
|
|
2327
2377
|
return singleton;
|
|
@@ -2329,7 +2379,7 @@ function getMcpUiHost() {
|
|
|
2329
2379
|
async function proxyClaudeUserMcp(orchestrator, projectDirs) {
|
|
2330
2380
|
if (orchestrator) return {};
|
|
2331
2381
|
const dirs = projectDirs.filter((d) => typeof d === "string" && d.length > 0);
|
|
2332
|
-
return getMcpUiHost().proxyEntries(listUserClaudeMcpServerEntries(
|
|
2382
|
+
return getMcpUiHost().proxyEntries(listUserClaudeMcpServerEntries(homedir6(), dirs), dirs);
|
|
2333
2383
|
}
|
|
2334
2384
|
function dirsKeyFor(projectDirs) {
|
|
2335
2385
|
if (!projectDirs?.length) return "";
|
|
@@ -2343,16 +2393,6 @@ function planModeTurnInstruction(planMode) {
|
|
|
2343
2393
|
return planMode ? PLAN_MODE_INSTRUCTION : PLAN_MODE_OFF_INSTRUCTION;
|
|
2344
2394
|
}
|
|
2345
2395
|
function permissionMode(thread) {
|
|
2346
|
-
if (thread.sourceType === "orchestration") {
|
|
2347
|
-
return {
|
|
2348
|
-
claude: "acceptEdits",
|
|
2349
|
-
opencodePermission: JSON.stringify({
|
|
2350
|
-
edit: "allow",
|
|
2351
|
-
bash: { "*": "allow", "rm -rf *": "deny" }
|
|
2352
|
-
}),
|
|
2353
|
-
codexSandbox: "danger-full-access"
|
|
2354
|
-
};
|
|
2355
|
-
}
|
|
2356
2396
|
if (thread.planMode) {
|
|
2357
2397
|
return {
|
|
2358
2398
|
claude: "plan",
|
|
@@ -2364,6 +2404,18 @@ function permissionMode(thread) {
|
|
|
2364
2404
|
codexSandbox: "read-only"
|
|
2365
2405
|
};
|
|
2366
2406
|
}
|
|
2407
|
+
if (thread.sourceType === "orchestration") {
|
|
2408
|
+
return {
|
|
2409
|
+
claude: "acceptEdits",
|
|
2410
|
+
// Unattended coordinators cannot answer permission prompts. Explicit
|
|
2411
|
+
// allows override the user's OpenCode denies for this process only.
|
|
2412
|
+
opencodePermission: JSON.stringify({
|
|
2413
|
+
edit: "allow",
|
|
2414
|
+
bash: { "*": "allow" }
|
|
2415
|
+
}),
|
|
2416
|
+
codexSandbox: "danger-full-access"
|
|
2417
|
+
};
|
|
2418
|
+
}
|
|
2367
2419
|
if (thread.autonomy === "full") {
|
|
2368
2420
|
return {
|
|
2369
2421
|
claude: "bypassPermissions",
|
|
@@ -2373,19 +2425,16 @@ function permissionMode(thread) {
|
|
|
2373
2425
|
}
|
|
2374
2426
|
return {
|
|
2375
2427
|
claude: "acceptEdits",
|
|
2376
|
-
opencodePermission: JSON.stringify({
|
|
2377
|
-
edit: "allow",
|
|
2378
|
-
bash: { "*": "allow", "rm -rf *": "deny" }
|
|
2379
|
-
}),
|
|
2428
|
+
opencodePermission: JSON.stringify({}),
|
|
2380
2429
|
codexSandbox: "workspace-write"
|
|
2381
2430
|
};
|
|
2382
2431
|
}
|
|
2383
2432
|
|
|
2384
2433
|
// src/agent-rpc/metadata.ts
|
|
2385
|
-
import { existsSync as existsSync9, readFileSync as readFileSync5, unlinkSync, writeFileSync as
|
|
2386
|
-
import { join as
|
|
2434
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5, unlinkSync, writeFileSync as writeFileSync5 } from "fs";
|
|
2435
|
+
import { join as join9 } from "path";
|
|
2387
2436
|
function agentRuntimeMetadataPath() {
|
|
2388
|
-
return
|
|
2437
|
+
return join9(appDataDir(), "agent-runtime.json");
|
|
2389
2438
|
}
|
|
2390
2439
|
function readAgentRuntimeMetadata() {
|
|
2391
2440
|
try {
|
|
@@ -2454,7 +2503,7 @@ function agentRpcChildEnv(rpc, cwd) {
|
|
|
2454
2503
|
// src/agents/claude-host.ts
|
|
2455
2504
|
import { existsSync as existsSync10 } from "fs";
|
|
2456
2505
|
import { createRequire as createRequire2 } from "module";
|
|
2457
|
-
import { dirname as dirname4, join as
|
|
2506
|
+
import { dirname as dirname4, join as join10 } from "path";
|
|
2458
2507
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2459
2508
|
|
|
2460
2509
|
// src/agent-rpc/client.ts
|
|
@@ -2499,17 +2548,17 @@ function entryDir() {
|
|
|
2499
2548
|
function claudeRunnerPath() {
|
|
2500
2549
|
const packagedDir = packagedCursorRuntimeDir();
|
|
2501
2550
|
if (packagedDir) {
|
|
2502
|
-
const packaged =
|
|
2551
|
+
const packaged = join10(packagedDir, "core-dist", "agents", "claude-runner.js");
|
|
2503
2552
|
if (existsSync10(packaged)) return packaged;
|
|
2504
2553
|
}
|
|
2505
2554
|
const root = entryDir();
|
|
2506
2555
|
const candidates = [
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2556
|
+
join10(root, "agents", "claude-runner.js"),
|
|
2557
|
+
join10(root, "agents", "claude-runner.cjs"),
|
|
2558
|
+
join10(root, "dist", "agents", "claude-runner.js"),
|
|
2559
|
+
join10(root, "dist", "agents", "claude-runner.cjs"),
|
|
2560
|
+
join10(root, "claude-runner.ts"),
|
|
2561
|
+
join10(root, "src", "agents", "claude-runner.ts")
|
|
2513
2562
|
];
|
|
2514
2563
|
for (const candidate of candidates) {
|
|
2515
2564
|
if (existsSync10(candidate)) return candidate;
|
|
@@ -2588,7 +2637,8 @@ function sessionCostUsdFromClaudeResult(obj) {
|
|
|
2588
2637
|
function claudeResultErrorDetail(obj) {
|
|
2589
2638
|
const isError = Boolean(obj.is_error) || typeof obj.subtype === "string" && /^error/i.test(obj.subtype);
|
|
2590
2639
|
const fromResult = typeof obj.result === "string" ? obj.result.trim() : "";
|
|
2591
|
-
|
|
2640
|
+
const shortFailure = fromResult.length > 0 && fromResult.length <= 300 && !fromResult.includes("\n") && looksLikeAgentFailureMessage(fromResult);
|
|
2641
|
+
if (fromResult && (isError || shortFailure)) {
|
|
2592
2642
|
return fromResult;
|
|
2593
2643
|
}
|
|
2594
2644
|
if (!isError) return null;
|
|
@@ -2835,7 +2885,7 @@ function eventsFromClaudeSystem(obj) {
|
|
|
2835
2885
|
data: `Context compressed${trigger}`,
|
|
2836
2886
|
replace: true
|
|
2837
2887
|
};
|
|
2838
|
-
if (meta.postTokens != null && meta.postTokens > 0) {
|
|
2888
|
+
if (meta.postTokens != null && meta.postTokens > 0 && !parentId) {
|
|
2839
2889
|
return [
|
|
2840
2890
|
thinking,
|
|
2841
2891
|
{
|
|
@@ -2916,7 +2966,7 @@ var claudeAdapter = {
|
|
|
2916
2966
|
);
|
|
2917
2967
|
}
|
|
2918
2968
|
const mode = permissionMode(thread);
|
|
2919
|
-
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-
|
|
2969
|
+
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-FPDZKUPF.js");
|
|
2920
2970
|
const isOrchestrator = isOrchestratorThread2(thread);
|
|
2921
2971
|
const rpc = worktreeAgentRpc(isOrchestrator);
|
|
2922
2972
|
const injectedServers = await buildInjectedMcpServers({
|
|
@@ -3016,6 +3066,7 @@ var claudeAdapter = {
|
|
|
3016
3066
|
cwd: thread.worktreePath,
|
|
3017
3067
|
stdin: useStdin ? `${promptText}
|
|
3018
3068
|
` : void 0,
|
|
3069
|
+
...mcpConfigPath ? { cleanupDirs: [dirname5(mcpConfigPath)] } : {},
|
|
3019
3070
|
// Nested Task/Agent thinking+text in stream-json (Claude Code 2.1.211+).
|
|
3020
3071
|
// Raise the -p background-agent wait so long TaskOutput polls are not
|
|
3021
3072
|
// abandoned at Claude Code’s 10-minute default.
|
|
@@ -3045,9 +3096,17 @@ var claudeAdapter = {
|
|
|
3045
3096
|
Array.isArray(message?.content) ? message.content : void 0,
|
|
3046
3097
|
parentId
|
|
3047
3098
|
);
|
|
3048
|
-
if (obj.type === "assistant") {
|
|
3099
|
+
if (obj.type === "assistant" && !parentId) {
|
|
3049
3100
|
const usage = usageFromClaude(message?.usage);
|
|
3050
|
-
|
|
3101
|
+
const messageId = message && typeof message.id === "string" ? message.id : void 0;
|
|
3102
|
+
if (usage) {
|
|
3103
|
+
events.push({
|
|
3104
|
+
type: "usage",
|
|
3105
|
+
data: usage,
|
|
3106
|
+
scope: "request",
|
|
3107
|
+
...messageId ? { messageId } : {}
|
|
3108
|
+
});
|
|
3109
|
+
}
|
|
3051
3110
|
}
|
|
3052
3111
|
if (events.length === 0) return null;
|
|
3053
3112
|
return events.length === 1 ? events[0] : events;
|
|
@@ -3134,56 +3193,47 @@ var claudeAdapter = {
|
|
|
3134
3193
|
return { file: claude, args, cwd: thread.worktreePath };
|
|
3135
3194
|
},
|
|
3136
3195
|
async listLinearIssues(_repoPath) {
|
|
3137
|
-
const
|
|
3138
|
-
|
|
3139
|
-
const { stdout, exitCode } = await run(
|
|
3140
|
-
claude,
|
|
3141
|
-
[
|
|
3142
|
-
"-p",
|
|
3143
|
-
prompt,
|
|
3144
|
-
"--output-format",
|
|
3145
|
-
"json",
|
|
3146
|
-
"--permission-mode",
|
|
3147
|
-
"bypassPermissions",
|
|
3148
|
-
"--allowedTools",
|
|
3149
|
-
"mcp__linear__*"
|
|
3150
|
-
],
|
|
3151
|
-
{ reject: false }
|
|
3152
|
-
);
|
|
3153
|
-
if (exitCode !== 0) return [];
|
|
3154
|
-
return parseIssuesJson(stdout);
|
|
3196
|
+
const { listAssignedLinearIssues: listAssignedLinearIssues2 } = await import("./linear-list-Q4M7AZO2.js");
|
|
3197
|
+
return listAssignedLinearIssues2();
|
|
3155
3198
|
}
|
|
3156
3199
|
};
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3200
|
+
|
|
3201
|
+
// src/agents/codex.ts
|
|
3202
|
+
import { existsSync as existsSync12, statSync as statSync2 } from "fs";
|
|
3203
|
+
import { homedir as homedir7 } from "os";
|
|
3204
|
+
import { join as join11 } from "path";
|
|
3205
|
+
|
|
3206
|
+
// src/agents/codex-items.ts
|
|
3207
|
+
function eventsFromCodexItem(eventType, item) {
|
|
3208
|
+
const itemType = item.type ?? item.item_type;
|
|
3209
|
+
if (itemType === "reasoning" && typeof item.text === "string" && item.text) {
|
|
3210
|
+
return { type: "thinking", data: item.text };
|
|
3211
|
+
}
|
|
3212
|
+
if (itemType !== "file_change" || !item.id) return null;
|
|
3213
|
+
const changes = Array.isArray(item.changes) ? item.changes : [];
|
|
3214
|
+
const paths = changes.map((change) => typeof change?.path === "string" ? change.path : "").filter(Boolean);
|
|
3215
|
+
const added = changes.some((change) => change?.kind === "add");
|
|
3216
|
+
const events = [
|
|
3217
|
+
{
|
|
3218
|
+
type: "tool_use",
|
|
3219
|
+
id: item.id,
|
|
3220
|
+
name: added ? "Write" : "Edit",
|
|
3221
|
+
input: paths.length ? { paths } : void 0
|
|
3178
3222
|
}
|
|
3223
|
+
];
|
|
3224
|
+
const finished = eventType === "item.completed" || item.status === "completed" || item.status === "failed";
|
|
3225
|
+
if (finished) {
|
|
3226
|
+
events.push({
|
|
3227
|
+
type: "tool_result",
|
|
3228
|
+
id: item.id,
|
|
3229
|
+
content: paths.join("\n") || void 0,
|
|
3230
|
+
isError: item.status === "failed"
|
|
3231
|
+
});
|
|
3179
3232
|
}
|
|
3180
|
-
return [];
|
|
3233
|
+
return events.length === 1 ? events[0] : events;
|
|
3181
3234
|
}
|
|
3182
3235
|
|
|
3183
3236
|
// src/agents/codex.ts
|
|
3184
|
-
import { existsSync as existsSync12, readFileSync as readFileSync6, statSync as statSync2 } from "fs";
|
|
3185
|
-
import { homedir as homedir6 } from "os";
|
|
3186
|
-
import { join as join10 } from "path";
|
|
3187
3237
|
var CODEX_PROMPT_ARG_MAX = 2e5;
|
|
3188
3238
|
var FALLBACK_CODEX_MODELS = [
|
|
3189
3239
|
{ id: "gpt-5.6-sol", displayName: "GPT-5.6 Sol" },
|
|
@@ -3228,25 +3278,19 @@ async function listCodexModels() {
|
|
|
3228
3278
|
return cachedCodexModels?.models ?? FALLBACK_CODEX_MODELS;
|
|
3229
3279
|
}
|
|
3230
3280
|
}
|
|
3231
|
-
function usageFromCodex(usage) {
|
|
3281
|
+
function usageFromCodex(usage, asContext = false) {
|
|
3232
3282
|
if (!usage) return null;
|
|
3233
|
-
|
|
3283
|
+
const mapped = fromInclusiveInputUsage({
|
|
3234
3284
|
inputTokens: Number(usage.input_tokens ?? 0),
|
|
3235
3285
|
outputTokens: Number(usage.output_tokens ?? 0),
|
|
3236
3286
|
cachedInputTokens: Number(usage.cached_input_tokens ?? 0)
|
|
3237
3287
|
});
|
|
3288
|
+
if (!mapped || !asContext) return mapped;
|
|
3289
|
+
const occ = requestOccupancy(mapped);
|
|
3290
|
+
return occ > 0 ? { ...mapped, lastRequestTokens: occ } : mapped;
|
|
3238
3291
|
}
|
|
3239
|
-
function
|
|
3240
|
-
|
|
3241
|
-
join10(homedir6(), ".codex", "config.toml"),
|
|
3242
|
-
join10(homedir6(), ".config", "codex", "config.toml")
|
|
3243
|
-
];
|
|
3244
|
-
for (const path of candidates) {
|
|
3245
|
-
if (!existsSync12(path)) continue;
|
|
3246
|
-
const text = readFileSync6(path, "utf8");
|
|
3247
|
-
if (/network_access\s*=\s*true/.test(text)) return true;
|
|
3248
|
-
}
|
|
3249
|
-
return false;
|
|
3292
|
+
function codexHomeDir() {
|
|
3293
|
+
return process.env.CODEX_HOME?.trim() || join11(homedir7(), ".codex");
|
|
3250
3294
|
}
|
|
3251
3295
|
function unwrapCodexMcpResult(result) {
|
|
3252
3296
|
if (result == null) return void 0;
|
|
@@ -3275,7 +3319,7 @@ function asRecord3(value) {
|
|
|
3275
3319
|
return void 0;
|
|
3276
3320
|
}
|
|
3277
3321
|
function codexLooksAuthenticated() {
|
|
3278
|
-
const authPath =
|
|
3322
|
+
const authPath = join11(codexHomeDir(), "auth.json");
|
|
3279
3323
|
if (!existsSync12(authPath)) return false;
|
|
3280
3324
|
try {
|
|
3281
3325
|
return statSync2(authPath).size > 2;
|
|
@@ -3314,18 +3358,13 @@ var codexAdapter = {
|
|
|
3314
3358
|
const authenticated = codexLooksAuthenticated();
|
|
3315
3359
|
const linearMcp = false;
|
|
3316
3360
|
const warnings = [];
|
|
3317
|
-
if (!codexConfigHasNetworkAccess()) {
|
|
3318
|
-
warnings.push(
|
|
3319
|
-
"Codex workspace-write blocks network by default \u2014 set [sandbox_workspace_write] network_access = true in ~/.codex/config.toml if agents need npm install etc."
|
|
3320
|
-
);
|
|
3321
|
-
}
|
|
3322
3361
|
return {
|
|
3323
3362
|
agent: "codex",
|
|
3324
3363
|
installed: true,
|
|
3325
3364
|
authenticated,
|
|
3326
3365
|
linearMcp,
|
|
3327
3366
|
warnings,
|
|
3328
|
-
reason: authenticated ? void 0 :
|
|
3367
|
+
reason: authenticated ? void 0 : `Codex auth not found \u2014 run \`codex login\` (expected ${join11(codexHomeDir(), "auth.json")})`
|
|
3329
3368
|
};
|
|
3330
3369
|
},
|
|
3331
3370
|
async buildTurn(thread, input) {
|
|
@@ -3350,6 +3389,12 @@ var codexAdapter = {
|
|
|
3350
3389
|
threadId: thread.id
|
|
3351
3390
|
});
|
|
3352
3391
|
const isolatePlugins = isOrchestrator || Boolean(thread.isolateCodexPlugins) || Boolean(normalizeTurnInput(input).isolateCodexPlugins);
|
|
3392
|
+
const gitEnv = await resolveAgentGitAuthEnv(process.env, {
|
|
3393
|
+
cwd: thread.worktreePath
|
|
3394
|
+
});
|
|
3395
|
+
const writableRoots = mode.codexSandbox === "workspace-write" ? await resolveCodexGitWritableRoots(thread.worktreePath) : [];
|
|
3396
|
+
const secretProfile = writeCodexMcpSecretProfile(injected);
|
|
3397
|
+
const effort = thread.effort?.trim() ?? "";
|
|
3353
3398
|
const mcpOverrides = [
|
|
3354
3399
|
// Worktree first try keeps plugins (Claude connectors). Coordinators
|
|
3355
3400
|
// isolate. After a fatal plugin MCP, the orchestrator retries with
|
|
@@ -3366,6 +3411,7 @@ var codexAdapter = {
|
|
|
3366
3411
|
const execOpts = [
|
|
3367
3412
|
// Global orchestration cwd is not a git repo; without this Codex ≥0.147
|
|
3368
3413
|
// refuses to start ("Not inside a trusted directory").
|
|
3414
|
+
...secretProfile ? ["-p", secretProfile.profile] : [],
|
|
3369
3415
|
"--skip-git-repo-check",
|
|
3370
3416
|
"--cd",
|
|
3371
3417
|
thread.worktreePath,
|
|
@@ -3375,14 +3421,16 @@ var codexAdapter = {
|
|
|
3375
3421
|
// `codex exec` rejects `--ask-for-approval` (global-only on newer CLIs).
|
|
3376
3422
|
"-c",
|
|
3377
3423
|
'approval_policy="never"',
|
|
3378
|
-
// Seatbelt cannot use the login Keychain
|
|
3379
|
-
// Default
|
|
3380
|
-
//
|
|
3381
|
-
// can
|
|
3424
|
+
// Seatbelt cannot use the login Keychain. inherit=all keeps GH_CONFIG_DIR
|
|
3425
|
+
// and GIT_CONFIG_*. Default excludes still strip *TOKEN*/*SECRET*/*KEY*;
|
|
3426
|
+
// GIT_CONFIG_KEY_n is re-set because it matches *KEY*. Linked worktrees
|
|
3427
|
+
// need the main repo `.git` as writable_roots so git commit can lock.
|
|
3382
3428
|
...codexUnattendedGitConfigArgs(mode.codexSandbox, {
|
|
3383
|
-
writableRoots
|
|
3429
|
+
writableRoots,
|
|
3430
|
+
preserveEnv: gitEnv
|
|
3384
3431
|
}),
|
|
3385
3432
|
...model ? ["--model", model] : [],
|
|
3433
|
+
...effort ? ["-c", `model_reasoning_effort=${JSON.stringify(effort)}`] : [],
|
|
3386
3434
|
...mcpOverrides
|
|
3387
3435
|
];
|
|
3388
3436
|
const args = sessionId ? ["exec", ...execOpts, "resume", sessionId, promptArg] : ["exec", ...execOpts, promptArg];
|
|
@@ -3391,7 +3439,8 @@ var codexAdapter = {
|
|
|
3391
3439
|
args,
|
|
3392
3440
|
cwd: thread.worktreePath,
|
|
3393
3441
|
stdin: useStdin ? `${prompt}
|
|
3394
|
-
` : void 0
|
|
3442
|
+
` : void 0,
|
|
3443
|
+
...secretProfile ? { cleanupDirs: [secretProfile.file] } : {}
|
|
3395
3444
|
};
|
|
3396
3445
|
},
|
|
3397
3446
|
parseEvent(line) {
|
|
@@ -3412,8 +3461,10 @@ var codexAdapter = {
|
|
|
3412
3461
|
if (typeof obj.item === "object" && obj.item !== null) {
|
|
3413
3462
|
const item = obj.item;
|
|
3414
3463
|
const itemType = item.type ?? item.item_type;
|
|
3464
|
+
const mapped = eventsFromCodexItem(type, item);
|
|
3465
|
+
if (mapped) return mapped;
|
|
3415
3466
|
if (itemType === "error") {
|
|
3416
|
-
const detail = item.message
|
|
3467
|
+
const detail = (typeof item.message === "string" ? item.message.trim() : "") || extractJsonErrorMessage(obj) || "Codex item error";
|
|
3417
3468
|
return { type: "stderr", data: detail };
|
|
3418
3469
|
}
|
|
3419
3470
|
if (itemType === "agent_message" && item.text) {
|
|
@@ -3442,14 +3493,14 @@ var codexAdapter = {
|
|
|
3442
3493
|
const events = [
|
|
3443
3494
|
{ type: "tool_use", id: item.id, name: "Bash", input }
|
|
3444
3495
|
];
|
|
3445
|
-
const finished = type === "item.completed" || item.status === "completed" || item.status === "failed";
|
|
3496
|
+
const finished = type === "item.completed" || item.status === "completed" || item.status === "failed" || item.status === "declined";
|
|
3446
3497
|
const output = typeof item.aggregated_output === "string" && item.aggregated_output ? item.aggregated_output : void 0;
|
|
3447
3498
|
if (finished) {
|
|
3448
3499
|
events.push({
|
|
3449
3500
|
type: "tool_result",
|
|
3450
3501
|
id: item.id,
|
|
3451
3502
|
content: output,
|
|
3452
|
-
isError: item.status === "failed"
|
|
3503
|
+
isError: item.status === "failed" || item.status === "declined"
|
|
3453
3504
|
});
|
|
3454
3505
|
} else if (output) {
|
|
3455
3506
|
events.push({
|
|
@@ -3492,7 +3543,7 @@ var codexAdapter = {
|
|
|
3492
3543
|
return events.length === 1 ? events[0] : events;
|
|
3493
3544
|
}
|
|
3494
3545
|
if (item.status === "failed") {
|
|
3495
|
-
const detail = item.message
|
|
3546
|
+
const detail = (typeof item.message === "string" ? item.message.trim() : "") || extractJsonErrorMessage(item) || `Codex ${itemType ?? "item"} failed`;
|
|
3496
3547
|
return { type: "stderr", data: detail };
|
|
3497
3548
|
}
|
|
3498
3549
|
}
|
|
@@ -3501,7 +3552,8 @@ var codexAdapter = {
|
|
|
3501
3552
|
return { type: "session_id", data: sid };
|
|
3502
3553
|
}
|
|
3503
3554
|
if (type === "turn.completed" || type === "turn_completed") {
|
|
3504
|
-
const
|
|
3555
|
+
const payload = obj;
|
|
3556
|
+
const usage = payload.last_token_usage ? usageFromCodex(payload.last_token_usage, true) : usageFromCodex(payload.usage);
|
|
3505
3557
|
return usage ? { type: "usage", data: usage, scope: "turn" } : null;
|
|
3506
3558
|
}
|
|
3507
3559
|
if (typeof obj.content === "string" && obj.content.trim()) {
|
|
@@ -3524,7 +3576,7 @@ var codexAdapter = {
|
|
|
3524
3576
|
if (sessionId) {
|
|
3525
3577
|
return {
|
|
3526
3578
|
file: codex,
|
|
3527
|
-
args: ["
|
|
3579
|
+
args: ["resume", sessionId],
|
|
3528
3580
|
cwd: thread.worktreePath
|
|
3529
3581
|
};
|
|
3530
3582
|
}
|
|
@@ -3535,56 +3587,34 @@ var codexAdapter = {
|
|
|
3535
3587
|
};
|
|
3536
3588
|
},
|
|
3537
3589
|
async listLinearIssues(_repoPath) {
|
|
3538
|
-
|
|
3539
|
-
const { stdout, exitCode } = await run(
|
|
3540
|
-
resolveAgentExecutable("codex"),
|
|
3541
|
-
[
|
|
3542
|
-
"exec",
|
|
3543
|
-
"--json",
|
|
3544
|
-
"--sandbox",
|
|
3545
|
-
"read-only",
|
|
3546
|
-
"-c",
|
|
3547
|
-
'approval_policy="never"',
|
|
3548
|
-
prompt
|
|
3549
|
-
],
|
|
3550
|
-
{ reject: false }
|
|
3551
|
-
);
|
|
3552
|
-
if (exitCode !== 0) return [];
|
|
3553
|
-
const match = stdout.match(/\[[\s\S]*\]/);
|
|
3554
|
-
if (!match) return [];
|
|
3555
|
-
try {
|
|
3556
|
-
const parsed = JSON.parse(match[0]);
|
|
3557
|
-
return Array.isArray(parsed) ? parsed : [];
|
|
3558
|
-
} catch {
|
|
3559
|
-
return [];
|
|
3560
|
-
}
|
|
3590
|
+
return listAssignedLinearIssues();
|
|
3561
3591
|
}
|
|
3562
3592
|
};
|
|
3563
3593
|
|
|
3564
3594
|
// src/agents/cursor.ts
|
|
3565
3595
|
import { existsSync as existsSync15 } from "fs";
|
|
3566
3596
|
import { createRequire as createRequire5 } from "module";
|
|
3567
|
-
import { dirname as
|
|
3597
|
+
import { dirname as dirname8, join as join14 } from "path";
|
|
3568
3598
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
3569
3599
|
|
|
3570
3600
|
// src/agents/cursor-sdk-resolve.ts
|
|
3571
|
-
import { existsSync as existsSync13, readFileSync as
|
|
3601
|
+
import { existsSync as existsSync13, readFileSync as readFileSync6 } from "fs";
|
|
3572
3602
|
import { createRequire as createRequire3 } from "module";
|
|
3573
|
-
import { basename, dirname as
|
|
3603
|
+
import { basename, dirname as dirname6, join as join12 } from "path";
|
|
3574
3604
|
import { fileURLToPath as fileURLToPath3, pathToFileURL } from "url";
|
|
3575
3605
|
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.";
|
|
3576
3606
|
function thisModuleFile() {
|
|
3577
3607
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
3578
|
-
if (cjsDir) return
|
|
3608
|
+
if (cjsDir) return join12(cjsDir, "cursor-sdk-resolve.js");
|
|
3579
3609
|
try {
|
|
3580
3610
|
return fileURLToPath3(import.meta.url);
|
|
3581
3611
|
} catch {
|
|
3582
|
-
return
|
|
3612
|
+
return join12(process.cwd(), "package.json");
|
|
3583
3613
|
}
|
|
3584
3614
|
}
|
|
3585
3615
|
function packageRootLooksLikeSdk(dir) {
|
|
3586
3616
|
try {
|
|
3587
|
-
const raw =
|
|
3617
|
+
const raw = readFileSync6(join12(dir, "package.json"), "utf8");
|
|
3588
3618
|
const pkg = JSON.parse(raw);
|
|
3589
3619
|
return pkg.name === "@cursor/sdk" && existsSync13(dir);
|
|
3590
3620
|
} catch {
|
|
@@ -3595,7 +3625,7 @@ function resolvedPackageRoot(fromFile) {
|
|
|
3595
3625
|
try {
|
|
3596
3626
|
const req = createRequire3(fromFile);
|
|
3597
3627
|
const pkgJson = req.resolve("@cursor/sdk/package.json");
|
|
3598
|
-
const root =
|
|
3628
|
+
const root = dirname6(pkgJson);
|
|
3599
3629
|
return packageRootLooksLikeSdk(root) ? root : null;
|
|
3600
3630
|
} catch {
|
|
3601
3631
|
return null;
|
|
@@ -3609,10 +3639,10 @@ function resolveCursorSdkRoot(opts) {
|
|
|
3609
3639
|
}
|
|
3610
3640
|
const globalNm = npmGlobalNodeModules(env);
|
|
3611
3641
|
if (globalNm) {
|
|
3612
|
-
const globalRoot =
|
|
3642
|
+
const globalRoot = join12(globalNm, "@cursor/sdk");
|
|
3613
3643
|
if (packageRootLooksLikeSdk(globalRoot)) return globalRoot;
|
|
3614
3644
|
}
|
|
3615
|
-
const cwdPkg =
|
|
3645
|
+
const cwdPkg = join12(process.cwd(), "package.json");
|
|
3616
3646
|
return resolvedPackageRoot(thisModuleFile()) ?? resolvedPackageRoot(cwdPkg);
|
|
3617
3647
|
}
|
|
3618
3648
|
function isCursorSdkInstalled(opts) {
|
|
@@ -3628,12 +3658,12 @@ function exportTarget(value) {
|
|
|
3628
3658
|
}
|
|
3629
3659
|
function cursorSdkEsmEntry(root) {
|
|
3630
3660
|
try {
|
|
3631
|
-
const pkg = JSON.parse(
|
|
3661
|
+
const pkg = JSON.parse(readFileSync6(join12(root, "package.json"), "utf8"));
|
|
3632
3662
|
const exp = pkg.exports;
|
|
3633
3663
|
const dot = exp && typeof exp === "object" && !Array.isArray(exp) && "." in exp ? exp["."] : exp;
|
|
3634
3664
|
const rel = exportTarget(dot) ?? (typeof pkg.module === "string" ? pkg.module : null);
|
|
3635
3665
|
if (!rel) return null;
|
|
3636
|
-
const entry =
|
|
3666
|
+
const entry = join12(root, rel);
|
|
3637
3667
|
return existsSync13(entry) ? entry : null;
|
|
3638
3668
|
} catch {
|
|
3639
3669
|
return null;
|
|
@@ -3650,7 +3680,7 @@ async function importCursorSdk(opts) {
|
|
|
3650
3680
|
try {
|
|
3651
3681
|
let entry = cursorSdkEsmEntry(root);
|
|
3652
3682
|
if (!entry) {
|
|
3653
|
-
const req = createRequire3(
|
|
3683
|
+
const req = createRequire3(join12(root, "package.json"));
|
|
3654
3684
|
entry = req.resolve("@cursor/sdk");
|
|
3655
3685
|
}
|
|
3656
3686
|
return unwrapCursorSdkModule(await import(pathToFileURL(entry).href));
|
|
@@ -3662,8 +3692,8 @@ function cursorSdkPlatformRipgrepPackage() {
|
|
|
3662
3692
|
return `@cursor/sdk-${process.platform}-${process.arch}`;
|
|
3663
3693
|
}
|
|
3664
3694
|
function nodeModulesDirForPackageRoot(packageRoot) {
|
|
3665
|
-
const parent =
|
|
3666
|
-
return basename(parent).startsWith("@") ?
|
|
3695
|
+
const parent = dirname6(packageRoot);
|
|
3696
|
+
return basename(parent).startsWith("@") ? dirname6(parent) : parent;
|
|
3667
3697
|
}
|
|
3668
3698
|
function cursorSdkRipgrepCandidate(opts) {
|
|
3669
3699
|
const root = resolveCursorSdkRoot(opts);
|
|
@@ -3671,9 +3701,9 @@ function cursorSdkRipgrepCandidate(opts) {
|
|
|
3671
3701
|
const nm = nodeModulesDirForPackageRoot(root);
|
|
3672
3702
|
const pkg = cursorSdkPlatformRipgrepPackage();
|
|
3673
3703
|
const bin = process.platform === "win32" ? "rg.exe" : "rg";
|
|
3674
|
-
const sibling =
|
|
3704
|
+
const sibling = join12(nm, pkg, "bin", bin);
|
|
3675
3705
|
if (existsSync13(sibling)) return sibling;
|
|
3676
|
-
const nested =
|
|
3706
|
+
const nested = join12(root, "node_modules", pkg, "bin", bin);
|
|
3677
3707
|
return existsSync13(nested) ? nested : null;
|
|
3678
3708
|
}
|
|
3679
3709
|
|
|
@@ -3702,7 +3732,8 @@ function preferredCursorCostCents(cost) {
|
|
|
3702
3732
|
}
|
|
3703
3733
|
function turnCostUsdFromCursorUsage(before, after) {
|
|
3704
3734
|
if (!after) return void 0;
|
|
3705
|
-
|
|
3735
|
+
if (before == null) return void 0;
|
|
3736
|
+
const beforeIds = new Set((before.runs ?? []).map((r) => r.runId));
|
|
3706
3737
|
const newRuns = (after.runs ?? []).filter((r) => !beforeIds.has(r.runId));
|
|
3707
3738
|
let sum = 0;
|
|
3708
3739
|
let any = false;
|
|
@@ -3714,7 +3745,6 @@ function turnCostUsdFromCursorUsage(before, after) {
|
|
|
3714
3745
|
}
|
|
3715
3746
|
}
|
|
3716
3747
|
if (any) return sum / 100;
|
|
3717
|
-
if (before == null) return void 0;
|
|
3718
3748
|
const afterCents = preferredCursorCostCents(after.cost);
|
|
3719
3749
|
if (afterCents == null) return void 0;
|
|
3720
3750
|
const beforeCents = preferredCursorCostCents(before.cost) ?? 0;
|
|
@@ -3857,7 +3887,7 @@ function cursorSdkMessageToEvents(msg) {
|
|
|
3857
3887
|
}
|
|
3858
3888
|
if (msg.type === "usage") {
|
|
3859
3889
|
const usage = usageFromCursor(msg.usage);
|
|
3860
|
-
if (usage) return [{ type: "usage", data: usage, scope: "
|
|
3890
|
+
if (usage) return [{ type: "usage", data: usage, scope: "turn" }];
|
|
3861
3891
|
}
|
|
3862
3892
|
if (msg.type === "status" && msg.status === "ERROR") {
|
|
3863
3893
|
const rawMessage = msg.message;
|
|
@@ -3891,7 +3921,7 @@ function parseCursorRunnerLine(line) {
|
|
|
3891
3921
|
// src/agents/cursor-ripgrep.ts
|
|
3892
3922
|
import { existsSync as existsSync14 } from "fs";
|
|
3893
3923
|
import { createRequire as createRequire4 } from "module";
|
|
3894
|
-
import { dirname as
|
|
3924
|
+
import { dirname as dirname7, isAbsolute as isAbsolute2, join as join13, parse, resolve as resolvePath } from "path";
|
|
3895
3925
|
var RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
|
|
3896
3926
|
function rgBinaryName() {
|
|
3897
3927
|
return process.platform === "win32" ? "rg.exe" : "rg";
|
|
@@ -3910,12 +3940,12 @@ function walkForBundledRipgrep(startFile) {
|
|
|
3910
3940
|
if (!startFile) return null;
|
|
3911
3941
|
const pkg = platformRipgrepPackage();
|
|
3912
3942
|
const name = rgBinaryName();
|
|
3913
|
-
let dir =
|
|
3943
|
+
let dir = dirname7(resolvePath(startFile));
|
|
3914
3944
|
const root = parse(dir).root;
|
|
3915
3945
|
while (dir !== root) {
|
|
3916
|
-
const hit = usableRipgrepPath(
|
|
3946
|
+
const hit = usableRipgrepPath(join13(dir, "node_modules", pkg, "bin", name));
|
|
3917
3947
|
if (hit) return hit;
|
|
3918
|
-
const next =
|
|
3948
|
+
const next = dirname7(dir);
|
|
3919
3949
|
if (next === dir) break;
|
|
3920
3950
|
dir = next;
|
|
3921
3951
|
}
|
|
@@ -3925,7 +3955,7 @@ function requireResolveBundledRipgrep(fromFile) {
|
|
|
3925
3955
|
try {
|
|
3926
3956
|
const req = createRequire4(fromFile);
|
|
3927
3957
|
const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
|
|
3928
|
-
return usableRipgrepPath(
|
|
3958
|
+
return usableRipgrepPath(join13(dirname7(pkgJson), "bin", rgBinaryName()));
|
|
3929
3959
|
} catch {
|
|
3930
3960
|
return null;
|
|
3931
3961
|
}
|
|
@@ -3999,11 +4029,11 @@ function entryDir2() {
|
|
|
3999
4029
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
4000
4030
|
if (cjsDir) return cjsDir;
|
|
4001
4031
|
try {
|
|
4002
|
-
return
|
|
4032
|
+
return dirname8(fileURLToPath4(import.meta.url));
|
|
4003
4033
|
} catch {
|
|
4004
4034
|
try {
|
|
4005
4035
|
const req = createRequire5(process.cwd() + "/");
|
|
4006
|
-
return
|
|
4036
|
+
return dirname8(req.resolve("@sideboard-ai/core"));
|
|
4007
4037
|
} catch {
|
|
4008
4038
|
return process.cwd();
|
|
4009
4039
|
}
|
|
@@ -4014,14 +4044,14 @@ function cursorRunnerPath() {
|
|
|
4014
4044
|
if (packaged) return packaged;
|
|
4015
4045
|
const root = entryDir2();
|
|
4016
4046
|
const candidates = [
|
|
4017
|
-
|
|
4018
|
-
|
|
4047
|
+
join14(root, "agents", "cursor-runner.js"),
|
|
4048
|
+
join14(root, "agents", "cursor-runner.cjs"),
|
|
4019
4049
|
// If somehow resolved from package root instead of dist/
|
|
4020
|
-
|
|
4021
|
-
|
|
4050
|
+
join14(root, "dist", "agents", "cursor-runner.js"),
|
|
4051
|
+
join14(root, "dist", "agents", "cursor-runner.cjs"),
|
|
4022
4052
|
// Source tree (dev): packages/core/src/agents/cursor-runner.ts
|
|
4023
|
-
|
|
4024
|
-
|
|
4053
|
+
join14(root, "cursor-runner.ts"),
|
|
4054
|
+
join14(root, "src", "agents", "cursor-runner.ts")
|
|
4025
4055
|
];
|
|
4026
4056
|
for (const candidate of candidates) {
|
|
4027
4057
|
if (existsSync15(candidate)) return candidate;
|
|
@@ -4062,6 +4092,7 @@ var cursorAdapter = {
|
|
|
4062
4092
|
},
|
|
4063
4093
|
async buildTurn(thread, input) {
|
|
4064
4094
|
const agentId = await this.resolveSessionId(thread.worktreePath, thread.sessionId);
|
|
4095
|
+
const fullPrompt = flattenTurnInput(input);
|
|
4065
4096
|
const prompt = flattenTurnInput(dropCachedPrefixOnResume(input, agentId));
|
|
4066
4097
|
const apiKey = resolveCursorApiKey() || void 0;
|
|
4067
4098
|
const isOrchestrator = isOrchestratorThread(thread);
|
|
@@ -4078,6 +4109,7 @@ var cursorAdapter = {
|
|
|
4078
4109
|
const mcpServers = toCursorMcpServers(injected);
|
|
4079
4110
|
const req = {
|
|
4080
4111
|
prompt,
|
|
4112
|
+
...fullPrompt !== prompt ? { freshPrompt: fullPrompt } : {},
|
|
4081
4113
|
cwd: thread.worktreePath,
|
|
4082
4114
|
threadId: thread.id,
|
|
4083
4115
|
agentId,
|
|
@@ -4104,8 +4136,9 @@ var cursorAdapter = {
|
|
|
4104
4136
|
stdin: JSON.stringify(req),
|
|
4105
4137
|
env: {
|
|
4106
4138
|
...launch.env,
|
|
4107
|
-
...cursorRipgrepEnv({ startFile: runner })
|
|
4108
|
-
|
|
4139
|
+
...cursorRipgrepEnv({ startFile: runner })
|
|
4140
|
+
// API key stays on the stdin request. Do not copy it into the child env,
|
|
4141
|
+
// where `ps` and crash dumps can see it. The runner reads `req.apiKey`.
|
|
4109
4142
|
}
|
|
4110
4143
|
};
|
|
4111
4144
|
},
|
|
@@ -4127,14 +4160,17 @@ var cursorAdapter = {
|
|
|
4127
4160
|
};
|
|
4128
4161
|
|
|
4129
4162
|
// src/agents/opencode.ts
|
|
4130
|
-
import { existsSync as
|
|
4163
|
+
import { existsSync as existsSync17 } from "fs";
|
|
4164
|
+
|
|
4165
|
+
// src/agent-rpc/opencode-host.ts
|
|
4166
|
+
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
4131
4167
|
|
|
4132
4168
|
// src/agent-rpc/opencode-hook.ts
|
|
4133
|
-
import { mkdirSync as
|
|
4134
|
-
import { join as
|
|
4169
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync4, readFileSync as readFileSync7, renameSync, writeFileSync as writeFileSync6 } from "fs";
|
|
4170
|
+
import { join as join15 } from "path";
|
|
4135
4171
|
var OPENCODE_PLUGIN_SOURCE = `import { tool } from "@opencode-ai/plugin"
|
|
4136
4172
|
|
|
4137
|
-
const
|
|
4173
|
+
const RPC_URL = process.env[${JSON.stringify(AGENT_RPC_URL_ENV)}] || ""
|
|
4138
4174
|
const TOKEN = process.env[${JSON.stringify(AGENT_RPC_TOKEN_ENV)}] || ""
|
|
4139
4175
|
const CWD = process.env[${JSON.stringify(AGENT_RPC_CWD_ENV)}] || ""
|
|
4140
4176
|
|
|
@@ -4147,24 +4183,29 @@ function jsonError(err) {
|
|
|
4147
4183
|
}
|
|
4148
4184
|
|
|
4149
4185
|
function socketUrl() {
|
|
4150
|
-
const u = new URL(
|
|
4186
|
+
const u = new URL(RPC_URL)
|
|
4151
4187
|
u.searchParams.set(${JSON.stringify(AGENT_RPC_TOKEN_QUERY)}, TOKEN)
|
|
4152
4188
|
return u.toString()
|
|
4153
4189
|
}
|
|
4154
4190
|
|
|
4155
4191
|
function call(method, params) {
|
|
4156
|
-
if (!
|
|
4192
|
+
if (!RPC_URL || !TOKEN) {
|
|
4157
4193
|
return Promise.resolve(jsonError(new Error("Agent RPC runtime is not running")))
|
|
4158
4194
|
}
|
|
4195
|
+
const timeoutMs = method === "job.wait" ? 130000 : 30000
|
|
4159
4196
|
return new Promise((resolve) => {
|
|
4160
4197
|
let settled = false
|
|
4198
|
+
let ws
|
|
4199
|
+
let timer
|
|
4161
4200
|
const done = (value) => {
|
|
4162
4201
|
if (settled) return
|
|
4163
4202
|
settled = true
|
|
4203
|
+
clearTimeout(timer)
|
|
4164
4204
|
try { ws.close() } catch {}
|
|
4165
4205
|
resolve(value)
|
|
4166
4206
|
}
|
|
4167
|
-
|
|
4207
|
+
timer = setTimeout(() => done(jsonError(new Error("Agent RPC timed out"))), timeoutMs)
|
|
4208
|
+
ws = new WebSocket(socketUrl())
|
|
4168
4209
|
const id = Date.now()
|
|
4169
4210
|
ws.addEventListener("open", () => {
|
|
4170
4211
|
ws.send(JSON.stringify({ jsonrpc: "2.0", id, method, params, authToken: TOKEN }))
|
|
@@ -4236,12 +4277,19 @@ export const SideboardRpc = async (ctx) => {
|
|
|
4236
4277
|
}
|
|
4237
4278
|
`;
|
|
4238
4279
|
function writeOpencodeRpcPlugin() {
|
|
4239
|
-
const
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4280
|
+
const pluginDir = join15(appDataDir(), "agent-rpc", "opencode");
|
|
4281
|
+
mkdirSync4(pluginDir, { recursive: true });
|
|
4282
|
+
const pluginFile = join15(pluginDir, "sideboard-rpc.js");
|
|
4283
|
+
if (existsSync16(pluginFile)) {
|
|
4284
|
+
try {
|
|
4285
|
+
if (readFileSync7(pluginFile, "utf8") === OPENCODE_PLUGIN_SOURCE) return pluginFile;
|
|
4286
|
+
} catch {
|
|
4287
|
+
}
|
|
4288
|
+
}
|
|
4289
|
+
const tmp = `${pluginFile}.${process.pid}.tmp`;
|
|
4290
|
+
writeFileSync6(tmp, OPENCODE_PLUGIN_SOURCE);
|
|
4291
|
+
renameSync(tmp, pluginFile);
|
|
4292
|
+
return pluginFile;
|
|
4245
4293
|
}
|
|
4246
4294
|
|
|
4247
4295
|
// src/agent-rpc/opencode-host.ts
|
|
@@ -4264,10 +4312,9 @@ async function buildOpencodeHostEnv(thread) {
|
|
|
4264
4312
|
const config = injected.length > 0 || disableNames.length > 0 ? JSON.parse(toOpencodeMcpConfigContent(injected, { disableNames })) : {};
|
|
4265
4313
|
const env = {};
|
|
4266
4314
|
if (rpc) {
|
|
4267
|
-
const
|
|
4268
|
-
env.OPENCODE_CONFIG_DIR = configDir;
|
|
4315
|
+
const pluginFile = writeOpencodeRpcPlugin();
|
|
4269
4316
|
Object.assign(env, agentRpcChildEnv(rpc, thread.worktreePath));
|
|
4270
|
-
config.plugin = [pluginFile];
|
|
4317
|
+
config.plugin = [pathToFileURL2(pluginFile).href];
|
|
4271
4318
|
}
|
|
4272
4319
|
if (Object.keys(config).length > 0) {
|
|
4273
4320
|
env.OPENCODE_CONFIG_CONTENT = JSON.stringify(config);
|
|
@@ -4334,7 +4381,7 @@ async function listOpencodeModels() {
|
|
|
4334
4381
|
if (opencode === "opencode") {
|
|
4335
4382
|
const which = await run("which", ["opencode"], { reject: false });
|
|
4336
4383
|
if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
|
|
4337
|
-
} else if (!
|
|
4384
|
+
} else if (!existsSync17(opencode)) {
|
|
4338
4385
|
return FALLBACK_OPENCODE_MODELS;
|
|
4339
4386
|
}
|
|
4340
4387
|
const listed = await run(opencode, ["models"], { reject: false });
|
|
@@ -4369,7 +4416,7 @@ var opencodeAdapter = {
|
|
|
4369
4416
|
async detect() {
|
|
4370
4417
|
const opencode = resolveAgentExecutable("opencode");
|
|
4371
4418
|
if (opencode !== "opencode") {
|
|
4372
|
-
if (!
|
|
4419
|
+
if (!existsSync17(opencode)) {
|
|
4373
4420
|
return {
|
|
4374
4421
|
agent: "opencode",
|
|
4375
4422
|
installed: false,
|
|
@@ -4423,6 +4470,11 @@ var opencodeAdapter = {
|
|
|
4423
4470
|
if (model) {
|
|
4424
4471
|
args.push("--model", model);
|
|
4425
4472
|
}
|
|
4473
|
+
args.push("--thinking");
|
|
4474
|
+
const variant = thread.effort?.trim() ?? "";
|
|
4475
|
+
if (variant && /^(minimal|low|medium|high|max|xhigh)$/i.test(variant)) {
|
|
4476
|
+
args.push("--variant", variant);
|
|
4477
|
+
}
|
|
4426
4478
|
const hostEnv = await buildOpencodeHostEnv(thread);
|
|
4427
4479
|
return {
|
|
4428
4480
|
file: resolveAgentExecutable("opencode"),
|
|
@@ -4455,6 +4507,10 @@ var opencodeAdapter = {
|
|
|
4455
4507
|
const text = obj.part?.text ?? obj.text;
|
|
4456
4508
|
if (text) return { type: "stdout", data: text };
|
|
4457
4509
|
}
|
|
4510
|
+
if (obj.type === "reasoning" || obj.type === "thinking") {
|
|
4511
|
+
const text = obj.part?.text ?? obj.text;
|
|
4512
|
+
if (typeof text === "string" && text) return { type: "thinking", data: text };
|
|
4513
|
+
}
|
|
4458
4514
|
if (obj.type === "tool_use") {
|
|
4459
4515
|
const part = obj.part;
|
|
4460
4516
|
const name = part?.tool ?? part?.name ?? obj.tool ?? obj.name ?? "tool";
|
|
@@ -4570,11 +4626,14 @@ var opencodeAdapter = {
|
|
|
4570
4626
|
const listed = await run(
|
|
4571
4627
|
resolveAgentExecutable("opencode"),
|
|
4572
4628
|
["session", "list", "--format", "json"],
|
|
4573
|
-
{ cwd: worktreePath, reject: false }
|
|
4629
|
+
{ cwd: worktreePath, reject: false, timeoutMs: 8e3 }
|
|
4574
4630
|
);
|
|
4575
|
-
if (listed.exitCode === 0
|
|
4631
|
+
if (listed.exitCode === 0) {
|
|
4632
|
+
const raw = listed.stdout.trim();
|
|
4633
|
+
if (!raw) return null;
|
|
4576
4634
|
try {
|
|
4577
|
-
const sessions = JSON.parse(
|
|
4635
|
+
const sessions = JSON.parse(raw);
|
|
4636
|
+
if (Array.isArray(sessions) && sessions.length === 0) return null;
|
|
4578
4637
|
if (Array.isArray(sessions) && sessions.length > 0) {
|
|
4579
4638
|
const norm = (p) => p.replace(/\/+$/, "");
|
|
4580
4639
|
const wt = norm(worktreePath);
|
|
@@ -4608,34 +4667,8 @@ var opencodeAdapter = {
|
|
|
4608
4667
|
};
|
|
4609
4668
|
},
|
|
4610
4669
|
async listLinearIssues(_repoPath) {
|
|
4611
|
-
const
|
|
4612
|
-
|
|
4613
|
-
resolveAgentExecutable("opencode"),
|
|
4614
|
-
["run", prompt, "--format", "json"],
|
|
4615
|
-
{
|
|
4616
|
-
reject: false,
|
|
4617
|
-
env: { OPENCODE_PERMISSION: JSON.stringify({ "*": "allow" }) }
|
|
4618
|
-
}
|
|
4619
|
-
);
|
|
4620
|
-
if (exitCode !== 0) return [];
|
|
4621
|
-
const texts = [];
|
|
4622
|
-
for (const line of stdout.split("\n")) {
|
|
4623
|
-
try {
|
|
4624
|
-
const obj = JSON.parse(line);
|
|
4625
|
-
if (obj.type === "text") {
|
|
4626
|
-
texts.push(obj.part?.text ?? obj.text ?? "");
|
|
4627
|
-
}
|
|
4628
|
-
} catch {
|
|
4629
|
-
}
|
|
4630
|
-
}
|
|
4631
|
-
const joined = texts.join("");
|
|
4632
|
-
const match = joined.match(/\[[\s\S]*\]/);
|
|
4633
|
-
if (!match) return [];
|
|
4634
|
-
try {
|
|
4635
|
-
return JSON.parse(match[0]);
|
|
4636
|
-
} catch {
|
|
4637
|
-
return [];
|
|
4638
|
-
}
|
|
4670
|
+
const { listAssignedLinearIssues: listAssignedLinearIssues2 } = await import("./linear-list-Q4M7AZO2.js");
|
|
4671
|
+
return listAssignedLinearIssues2();
|
|
4639
4672
|
}
|
|
4640
4673
|
};
|
|
4641
4674
|
|
|
@@ -5034,9 +5067,9 @@ function formatClaudeUsageOverLimitWait(windows, now = /* @__PURE__ */ new Date(
|
|
|
5034
5067
|
}
|
|
5035
5068
|
|
|
5036
5069
|
// src/agents/claude-usage-client.ts
|
|
5037
|
-
import { existsSync as
|
|
5038
|
-
import { homedir as
|
|
5039
|
-
import { join as
|
|
5070
|
+
import { existsSync as existsSync18, readFileSync as readFileSync8 } from "fs";
|
|
5071
|
+
import { homedir as homedir8 } from "os";
|
|
5072
|
+
import { join as join16 } from "path";
|
|
5040
5073
|
var CLAUDE_OAUTH_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
|
|
5041
5074
|
var CLAUDE_USAGE_TTL_MS = 9e4;
|
|
5042
5075
|
var CLAUDE_USAGE_ERROR_TTL_MS = 5 * 6e4;
|
|
@@ -5076,12 +5109,12 @@ function accessTokenFromCredentialsJson(raw) {
|
|
|
5076
5109
|
}
|
|
5077
5110
|
}
|
|
5078
5111
|
function claudeCredentialsPath(configDir) {
|
|
5079
|
-
const root = configDir?.trim() || process.env.CLAUDE_CONFIG_DIR?.trim() ||
|
|
5080
|
-
return
|
|
5112
|
+
const root = configDir?.trim() || process.env.CLAUDE_CONFIG_DIR?.trim() || join16(homedir8(), ".claude");
|
|
5113
|
+
return join16(root, ".credentials.json");
|
|
5081
5114
|
}
|
|
5082
5115
|
async function readFileAccessToken(configDir) {
|
|
5083
5116
|
const path = claudeCredentialsPath(configDir);
|
|
5084
|
-
if (!
|
|
5117
|
+
if (!existsSync18(path)) return null;
|
|
5085
5118
|
try {
|
|
5086
5119
|
return accessTokenFromCredentialsJson(readFileSync8(path, "utf8"));
|
|
5087
5120
|
} catch {
|