@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
|
@@ -4,21 +4,24 @@ import {
|
|
|
4
4
|
ensureCliTeamTracked,
|
|
5
5
|
ensureConnectedBrightsyTeamTokens
|
|
6
6
|
} from "./chunk-S5CJUIPY.js";
|
|
7
|
+
import {
|
|
8
|
+
listAssignedLinearIssues
|
|
9
|
+
} from "./chunk-TMCK5TLA.js";
|
|
7
10
|
import {
|
|
8
11
|
looksLikeConversationSummary,
|
|
9
12
|
looksLikeSkillBody,
|
|
10
13
|
skillCommandFromBody,
|
|
11
14
|
withEventParentId
|
|
12
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-OOXRMTU6.js";
|
|
13
16
|
import {
|
|
14
17
|
isOrchestratorThread
|
|
15
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-FWVUGLBG.js";
|
|
16
19
|
import {
|
|
17
20
|
codexUnattendedGitConfigArgs,
|
|
18
21
|
mergeAgentGitAuthEnv,
|
|
19
22
|
resolveAgentGitAuthEnv,
|
|
20
23
|
resolveCodexGitWritableRoots
|
|
21
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-KECHK3ZT.js";
|
|
22
25
|
import {
|
|
23
26
|
loadBrightsyConfig
|
|
24
27
|
} from "./chunk-RSA47QYR.js";
|
|
@@ -45,13 +48,13 @@ import {
|
|
|
45
48
|
packagedMcpStdioPath,
|
|
46
49
|
parseCursorRunnerLine,
|
|
47
50
|
resolveNodeLaunch
|
|
48
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-NURZOXGN.js";
|
|
49
52
|
import {
|
|
50
53
|
extractJsonErrorMessage,
|
|
51
54
|
formatUnknownDetail,
|
|
52
55
|
looksLikeAgentFailureMessage,
|
|
53
56
|
looksLikeBrightsyEmptyCompletion
|
|
54
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-OPXEJJBM.js";
|
|
55
58
|
import {
|
|
56
59
|
githubAgentAuthReady,
|
|
57
60
|
run
|
|
@@ -66,7 +69,7 @@ import {
|
|
|
66
69
|
PILOT_TOOL_DESCRIPTIONS,
|
|
67
70
|
PILOT_TOOL_NAMES,
|
|
68
71
|
agentRpcConnectFromMetadata
|
|
69
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-SUZOPJZC.js";
|
|
70
73
|
import {
|
|
71
74
|
claudeChromeEnabled,
|
|
72
75
|
fromInclusiveInputUsage,
|
|
@@ -74,9 +77,10 @@ import {
|
|
|
74
77
|
isLinearConnected,
|
|
75
78
|
isPosthogConnected,
|
|
76
79
|
loadAppSettings,
|
|
80
|
+
requestOccupancy,
|
|
77
81
|
resolveAgentExecutable,
|
|
78
82
|
resolveClaudeExecutable
|
|
79
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-QPSKQP6E.js";
|
|
80
84
|
import {
|
|
81
85
|
isElectronLikeCommand,
|
|
82
86
|
unwrapStrippedElectronLaunch
|
|
@@ -514,6 +518,7 @@ var brightsyAdapter = {
|
|
|
514
518
|
|
|
515
519
|
// src/agents/claude.ts
|
|
516
520
|
import { existsSync as existsSync7 } from "fs";
|
|
521
|
+
import { dirname as dirname4 } from "path";
|
|
517
522
|
|
|
518
523
|
// src/agents/claude-mcp-status.ts
|
|
519
524
|
var SIDEBOARD_CONNECTOR_SERVICES = [
|
|
@@ -630,7 +635,7 @@ function isNotableMcpInitStatus(server, sideboardOk, coverage) {
|
|
|
630
635
|
|
|
631
636
|
// src/mcp-ui/host.ts
|
|
632
637
|
import { createHash } from "crypto";
|
|
633
|
-
import { homedir as
|
|
638
|
+
import { homedir as homedir5 } from "os";
|
|
634
639
|
|
|
635
640
|
// src/agents/orch-mcp-isolation.ts
|
|
636
641
|
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
|
|
@@ -987,20 +992,20 @@ function readJson(path) {
|
|
|
987
992
|
}
|
|
988
993
|
|
|
989
994
|
// src/agents/orch-mcp-isolation.ts
|
|
990
|
-
import { homedir as
|
|
991
|
-
import { join as
|
|
995
|
+
import { homedir as homedir4 } from "os";
|
|
996
|
+
import { join as join5 } from "path";
|
|
992
997
|
import { parse as parseToml } from "smol-toml";
|
|
993
998
|
|
|
994
999
|
// src/agents/user-mcp-config.ts
|
|
995
|
-
import { existsSync as existsSync4, mkdirSync, readFileSync as readFileSync2, writeFileSync as
|
|
996
|
-
import { homedir as
|
|
997
|
-
import { dirname as dirname2, join as
|
|
1000
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
1001
|
+
import { homedir as homedir3 } from "os";
|
|
1002
|
+
import { dirname as dirname2, join as join4 } from "path";
|
|
998
1003
|
|
|
999
1004
|
// src/agents/injected-mcp.ts
|
|
1000
|
-
import { existsSync as existsSync3, mkdtempSync, writeFileSync } from "fs";
|
|
1005
|
+
import { existsSync as existsSync3, mkdtempSync, writeFileSync as writeFileSync2 } from "fs";
|
|
1001
1006
|
import { createRequire } from "module";
|
|
1002
1007
|
import { tmpdir } from "os";
|
|
1003
|
-
import { dirname, join as
|
|
1008
|
+
import { dirname, join as join3 } from "path";
|
|
1004
1009
|
import { fileURLToPath } from "url";
|
|
1005
1010
|
|
|
1006
1011
|
// src/mcp/profile.ts
|
|
@@ -1095,6 +1100,44 @@ function sideboardMcpProfile(env = process.env) {
|
|
|
1095
1100
|
return env[SIDEBOARD_MCP_PROFILE_ENV]?.trim().toLowerCase() === "worktree" ? "worktree" : "orchestration";
|
|
1096
1101
|
}
|
|
1097
1102
|
|
|
1103
|
+
// src/agents/codex-mcp-profile.ts
|
|
1104
|
+
import { randomBytes } from "crypto";
|
|
1105
|
+
import { mkdirSync, writeFileSync } from "fs";
|
|
1106
|
+
import { homedir as homedir2 } from "os";
|
|
1107
|
+
import { join as join2 } from "path";
|
|
1108
|
+
function isCodexSecretEnvKey(key) {
|
|
1109
|
+
return /token|secret|password|credential|oauth|api_key|_key$/i.test(key);
|
|
1110
|
+
}
|
|
1111
|
+
function tomlBasicString(value) {
|
|
1112
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r")}"`;
|
|
1113
|
+
}
|
|
1114
|
+
function secretEnv(env) {
|
|
1115
|
+
if (!env) return void 0;
|
|
1116
|
+
const out = { ...env };
|
|
1117
|
+
delete out.ELECTRON_RUN_AS_NODE;
|
|
1118
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
1119
|
+
}
|
|
1120
|
+
function writeCodexMcpSecretProfile(servers) {
|
|
1121
|
+
const blocks = [];
|
|
1122
|
+
for (const s of servers) {
|
|
1123
|
+
const env = secretEnv(s.env);
|
|
1124
|
+
if (!env) continue;
|
|
1125
|
+
const secrets = Object.entries(env).filter(([key]) => isCodexSecretEnvKey(key));
|
|
1126
|
+
if (secrets.length === 0) continue;
|
|
1127
|
+
const lines = [`[mcp_servers.${s.name}.env]`];
|
|
1128
|
+
for (const [key, value] of secrets) lines.push(`${key} = ${tomlBasicString(value)}`);
|
|
1129
|
+
blocks.push(lines.join("\n"));
|
|
1130
|
+
}
|
|
1131
|
+
if (blocks.length === 0) return null;
|
|
1132
|
+
const home = process.env.CODEX_HOME?.trim() || join2(homedir2(), ".codex");
|
|
1133
|
+
mkdirSync(home, { recursive: true, mode: 448 });
|
|
1134
|
+
const profile = `sideboard-${randomBytes(8).toString("hex")}`;
|
|
1135
|
+
const file = join2(home, `${profile}.config.toml`);
|
|
1136
|
+
writeFileSync(file, `${blocks.join("\n\n")}
|
|
1137
|
+
`, { mode: 384 });
|
|
1138
|
+
return { profile, file };
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1098
1141
|
// src/agents/injected-mcp.ts
|
|
1099
1142
|
var SIDEBOARD_MCP_ALLOWED_TOOLS = [
|
|
1100
1143
|
"mcp__sideboard",
|
|
@@ -1234,7 +1277,7 @@ function corePackageDir() {
|
|
|
1234
1277
|
} catch {
|
|
1235
1278
|
}
|
|
1236
1279
|
try {
|
|
1237
|
-
const req = createRequire(
|
|
1280
|
+
const req = createRequire(join3(process.cwd(), "package.json"));
|
|
1238
1281
|
return dirname(req.resolve("@sideboard-ai/core"));
|
|
1239
1282
|
} catch {
|
|
1240
1283
|
return process.cwd();
|
|
@@ -1248,13 +1291,13 @@ function findSideboardMcpJsEntry() {
|
|
|
1248
1291
|
let dir = corePackageDir();
|
|
1249
1292
|
for (let i = 0; i < 10; i++) {
|
|
1250
1293
|
const candidates = [
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1294
|
+
join3(dir, "mcp/run-stdio.js"),
|
|
1295
|
+
join3(dir, "mcp/run-stdio.cjs"),
|
|
1296
|
+
join3(dir, "dist/mcp/run-stdio.js"),
|
|
1297
|
+
join3(dir, "dist/mcp/run-stdio.cjs"),
|
|
1298
|
+
join3(dir, "packages/core/dist/mcp/run-stdio.js"),
|
|
1299
|
+
join3(dir, "packages/cli/dist/index.js"),
|
|
1300
|
+
join3(dir, "cli/dist/index.js")
|
|
1258
1301
|
];
|
|
1259
1302
|
for (const p of candidates) {
|
|
1260
1303
|
if (existsSync3(p) && !isAsarPath(p)) return p;
|
|
@@ -1362,6 +1405,7 @@ function toCodexMcpConfigArgs(servers) {
|
|
|
1362
1405
|
const env = mcpSpawnEnv(s.env);
|
|
1363
1406
|
if (env) {
|
|
1364
1407
|
for (const [key, value] of Object.entries(env)) {
|
|
1408
|
+
if (isCodexSecretEnvKey(key)) continue;
|
|
1365
1409
|
args.push("-c", `${prefix}.env.${key}=${JSON.stringify(value)}`);
|
|
1366
1410
|
}
|
|
1367
1411
|
}
|
|
@@ -1420,9 +1464,9 @@ function mcpServersRecord(servers, extraServers) {
|
|
|
1420
1464
|
function writeMcpServersConfig(servers, extraServers) {
|
|
1421
1465
|
const mcpServers = mcpServersRecord(servers, extraServers);
|
|
1422
1466
|
if (Object.keys(mcpServers).length === 0) return null;
|
|
1423
|
-
const dir = mkdtempSync(
|
|
1424
|
-
const cfgPath =
|
|
1425
|
-
|
|
1467
|
+
const dir = mkdtempSync(join3(tmpdir(), "sideboard-mcp-"));
|
|
1468
|
+
const cfgPath = join3(dir, "mcp.json");
|
|
1469
|
+
writeFileSync2(cfgPath, JSON.stringify({ mcpServers }, null, 2), { mode: 384 });
|
|
1426
1470
|
return cfgPath;
|
|
1427
1471
|
}
|
|
1428
1472
|
async function writeInjectedMcpConfig(opts) {
|
|
@@ -1431,10 +1475,10 @@ async function writeInjectedMcpConfig(opts) {
|
|
|
1431
1475
|
|
|
1432
1476
|
// src/agents/user-mcp-config.ts
|
|
1433
1477
|
function userCursorMcpConfigPath() {
|
|
1434
|
-
return
|
|
1478
|
+
return join4(homedir3(), ".cursor", "mcp.json");
|
|
1435
1479
|
}
|
|
1436
1480
|
function userClaudeMcpConfigPath() {
|
|
1437
|
-
return
|
|
1481
|
+
return join4(homedir3(), ".claude.json");
|
|
1438
1482
|
}
|
|
1439
1483
|
function asObject(value) {
|
|
1440
1484
|
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
@@ -1469,8 +1513,8 @@ function writeMergedMcpServersJson(configPath, sideboard) {
|
|
|
1469
1513
|
}
|
|
1470
1514
|
}
|
|
1471
1515
|
const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
|
|
1472
|
-
|
|
1473
|
-
|
|
1516
|
+
mkdirSync2(dirname2(configPath), { recursive: true });
|
|
1517
|
+
writeFileSync3(configPath, `${JSON.stringify(next, null, 2)}
|
|
1474
1518
|
`);
|
|
1475
1519
|
}
|
|
1476
1520
|
function launchFromResolved(server) {
|
|
@@ -1529,13 +1573,19 @@ function readText(path) {
|
|
|
1529
1573
|
return "";
|
|
1530
1574
|
}
|
|
1531
1575
|
}
|
|
1532
|
-
function userCodexConfigPaths(home =
|
|
1533
|
-
|
|
1576
|
+
function userCodexConfigPaths(home = homedir4()) {
|
|
1577
|
+
const paths = [
|
|
1578
|
+
join5(home, ".codex", "config.toml"),
|
|
1579
|
+
join5(home, ".config", "codex", "config.toml")
|
|
1580
|
+
];
|
|
1581
|
+
const codexHome = process.env.CODEX_HOME?.trim();
|
|
1582
|
+
if (codexHome) paths.unshift(join5(codexHome, "config.toml"));
|
|
1583
|
+
return paths;
|
|
1534
1584
|
}
|
|
1535
|
-
function userOpencodeConfigPaths(home =
|
|
1585
|
+
function userOpencodeConfigPaths(home = homedir4()) {
|
|
1536
1586
|
return [
|
|
1537
|
-
|
|
1538
|
-
|
|
1587
|
+
join5(home, ".config", "opencode", "opencode.json"),
|
|
1588
|
+
join5(home, ".config", "opencode", "opencode.jsonc")
|
|
1539
1589
|
];
|
|
1540
1590
|
}
|
|
1541
1591
|
function userMcpNamesToDisable(opts) {
|
|
@@ -1554,7 +1604,7 @@ function userMcpNamesToDisable(opts) {
|
|
|
1554
1604
|
}
|
|
1555
1605
|
return out;
|
|
1556
1606
|
}
|
|
1557
|
-
function listUserCodexMcpNames(home =
|
|
1607
|
+
function listUserCodexMcpNames(home = homedir4()) {
|
|
1558
1608
|
const names = [];
|
|
1559
1609
|
for (const path of userCodexConfigPaths(home)) {
|
|
1560
1610
|
if (!existsSync5(path)) continue;
|
|
@@ -1562,7 +1612,7 @@ function listUserCodexMcpNames(home = homedir3()) {
|
|
|
1562
1612
|
}
|
|
1563
1613
|
return names;
|
|
1564
1614
|
}
|
|
1565
|
-
function listUserOpencodeMcpNames(home =
|
|
1615
|
+
function listUserOpencodeMcpNames(home = homedir4()) {
|
|
1566
1616
|
const names = [];
|
|
1567
1617
|
for (const path of userOpencodeConfigPaths(home)) {
|
|
1568
1618
|
if (!existsSync5(path)) continue;
|
|
@@ -1570,12 +1620,12 @@ function listUserOpencodeMcpNames(home = homedir3()) {
|
|
|
1570
1620
|
}
|
|
1571
1621
|
return names;
|
|
1572
1622
|
}
|
|
1573
|
-
function userClaudeMcpConfigObject(home =
|
|
1574
|
-
const claudePath = home ===
|
|
1623
|
+
function userClaudeMcpConfigObject(home = homedir4()) {
|
|
1624
|
+
const claudePath = home === homedir4() ? userClaudeMcpConfigPath() : join5(home, ".claude.json");
|
|
1575
1625
|
if (!existsSync5(claudePath)) return {};
|
|
1576
1626
|
return asObject2(asObject2(readJsonObject(claudePath)).mcpServers);
|
|
1577
1627
|
}
|
|
1578
|
-
function listUserClaudeMcpServerEntries(home =
|
|
1628
|
+
function listUserClaudeMcpServerEntries(home = homedir4(), projectDirs) {
|
|
1579
1629
|
const out = {};
|
|
1580
1630
|
for (const [name, entry] of Object.entries(
|
|
1581
1631
|
listEnabledClaudePluginMcpServers({ home, projectDirs })
|
|
@@ -1613,7 +1663,7 @@ function toCodexUnattendedAppsArgs() {
|
|
|
1613
1663
|
}
|
|
1614
1664
|
|
|
1615
1665
|
// src/mcp-ui/proxy-http.ts
|
|
1616
|
-
import { randomBytes, randomUUID } from "crypto";
|
|
1666
|
+
import { randomBytes as randomBytes2, randomUUID } from "crypto";
|
|
1617
1667
|
import { createServer } from "http";
|
|
1618
1668
|
import { Server as Server2 } from "@modelcontextprotocol/sdk/server/index.js";
|
|
1619
1669
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
@@ -1710,7 +1760,7 @@ function listedTool(tool) {
|
|
|
1710
1760
|
|
|
1711
1761
|
// src/mcp-ui/proxy-http.ts
|
|
1712
1762
|
async function listenMcpUiProxy(opts) {
|
|
1713
|
-
const token =
|
|
1763
|
+
const token = randomBytes2(24).toString("hex");
|
|
1714
1764
|
const transports = /* @__PURE__ */ new Map();
|
|
1715
1765
|
const httpServer = createServer((req, res) => {
|
|
1716
1766
|
void handle(req, res);
|
|
@@ -2083,7 +2133,7 @@ var singleton;
|
|
|
2083
2133
|
function getMcpUiHost() {
|
|
2084
2134
|
if (!singleton) {
|
|
2085
2135
|
singleton = new McpUiHost({
|
|
2086
|
-
entries: (projectDirs) => listUserClaudeMcpServerEntries(
|
|
2136
|
+
entries: (projectDirs) => listUserClaudeMcpServerEntries(homedir5(), projectDirs)
|
|
2087
2137
|
});
|
|
2088
2138
|
}
|
|
2089
2139
|
return singleton;
|
|
@@ -2091,7 +2141,7 @@ function getMcpUiHost() {
|
|
|
2091
2141
|
async function proxyClaudeUserMcp(orchestrator, projectDirs) {
|
|
2092
2142
|
if (orchestrator) return {};
|
|
2093
2143
|
const dirs = projectDirs.filter((d) => typeof d === "string" && d.length > 0);
|
|
2094
|
-
return getMcpUiHost().proxyEntries(listUserClaudeMcpServerEntries(
|
|
2144
|
+
return getMcpUiHost().proxyEntries(listUserClaudeMcpServerEntries(homedir5(), dirs), dirs);
|
|
2095
2145
|
}
|
|
2096
2146
|
function closeMcpUiHost() {
|
|
2097
2147
|
const host = singleton;
|
|
@@ -2110,16 +2160,6 @@ function planModeTurnInstruction(planMode) {
|
|
|
2110
2160
|
return planMode ? PLAN_MODE_INSTRUCTION : PLAN_MODE_OFF_INSTRUCTION;
|
|
2111
2161
|
}
|
|
2112
2162
|
function permissionMode(thread) {
|
|
2113
|
-
if (thread.sourceType === "orchestration") {
|
|
2114
|
-
return {
|
|
2115
|
-
claude: "acceptEdits",
|
|
2116
|
-
opencodePermission: JSON.stringify({
|
|
2117
|
-
edit: "allow",
|
|
2118
|
-
bash: { "*": "allow", "rm -rf *": "deny" }
|
|
2119
|
-
}),
|
|
2120
|
-
codexSandbox: "danger-full-access"
|
|
2121
|
-
};
|
|
2122
|
-
}
|
|
2123
2163
|
if (thread.planMode) {
|
|
2124
2164
|
return {
|
|
2125
2165
|
claude: "plan",
|
|
@@ -2131,6 +2171,18 @@ function permissionMode(thread) {
|
|
|
2131
2171
|
codexSandbox: "read-only"
|
|
2132
2172
|
};
|
|
2133
2173
|
}
|
|
2174
|
+
if (thread.sourceType === "orchestration") {
|
|
2175
|
+
return {
|
|
2176
|
+
claude: "acceptEdits",
|
|
2177
|
+
// Unattended coordinators cannot answer permission prompts. Explicit
|
|
2178
|
+
// allows override the user's OpenCode denies for this process only.
|
|
2179
|
+
opencodePermission: JSON.stringify({
|
|
2180
|
+
edit: "allow",
|
|
2181
|
+
bash: { "*": "allow" }
|
|
2182
|
+
}),
|
|
2183
|
+
codexSandbox: "danger-full-access"
|
|
2184
|
+
};
|
|
2185
|
+
}
|
|
2134
2186
|
if (thread.autonomy === "full") {
|
|
2135
2187
|
return {
|
|
2136
2188
|
claude: "bypassPermissions",
|
|
@@ -2140,10 +2192,7 @@ function permissionMode(thread) {
|
|
|
2140
2192
|
}
|
|
2141
2193
|
return {
|
|
2142
2194
|
claude: "acceptEdits",
|
|
2143
|
-
opencodePermission: JSON.stringify({
|
|
2144
|
-
edit: "allow",
|
|
2145
|
-
bash: { "*": "allow", "rm -rf *": "deny" }
|
|
2146
|
-
}),
|
|
2195
|
+
opencodePermission: JSON.stringify({}),
|
|
2147
2196
|
codexSandbox: "workspace-write"
|
|
2148
2197
|
};
|
|
2149
2198
|
}
|
|
@@ -2164,7 +2213,7 @@ function agentRpcChildEnv(rpc, cwd) {
|
|
|
2164
2213
|
// src/agents/claude-host.ts
|
|
2165
2214
|
import { existsSync as existsSync6 } from "fs";
|
|
2166
2215
|
import { createRequire as createRequire2 } from "module";
|
|
2167
|
-
import { dirname as dirname3, join as
|
|
2216
|
+
import { dirname as dirname3, join as join6 } from "path";
|
|
2168
2217
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2169
2218
|
function claudePilotSdkAllowedTools() {
|
|
2170
2219
|
return PILOT_TOOL_NAMES.map(
|
|
@@ -2192,17 +2241,17 @@ function entryDir() {
|
|
|
2192
2241
|
function claudeRunnerPath() {
|
|
2193
2242
|
const packagedDir = packagedCursorRuntimeDir();
|
|
2194
2243
|
if (packagedDir) {
|
|
2195
|
-
const packaged =
|
|
2244
|
+
const packaged = join6(packagedDir, "core-dist", "agents", "claude-runner.js");
|
|
2196
2245
|
if (existsSync6(packaged)) return packaged;
|
|
2197
2246
|
}
|
|
2198
2247
|
const root = entryDir();
|
|
2199
2248
|
const candidates = [
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2249
|
+
join6(root, "agents", "claude-runner.js"),
|
|
2250
|
+
join6(root, "agents", "claude-runner.cjs"),
|
|
2251
|
+
join6(root, "dist", "agents", "claude-runner.js"),
|
|
2252
|
+
join6(root, "dist", "agents", "claude-runner.cjs"),
|
|
2253
|
+
join6(root, "claude-runner.ts"),
|
|
2254
|
+
join6(root, "src", "agents", "claude-runner.ts")
|
|
2206
2255
|
];
|
|
2207
2256
|
for (const candidate of candidates) {
|
|
2208
2257
|
if (existsSync6(candidate)) return candidate;
|
|
@@ -2281,7 +2330,8 @@ function sessionCostUsdFromClaudeResult(obj) {
|
|
|
2281
2330
|
function claudeResultErrorDetail(obj) {
|
|
2282
2331
|
const isError = Boolean(obj.is_error) || typeof obj.subtype === "string" && /^error/i.test(obj.subtype);
|
|
2283
2332
|
const fromResult = typeof obj.result === "string" ? obj.result.trim() : "";
|
|
2284
|
-
|
|
2333
|
+
const shortFailure = fromResult.length > 0 && fromResult.length <= 300 && !fromResult.includes("\n") && looksLikeAgentFailureMessage(fromResult);
|
|
2334
|
+
if (fromResult && (isError || shortFailure)) {
|
|
2285
2335
|
return fromResult;
|
|
2286
2336
|
}
|
|
2287
2337
|
if (!isError) return null;
|
|
@@ -2528,7 +2578,7 @@ function eventsFromClaudeSystem(obj) {
|
|
|
2528
2578
|
data: `Context compressed${trigger}`,
|
|
2529
2579
|
replace: true
|
|
2530
2580
|
};
|
|
2531
|
-
if (meta.postTokens != null && meta.postTokens > 0) {
|
|
2581
|
+
if (meta.postTokens != null && meta.postTokens > 0 && !parentId) {
|
|
2532
2582
|
return [
|
|
2533
2583
|
thinking,
|
|
2534
2584
|
{
|
|
@@ -2609,7 +2659,7 @@ var claudeAdapter = {
|
|
|
2609
2659
|
);
|
|
2610
2660
|
}
|
|
2611
2661
|
const mode = permissionMode(thread);
|
|
2612
|
-
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-
|
|
2662
|
+
const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-UIEXAG2B.js");
|
|
2613
2663
|
const isOrchestrator = isOrchestratorThread2(thread);
|
|
2614
2664
|
const rpc = worktreeAgentRpc(isOrchestrator);
|
|
2615
2665
|
const injectedServers = await buildInjectedMcpServers({
|
|
@@ -2709,6 +2759,7 @@ var claudeAdapter = {
|
|
|
2709
2759
|
cwd: thread.worktreePath,
|
|
2710
2760
|
stdin: useStdin ? `${promptText}
|
|
2711
2761
|
` : void 0,
|
|
2762
|
+
...mcpConfigPath ? { cleanupDirs: [dirname4(mcpConfigPath)] } : {},
|
|
2712
2763
|
// Nested Task/Agent thinking+text in stream-json (Claude Code 2.1.211+).
|
|
2713
2764
|
// Raise the -p background-agent wait so long TaskOutput polls are not
|
|
2714
2765
|
// abandoned at Claude Code’s 10-minute default.
|
|
@@ -2738,9 +2789,17 @@ var claudeAdapter = {
|
|
|
2738
2789
|
Array.isArray(message?.content) ? message.content : void 0,
|
|
2739
2790
|
parentId
|
|
2740
2791
|
);
|
|
2741
|
-
if (obj.type === "assistant") {
|
|
2792
|
+
if (obj.type === "assistant" && !parentId) {
|
|
2742
2793
|
const usage = usageFromClaude(message?.usage);
|
|
2743
|
-
|
|
2794
|
+
const messageId = message && typeof message.id === "string" ? message.id : void 0;
|
|
2795
|
+
if (usage) {
|
|
2796
|
+
events.push({
|
|
2797
|
+
type: "usage",
|
|
2798
|
+
data: usage,
|
|
2799
|
+
scope: "request",
|
|
2800
|
+
...messageId ? { messageId } : {}
|
|
2801
|
+
});
|
|
2802
|
+
}
|
|
2744
2803
|
}
|
|
2745
2804
|
if (events.length === 0) return null;
|
|
2746
2805
|
return events.length === 1 ? events[0] : events;
|
|
@@ -2827,56 +2886,47 @@ var claudeAdapter = {
|
|
|
2827
2886
|
return { file: claude, args, cwd: thread.worktreePath };
|
|
2828
2887
|
},
|
|
2829
2888
|
async listLinearIssues(_repoPath) {
|
|
2830
|
-
const
|
|
2831
|
-
|
|
2832
|
-
const { stdout, exitCode } = await run(
|
|
2833
|
-
claude,
|
|
2834
|
-
[
|
|
2835
|
-
"-p",
|
|
2836
|
-
prompt,
|
|
2837
|
-
"--output-format",
|
|
2838
|
-
"json",
|
|
2839
|
-
"--permission-mode",
|
|
2840
|
-
"bypassPermissions",
|
|
2841
|
-
"--allowedTools",
|
|
2842
|
-
"mcp__linear__*"
|
|
2843
|
-
],
|
|
2844
|
-
{ reject: false }
|
|
2845
|
-
);
|
|
2846
|
-
if (exitCode !== 0) return [];
|
|
2847
|
-
return parseIssuesJson(stdout);
|
|
2889
|
+
const { listAssignedLinearIssues: listAssignedLinearIssues2 } = await import("./linear-list-A37WLUBO.js");
|
|
2890
|
+
return listAssignedLinearIssues2();
|
|
2848
2891
|
}
|
|
2849
2892
|
};
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2893
|
+
|
|
2894
|
+
// src/agents/codex.ts
|
|
2895
|
+
import { existsSync as existsSync8, statSync } from "fs";
|
|
2896
|
+
import { homedir as homedir6 } from "os";
|
|
2897
|
+
import { join as join7 } from "path";
|
|
2898
|
+
|
|
2899
|
+
// src/agents/codex-items.ts
|
|
2900
|
+
function eventsFromCodexItem(eventType, item) {
|
|
2901
|
+
const itemType = item.type ?? item.item_type;
|
|
2902
|
+
if (itemType === "reasoning" && typeof item.text === "string" && item.text) {
|
|
2903
|
+
return { type: "thinking", data: item.text };
|
|
2904
|
+
}
|
|
2905
|
+
if (itemType !== "file_change" || !item.id) return null;
|
|
2906
|
+
const changes = Array.isArray(item.changes) ? item.changes : [];
|
|
2907
|
+
const paths = changes.map((change) => typeof change?.path === "string" ? change.path : "").filter(Boolean);
|
|
2908
|
+
const added = changes.some((change) => change?.kind === "add");
|
|
2909
|
+
const events = [
|
|
2910
|
+
{
|
|
2911
|
+
type: "tool_use",
|
|
2912
|
+
id: item.id,
|
|
2913
|
+
name: added ? "Write" : "Edit",
|
|
2914
|
+
input: paths.length ? { paths } : void 0
|
|
2871
2915
|
}
|
|
2916
|
+
];
|
|
2917
|
+
const finished = eventType === "item.completed" || item.status === "completed" || item.status === "failed";
|
|
2918
|
+
if (finished) {
|
|
2919
|
+
events.push({
|
|
2920
|
+
type: "tool_result",
|
|
2921
|
+
id: item.id,
|
|
2922
|
+
content: paths.join("\n") || void 0,
|
|
2923
|
+
isError: item.status === "failed"
|
|
2924
|
+
});
|
|
2872
2925
|
}
|
|
2873
|
-
return [];
|
|
2926
|
+
return events.length === 1 ? events[0] : events;
|
|
2874
2927
|
}
|
|
2875
2928
|
|
|
2876
2929
|
// src/agents/codex.ts
|
|
2877
|
-
import { existsSync as existsSync8, readFileSync as readFileSync4, statSync } from "fs";
|
|
2878
|
-
import { homedir as homedir5 } from "os";
|
|
2879
|
-
import { join as join6 } from "path";
|
|
2880
2930
|
var CODEX_PROMPT_ARG_MAX = 2e5;
|
|
2881
2931
|
var FALLBACK_CODEX_MODELS = [
|
|
2882
2932
|
{ id: "gpt-5.6-sol", displayName: "GPT-5.6 Sol" },
|
|
@@ -2921,25 +2971,19 @@ async function listCodexModels() {
|
|
|
2921
2971
|
return cachedCodexModels?.models ?? FALLBACK_CODEX_MODELS;
|
|
2922
2972
|
}
|
|
2923
2973
|
}
|
|
2924
|
-
function usageFromCodex(usage) {
|
|
2974
|
+
function usageFromCodex(usage, asContext = false) {
|
|
2925
2975
|
if (!usage) return null;
|
|
2926
|
-
|
|
2976
|
+
const mapped = fromInclusiveInputUsage({
|
|
2927
2977
|
inputTokens: Number(usage.input_tokens ?? 0),
|
|
2928
2978
|
outputTokens: Number(usage.output_tokens ?? 0),
|
|
2929
2979
|
cachedInputTokens: Number(usage.cached_input_tokens ?? 0)
|
|
2930
2980
|
});
|
|
2981
|
+
if (!mapped || !asContext) return mapped;
|
|
2982
|
+
const occ = requestOccupancy(mapped);
|
|
2983
|
+
return occ > 0 ? { ...mapped, lastRequestTokens: occ } : mapped;
|
|
2931
2984
|
}
|
|
2932
|
-
function
|
|
2933
|
-
|
|
2934
|
-
join6(homedir5(), ".codex", "config.toml"),
|
|
2935
|
-
join6(homedir5(), ".config", "codex", "config.toml")
|
|
2936
|
-
];
|
|
2937
|
-
for (const path of candidates) {
|
|
2938
|
-
if (!existsSync8(path)) continue;
|
|
2939
|
-
const text = readFileSync4(path, "utf8");
|
|
2940
|
-
if (/network_access\s*=\s*true/.test(text)) return true;
|
|
2941
|
-
}
|
|
2942
|
-
return false;
|
|
2985
|
+
function codexHomeDir() {
|
|
2986
|
+
return process.env.CODEX_HOME?.trim() || join7(homedir6(), ".codex");
|
|
2943
2987
|
}
|
|
2944
2988
|
function unwrapCodexMcpResult(result) {
|
|
2945
2989
|
if (result == null) return void 0;
|
|
@@ -2968,7 +3012,7 @@ function asRecord3(value) {
|
|
|
2968
3012
|
return void 0;
|
|
2969
3013
|
}
|
|
2970
3014
|
function codexLooksAuthenticated() {
|
|
2971
|
-
const authPath =
|
|
3015
|
+
const authPath = join7(codexHomeDir(), "auth.json");
|
|
2972
3016
|
if (!existsSync8(authPath)) return false;
|
|
2973
3017
|
try {
|
|
2974
3018
|
return statSync(authPath).size > 2;
|
|
@@ -3007,18 +3051,13 @@ var codexAdapter = {
|
|
|
3007
3051
|
const authenticated = codexLooksAuthenticated();
|
|
3008
3052
|
const linearMcp = false;
|
|
3009
3053
|
const warnings = [];
|
|
3010
|
-
if (!codexConfigHasNetworkAccess()) {
|
|
3011
|
-
warnings.push(
|
|
3012
|
-
"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."
|
|
3013
|
-
);
|
|
3014
|
-
}
|
|
3015
3054
|
return {
|
|
3016
3055
|
agent: "codex",
|
|
3017
3056
|
installed: true,
|
|
3018
3057
|
authenticated,
|
|
3019
3058
|
linearMcp,
|
|
3020
3059
|
warnings,
|
|
3021
|
-
reason: authenticated ? void 0 :
|
|
3060
|
+
reason: authenticated ? void 0 : `Codex auth not found \u2014 run \`codex login\` (expected ${join7(codexHomeDir(), "auth.json")})`
|
|
3022
3061
|
};
|
|
3023
3062
|
},
|
|
3024
3063
|
async buildTurn(thread, input) {
|
|
@@ -3043,6 +3082,12 @@ var codexAdapter = {
|
|
|
3043
3082
|
threadId: thread.id
|
|
3044
3083
|
});
|
|
3045
3084
|
const isolatePlugins = isOrchestrator || Boolean(thread.isolateCodexPlugins) || Boolean(normalizeTurnInput(input).isolateCodexPlugins);
|
|
3085
|
+
const gitEnv = await resolveAgentGitAuthEnv(process.env, {
|
|
3086
|
+
cwd: thread.worktreePath
|
|
3087
|
+
});
|
|
3088
|
+
const writableRoots = mode.codexSandbox === "workspace-write" ? await resolveCodexGitWritableRoots(thread.worktreePath) : [];
|
|
3089
|
+
const secretProfile = writeCodexMcpSecretProfile(injected);
|
|
3090
|
+
const effort = thread.effort?.trim() ?? "";
|
|
3046
3091
|
const mcpOverrides = [
|
|
3047
3092
|
// Worktree first try keeps plugins (Claude connectors). Coordinators
|
|
3048
3093
|
// isolate. After a fatal plugin MCP, the orchestrator retries with
|
|
@@ -3059,6 +3104,7 @@ var codexAdapter = {
|
|
|
3059
3104
|
const execOpts = [
|
|
3060
3105
|
// Global orchestration cwd is not a git repo; without this Codex ≥0.147
|
|
3061
3106
|
// refuses to start ("Not inside a trusted directory").
|
|
3107
|
+
...secretProfile ? ["-p", secretProfile.profile] : [],
|
|
3062
3108
|
"--skip-git-repo-check",
|
|
3063
3109
|
"--cd",
|
|
3064
3110
|
thread.worktreePath,
|
|
@@ -3068,14 +3114,16 @@ var codexAdapter = {
|
|
|
3068
3114
|
// `codex exec` rejects `--ask-for-approval` (global-only on newer CLIs).
|
|
3069
3115
|
"-c",
|
|
3070
3116
|
'approval_policy="never"',
|
|
3071
|
-
// Seatbelt cannot use the login Keychain
|
|
3072
|
-
// Default
|
|
3073
|
-
//
|
|
3074
|
-
// can
|
|
3117
|
+
// Seatbelt cannot use the login Keychain. inherit=all keeps GH_CONFIG_DIR
|
|
3118
|
+
// and GIT_CONFIG_*. Default excludes still strip *TOKEN*/*SECRET*/*KEY*;
|
|
3119
|
+
// GIT_CONFIG_KEY_n is re-set because it matches *KEY*. Linked worktrees
|
|
3120
|
+
// need the main repo `.git` as writable_roots so git commit can lock.
|
|
3075
3121
|
...codexUnattendedGitConfigArgs(mode.codexSandbox, {
|
|
3076
|
-
writableRoots
|
|
3122
|
+
writableRoots,
|
|
3123
|
+
preserveEnv: gitEnv
|
|
3077
3124
|
}),
|
|
3078
3125
|
...model ? ["--model", model] : [],
|
|
3126
|
+
...effort ? ["-c", `model_reasoning_effort=${JSON.stringify(effort)}`] : [],
|
|
3079
3127
|
...mcpOverrides
|
|
3080
3128
|
];
|
|
3081
3129
|
const args = sessionId ? ["exec", ...execOpts, "resume", sessionId, promptArg] : ["exec", ...execOpts, promptArg];
|
|
@@ -3084,7 +3132,8 @@ var codexAdapter = {
|
|
|
3084
3132
|
args,
|
|
3085
3133
|
cwd: thread.worktreePath,
|
|
3086
3134
|
stdin: useStdin ? `${prompt}
|
|
3087
|
-
` : void 0
|
|
3135
|
+
` : void 0,
|
|
3136
|
+
...secretProfile ? { cleanupDirs: [secretProfile.file] } : {}
|
|
3088
3137
|
};
|
|
3089
3138
|
},
|
|
3090
3139
|
parseEvent(line) {
|
|
@@ -3105,8 +3154,10 @@ var codexAdapter = {
|
|
|
3105
3154
|
if (typeof obj.item === "object" && obj.item !== null) {
|
|
3106
3155
|
const item = obj.item;
|
|
3107
3156
|
const itemType = item.type ?? item.item_type;
|
|
3157
|
+
const mapped = eventsFromCodexItem(type, item);
|
|
3158
|
+
if (mapped) return mapped;
|
|
3108
3159
|
if (itemType === "error") {
|
|
3109
|
-
const detail = item.message
|
|
3160
|
+
const detail = (typeof item.message === "string" ? item.message.trim() : "") || extractJsonErrorMessage(obj) || "Codex item error";
|
|
3110
3161
|
return { type: "stderr", data: detail };
|
|
3111
3162
|
}
|
|
3112
3163
|
if (itemType === "agent_message" && item.text) {
|
|
@@ -3135,14 +3186,14 @@ var codexAdapter = {
|
|
|
3135
3186
|
const events = [
|
|
3136
3187
|
{ type: "tool_use", id: item.id, name: "Bash", input }
|
|
3137
3188
|
];
|
|
3138
|
-
const finished = type === "item.completed" || item.status === "completed" || item.status === "failed";
|
|
3189
|
+
const finished = type === "item.completed" || item.status === "completed" || item.status === "failed" || item.status === "declined";
|
|
3139
3190
|
const output = typeof item.aggregated_output === "string" && item.aggregated_output ? item.aggregated_output : void 0;
|
|
3140
3191
|
if (finished) {
|
|
3141
3192
|
events.push({
|
|
3142
3193
|
type: "tool_result",
|
|
3143
3194
|
id: item.id,
|
|
3144
3195
|
content: output,
|
|
3145
|
-
isError: item.status === "failed"
|
|
3196
|
+
isError: item.status === "failed" || item.status === "declined"
|
|
3146
3197
|
});
|
|
3147
3198
|
} else if (output) {
|
|
3148
3199
|
events.push({
|
|
@@ -3185,7 +3236,7 @@ var codexAdapter = {
|
|
|
3185
3236
|
return events.length === 1 ? events[0] : events;
|
|
3186
3237
|
}
|
|
3187
3238
|
if (item.status === "failed") {
|
|
3188
|
-
const detail = item.message
|
|
3239
|
+
const detail = (typeof item.message === "string" ? item.message.trim() : "") || extractJsonErrorMessage(item) || `Codex ${itemType ?? "item"} failed`;
|
|
3189
3240
|
return { type: "stderr", data: detail };
|
|
3190
3241
|
}
|
|
3191
3242
|
}
|
|
@@ -3194,7 +3245,8 @@ var codexAdapter = {
|
|
|
3194
3245
|
return { type: "session_id", data: sid };
|
|
3195
3246
|
}
|
|
3196
3247
|
if (type === "turn.completed" || type === "turn_completed") {
|
|
3197
|
-
const
|
|
3248
|
+
const payload = obj;
|
|
3249
|
+
const usage = payload.last_token_usage ? usageFromCodex(payload.last_token_usage, true) : usageFromCodex(payload.usage);
|
|
3198
3250
|
return usage ? { type: "usage", data: usage, scope: "turn" } : null;
|
|
3199
3251
|
}
|
|
3200
3252
|
if (typeof obj.content === "string" && obj.content.trim()) {
|
|
@@ -3217,7 +3269,7 @@ var codexAdapter = {
|
|
|
3217
3269
|
if (sessionId) {
|
|
3218
3270
|
return {
|
|
3219
3271
|
file: codex,
|
|
3220
|
-
args: ["
|
|
3272
|
+
args: ["resume", sessionId],
|
|
3221
3273
|
cwd: thread.worktreePath
|
|
3222
3274
|
};
|
|
3223
3275
|
}
|
|
@@ -3228,36 +3280,14 @@ var codexAdapter = {
|
|
|
3228
3280
|
};
|
|
3229
3281
|
},
|
|
3230
3282
|
async listLinearIssues(_repoPath) {
|
|
3231
|
-
|
|
3232
|
-
const { stdout, exitCode } = await run(
|
|
3233
|
-
resolveAgentExecutable("codex"),
|
|
3234
|
-
[
|
|
3235
|
-
"exec",
|
|
3236
|
-
"--json",
|
|
3237
|
-
"--sandbox",
|
|
3238
|
-
"read-only",
|
|
3239
|
-
"-c",
|
|
3240
|
-
'approval_policy="never"',
|
|
3241
|
-
prompt
|
|
3242
|
-
],
|
|
3243
|
-
{ reject: false }
|
|
3244
|
-
);
|
|
3245
|
-
if (exitCode !== 0) return [];
|
|
3246
|
-
const match = stdout.match(/\[[\s\S]*\]/);
|
|
3247
|
-
if (!match) return [];
|
|
3248
|
-
try {
|
|
3249
|
-
const parsed = JSON.parse(match[0]);
|
|
3250
|
-
return Array.isArray(parsed) ? parsed : [];
|
|
3251
|
-
} catch {
|
|
3252
|
-
return [];
|
|
3253
|
-
}
|
|
3283
|
+
return listAssignedLinearIssues();
|
|
3254
3284
|
}
|
|
3255
3285
|
};
|
|
3256
3286
|
|
|
3257
3287
|
// src/agents/cursor.ts
|
|
3258
3288
|
import { existsSync as existsSync9 } from "fs";
|
|
3259
3289
|
import { createRequire as createRequire3 } from "module";
|
|
3260
|
-
import { dirname as
|
|
3290
|
+
import { dirname as dirname5, join as join8 } from "path";
|
|
3261
3291
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3262
3292
|
var FALLBACK_CURSOR_MODELS = [
|
|
3263
3293
|
{ id: "default", displayName: "Auto" },
|
|
@@ -3309,11 +3339,11 @@ function entryDir2() {
|
|
|
3309
3339
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
3310
3340
|
if (cjsDir) return cjsDir;
|
|
3311
3341
|
try {
|
|
3312
|
-
return
|
|
3342
|
+
return dirname5(fileURLToPath3(import.meta.url));
|
|
3313
3343
|
} catch {
|
|
3314
3344
|
try {
|
|
3315
3345
|
const req = createRequire3(process.cwd() + "/");
|
|
3316
|
-
return
|
|
3346
|
+
return dirname5(req.resolve("@sideboard-ai/core"));
|
|
3317
3347
|
} catch {
|
|
3318
3348
|
return process.cwd();
|
|
3319
3349
|
}
|
|
@@ -3324,14 +3354,14 @@ function cursorRunnerPath() {
|
|
|
3324
3354
|
if (packaged) return packaged;
|
|
3325
3355
|
const root = entryDir2();
|
|
3326
3356
|
const candidates = [
|
|
3327
|
-
|
|
3328
|
-
|
|
3357
|
+
join8(root, "agents", "cursor-runner.js"),
|
|
3358
|
+
join8(root, "agents", "cursor-runner.cjs"),
|
|
3329
3359
|
// If somehow resolved from package root instead of dist/
|
|
3330
|
-
|
|
3331
|
-
|
|
3360
|
+
join8(root, "dist", "agents", "cursor-runner.js"),
|
|
3361
|
+
join8(root, "dist", "agents", "cursor-runner.cjs"),
|
|
3332
3362
|
// Source tree (dev): packages/core/src/agents/cursor-runner.ts
|
|
3333
|
-
|
|
3334
|
-
|
|
3363
|
+
join8(root, "cursor-runner.ts"),
|
|
3364
|
+
join8(root, "src", "agents", "cursor-runner.ts")
|
|
3335
3365
|
];
|
|
3336
3366
|
for (const candidate of candidates) {
|
|
3337
3367
|
if (existsSync9(candidate)) return candidate;
|
|
@@ -3372,6 +3402,7 @@ var cursorAdapter = {
|
|
|
3372
3402
|
},
|
|
3373
3403
|
async buildTurn(thread, input) {
|
|
3374
3404
|
const agentId = await this.resolveSessionId(thread.worktreePath, thread.sessionId);
|
|
3405
|
+
const fullPrompt = flattenTurnInput(input);
|
|
3375
3406
|
const prompt = flattenTurnInput(dropCachedPrefixOnResume(input, agentId));
|
|
3376
3407
|
const apiKey = resolveCursorApiKey() || void 0;
|
|
3377
3408
|
const isOrchestrator = isOrchestratorThread(thread);
|
|
@@ -3388,6 +3419,7 @@ var cursorAdapter = {
|
|
|
3388
3419
|
const mcpServers = toCursorMcpServers(injected);
|
|
3389
3420
|
const req = {
|
|
3390
3421
|
prompt,
|
|
3422
|
+
...fullPrompt !== prompt ? { freshPrompt: fullPrompt } : {},
|
|
3391
3423
|
cwd: thread.worktreePath,
|
|
3392
3424
|
threadId: thread.id,
|
|
3393
3425
|
agentId,
|
|
@@ -3414,8 +3446,9 @@ var cursorAdapter = {
|
|
|
3414
3446
|
stdin: JSON.stringify(req),
|
|
3415
3447
|
env: {
|
|
3416
3448
|
...launch.env,
|
|
3417
|
-
...cursorRipgrepEnv({ startFile: runner })
|
|
3418
|
-
|
|
3449
|
+
...cursorRipgrepEnv({ startFile: runner })
|
|
3450
|
+
// API key stays on the stdin request. Do not copy it into the child env,
|
|
3451
|
+
// where `ps` and crash dumps can see it. The runner reads `req.apiKey`.
|
|
3419
3452
|
}
|
|
3420
3453
|
};
|
|
3421
3454
|
},
|
|
@@ -3437,14 +3470,17 @@ var cursorAdapter = {
|
|
|
3437
3470
|
};
|
|
3438
3471
|
|
|
3439
3472
|
// src/agents/opencode.ts
|
|
3440
|
-
import { existsSync as
|
|
3473
|
+
import { existsSync as existsSync11 } from "fs";
|
|
3474
|
+
|
|
3475
|
+
// src/agent-rpc/opencode-host.ts
|
|
3476
|
+
import { pathToFileURL } from "url";
|
|
3441
3477
|
|
|
3442
3478
|
// src/agent-rpc/opencode-hook.ts
|
|
3443
|
-
import { mkdirSync as
|
|
3444
|
-
import { join as
|
|
3479
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync, writeFileSync as writeFileSync4 } from "fs";
|
|
3480
|
+
import { join as join9 } from "path";
|
|
3445
3481
|
var OPENCODE_PLUGIN_SOURCE = `import { tool } from "@opencode-ai/plugin"
|
|
3446
3482
|
|
|
3447
|
-
const
|
|
3483
|
+
const RPC_URL = process.env[${JSON.stringify(AGENT_RPC_URL_ENV)}] || ""
|
|
3448
3484
|
const TOKEN = process.env[${JSON.stringify(AGENT_RPC_TOKEN_ENV)}] || ""
|
|
3449
3485
|
const CWD = process.env[${JSON.stringify(AGENT_RPC_CWD_ENV)}] || ""
|
|
3450
3486
|
|
|
@@ -3457,24 +3493,29 @@ function jsonError(err) {
|
|
|
3457
3493
|
}
|
|
3458
3494
|
|
|
3459
3495
|
function socketUrl() {
|
|
3460
|
-
const u = new URL(
|
|
3496
|
+
const u = new URL(RPC_URL)
|
|
3461
3497
|
u.searchParams.set(${JSON.stringify(AGENT_RPC_TOKEN_QUERY)}, TOKEN)
|
|
3462
3498
|
return u.toString()
|
|
3463
3499
|
}
|
|
3464
3500
|
|
|
3465
3501
|
function call(method, params) {
|
|
3466
|
-
if (!
|
|
3502
|
+
if (!RPC_URL || !TOKEN) {
|
|
3467
3503
|
return Promise.resolve(jsonError(new Error("Agent RPC runtime is not running")))
|
|
3468
3504
|
}
|
|
3505
|
+
const timeoutMs = method === "job.wait" ? 130000 : 30000
|
|
3469
3506
|
return new Promise((resolve) => {
|
|
3470
3507
|
let settled = false
|
|
3508
|
+
let ws
|
|
3509
|
+
let timer
|
|
3471
3510
|
const done = (value) => {
|
|
3472
3511
|
if (settled) return
|
|
3473
3512
|
settled = true
|
|
3513
|
+
clearTimeout(timer)
|
|
3474
3514
|
try { ws.close() } catch {}
|
|
3475
3515
|
resolve(value)
|
|
3476
3516
|
}
|
|
3477
|
-
|
|
3517
|
+
timer = setTimeout(() => done(jsonError(new Error("Agent RPC timed out"))), timeoutMs)
|
|
3518
|
+
ws = new WebSocket(socketUrl())
|
|
3478
3519
|
const id = Date.now()
|
|
3479
3520
|
ws.addEventListener("open", () => {
|
|
3480
3521
|
ws.send(JSON.stringify({ jsonrpc: "2.0", id, method, params, authToken: TOKEN }))
|
|
@@ -3546,12 +3587,19 @@ export const SideboardRpc = async (ctx) => {
|
|
|
3546
3587
|
}
|
|
3547
3588
|
`;
|
|
3548
3589
|
function writeOpencodeRpcPlugin() {
|
|
3549
|
-
const
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3590
|
+
const pluginDir = join9(appDataDir(), "agent-rpc", "opencode");
|
|
3591
|
+
mkdirSync3(pluginDir, { recursive: true });
|
|
3592
|
+
const pluginFile = join9(pluginDir, "sideboard-rpc.js");
|
|
3593
|
+
if (existsSync10(pluginFile)) {
|
|
3594
|
+
try {
|
|
3595
|
+
if (readFileSync4(pluginFile, "utf8") === OPENCODE_PLUGIN_SOURCE) return pluginFile;
|
|
3596
|
+
} catch {
|
|
3597
|
+
}
|
|
3598
|
+
}
|
|
3599
|
+
const tmp = `${pluginFile}.${process.pid}.tmp`;
|
|
3600
|
+
writeFileSync4(tmp, OPENCODE_PLUGIN_SOURCE);
|
|
3601
|
+
renameSync(tmp, pluginFile);
|
|
3602
|
+
return pluginFile;
|
|
3555
3603
|
}
|
|
3556
3604
|
|
|
3557
3605
|
// src/agent-rpc/opencode-host.ts
|
|
@@ -3574,10 +3622,9 @@ async function buildOpencodeHostEnv(thread) {
|
|
|
3574
3622
|
const config = injected.length > 0 || disableNames.length > 0 ? JSON.parse(toOpencodeMcpConfigContent(injected, { disableNames })) : {};
|
|
3575
3623
|
const env = {};
|
|
3576
3624
|
if (rpc) {
|
|
3577
|
-
const
|
|
3578
|
-
env.OPENCODE_CONFIG_DIR = configDir;
|
|
3625
|
+
const pluginFile = writeOpencodeRpcPlugin();
|
|
3579
3626
|
Object.assign(env, agentRpcChildEnv(rpc, thread.worktreePath));
|
|
3580
|
-
config.plugin = [pluginFile];
|
|
3627
|
+
config.plugin = [pathToFileURL(pluginFile).href];
|
|
3581
3628
|
}
|
|
3582
3629
|
if (Object.keys(config).length > 0) {
|
|
3583
3630
|
env.OPENCODE_CONFIG_CONTENT = JSON.stringify(config);
|
|
@@ -3644,7 +3691,7 @@ async function listOpencodeModels() {
|
|
|
3644
3691
|
if (opencode === "opencode") {
|
|
3645
3692
|
const which = await run("which", ["opencode"], { reject: false });
|
|
3646
3693
|
if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
|
|
3647
|
-
} else if (!
|
|
3694
|
+
} else if (!existsSync11(opencode)) {
|
|
3648
3695
|
return FALLBACK_OPENCODE_MODELS;
|
|
3649
3696
|
}
|
|
3650
3697
|
const listed = await run(opencode, ["models"], { reject: false });
|
|
@@ -3679,7 +3726,7 @@ var opencodeAdapter = {
|
|
|
3679
3726
|
async detect() {
|
|
3680
3727
|
const opencode = resolveAgentExecutable("opencode");
|
|
3681
3728
|
if (opencode !== "opencode") {
|
|
3682
|
-
if (!
|
|
3729
|
+
if (!existsSync11(opencode)) {
|
|
3683
3730
|
return {
|
|
3684
3731
|
agent: "opencode",
|
|
3685
3732
|
installed: false,
|
|
@@ -3733,6 +3780,11 @@ var opencodeAdapter = {
|
|
|
3733
3780
|
if (model) {
|
|
3734
3781
|
args.push("--model", model);
|
|
3735
3782
|
}
|
|
3783
|
+
args.push("--thinking");
|
|
3784
|
+
const variant = thread.effort?.trim() ?? "";
|
|
3785
|
+
if (variant && /^(minimal|low|medium|high|max|xhigh)$/i.test(variant)) {
|
|
3786
|
+
args.push("--variant", variant);
|
|
3787
|
+
}
|
|
3736
3788
|
const hostEnv = await buildOpencodeHostEnv(thread);
|
|
3737
3789
|
return {
|
|
3738
3790
|
file: resolveAgentExecutable("opencode"),
|
|
@@ -3765,6 +3817,10 @@ var opencodeAdapter = {
|
|
|
3765
3817
|
const text = obj.part?.text ?? obj.text;
|
|
3766
3818
|
if (text) return { type: "stdout", data: text };
|
|
3767
3819
|
}
|
|
3820
|
+
if (obj.type === "reasoning" || obj.type === "thinking") {
|
|
3821
|
+
const text = obj.part?.text ?? obj.text;
|
|
3822
|
+
if (typeof text === "string" && text) return { type: "thinking", data: text };
|
|
3823
|
+
}
|
|
3768
3824
|
if (obj.type === "tool_use") {
|
|
3769
3825
|
const part = obj.part;
|
|
3770
3826
|
const name = part?.tool ?? part?.name ?? obj.tool ?? obj.name ?? "tool";
|
|
@@ -3880,11 +3936,14 @@ var opencodeAdapter = {
|
|
|
3880
3936
|
const listed = await run(
|
|
3881
3937
|
resolveAgentExecutable("opencode"),
|
|
3882
3938
|
["session", "list", "--format", "json"],
|
|
3883
|
-
{ cwd: worktreePath, reject: false }
|
|
3939
|
+
{ cwd: worktreePath, reject: false, timeoutMs: 8e3 }
|
|
3884
3940
|
);
|
|
3885
|
-
if (listed.exitCode === 0
|
|
3941
|
+
if (listed.exitCode === 0) {
|
|
3942
|
+
const raw = listed.stdout.trim();
|
|
3943
|
+
if (!raw) return null;
|
|
3886
3944
|
try {
|
|
3887
|
-
const sessions = JSON.parse(
|
|
3945
|
+
const sessions = JSON.parse(raw);
|
|
3946
|
+
if (Array.isArray(sessions) && sessions.length === 0) return null;
|
|
3888
3947
|
if (Array.isArray(sessions) && sessions.length > 0) {
|
|
3889
3948
|
const norm = (p) => p.replace(/\/+$/, "");
|
|
3890
3949
|
const wt = norm(worktreePath);
|
|
@@ -3918,34 +3977,8 @@ var opencodeAdapter = {
|
|
|
3918
3977
|
};
|
|
3919
3978
|
},
|
|
3920
3979
|
async listLinearIssues(_repoPath) {
|
|
3921
|
-
const
|
|
3922
|
-
|
|
3923
|
-
resolveAgentExecutable("opencode"),
|
|
3924
|
-
["run", prompt, "--format", "json"],
|
|
3925
|
-
{
|
|
3926
|
-
reject: false,
|
|
3927
|
-
env: { OPENCODE_PERMISSION: JSON.stringify({ "*": "allow" }) }
|
|
3928
|
-
}
|
|
3929
|
-
);
|
|
3930
|
-
if (exitCode !== 0) return [];
|
|
3931
|
-
const texts = [];
|
|
3932
|
-
for (const line of stdout.split("\n")) {
|
|
3933
|
-
try {
|
|
3934
|
-
const obj = JSON.parse(line);
|
|
3935
|
-
if (obj.type === "text") {
|
|
3936
|
-
texts.push(obj.part?.text ?? obj.text ?? "");
|
|
3937
|
-
}
|
|
3938
|
-
} catch {
|
|
3939
|
-
}
|
|
3940
|
-
}
|
|
3941
|
-
const joined = texts.join("");
|
|
3942
|
-
const match = joined.match(/\[[\s\S]*\]/);
|
|
3943
|
-
if (!match) return [];
|
|
3944
|
-
try {
|
|
3945
|
-
return JSON.parse(match[0]);
|
|
3946
|
-
} catch {
|
|
3947
|
-
return [];
|
|
3948
|
-
}
|
|
3980
|
+
const { listAssignedLinearIssues: listAssignedLinearIssues2 } = await import("./linear-list-A37WLUBO.js");
|
|
3981
|
+
return listAssignedLinearIssues2();
|
|
3949
3982
|
}
|
|
3950
3983
|
};
|
|
3951
3984
|
|
|
@@ -4344,9 +4377,9 @@ function formatClaudeUsageOverLimitWait(windows, now = /* @__PURE__ */ new Date(
|
|
|
4344
4377
|
}
|
|
4345
4378
|
|
|
4346
4379
|
// src/agents/claude-usage-client.ts
|
|
4347
|
-
import { existsSync as
|
|
4348
|
-
import { homedir as
|
|
4349
|
-
import { join as
|
|
4380
|
+
import { existsSync as existsSync12, readFileSync as readFileSync5 } from "fs";
|
|
4381
|
+
import { homedir as homedir7 } from "os";
|
|
4382
|
+
import { join as join10 } from "path";
|
|
4350
4383
|
var CLAUDE_OAUTH_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
|
|
4351
4384
|
var CLAUDE_USAGE_TTL_MS = 9e4;
|
|
4352
4385
|
var CLAUDE_USAGE_ERROR_TTL_MS = 5 * 6e4;
|
|
@@ -4386,12 +4419,12 @@ function accessTokenFromCredentialsJson(raw) {
|
|
|
4386
4419
|
}
|
|
4387
4420
|
}
|
|
4388
4421
|
function claudeCredentialsPath(configDir) {
|
|
4389
|
-
const root = configDir?.trim() || process.env.CLAUDE_CONFIG_DIR?.trim() ||
|
|
4390
|
-
return
|
|
4422
|
+
const root = configDir?.trim() || process.env.CLAUDE_CONFIG_DIR?.trim() || join10(homedir7(), ".claude");
|
|
4423
|
+
return join10(root, ".credentials.json");
|
|
4391
4424
|
}
|
|
4392
4425
|
async function readFileAccessToken(configDir) {
|
|
4393
4426
|
const path = claudeCredentialsPath(configDir);
|
|
4394
|
-
if (!
|
|
4427
|
+
if (!existsSync12(path)) return null;
|
|
4395
4428
|
try {
|
|
4396
4429
|
return accessTokenFromCredentialsJson(readFileSync5(path, "utf8"));
|
|
4397
4430
|
} catch {
|