@sideboard-ai/core 0.1.324 → 0.1.325
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-5ZY3ZUUO.js → abletime-M7STTMZT.js} +6 -5
- package/dist/{abletime-CU2UPMJF.js → abletime-VL234MCP.js} +5 -4
- package/dist/{abletime-oauth-7EOSBEFM.js → abletime-oauth-LMMGMAPA.js} +3 -3
- package/dist/{abletime-oauth-4TTCR3CT.js → abletime-oauth-P4ZFBEAL.js} +3 -3
- package/dist/{abletime-rest-3TG4G7LW.js → abletime-rest-DLV7EIWS.js} +3 -3
- package/dist/{abletime-rest-KOKE7V4B.js → abletime-rest-GOI7HELR.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 +96 -31
- package/dist/agents/cursor-runner.js +74 -24
- package/dist/{agents-YK65UDLT.js → agents-LDRM3BTY.js} +9 -8
- package/dist/{agents-LUSTCMDN.js → agents-MBIEAETM.js} +12 -11
- package/dist/{app-settings-I5HM5RMP.js → app-settings-E7DMMEKC.js} +1 -1
- package/dist/{app-settings-XIF4EC4K.js → app-settings-UQHUNOLV.js} +1 -1
- package/dist/{chunk-INBUV7HY.js → chunk-2UP3XD2D.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-BYUCNIXK.js → chunk-7G27TB4M.js} +6 -6
- package/dist/chunk-7LUOLYFM.js +1445 -0
- package/dist/{chunk-Y3WREIPQ.js → chunk-A76MKMSF.js} +12 -210
- package/dist/{chunk-JE3JLHMO.js → chunk-APKUI4BP.js} +3 -3
- package/dist/{chunk-FR3SAYUL.js → chunk-AQEKPJWU.js} +5 -5
- package/dist/{chunk-QOS4465Y.js → chunk-BOFYI6LC.js} +1 -1
- package/dist/{chunk-FUFNMUNR.js → chunk-BTF3ATST.js} +7 -8
- package/dist/{chunk-OIHRC2ZJ.js → chunk-CI4M54LS.js} +22 -2
- package/dist/chunk-DBKHL7NC.js +214 -0
- package/dist/{chunk-ROOZDDFA.js → chunk-EO6ZFLG6.js} +7 -8
- package/dist/chunk-EZR6W4B3.js +1259 -0
- package/dist/{chunk-MZIZTSR2.js → chunk-F65JMKUR.js} +2 -2
- package/dist/chunk-F6GE7V3Q.js +216 -0
- package/dist/{chunk-7MQSYPAY.js → chunk-GNLKBS3U.js} +206 -188
- package/dist/{chunk-EKU7FQVG.js → chunk-H36GKGU2.js} +2 -2
- package/dist/{chunk-7D5QIU3N.js → chunk-HG6KS7OT.js} +294 -265
- package/dist/chunk-MBT6WDAB.js +28 -0
- package/dist/{chunk-JH5SMVM5.js → chunk-MFMDZAA6.js} +262 -233
- package/dist/{chunk-7PVT73H6.js → chunk-NWGINMEA.js} +12 -210
- 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-PPTJMBUY.js +25 -0
- package/dist/{chunk-B4CDSSRN.js → chunk-Q3FHTGIW.js} +2 -0
- package/dist/{chunk-EJ66LEKH.js → chunk-RZJTGBXY.js} +22 -2
- package/dist/{chunk-DF5BM5OY.js → chunk-SACHHTBJ.js} +207 -186
- package/dist/{chunk-5GDJSFCT.js → chunk-SK6NYGPD.js} +2 -2
- package/dist/{chunk-74OPNF7U.js → chunk-SQQBU7Z6.js} +2 -2
- package/dist/{chunk-Q3YJZPQI.js → chunk-SS6CYGLF.js} +3 -3
- package/dist/{chunk-YDUHLWI5.js → chunk-SUZOPJZC.js} +21 -7
- package/dist/{chunk-ZHGMRBSC.js → chunk-U5WO6MEB.js} +3 -3
- package/dist/{chunk-NXUN4U5P.js → chunk-VAFQS4D2.js} +2 -2
- package/dist/chunk-W3ZLE4PO.js +77 -0
- package/dist/{chunk-RR4WCGNB.js → chunk-WYEST76H.js} +7 -7
- package/dist/{chunk-ODH3XHMI.js → chunk-ZEUMWHOH.js} +5 -5
- package/dist/{chunk-ZIRQZUZY.js → chunk-ZHDXLDLA.js} +3 -3
- package/dist/{chunk-IFWGG2M2.js → chunk-ZSHS46V5.js} +2 -0
- package/dist/{conductor-JFABMXDA.js → conductor-D4KFZF54.js} +6 -6
- package/dist/{conductor-SPZOTC7W.js → conductor-KB7L7NQN.js} +7 -7
- package/dist/{coordinator-prompt-K66RGNWK.js → coordinator-prompt-OBXEC63K.js} +4 -4
- package/dist/{coordinator-prompt-Z6UFHFDH.js → coordinator-prompt-SUO4FRY3.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-UHU2FXTY.js} +4 -4
- package/dist/{global-workspace-RHEO55B4.js → global-workspace-Z2SURNHA.js} +4 -4
- package/dist/index.cjs +21112 -20864
- package/dist/index.d.cts +25 -9
- package/dist/index.d.ts +25 -9
- package/dist/index.js +343 -1678
- package/dist/linear-HFUOUJ5H.js +67 -0
- package/dist/linear-SIHEBU3X.js +69 -0
- package/dist/linear-list-63I7QUC6.js +6 -0
- package/dist/linear-list-JFV3EES6.js +8 -0
- package/dist/mcp/run-stdio.cjs +15654 -15398
- package/dist/mcp/run-stdio.js +67 -1247
- package/dist/{optional-cli-RMMS5L6F.js → optional-cli-U2GUA2X6.js} +3 -3
- package/dist/{optional-cli-Y3Z3GIPZ.js → optional-cli-ULDP3O5S.js} +4 -4
- package/dist/{orchestrator-7VTAUY24.js → orchestrator-3H4KNGPN.js} +15 -13
- package/dist/{orchestrator-2O6OJQLX.js → orchestrator-6ROMEWBP.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-MG5JHRKW.js} +4 -4
- package/dist/{workspaces-42E6AGXD.js → workspaces-QJNKEGEM.js} +4 -4
- package/dist/{worktree-ZDA2UJ7C.js → worktree-KSJPTHGZ.js} +3 -3
- package/dist/{worktree-4NGXCCUO.js → worktree-MYJYUHZM.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-ZHDXLDLA.js";
|
|
28
16
|
import {
|
|
29
17
|
codexUnattendedGitConfigArgs,
|
|
30
18
|
mergeAgentGitAuthEnv,
|
|
31
19
|
resolveAgentGitAuthEnv,
|
|
32
20
|
resolveCodexGitWritableRoots
|
|
33
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-EO6ZFLG6.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-MBT6WDAB.js";
|
|
34
37
|
import {
|
|
35
38
|
githubAgentAuthReady,
|
|
36
39
|
npmGlobalNodeModules,
|
|
@@ -45,7 +48,7 @@ import {
|
|
|
45
48
|
loadAppSettings,
|
|
46
49
|
resolveAgentExecutable,
|
|
47
50
|
resolveClaudeExecutable
|
|
48
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-CI4M54LS.js";
|
|
49
52
|
import {
|
|
50
53
|
isElectronLikeCommand,
|
|
51
54
|
unwrapStrippedElectronLaunch,
|
|
@@ -57,7 +60,7 @@ import {
|
|
|
57
60
|
CLAUDE_POSTHOG_CONNECTOR_ALLOWED_TOOLS,
|
|
58
61
|
CLAUDE_PRINT_BG_WAIT_CEILING_MS,
|
|
59
62
|
mcpAllowToolsFromNames
|
|
60
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-Q3FHTGIW.js";
|
|
61
64
|
import {
|
|
62
65
|
appDataDir
|
|
63
66
|
} from "./chunk-WOU343SI.js";
|
|
@@ -448,6 +451,7 @@ var brightsyAdapter = {
|
|
|
448
451
|
|
|
449
452
|
// src/agents/claude.ts
|
|
450
453
|
import { existsSync as existsSync11 } from "fs";
|
|
454
|
+
import { dirname as dirname5 } from "path";
|
|
451
455
|
|
|
452
456
|
// src/agents/claude-mcp-status.ts
|
|
453
457
|
var SIDEBOARD_CONNECTOR_SERVICES = [
|
|
@@ -564,7 +568,7 @@ function isNotableMcpInitStatus(server, sideboardOk, coverage) {
|
|
|
564
568
|
|
|
565
569
|
// src/mcp-ui/host.ts
|
|
566
570
|
import { createHash } from "crypto";
|
|
567
|
-
import { homedir as
|
|
571
|
+
import { homedir as homedir6 } from "os";
|
|
568
572
|
|
|
569
573
|
// src/agents/orch-mcp-isolation.ts
|
|
570
574
|
import { existsSync as existsSync8, readFileSync as readFileSync4 } from "fs";
|
|
@@ -921,20 +925,20 @@ function readJson(path) {
|
|
|
921
925
|
}
|
|
922
926
|
|
|
923
927
|
// src/agents/orch-mcp-isolation.ts
|
|
924
|
-
import { homedir as
|
|
925
|
-
import { join as
|
|
928
|
+
import { homedir as homedir5 } from "os";
|
|
929
|
+
import { join as join8 } from "path";
|
|
926
930
|
import { parse as parseToml } from "smol-toml";
|
|
927
931
|
|
|
928
932
|
// src/agents/user-mcp-config.ts
|
|
929
|
-
import { existsSync as existsSync7, mkdirSync as
|
|
930
|
-
import { homedir as
|
|
931
|
-
import { dirname as dirname3, join as
|
|
933
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
934
|
+
import { homedir as homedir4 } from "os";
|
|
935
|
+
import { dirname as dirname3, join as join7 } from "path";
|
|
932
936
|
|
|
933
937
|
// src/agents/injected-mcp.ts
|
|
934
|
-
import { existsSync as existsSync6, mkdtempSync, writeFileSync as
|
|
938
|
+
import { existsSync as existsSync6, mkdtempSync, writeFileSync as writeFileSync3 } from "fs";
|
|
935
939
|
import { createRequire } from "module";
|
|
936
940
|
import { tmpdir } from "os";
|
|
937
|
-
import { dirname as dirname2, join as
|
|
941
|
+
import { dirname as dirname2, join as join6 } from "path";
|
|
938
942
|
import { fileURLToPath } from "url";
|
|
939
943
|
|
|
940
944
|
// src/agent-rpc/protocol.ts
|
|
@@ -1401,6 +1405,44 @@ async function resolveNodeLaunch(scriptPath) {
|
|
|
1401
1405
|
};
|
|
1402
1406
|
}
|
|
1403
1407
|
|
|
1408
|
+
// src/agents/codex-mcp-profile.ts
|
|
1409
|
+
import { randomBytes } from "crypto";
|
|
1410
|
+
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
1411
|
+
import { homedir as homedir3 } from "os";
|
|
1412
|
+
import { join as join5 } from "path";
|
|
1413
|
+
function isCodexSecretEnvKey(key) {
|
|
1414
|
+
return /token|secret|password|credential|oauth|api_key|_key$/i.test(key);
|
|
1415
|
+
}
|
|
1416
|
+
function tomlBasicString(value) {
|
|
1417
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r")}"`;
|
|
1418
|
+
}
|
|
1419
|
+
function secretEnv(env) {
|
|
1420
|
+
if (!env) return void 0;
|
|
1421
|
+
const out = { ...env };
|
|
1422
|
+
delete out.ELECTRON_RUN_AS_NODE;
|
|
1423
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
1424
|
+
}
|
|
1425
|
+
function writeCodexMcpSecretProfile(servers) {
|
|
1426
|
+
const blocks = [];
|
|
1427
|
+
for (const s of servers) {
|
|
1428
|
+
const env = secretEnv(s.env);
|
|
1429
|
+
if (!env) continue;
|
|
1430
|
+
const secrets = Object.entries(env).filter(([key]) => isCodexSecretEnvKey(key));
|
|
1431
|
+
if (secrets.length === 0) continue;
|
|
1432
|
+
const lines = [`[mcp_servers.${s.name}.env]`];
|
|
1433
|
+
for (const [key, value] of secrets) lines.push(`${key} = ${tomlBasicString(value)}`);
|
|
1434
|
+
blocks.push(lines.join("\n"));
|
|
1435
|
+
}
|
|
1436
|
+
if (blocks.length === 0) return null;
|
|
1437
|
+
const home = process.env.CODEX_HOME?.trim() || join5(homedir3(), ".codex");
|
|
1438
|
+
mkdirSync2(home, { recursive: true, mode: 448 });
|
|
1439
|
+
const profile = `sideboard-${randomBytes(8).toString("hex")}`;
|
|
1440
|
+
const file = join5(home, `${profile}.config.toml`);
|
|
1441
|
+
writeFileSync2(file, `${blocks.join("\n\n")}
|
|
1442
|
+
`, { mode: 384 });
|
|
1443
|
+
return { profile, file };
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1404
1446
|
// src/agents/injected-mcp.ts
|
|
1405
1447
|
var SIDEBOARD_MCP_ALLOWED_TOOLS = [
|
|
1406
1448
|
"mcp__sideboard",
|
|
@@ -1536,7 +1578,7 @@ function corePackageDir() {
|
|
|
1536
1578
|
} catch {
|
|
1537
1579
|
}
|
|
1538
1580
|
try {
|
|
1539
|
-
const req = createRequire(
|
|
1581
|
+
const req = createRequire(join6(process.cwd(), "package.json"));
|
|
1540
1582
|
return dirname2(req.resolve("@sideboard-ai/core"));
|
|
1541
1583
|
} catch {
|
|
1542
1584
|
return process.cwd();
|
|
@@ -1550,13 +1592,13 @@ function findSideboardMcpJsEntry() {
|
|
|
1550
1592
|
let dir = corePackageDir();
|
|
1551
1593
|
for (let i = 0; i < 10; i++) {
|
|
1552
1594
|
const candidates = [
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1595
|
+
join6(dir, "mcp/run-stdio.js"),
|
|
1596
|
+
join6(dir, "mcp/run-stdio.cjs"),
|
|
1597
|
+
join6(dir, "dist/mcp/run-stdio.js"),
|
|
1598
|
+
join6(dir, "dist/mcp/run-stdio.cjs"),
|
|
1599
|
+
join6(dir, "packages/core/dist/mcp/run-stdio.js"),
|
|
1600
|
+
join6(dir, "packages/cli/dist/index.js"),
|
|
1601
|
+
join6(dir, "cli/dist/index.js")
|
|
1560
1602
|
];
|
|
1561
1603
|
for (const p of candidates) {
|
|
1562
1604
|
if (existsSync6(p) && !isAsarPath(p)) return p;
|
|
@@ -1664,6 +1706,7 @@ function toCodexMcpConfigArgs(servers) {
|
|
|
1664
1706
|
const env = mcpSpawnEnv(s.env);
|
|
1665
1707
|
if (env) {
|
|
1666
1708
|
for (const [key, value] of Object.entries(env)) {
|
|
1709
|
+
if (isCodexSecretEnvKey(key)) continue;
|
|
1667
1710
|
args.push("-c", `${prefix}.env.${key}=${JSON.stringify(value)}`);
|
|
1668
1711
|
}
|
|
1669
1712
|
}
|
|
@@ -1722,15 +1765,15 @@ function mcpServersRecord(servers, extraServers) {
|
|
|
1722
1765
|
function writeMcpServersConfig(servers, extraServers) {
|
|
1723
1766
|
const mcpServers = mcpServersRecord(servers, extraServers);
|
|
1724
1767
|
if (Object.keys(mcpServers).length === 0) return null;
|
|
1725
|
-
const dir = mkdtempSync(
|
|
1726
|
-
const cfgPath =
|
|
1727
|
-
|
|
1768
|
+
const dir = mkdtempSync(join6(tmpdir(), "sideboard-mcp-"));
|
|
1769
|
+
const cfgPath = join6(dir, "mcp.json");
|
|
1770
|
+
writeFileSync3(cfgPath, JSON.stringify({ mcpServers }, null, 2), { mode: 384 });
|
|
1728
1771
|
return cfgPath;
|
|
1729
1772
|
}
|
|
1730
1773
|
|
|
1731
1774
|
// src/agents/user-mcp-config.ts
|
|
1732
1775
|
function userClaudeMcpConfigPath() {
|
|
1733
|
-
return
|
|
1776
|
+
return join7(homedir4(), ".claude.json");
|
|
1734
1777
|
}
|
|
1735
1778
|
|
|
1736
1779
|
// src/agents/orch-mcp-isolation.ts
|
|
@@ -1767,13 +1810,19 @@ function readText(path) {
|
|
|
1767
1810
|
return "";
|
|
1768
1811
|
}
|
|
1769
1812
|
}
|
|
1770
|
-
function userCodexConfigPaths(home =
|
|
1771
|
-
|
|
1813
|
+
function userCodexConfigPaths(home = homedir5()) {
|
|
1814
|
+
const paths = [
|
|
1815
|
+
join8(home, ".codex", "config.toml"),
|
|
1816
|
+
join8(home, ".config", "codex", "config.toml")
|
|
1817
|
+
];
|
|
1818
|
+
const codexHome = process.env.CODEX_HOME?.trim();
|
|
1819
|
+
if (codexHome) paths.unshift(join8(codexHome, "config.toml"));
|
|
1820
|
+
return paths;
|
|
1772
1821
|
}
|
|
1773
|
-
function userOpencodeConfigPaths(home =
|
|
1822
|
+
function userOpencodeConfigPaths(home = homedir5()) {
|
|
1774
1823
|
return [
|
|
1775
|
-
|
|
1776
|
-
|
|
1824
|
+
join8(home, ".config", "opencode", "opencode.json"),
|
|
1825
|
+
join8(home, ".config", "opencode", "opencode.jsonc")
|
|
1777
1826
|
];
|
|
1778
1827
|
}
|
|
1779
1828
|
function userMcpNamesToDisable(opts) {
|
|
@@ -1792,7 +1841,7 @@ function userMcpNamesToDisable(opts) {
|
|
|
1792
1841
|
}
|
|
1793
1842
|
return out;
|
|
1794
1843
|
}
|
|
1795
|
-
function listUserCodexMcpNames(home =
|
|
1844
|
+
function listUserCodexMcpNames(home = homedir5()) {
|
|
1796
1845
|
const names = [];
|
|
1797
1846
|
for (const path of userCodexConfigPaths(home)) {
|
|
1798
1847
|
if (!existsSync8(path)) continue;
|
|
@@ -1800,7 +1849,7 @@ function listUserCodexMcpNames(home = homedir4()) {
|
|
|
1800
1849
|
}
|
|
1801
1850
|
return names;
|
|
1802
1851
|
}
|
|
1803
|
-
function listUserOpencodeMcpNames(home =
|
|
1852
|
+
function listUserOpencodeMcpNames(home = homedir5()) {
|
|
1804
1853
|
const names = [];
|
|
1805
1854
|
for (const path of userOpencodeConfigPaths(home)) {
|
|
1806
1855
|
if (!existsSync8(path)) continue;
|
|
@@ -1808,12 +1857,12 @@ function listUserOpencodeMcpNames(home = homedir4()) {
|
|
|
1808
1857
|
}
|
|
1809
1858
|
return names;
|
|
1810
1859
|
}
|
|
1811
|
-
function userClaudeMcpConfigObject(home =
|
|
1812
|
-
const claudePath = home ===
|
|
1860
|
+
function userClaudeMcpConfigObject(home = homedir5()) {
|
|
1861
|
+
const claudePath = home === homedir5() ? userClaudeMcpConfigPath() : join8(home, ".claude.json");
|
|
1813
1862
|
if (!existsSync8(claudePath)) return {};
|
|
1814
1863
|
return asObject(asObject(readJsonObject(claudePath)).mcpServers);
|
|
1815
1864
|
}
|
|
1816
|
-
function listUserClaudeMcpServerEntries(home =
|
|
1865
|
+
function listUserClaudeMcpServerEntries(home = homedir5(), projectDirs) {
|
|
1817
1866
|
const out = {};
|
|
1818
1867
|
for (const [name, entry] of Object.entries(
|
|
1819
1868
|
listEnabledClaudePluginMcpServers({ home, projectDirs })
|
|
@@ -1851,7 +1900,7 @@ function toCodexUnattendedAppsArgs() {
|
|
|
1851
1900
|
}
|
|
1852
1901
|
|
|
1853
1902
|
// src/mcp-ui/proxy-http.ts
|
|
1854
|
-
import { randomBytes, randomUUID } from "crypto";
|
|
1903
|
+
import { randomBytes as randomBytes2, randomUUID } from "crypto";
|
|
1855
1904
|
import { createServer } from "http";
|
|
1856
1905
|
import { Server as Server2 } from "@modelcontextprotocol/sdk/server/index.js";
|
|
1857
1906
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
@@ -1948,7 +1997,7 @@ function listedTool(tool) {
|
|
|
1948
1997
|
|
|
1949
1998
|
// src/mcp-ui/proxy-http.ts
|
|
1950
1999
|
async function listenMcpUiProxy(opts) {
|
|
1951
|
-
const token =
|
|
2000
|
+
const token = randomBytes2(24).toString("hex");
|
|
1952
2001
|
const transports = /* @__PURE__ */ new Map();
|
|
1953
2002
|
const httpServer = createServer((req, res) => {
|
|
1954
2003
|
void handle(req, res);
|
|
@@ -2321,7 +2370,7 @@ var singleton;
|
|
|
2321
2370
|
function getMcpUiHost() {
|
|
2322
2371
|
if (!singleton) {
|
|
2323
2372
|
singleton = new McpUiHost({
|
|
2324
|
-
entries: (projectDirs) => listUserClaudeMcpServerEntries(
|
|
2373
|
+
entries: (projectDirs) => listUserClaudeMcpServerEntries(homedir6(), projectDirs)
|
|
2325
2374
|
});
|
|
2326
2375
|
}
|
|
2327
2376
|
return singleton;
|
|
@@ -2329,7 +2378,7 @@ function getMcpUiHost() {
|
|
|
2329
2378
|
async function proxyClaudeUserMcp(orchestrator, projectDirs) {
|
|
2330
2379
|
if (orchestrator) return {};
|
|
2331
2380
|
const dirs = projectDirs.filter((d) => typeof d === "string" && d.length > 0);
|
|
2332
|
-
return getMcpUiHost().proxyEntries(listUserClaudeMcpServerEntries(
|
|
2381
|
+
return getMcpUiHost().proxyEntries(listUserClaudeMcpServerEntries(homedir6(), dirs), dirs);
|
|
2333
2382
|
}
|
|
2334
2383
|
function dirsKeyFor(projectDirs) {
|
|
2335
2384
|
if (!projectDirs?.length) return "";
|
|
@@ -2343,16 +2392,6 @@ function planModeTurnInstruction(planMode) {
|
|
|
2343
2392
|
return planMode ? PLAN_MODE_INSTRUCTION : PLAN_MODE_OFF_INSTRUCTION;
|
|
2344
2393
|
}
|
|
2345
2394
|
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
2395
|
if (thread.planMode) {
|
|
2357
2396
|
return {
|
|
2358
2397
|
claude: "plan",
|
|
@@ -2364,6 +2403,18 @@ function permissionMode(thread) {
|
|
|
2364
2403
|
codexSandbox: "read-only"
|
|
2365
2404
|
};
|
|
2366
2405
|
}
|
|
2406
|
+
if (thread.sourceType === "orchestration") {
|
|
2407
|
+
return {
|
|
2408
|
+
claude: "acceptEdits",
|
|
2409
|
+
// Unattended coordinators cannot answer permission prompts. Explicit
|
|
2410
|
+
// allows override the user's OpenCode denies for this process only.
|
|
2411
|
+
opencodePermission: JSON.stringify({
|
|
2412
|
+
edit: "allow",
|
|
2413
|
+
bash: { "*": "allow" }
|
|
2414
|
+
}),
|
|
2415
|
+
codexSandbox: "danger-full-access"
|
|
2416
|
+
};
|
|
2417
|
+
}
|
|
2367
2418
|
if (thread.autonomy === "full") {
|
|
2368
2419
|
return {
|
|
2369
2420
|
claude: "bypassPermissions",
|
|
@@ -2373,19 +2424,16 @@ function permissionMode(thread) {
|
|
|
2373
2424
|
}
|
|
2374
2425
|
return {
|
|
2375
2426
|
claude: "acceptEdits",
|
|
2376
|
-
opencodePermission: JSON.stringify({
|
|
2377
|
-
edit: "allow",
|
|
2378
|
-
bash: { "*": "allow", "rm -rf *": "deny" }
|
|
2379
|
-
}),
|
|
2427
|
+
opencodePermission: JSON.stringify({}),
|
|
2380
2428
|
codexSandbox: "workspace-write"
|
|
2381
2429
|
};
|
|
2382
2430
|
}
|
|
2383
2431
|
|
|
2384
2432
|
// src/agent-rpc/metadata.ts
|
|
2385
|
-
import { existsSync as existsSync9, readFileSync as readFileSync5, unlinkSync, writeFileSync as
|
|
2386
|
-
import { join as
|
|
2433
|
+
import { existsSync as existsSync9, readFileSync as readFileSync5, unlinkSync, writeFileSync as writeFileSync5 } from "fs";
|
|
2434
|
+
import { join as join9 } from "path";
|
|
2387
2435
|
function agentRuntimeMetadataPath() {
|
|
2388
|
-
return
|
|
2436
|
+
return join9(appDataDir(), "agent-runtime.json");
|
|
2389
2437
|
}
|
|
2390
2438
|
function readAgentRuntimeMetadata() {
|
|
2391
2439
|
try {
|
|
@@ -2454,7 +2502,7 @@ function agentRpcChildEnv(rpc, cwd) {
|
|
|
2454
2502
|
// src/agents/claude-host.ts
|
|
2455
2503
|
import { existsSync as existsSync10 } from "fs";
|
|
2456
2504
|
import { createRequire as createRequire2 } from "module";
|
|
2457
|
-
import { dirname as dirname4, join as
|
|
2505
|
+
import { dirname as dirname4, join as join10 } from "path";
|
|
2458
2506
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2459
2507
|
|
|
2460
2508
|
// src/agent-rpc/client.ts
|
|
@@ -2499,17 +2547,17 @@ function entryDir() {
|
|
|
2499
2547
|
function claudeRunnerPath() {
|
|
2500
2548
|
const packagedDir = packagedCursorRuntimeDir();
|
|
2501
2549
|
if (packagedDir) {
|
|
2502
|
-
const packaged =
|
|
2550
|
+
const packaged = join10(packagedDir, "core-dist", "agents", "claude-runner.js");
|
|
2503
2551
|
if (existsSync10(packaged)) return packaged;
|
|
2504
2552
|
}
|
|
2505
2553
|
const root = entryDir();
|
|
2506
2554
|
const candidates = [
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2555
|
+
join10(root, "agents", "claude-runner.js"),
|
|
2556
|
+
join10(root, "agents", "claude-runner.cjs"),
|
|
2557
|
+
join10(root, "dist", "agents", "claude-runner.js"),
|
|
2558
|
+
join10(root, "dist", "agents", "claude-runner.cjs"),
|
|
2559
|
+
join10(root, "claude-runner.ts"),
|
|
2560
|
+
join10(root, "src", "agents", "claude-runner.ts")
|
|
2513
2561
|
];
|
|
2514
2562
|
for (const candidate of candidates) {
|
|
2515
2563
|
if (existsSync10(candidate)) return candidate;
|
|
@@ -2588,7 +2636,8 @@ function sessionCostUsdFromClaudeResult(obj) {
|
|
|
2588
2636
|
function claudeResultErrorDetail(obj) {
|
|
2589
2637
|
const isError = Boolean(obj.is_error) || typeof obj.subtype === "string" && /^error/i.test(obj.subtype);
|
|
2590
2638
|
const fromResult = typeof obj.result === "string" ? obj.result.trim() : "";
|
|
2591
|
-
|
|
2639
|
+
const shortFailure = fromResult.length > 0 && fromResult.length <= 300 && !fromResult.includes("\n") && looksLikeAgentFailureMessage(fromResult);
|
|
2640
|
+
if (fromResult && (isError || shortFailure)) {
|
|
2592
2641
|
return fromResult;
|
|
2593
2642
|
}
|
|
2594
2643
|
if (!isError) return null;
|
|
@@ -2835,7 +2884,7 @@ function eventsFromClaudeSystem(obj) {
|
|
|
2835
2884
|
data: `Context compressed${trigger}`,
|
|
2836
2885
|
replace: true
|
|
2837
2886
|
};
|
|
2838
|
-
if (meta.postTokens != null && meta.postTokens > 0) {
|
|
2887
|
+
if (meta.postTokens != null && meta.postTokens > 0 && !parentId) {
|
|
2839
2888
|
return [
|
|
2840
2889
|
thinking,
|
|
2841
2890
|
{
|
|
@@ -2916,7 +2965,7 @@ var claudeAdapter = {
|
|
|
2916
2965
|
);
|
|
2917
2966
|
}
|
|
2918
2967
|
const mode = permissionMode(thread);
|
|
2919
|
-
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-
|
|
2968
|
+
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-UHU2FXTY.js");
|
|
2920
2969
|
const isOrchestrator = isOrchestratorThread2(thread);
|
|
2921
2970
|
const rpc = worktreeAgentRpc(isOrchestrator);
|
|
2922
2971
|
const injectedServers = await buildInjectedMcpServers({
|
|
@@ -3016,6 +3065,7 @@ var claudeAdapter = {
|
|
|
3016
3065
|
cwd: thread.worktreePath,
|
|
3017
3066
|
stdin: useStdin ? `${promptText}
|
|
3018
3067
|
` : void 0,
|
|
3068
|
+
...mcpConfigPath ? { cleanupDirs: [dirname5(mcpConfigPath)] } : {},
|
|
3019
3069
|
// Nested Task/Agent thinking+text in stream-json (Claude Code 2.1.211+).
|
|
3020
3070
|
// Raise the -p background-agent wait so long TaskOutput polls are not
|
|
3021
3071
|
// abandoned at Claude Code’s 10-minute default.
|
|
@@ -3045,9 +3095,17 @@ var claudeAdapter = {
|
|
|
3045
3095
|
Array.isArray(message?.content) ? message.content : void 0,
|
|
3046
3096
|
parentId
|
|
3047
3097
|
);
|
|
3048
|
-
if (obj.type === "assistant") {
|
|
3098
|
+
if (obj.type === "assistant" && !parentId) {
|
|
3049
3099
|
const usage = usageFromClaude(message?.usage);
|
|
3050
|
-
|
|
3100
|
+
const messageId = message && typeof message.id === "string" ? message.id : void 0;
|
|
3101
|
+
if (usage) {
|
|
3102
|
+
events.push({
|
|
3103
|
+
type: "usage",
|
|
3104
|
+
data: usage,
|
|
3105
|
+
scope: "request",
|
|
3106
|
+
...messageId ? { messageId } : {}
|
|
3107
|
+
});
|
|
3108
|
+
}
|
|
3051
3109
|
}
|
|
3052
3110
|
if (events.length === 0) return null;
|
|
3053
3111
|
return events.length === 1 ? events[0] : events;
|
|
@@ -3134,56 +3192,47 @@ var claudeAdapter = {
|
|
|
3134
3192
|
return { file: claude, args, cwd: thread.worktreePath };
|
|
3135
3193
|
},
|
|
3136
3194
|
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);
|
|
3195
|
+
const { listAssignedLinearIssues: listAssignedLinearIssues2 } = await import("./linear-list-JFV3EES6.js");
|
|
3196
|
+
return listAssignedLinearIssues2();
|
|
3155
3197
|
}
|
|
3156
3198
|
};
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3199
|
+
|
|
3200
|
+
// src/agents/codex.ts
|
|
3201
|
+
import { existsSync as existsSync12, statSync as statSync2 } from "fs";
|
|
3202
|
+
import { homedir as homedir7 } from "os";
|
|
3203
|
+
import { join as join11 } from "path";
|
|
3204
|
+
|
|
3205
|
+
// src/agents/codex-items.ts
|
|
3206
|
+
function eventsFromCodexItem(eventType, item) {
|
|
3207
|
+
const itemType = item.type ?? item.item_type;
|
|
3208
|
+
if (itemType === "reasoning" && typeof item.text === "string" && item.text) {
|
|
3209
|
+
return { type: "thinking", data: item.text };
|
|
3210
|
+
}
|
|
3211
|
+
if (itemType !== "file_change" || !item.id) return null;
|
|
3212
|
+
const changes = Array.isArray(item.changes) ? item.changes : [];
|
|
3213
|
+
const paths = changes.map((change) => typeof change?.path === "string" ? change.path : "").filter(Boolean);
|
|
3214
|
+
const added = changes.some((change) => change?.kind === "add");
|
|
3215
|
+
const events = [
|
|
3216
|
+
{
|
|
3217
|
+
type: "tool_use",
|
|
3218
|
+
id: item.id,
|
|
3219
|
+
name: added ? "Write" : "Edit",
|
|
3220
|
+
input: paths.length ? { paths } : void 0
|
|
3178
3221
|
}
|
|
3222
|
+
];
|
|
3223
|
+
const finished = eventType === "item.completed" || item.status === "completed" || item.status === "failed";
|
|
3224
|
+
if (finished) {
|
|
3225
|
+
events.push({
|
|
3226
|
+
type: "tool_result",
|
|
3227
|
+
id: item.id,
|
|
3228
|
+
content: paths.join("\n") || void 0,
|
|
3229
|
+
isError: item.status === "failed"
|
|
3230
|
+
});
|
|
3179
3231
|
}
|
|
3180
|
-
return [];
|
|
3232
|
+
return events.length === 1 ? events[0] : events;
|
|
3181
3233
|
}
|
|
3182
3234
|
|
|
3183
3235
|
// 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
3236
|
var CODEX_PROMPT_ARG_MAX = 2e5;
|
|
3188
3237
|
var FALLBACK_CODEX_MODELS = [
|
|
3189
3238
|
{ id: "gpt-5.6-sol", displayName: "GPT-5.6 Sol" },
|
|
@@ -3236,17 +3285,8 @@ function usageFromCodex(usage) {
|
|
|
3236
3285
|
cachedInputTokens: Number(usage.cached_input_tokens ?? 0)
|
|
3237
3286
|
});
|
|
3238
3287
|
}
|
|
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;
|
|
3288
|
+
function codexHomeDir() {
|
|
3289
|
+
return process.env.CODEX_HOME?.trim() || join11(homedir7(), ".codex");
|
|
3250
3290
|
}
|
|
3251
3291
|
function unwrapCodexMcpResult(result) {
|
|
3252
3292
|
if (result == null) return void 0;
|
|
@@ -3275,7 +3315,7 @@ function asRecord3(value) {
|
|
|
3275
3315
|
return void 0;
|
|
3276
3316
|
}
|
|
3277
3317
|
function codexLooksAuthenticated() {
|
|
3278
|
-
const authPath =
|
|
3318
|
+
const authPath = join11(codexHomeDir(), "auth.json");
|
|
3279
3319
|
if (!existsSync12(authPath)) return false;
|
|
3280
3320
|
try {
|
|
3281
3321
|
return statSync2(authPath).size > 2;
|
|
@@ -3314,18 +3354,13 @@ var codexAdapter = {
|
|
|
3314
3354
|
const authenticated = codexLooksAuthenticated();
|
|
3315
3355
|
const linearMcp = false;
|
|
3316
3356
|
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
3357
|
return {
|
|
3323
3358
|
agent: "codex",
|
|
3324
3359
|
installed: true,
|
|
3325
3360
|
authenticated,
|
|
3326
3361
|
linearMcp,
|
|
3327
3362
|
warnings,
|
|
3328
|
-
reason: authenticated ? void 0 :
|
|
3363
|
+
reason: authenticated ? void 0 : `Codex auth not found \u2014 run \`codex login\` (expected ${join11(codexHomeDir(), "auth.json")})`
|
|
3329
3364
|
};
|
|
3330
3365
|
},
|
|
3331
3366
|
async buildTurn(thread, input) {
|
|
@@ -3350,6 +3385,12 @@ var codexAdapter = {
|
|
|
3350
3385
|
threadId: thread.id
|
|
3351
3386
|
});
|
|
3352
3387
|
const isolatePlugins = isOrchestrator || Boolean(thread.isolateCodexPlugins) || Boolean(normalizeTurnInput(input).isolateCodexPlugins);
|
|
3388
|
+
const gitEnv = await resolveAgentGitAuthEnv(process.env, {
|
|
3389
|
+
cwd: thread.worktreePath
|
|
3390
|
+
});
|
|
3391
|
+
const writableRoots = mode.codexSandbox === "workspace-write" ? await resolveCodexGitWritableRoots(thread.worktreePath) : [];
|
|
3392
|
+
const secretProfile = writeCodexMcpSecretProfile(injected);
|
|
3393
|
+
const effort = thread.effort?.trim() ?? "";
|
|
3353
3394
|
const mcpOverrides = [
|
|
3354
3395
|
// Worktree first try keeps plugins (Claude connectors). Coordinators
|
|
3355
3396
|
// isolate. After a fatal plugin MCP, the orchestrator retries with
|
|
@@ -3366,6 +3407,7 @@ var codexAdapter = {
|
|
|
3366
3407
|
const execOpts = [
|
|
3367
3408
|
// Global orchestration cwd is not a git repo; without this Codex ≥0.147
|
|
3368
3409
|
// refuses to start ("Not inside a trusted directory").
|
|
3410
|
+
...secretProfile ? ["-p", secretProfile.profile] : [],
|
|
3369
3411
|
"--skip-git-repo-check",
|
|
3370
3412
|
"--cd",
|
|
3371
3413
|
thread.worktreePath,
|
|
@@ -3375,14 +3417,16 @@ var codexAdapter = {
|
|
|
3375
3417
|
// `codex exec` rejects `--ask-for-approval` (global-only on newer CLIs).
|
|
3376
3418
|
"-c",
|
|
3377
3419
|
'approval_policy="never"',
|
|
3378
|
-
// Seatbelt cannot use the login Keychain
|
|
3379
|
-
// Default
|
|
3380
|
-
//
|
|
3381
|
-
// can
|
|
3420
|
+
// Seatbelt cannot use the login Keychain. inherit=all keeps GH_CONFIG_DIR
|
|
3421
|
+
// and GIT_CONFIG_*. Default excludes still strip *TOKEN*/*SECRET*/*KEY*;
|
|
3422
|
+
// GIT_CONFIG_KEY_n is re-set because it matches *KEY*. Linked worktrees
|
|
3423
|
+
// need the main repo `.git` as writable_roots so git commit can lock.
|
|
3382
3424
|
...codexUnattendedGitConfigArgs(mode.codexSandbox, {
|
|
3383
|
-
writableRoots
|
|
3425
|
+
writableRoots,
|
|
3426
|
+
preserveEnv: gitEnv
|
|
3384
3427
|
}),
|
|
3385
3428
|
...model ? ["--model", model] : [],
|
|
3429
|
+
...effort ? ["-c", `model_reasoning_effort=${JSON.stringify(effort)}`] : [],
|
|
3386
3430
|
...mcpOverrides
|
|
3387
3431
|
];
|
|
3388
3432
|
const args = sessionId ? ["exec", ...execOpts, "resume", sessionId, promptArg] : ["exec", ...execOpts, promptArg];
|
|
@@ -3391,7 +3435,8 @@ var codexAdapter = {
|
|
|
3391
3435
|
args,
|
|
3392
3436
|
cwd: thread.worktreePath,
|
|
3393
3437
|
stdin: useStdin ? `${prompt}
|
|
3394
|
-
` : void 0
|
|
3438
|
+
` : void 0,
|
|
3439
|
+
...secretProfile ? { cleanupDirs: [secretProfile.file] } : {}
|
|
3395
3440
|
};
|
|
3396
3441
|
},
|
|
3397
3442
|
parseEvent(line) {
|
|
@@ -3412,8 +3457,10 @@ var codexAdapter = {
|
|
|
3412
3457
|
if (typeof obj.item === "object" && obj.item !== null) {
|
|
3413
3458
|
const item = obj.item;
|
|
3414
3459
|
const itemType = item.type ?? item.item_type;
|
|
3460
|
+
const mapped = eventsFromCodexItem(type, item);
|
|
3461
|
+
if (mapped) return mapped;
|
|
3415
3462
|
if (itemType === "error") {
|
|
3416
|
-
const detail = item.message
|
|
3463
|
+
const detail = (typeof item.message === "string" ? item.message.trim() : "") || extractJsonErrorMessage(obj) || "Codex item error";
|
|
3417
3464
|
return { type: "stderr", data: detail };
|
|
3418
3465
|
}
|
|
3419
3466
|
if (itemType === "agent_message" && item.text) {
|
|
@@ -3442,14 +3489,14 @@ var codexAdapter = {
|
|
|
3442
3489
|
const events = [
|
|
3443
3490
|
{ type: "tool_use", id: item.id, name: "Bash", input }
|
|
3444
3491
|
];
|
|
3445
|
-
const finished = type === "item.completed" || item.status === "completed" || item.status === "failed";
|
|
3492
|
+
const finished = type === "item.completed" || item.status === "completed" || item.status === "failed" || item.status === "declined";
|
|
3446
3493
|
const output = typeof item.aggregated_output === "string" && item.aggregated_output ? item.aggregated_output : void 0;
|
|
3447
3494
|
if (finished) {
|
|
3448
3495
|
events.push({
|
|
3449
3496
|
type: "tool_result",
|
|
3450
3497
|
id: item.id,
|
|
3451
3498
|
content: output,
|
|
3452
|
-
isError: item.status === "failed"
|
|
3499
|
+
isError: item.status === "failed" || item.status === "declined"
|
|
3453
3500
|
});
|
|
3454
3501
|
} else if (output) {
|
|
3455
3502
|
events.push({
|
|
@@ -3492,7 +3539,7 @@ var codexAdapter = {
|
|
|
3492
3539
|
return events.length === 1 ? events[0] : events;
|
|
3493
3540
|
}
|
|
3494
3541
|
if (item.status === "failed") {
|
|
3495
|
-
const detail = item.message
|
|
3542
|
+
const detail = (typeof item.message === "string" ? item.message.trim() : "") || extractJsonErrorMessage(item) || `Codex ${itemType ?? "item"} failed`;
|
|
3496
3543
|
return { type: "stderr", data: detail };
|
|
3497
3544
|
}
|
|
3498
3545
|
}
|
|
@@ -3501,7 +3548,8 @@ var codexAdapter = {
|
|
|
3501
3548
|
return { type: "session_id", data: sid };
|
|
3502
3549
|
}
|
|
3503
3550
|
if (type === "turn.completed" || type === "turn_completed") {
|
|
3504
|
-
const
|
|
3551
|
+
const payload = obj;
|
|
3552
|
+
const usage = usageFromCodex(payload.last_token_usage ?? payload.usage);
|
|
3505
3553
|
return usage ? { type: "usage", data: usage, scope: "turn" } : null;
|
|
3506
3554
|
}
|
|
3507
3555
|
if (typeof obj.content === "string" && obj.content.trim()) {
|
|
@@ -3524,7 +3572,7 @@ var codexAdapter = {
|
|
|
3524
3572
|
if (sessionId) {
|
|
3525
3573
|
return {
|
|
3526
3574
|
file: codex,
|
|
3527
|
-
args: ["
|
|
3575
|
+
args: ["resume", sessionId],
|
|
3528
3576
|
cwd: thread.worktreePath
|
|
3529
3577
|
};
|
|
3530
3578
|
}
|
|
@@ -3535,56 +3583,34 @@ var codexAdapter = {
|
|
|
3535
3583
|
};
|
|
3536
3584
|
},
|
|
3537
3585
|
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
|
-
}
|
|
3586
|
+
return listAssignedLinearIssues();
|
|
3561
3587
|
}
|
|
3562
3588
|
};
|
|
3563
3589
|
|
|
3564
3590
|
// src/agents/cursor.ts
|
|
3565
3591
|
import { existsSync as existsSync15 } from "fs";
|
|
3566
3592
|
import { createRequire as createRequire5 } from "module";
|
|
3567
|
-
import { dirname as
|
|
3593
|
+
import { dirname as dirname8, join as join14 } from "path";
|
|
3568
3594
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
3569
3595
|
|
|
3570
3596
|
// src/agents/cursor-sdk-resolve.ts
|
|
3571
|
-
import { existsSync as existsSync13, readFileSync as
|
|
3597
|
+
import { existsSync as existsSync13, readFileSync as readFileSync6 } from "fs";
|
|
3572
3598
|
import { createRequire as createRequire3 } from "module";
|
|
3573
|
-
import { basename, dirname as
|
|
3599
|
+
import { basename, dirname as dirname6, join as join12 } from "path";
|
|
3574
3600
|
import { fileURLToPath as fileURLToPath3, pathToFileURL } from "url";
|
|
3575
3601
|
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
3602
|
function thisModuleFile() {
|
|
3577
3603
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
3578
|
-
if (cjsDir) return
|
|
3604
|
+
if (cjsDir) return join12(cjsDir, "cursor-sdk-resolve.js");
|
|
3579
3605
|
try {
|
|
3580
3606
|
return fileURLToPath3(import.meta.url);
|
|
3581
3607
|
} catch {
|
|
3582
|
-
return
|
|
3608
|
+
return join12(process.cwd(), "package.json");
|
|
3583
3609
|
}
|
|
3584
3610
|
}
|
|
3585
3611
|
function packageRootLooksLikeSdk(dir) {
|
|
3586
3612
|
try {
|
|
3587
|
-
const raw =
|
|
3613
|
+
const raw = readFileSync6(join12(dir, "package.json"), "utf8");
|
|
3588
3614
|
const pkg = JSON.parse(raw);
|
|
3589
3615
|
return pkg.name === "@cursor/sdk" && existsSync13(dir);
|
|
3590
3616
|
} catch {
|
|
@@ -3595,7 +3621,7 @@ function resolvedPackageRoot(fromFile) {
|
|
|
3595
3621
|
try {
|
|
3596
3622
|
const req = createRequire3(fromFile);
|
|
3597
3623
|
const pkgJson = req.resolve("@cursor/sdk/package.json");
|
|
3598
|
-
const root =
|
|
3624
|
+
const root = dirname6(pkgJson);
|
|
3599
3625
|
return packageRootLooksLikeSdk(root) ? root : null;
|
|
3600
3626
|
} catch {
|
|
3601
3627
|
return null;
|
|
@@ -3609,10 +3635,10 @@ function resolveCursorSdkRoot(opts) {
|
|
|
3609
3635
|
}
|
|
3610
3636
|
const globalNm = npmGlobalNodeModules(env);
|
|
3611
3637
|
if (globalNm) {
|
|
3612
|
-
const globalRoot =
|
|
3638
|
+
const globalRoot = join12(globalNm, "@cursor/sdk");
|
|
3613
3639
|
if (packageRootLooksLikeSdk(globalRoot)) return globalRoot;
|
|
3614
3640
|
}
|
|
3615
|
-
const cwdPkg =
|
|
3641
|
+
const cwdPkg = join12(process.cwd(), "package.json");
|
|
3616
3642
|
return resolvedPackageRoot(thisModuleFile()) ?? resolvedPackageRoot(cwdPkg);
|
|
3617
3643
|
}
|
|
3618
3644
|
function isCursorSdkInstalled(opts) {
|
|
@@ -3628,12 +3654,12 @@ function exportTarget(value) {
|
|
|
3628
3654
|
}
|
|
3629
3655
|
function cursorSdkEsmEntry(root) {
|
|
3630
3656
|
try {
|
|
3631
|
-
const pkg = JSON.parse(
|
|
3657
|
+
const pkg = JSON.parse(readFileSync6(join12(root, "package.json"), "utf8"));
|
|
3632
3658
|
const exp = pkg.exports;
|
|
3633
3659
|
const dot = exp && typeof exp === "object" && !Array.isArray(exp) && "." in exp ? exp["."] : exp;
|
|
3634
3660
|
const rel = exportTarget(dot) ?? (typeof pkg.module === "string" ? pkg.module : null);
|
|
3635
3661
|
if (!rel) return null;
|
|
3636
|
-
const entry =
|
|
3662
|
+
const entry = join12(root, rel);
|
|
3637
3663
|
return existsSync13(entry) ? entry : null;
|
|
3638
3664
|
} catch {
|
|
3639
3665
|
return null;
|
|
@@ -3650,7 +3676,7 @@ async function importCursorSdk(opts) {
|
|
|
3650
3676
|
try {
|
|
3651
3677
|
let entry = cursorSdkEsmEntry(root);
|
|
3652
3678
|
if (!entry) {
|
|
3653
|
-
const req = createRequire3(
|
|
3679
|
+
const req = createRequire3(join12(root, "package.json"));
|
|
3654
3680
|
entry = req.resolve("@cursor/sdk");
|
|
3655
3681
|
}
|
|
3656
3682
|
return unwrapCursorSdkModule(await import(pathToFileURL(entry).href));
|
|
@@ -3662,8 +3688,8 @@ function cursorSdkPlatformRipgrepPackage() {
|
|
|
3662
3688
|
return `@cursor/sdk-${process.platform}-${process.arch}`;
|
|
3663
3689
|
}
|
|
3664
3690
|
function nodeModulesDirForPackageRoot(packageRoot) {
|
|
3665
|
-
const parent =
|
|
3666
|
-
return basename(parent).startsWith("@") ?
|
|
3691
|
+
const parent = dirname6(packageRoot);
|
|
3692
|
+
return basename(parent).startsWith("@") ? dirname6(parent) : parent;
|
|
3667
3693
|
}
|
|
3668
3694
|
function cursorSdkRipgrepCandidate(opts) {
|
|
3669
3695
|
const root = resolveCursorSdkRoot(opts);
|
|
@@ -3671,9 +3697,9 @@ function cursorSdkRipgrepCandidate(opts) {
|
|
|
3671
3697
|
const nm = nodeModulesDirForPackageRoot(root);
|
|
3672
3698
|
const pkg = cursorSdkPlatformRipgrepPackage();
|
|
3673
3699
|
const bin = process.platform === "win32" ? "rg.exe" : "rg";
|
|
3674
|
-
const sibling =
|
|
3700
|
+
const sibling = join12(nm, pkg, "bin", bin);
|
|
3675
3701
|
if (existsSync13(sibling)) return sibling;
|
|
3676
|
-
const nested =
|
|
3702
|
+
const nested = join12(root, "node_modules", pkg, "bin", bin);
|
|
3677
3703
|
return existsSync13(nested) ? nested : null;
|
|
3678
3704
|
}
|
|
3679
3705
|
|
|
@@ -3702,7 +3728,8 @@ function preferredCursorCostCents(cost) {
|
|
|
3702
3728
|
}
|
|
3703
3729
|
function turnCostUsdFromCursorUsage(before, after) {
|
|
3704
3730
|
if (!after) return void 0;
|
|
3705
|
-
|
|
3731
|
+
if (before == null) return void 0;
|
|
3732
|
+
const beforeIds = new Set((before.runs ?? []).map((r) => r.runId));
|
|
3706
3733
|
const newRuns = (after.runs ?? []).filter((r) => !beforeIds.has(r.runId));
|
|
3707
3734
|
let sum = 0;
|
|
3708
3735
|
let any = false;
|
|
@@ -3714,7 +3741,6 @@ function turnCostUsdFromCursorUsage(before, after) {
|
|
|
3714
3741
|
}
|
|
3715
3742
|
}
|
|
3716
3743
|
if (any) return sum / 100;
|
|
3717
|
-
if (before == null) return void 0;
|
|
3718
3744
|
const afterCents = preferredCursorCostCents(after.cost);
|
|
3719
3745
|
if (afterCents == null) return void 0;
|
|
3720
3746
|
const beforeCents = preferredCursorCostCents(before.cost) ?? 0;
|
|
@@ -3891,7 +3917,7 @@ function parseCursorRunnerLine(line) {
|
|
|
3891
3917
|
// src/agents/cursor-ripgrep.ts
|
|
3892
3918
|
import { existsSync as existsSync14 } from "fs";
|
|
3893
3919
|
import { createRequire as createRequire4 } from "module";
|
|
3894
|
-
import { dirname as
|
|
3920
|
+
import { dirname as dirname7, isAbsolute as isAbsolute2, join as join13, parse, resolve as resolvePath } from "path";
|
|
3895
3921
|
var RIPGREP_ENV = "CURSOR_RIPGREP_PATH";
|
|
3896
3922
|
function rgBinaryName() {
|
|
3897
3923
|
return process.platform === "win32" ? "rg.exe" : "rg";
|
|
@@ -3910,12 +3936,12 @@ function walkForBundledRipgrep(startFile) {
|
|
|
3910
3936
|
if (!startFile) return null;
|
|
3911
3937
|
const pkg = platformRipgrepPackage();
|
|
3912
3938
|
const name = rgBinaryName();
|
|
3913
|
-
let dir =
|
|
3939
|
+
let dir = dirname7(resolvePath(startFile));
|
|
3914
3940
|
const root = parse(dir).root;
|
|
3915
3941
|
while (dir !== root) {
|
|
3916
|
-
const hit = usableRipgrepPath(
|
|
3942
|
+
const hit = usableRipgrepPath(join13(dir, "node_modules", pkg, "bin", name));
|
|
3917
3943
|
if (hit) return hit;
|
|
3918
|
-
const next =
|
|
3944
|
+
const next = dirname7(dir);
|
|
3919
3945
|
if (next === dir) break;
|
|
3920
3946
|
dir = next;
|
|
3921
3947
|
}
|
|
@@ -3925,7 +3951,7 @@ function requireResolveBundledRipgrep(fromFile) {
|
|
|
3925
3951
|
try {
|
|
3926
3952
|
const req = createRequire4(fromFile);
|
|
3927
3953
|
const pkgJson = req.resolve(`${platformRipgrepPackage()}/package.json`);
|
|
3928
|
-
return usableRipgrepPath(
|
|
3954
|
+
return usableRipgrepPath(join13(dirname7(pkgJson), "bin", rgBinaryName()));
|
|
3929
3955
|
} catch {
|
|
3930
3956
|
return null;
|
|
3931
3957
|
}
|
|
@@ -3999,11 +4025,11 @@ function entryDir2() {
|
|
|
3999
4025
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
4000
4026
|
if (cjsDir) return cjsDir;
|
|
4001
4027
|
try {
|
|
4002
|
-
return
|
|
4028
|
+
return dirname8(fileURLToPath4(import.meta.url));
|
|
4003
4029
|
} catch {
|
|
4004
4030
|
try {
|
|
4005
4031
|
const req = createRequire5(process.cwd() + "/");
|
|
4006
|
-
return
|
|
4032
|
+
return dirname8(req.resolve("@sideboard-ai/core"));
|
|
4007
4033
|
} catch {
|
|
4008
4034
|
return process.cwd();
|
|
4009
4035
|
}
|
|
@@ -4014,14 +4040,14 @@ function cursorRunnerPath() {
|
|
|
4014
4040
|
if (packaged) return packaged;
|
|
4015
4041
|
const root = entryDir2();
|
|
4016
4042
|
const candidates = [
|
|
4017
|
-
|
|
4018
|
-
|
|
4043
|
+
join14(root, "agents", "cursor-runner.js"),
|
|
4044
|
+
join14(root, "agents", "cursor-runner.cjs"),
|
|
4019
4045
|
// If somehow resolved from package root instead of dist/
|
|
4020
|
-
|
|
4021
|
-
|
|
4046
|
+
join14(root, "dist", "agents", "cursor-runner.js"),
|
|
4047
|
+
join14(root, "dist", "agents", "cursor-runner.cjs"),
|
|
4022
4048
|
// Source tree (dev): packages/core/src/agents/cursor-runner.ts
|
|
4023
|
-
|
|
4024
|
-
|
|
4049
|
+
join14(root, "cursor-runner.ts"),
|
|
4050
|
+
join14(root, "src", "agents", "cursor-runner.ts")
|
|
4025
4051
|
];
|
|
4026
4052
|
for (const candidate of candidates) {
|
|
4027
4053
|
if (existsSync15(candidate)) return candidate;
|
|
@@ -4062,6 +4088,7 @@ var cursorAdapter = {
|
|
|
4062
4088
|
},
|
|
4063
4089
|
async buildTurn(thread, input) {
|
|
4064
4090
|
const agentId = await this.resolveSessionId(thread.worktreePath, thread.sessionId);
|
|
4091
|
+
const fullPrompt = flattenTurnInput(input);
|
|
4065
4092
|
const prompt = flattenTurnInput(dropCachedPrefixOnResume(input, agentId));
|
|
4066
4093
|
const apiKey = resolveCursorApiKey() || void 0;
|
|
4067
4094
|
const isOrchestrator = isOrchestratorThread(thread);
|
|
@@ -4078,6 +4105,7 @@ var cursorAdapter = {
|
|
|
4078
4105
|
const mcpServers = toCursorMcpServers(injected);
|
|
4079
4106
|
const req = {
|
|
4080
4107
|
prompt,
|
|
4108
|
+
...fullPrompt !== prompt ? { freshPrompt: fullPrompt } : {},
|
|
4081
4109
|
cwd: thread.worktreePath,
|
|
4082
4110
|
threadId: thread.id,
|
|
4083
4111
|
agentId,
|
|
@@ -4104,8 +4132,9 @@ var cursorAdapter = {
|
|
|
4104
4132
|
stdin: JSON.stringify(req),
|
|
4105
4133
|
env: {
|
|
4106
4134
|
...launch.env,
|
|
4107
|
-
...cursorRipgrepEnv({ startFile: runner })
|
|
4108
|
-
|
|
4135
|
+
...cursorRipgrepEnv({ startFile: runner })
|
|
4136
|
+
// API key stays on the stdin request. Do not copy it into the child env,
|
|
4137
|
+
// where `ps` and crash dumps can see it. The runner reads `req.apiKey`.
|
|
4109
4138
|
}
|
|
4110
4139
|
};
|
|
4111
4140
|
},
|
|
@@ -4127,14 +4156,17 @@ var cursorAdapter = {
|
|
|
4127
4156
|
};
|
|
4128
4157
|
|
|
4129
4158
|
// src/agents/opencode.ts
|
|
4130
|
-
import { existsSync as
|
|
4159
|
+
import { existsSync as existsSync17 } from "fs";
|
|
4160
|
+
|
|
4161
|
+
// src/agent-rpc/opencode-host.ts
|
|
4162
|
+
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
4131
4163
|
|
|
4132
4164
|
// src/agent-rpc/opencode-hook.ts
|
|
4133
|
-
import { mkdirSync as
|
|
4134
|
-
import { join as
|
|
4165
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync4, readFileSync as readFileSync7, renameSync, writeFileSync as writeFileSync6 } from "fs";
|
|
4166
|
+
import { join as join15 } from "path";
|
|
4135
4167
|
var OPENCODE_PLUGIN_SOURCE = `import { tool } from "@opencode-ai/plugin"
|
|
4136
4168
|
|
|
4137
|
-
const
|
|
4169
|
+
const RPC_URL = process.env[${JSON.stringify(AGENT_RPC_URL_ENV)}] || ""
|
|
4138
4170
|
const TOKEN = process.env[${JSON.stringify(AGENT_RPC_TOKEN_ENV)}] || ""
|
|
4139
4171
|
const CWD = process.env[${JSON.stringify(AGENT_RPC_CWD_ENV)}] || ""
|
|
4140
4172
|
|
|
@@ -4147,24 +4179,29 @@ function jsonError(err) {
|
|
|
4147
4179
|
}
|
|
4148
4180
|
|
|
4149
4181
|
function socketUrl() {
|
|
4150
|
-
const u = new URL(
|
|
4182
|
+
const u = new URL(RPC_URL)
|
|
4151
4183
|
u.searchParams.set(${JSON.stringify(AGENT_RPC_TOKEN_QUERY)}, TOKEN)
|
|
4152
4184
|
return u.toString()
|
|
4153
4185
|
}
|
|
4154
4186
|
|
|
4155
4187
|
function call(method, params) {
|
|
4156
|
-
if (!
|
|
4188
|
+
if (!RPC_URL || !TOKEN) {
|
|
4157
4189
|
return Promise.resolve(jsonError(new Error("Agent RPC runtime is not running")))
|
|
4158
4190
|
}
|
|
4191
|
+
const timeoutMs = method === "job.wait" ? 130000 : 30000
|
|
4159
4192
|
return new Promise((resolve) => {
|
|
4160
4193
|
let settled = false
|
|
4194
|
+
let ws
|
|
4195
|
+
let timer
|
|
4161
4196
|
const done = (value) => {
|
|
4162
4197
|
if (settled) return
|
|
4163
4198
|
settled = true
|
|
4199
|
+
clearTimeout(timer)
|
|
4164
4200
|
try { ws.close() } catch {}
|
|
4165
4201
|
resolve(value)
|
|
4166
4202
|
}
|
|
4167
|
-
|
|
4203
|
+
timer = setTimeout(() => done(jsonError(new Error("Agent RPC timed out"))), timeoutMs)
|
|
4204
|
+
ws = new WebSocket(socketUrl())
|
|
4168
4205
|
const id = Date.now()
|
|
4169
4206
|
ws.addEventListener("open", () => {
|
|
4170
4207
|
ws.send(JSON.stringify({ jsonrpc: "2.0", id, method, params, authToken: TOKEN }))
|
|
@@ -4236,12 +4273,19 @@ export const SideboardRpc = async (ctx) => {
|
|
|
4236
4273
|
}
|
|
4237
4274
|
`;
|
|
4238
4275
|
function writeOpencodeRpcPlugin() {
|
|
4239
|
-
const
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4276
|
+
const pluginDir = join15(appDataDir(), "agent-rpc", "opencode");
|
|
4277
|
+
mkdirSync4(pluginDir, { recursive: true });
|
|
4278
|
+
const pluginFile = join15(pluginDir, "sideboard-rpc.js");
|
|
4279
|
+
if (existsSync16(pluginFile)) {
|
|
4280
|
+
try {
|
|
4281
|
+
if (readFileSync7(pluginFile, "utf8") === OPENCODE_PLUGIN_SOURCE) return pluginFile;
|
|
4282
|
+
} catch {
|
|
4283
|
+
}
|
|
4284
|
+
}
|
|
4285
|
+
const tmp = `${pluginFile}.${process.pid}.tmp`;
|
|
4286
|
+
writeFileSync6(tmp, OPENCODE_PLUGIN_SOURCE);
|
|
4287
|
+
renameSync(tmp, pluginFile);
|
|
4288
|
+
return pluginFile;
|
|
4245
4289
|
}
|
|
4246
4290
|
|
|
4247
4291
|
// src/agent-rpc/opencode-host.ts
|
|
@@ -4264,10 +4308,9 @@ async function buildOpencodeHostEnv(thread) {
|
|
|
4264
4308
|
const config = injected.length > 0 || disableNames.length > 0 ? JSON.parse(toOpencodeMcpConfigContent(injected, { disableNames })) : {};
|
|
4265
4309
|
const env = {};
|
|
4266
4310
|
if (rpc) {
|
|
4267
|
-
const
|
|
4268
|
-
env.OPENCODE_CONFIG_DIR = configDir;
|
|
4311
|
+
const pluginFile = writeOpencodeRpcPlugin();
|
|
4269
4312
|
Object.assign(env, agentRpcChildEnv(rpc, thread.worktreePath));
|
|
4270
|
-
config.plugin = [pluginFile];
|
|
4313
|
+
config.plugin = [pathToFileURL2(pluginFile).href];
|
|
4271
4314
|
}
|
|
4272
4315
|
if (Object.keys(config).length > 0) {
|
|
4273
4316
|
env.OPENCODE_CONFIG_CONTENT = JSON.stringify(config);
|
|
@@ -4334,7 +4377,7 @@ async function listOpencodeModels() {
|
|
|
4334
4377
|
if (opencode === "opencode") {
|
|
4335
4378
|
const which = await run("which", ["opencode"], { reject: false });
|
|
4336
4379
|
if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
|
|
4337
|
-
} else if (!
|
|
4380
|
+
} else if (!existsSync17(opencode)) {
|
|
4338
4381
|
return FALLBACK_OPENCODE_MODELS;
|
|
4339
4382
|
}
|
|
4340
4383
|
const listed = await run(opencode, ["models"], { reject: false });
|
|
@@ -4369,7 +4412,7 @@ var opencodeAdapter = {
|
|
|
4369
4412
|
async detect() {
|
|
4370
4413
|
const opencode = resolveAgentExecutable("opencode");
|
|
4371
4414
|
if (opencode !== "opencode") {
|
|
4372
|
-
if (!
|
|
4415
|
+
if (!existsSync17(opencode)) {
|
|
4373
4416
|
return {
|
|
4374
4417
|
agent: "opencode",
|
|
4375
4418
|
installed: false,
|
|
@@ -4423,6 +4466,11 @@ var opencodeAdapter = {
|
|
|
4423
4466
|
if (model) {
|
|
4424
4467
|
args.push("--model", model);
|
|
4425
4468
|
}
|
|
4469
|
+
args.push("--thinking");
|
|
4470
|
+
const variant = thread.effort?.trim() ?? "";
|
|
4471
|
+
if (variant && /^(minimal|low|medium|high|max|xhigh)$/i.test(variant)) {
|
|
4472
|
+
args.push("--variant", variant);
|
|
4473
|
+
}
|
|
4426
4474
|
const hostEnv = await buildOpencodeHostEnv(thread);
|
|
4427
4475
|
return {
|
|
4428
4476
|
file: resolveAgentExecutable("opencode"),
|
|
@@ -4455,6 +4503,10 @@ var opencodeAdapter = {
|
|
|
4455
4503
|
const text = obj.part?.text ?? obj.text;
|
|
4456
4504
|
if (text) return { type: "stdout", data: text };
|
|
4457
4505
|
}
|
|
4506
|
+
if (obj.type === "reasoning" || obj.type === "thinking") {
|
|
4507
|
+
const text = obj.part?.text ?? obj.text;
|
|
4508
|
+
if (typeof text === "string" && text) return { type: "thinking", data: text };
|
|
4509
|
+
}
|
|
4458
4510
|
if (obj.type === "tool_use") {
|
|
4459
4511
|
const part = obj.part;
|
|
4460
4512
|
const name = part?.tool ?? part?.name ?? obj.tool ?? obj.name ?? "tool";
|
|
@@ -4570,11 +4622,14 @@ var opencodeAdapter = {
|
|
|
4570
4622
|
const listed = await run(
|
|
4571
4623
|
resolveAgentExecutable("opencode"),
|
|
4572
4624
|
["session", "list", "--format", "json"],
|
|
4573
|
-
{ cwd: worktreePath, reject: false }
|
|
4625
|
+
{ cwd: worktreePath, reject: false, timeoutMs: 8e3 }
|
|
4574
4626
|
);
|
|
4575
|
-
if (listed.exitCode === 0
|
|
4627
|
+
if (listed.exitCode === 0) {
|
|
4628
|
+
const raw = listed.stdout.trim();
|
|
4629
|
+
if (!raw) return null;
|
|
4576
4630
|
try {
|
|
4577
|
-
const sessions = JSON.parse(
|
|
4631
|
+
const sessions = JSON.parse(raw);
|
|
4632
|
+
if (Array.isArray(sessions) && sessions.length === 0) return null;
|
|
4578
4633
|
if (Array.isArray(sessions) && sessions.length > 0) {
|
|
4579
4634
|
const norm = (p) => p.replace(/\/+$/, "");
|
|
4580
4635
|
const wt = norm(worktreePath);
|
|
@@ -4608,34 +4663,8 @@ var opencodeAdapter = {
|
|
|
4608
4663
|
};
|
|
4609
4664
|
},
|
|
4610
4665
|
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
|
-
}
|
|
4666
|
+
const { listAssignedLinearIssues: listAssignedLinearIssues2 } = await import("./linear-list-JFV3EES6.js");
|
|
4667
|
+
return listAssignedLinearIssues2();
|
|
4639
4668
|
}
|
|
4640
4669
|
};
|
|
4641
4670
|
|
|
@@ -5034,9 +5063,9 @@ function formatClaudeUsageOverLimitWait(windows, now = /* @__PURE__ */ new Date(
|
|
|
5034
5063
|
}
|
|
5035
5064
|
|
|
5036
5065
|
// src/agents/claude-usage-client.ts
|
|
5037
|
-
import { existsSync as
|
|
5038
|
-
import { homedir as
|
|
5039
|
-
import { join as
|
|
5066
|
+
import { existsSync as existsSync18, readFileSync as readFileSync8 } from "fs";
|
|
5067
|
+
import { homedir as homedir8 } from "os";
|
|
5068
|
+
import { join as join16 } from "path";
|
|
5040
5069
|
var CLAUDE_OAUTH_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
|
|
5041
5070
|
var CLAUDE_USAGE_TTL_MS = 9e4;
|
|
5042
5071
|
var CLAUDE_USAGE_ERROR_TTL_MS = 5 * 6e4;
|
|
@@ -5076,12 +5105,12 @@ function accessTokenFromCredentialsJson(raw) {
|
|
|
5076
5105
|
}
|
|
5077
5106
|
}
|
|
5078
5107
|
function claudeCredentialsPath(configDir) {
|
|
5079
|
-
const root = configDir?.trim() || process.env.CLAUDE_CONFIG_DIR?.trim() ||
|
|
5080
|
-
return
|
|
5108
|
+
const root = configDir?.trim() || process.env.CLAUDE_CONFIG_DIR?.trim() || join16(homedir8(), ".claude");
|
|
5109
|
+
return join16(root, ".credentials.json");
|
|
5081
5110
|
}
|
|
5082
5111
|
async function readFileAccessToken(configDir) {
|
|
5083
5112
|
const path = claudeCredentialsPath(configDir);
|
|
5084
|
-
if (!
|
|
5113
|
+
if (!existsSync18(path)) return null;
|
|
5085
5114
|
try {
|
|
5086
5115
|
return accessTokenFromCredentialsJson(readFileSync8(path, "utf8"));
|
|
5087
5116
|
} catch {
|