@sideboard-ai/core 0.1.323 → 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.
Files changed (83) hide show
  1. package/dist/{abletime-5ZY3ZUUO.js → abletime-M7STTMZT.js} +6 -5
  2. package/dist/{abletime-CU2UPMJF.js → abletime-VL234MCP.js} +5 -4
  3. package/dist/{abletime-oauth-7EOSBEFM.js → abletime-oauth-LMMGMAPA.js} +3 -3
  4. package/dist/{abletime-oauth-4TTCR3CT.js → abletime-oauth-P4ZFBEAL.js} +3 -3
  5. package/dist/{abletime-rest-3TG4G7LW.js → abletime-rest-DLV7EIWS.js} +3 -3
  6. package/dist/{abletime-rest-KOKE7V4B.js → abletime-rest-GOI7HELR.js} +3 -3
  7. package/dist/agents/claude-runner.cjs +59 -22
  8. package/dist/agents/claude-runner.js +39 -16
  9. package/dist/agents/cursor-runner.cjs +96 -31
  10. package/dist/agents/cursor-runner.js +74 -24
  11. package/dist/{agents-2ZXORBEJ.js → agents-LDRM3BTY.js} +9 -8
  12. package/dist/{agents-SPRAOMGI.js → agents-MBIEAETM.js} +12 -11
  13. package/dist/{app-settings-I5HM5RMP.js → app-settings-E7DMMEKC.js} +1 -1
  14. package/dist/{app-settings-XIF4EC4K.js → app-settings-UQHUNOLV.js} +1 -1
  15. package/dist/{chunk-INBUV7HY.js → chunk-2UP3XD2D.js} +2 -2
  16. package/dist/{chunk-EQ52JR3Q.js → chunk-5MXLDDYF.js} +1 -1
  17. package/dist/{chunk-NCHOTN3C.js → chunk-5YCKATG6.js} +4 -3
  18. package/dist/{chunk-SKO7IGKU.js → chunk-7G27TB4M.js} +6 -6
  19. package/dist/chunk-7LUOLYFM.js +1445 -0
  20. package/dist/{chunk-Y3WREIPQ.js → chunk-A76MKMSF.js} +12 -210
  21. package/dist/{chunk-6W3XRKD5.js → chunk-APKUI4BP.js} +6 -7
  22. package/dist/{chunk-FR3SAYUL.js → chunk-AQEKPJWU.js} +5 -5
  23. package/dist/{chunk-QOS4465Y.js → chunk-BOFYI6LC.js} +1 -1
  24. package/dist/{chunk-FUFNMUNR.js → chunk-BTF3ATST.js} +7 -8
  25. package/dist/{chunk-OIHRC2ZJ.js → chunk-CI4M54LS.js} +22 -2
  26. package/dist/chunk-DBKHL7NC.js +214 -0
  27. package/dist/{chunk-ROOZDDFA.js → chunk-EO6ZFLG6.js} +7 -8
  28. package/dist/chunk-EZR6W4B3.js +1259 -0
  29. package/dist/{chunk-MZIZTSR2.js → chunk-F65JMKUR.js} +2 -2
  30. package/dist/chunk-F6GE7V3Q.js +216 -0
  31. package/dist/{chunk-4C5PQ7JA.js → chunk-GNLKBS3U.js} +206 -188
  32. package/dist/{chunk-EKU7FQVG.js → chunk-H36GKGU2.js} +2 -2
  33. package/dist/{chunk-53SBTCKF.js → chunk-HG6KS7OT.js} +294 -265
  34. package/dist/chunk-MBT6WDAB.js +28 -0
  35. package/dist/{chunk-D3VSKNVA.js → chunk-MFMDZAA6.js} +262 -233
  36. package/dist/{chunk-7PVT73H6.js → chunk-NWGINMEA.js} +12 -210
  37. package/dist/{chunk-QIC2JXHW.js → chunk-OOXRMTU6.js} +1 -1
  38. package/dist/{chunk-5XNT6BCG.js → chunk-OPXEJJBM.js} +1 -1
  39. package/dist/chunk-OYRN356W.js +80 -0
  40. package/dist/chunk-PPTJMBUY.js +25 -0
  41. package/dist/{chunk-B4CDSSRN.js → chunk-Q3FHTGIW.js} +2 -0
  42. package/dist/{chunk-EJ66LEKH.js → chunk-RZJTGBXY.js} +22 -2
  43. package/dist/{chunk-JDX3474T.js → chunk-SACHHTBJ.js} +207 -186
  44. package/dist/{chunk-5GDJSFCT.js → chunk-SK6NYGPD.js} +2 -2
  45. package/dist/{chunk-74OPNF7U.js → chunk-SQQBU7Z6.js} +2 -2
  46. package/dist/{chunk-Q3YJZPQI.js → chunk-SS6CYGLF.js} +3 -3
  47. package/dist/{chunk-YDUHLWI5.js → chunk-SUZOPJZC.js} +21 -7
  48. package/dist/{chunk-ZHGMRBSC.js → chunk-U5WO6MEB.js} +3 -3
  49. package/dist/{chunk-NXUN4U5P.js → chunk-VAFQS4D2.js} +2 -2
  50. package/dist/chunk-W3ZLE4PO.js +77 -0
  51. package/dist/{chunk-RTVS3M74.js → chunk-WYEST76H.js} +7 -7
  52. package/dist/{chunk-ODH3XHMI.js → chunk-ZEUMWHOH.js} +5 -5
  53. package/dist/{chunk-MYVKOIIY.js → chunk-ZHDXLDLA.js} +6 -7
  54. package/dist/{chunk-IFWGG2M2.js → chunk-ZSHS46V5.js} +2 -0
  55. package/dist/{conductor-52KTQ3IM.js → conductor-D4KFZF54.js} +6 -6
  56. package/dist/{conductor-FB7MKLRN.js → conductor-KB7L7NQN.js} +7 -7
  57. package/dist/{coordinator-prompt-7HXV7HJ5.js → coordinator-prompt-OBXEC63K.js} +4 -4
  58. package/dist/{coordinator-prompt-7W7WPY4X.js → coordinator-prompt-SUO4FRY3.js} +4 -4
  59. package/dist/{cursor-recover-TEBFKAZ4.js → cursor-recover-7F46PAJ5.js} +1 -1
  60. package/dist/{cursor-recover-OWPQUHFH.js → cursor-recover-BDIAZIE3.js} +1 -1
  61. package/dist/{global-workspace-EI3KBGZE.js → global-workspace-UHU2FXTY.js} +4 -4
  62. package/dist/{global-workspace-5BWUTSPJ.js → global-workspace-Z2SURNHA.js} +4 -4
  63. package/dist/index.cjs +21115 -20868
  64. package/dist/index.d.cts +28 -12
  65. package/dist/index.d.ts +28 -12
  66. package/dist/index.js +343 -1678
  67. package/dist/linear-HFUOUJ5H.js +67 -0
  68. package/dist/linear-SIHEBU3X.js +69 -0
  69. package/dist/linear-list-63I7QUC6.js +6 -0
  70. package/dist/linear-list-JFV3EES6.js +8 -0
  71. package/dist/mcp/run-stdio.cjs +15909 -15654
  72. package/dist/mcp/run-stdio.js +67 -1247
  73. package/dist/{optional-cli-RMMS5L6F.js → optional-cli-U2GUA2X6.js} +3 -3
  74. package/dist/{optional-cli-Y3Z3GIPZ.js → optional-cli-ULDP3O5S.js} +4 -4
  75. package/dist/{orchestrator-RMPZETOO.js → orchestrator-3H4KNGPN.js} +15 -13
  76. package/dist/{orchestrator-2RDE2YS3.js → orchestrator-6ROMEWBP.js} +14 -12
  77. package/dist/{thread-store-3F7GR64A.js → thread-store-4ZN3DS2W.js} +1 -1
  78. package/dist/{thread-store-JRSL4HQY.js → thread-store-IC4BQXDW.js} +1 -1
  79. package/dist/{workspaces-LJQS73K6.js → workspaces-MG5JHRKW.js} +4 -4
  80. package/dist/{workspaces-OPQ5NMM6.js → workspaces-QJNKEGEM.js} +4 -4
  81. package/dist/{worktree-ZDA2UJ7C.js → worktree-KSJPTHGZ.js} +3 -3
  82. package/dist/{worktree-4NGXCCUO.js → worktree-MYJYUHZM.js} +3 -3
  83. 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-PPTJMBUY.js";
7
10
  import {
8
11
  looksLikeConversationSummary,
9
12
  looksLikeSkillBody,
10
13
  skillCommandFromBody,
11
14
  withEventParentId
12
- } from "./chunk-QIC2JXHW.js";
15
+ } from "./chunk-OOXRMTU6.js";
13
16
  import {
14
17
  isOrchestratorThread
15
- } from "./chunk-6W3XRKD5.js";
18
+ } from "./chunk-APKUI4BP.js";
16
19
  import {
17
20
  codexUnattendedGitConfigArgs,
18
21
  mergeAgentGitAuthEnv,
19
22
  resolveAgentGitAuthEnv,
20
23
  resolveCodexGitWritableRoots
21
- } from "./chunk-FUFNMUNR.js";
24
+ } from "./chunk-BTF3ATST.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-ZHGMRBSC.js";
51
+ } from "./chunk-U5WO6MEB.js";
49
52
  import {
50
53
  extractJsonErrorMessage,
51
54
  formatUnknownDetail,
52
55
  looksLikeAgentFailureMessage,
53
56
  looksLikeBrightsyEmptyCompletion
54
- } from "./chunk-5XNT6BCG.js";
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-YDUHLWI5.js";
72
+ } from "./chunk-SUZOPJZC.js";
70
73
  import {
71
74
  claudeChromeEnabled,
72
75
  fromInclusiveInputUsage,
@@ -76,7 +79,7 @@ import {
76
79
  loadAppSettings,
77
80
  resolveAgentExecutable,
78
81
  resolveClaudeExecutable
79
- } from "./chunk-EJ66LEKH.js";
82
+ } from "./chunk-RZJTGBXY.js";
80
83
  import {
81
84
  isElectronLikeCommand,
82
85
  unwrapStrippedElectronLaunch
@@ -514,6 +517,7 @@ var brightsyAdapter = {
514
517
 
515
518
  // src/agents/claude.ts
516
519
  import { existsSync as existsSync7 } from "fs";
520
+ import { dirname as dirname4 } from "path";
517
521
 
518
522
  // src/agents/claude-mcp-status.ts
519
523
  var SIDEBOARD_CONNECTOR_SERVICES = [
@@ -630,7 +634,7 @@ function isNotableMcpInitStatus(server, sideboardOk, coverage) {
630
634
 
631
635
  // src/mcp-ui/host.ts
632
636
  import { createHash } from "crypto";
633
- import { homedir as homedir4 } from "os";
637
+ import { homedir as homedir5 } from "os";
634
638
 
635
639
  // src/agents/orch-mcp-isolation.ts
636
640
  import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
@@ -987,20 +991,20 @@ function readJson(path) {
987
991
  }
988
992
 
989
993
  // src/agents/orch-mcp-isolation.ts
990
- import { homedir as homedir3 } from "os";
991
- import { join as join4 } from "path";
994
+ import { homedir as homedir4 } from "os";
995
+ import { join as join5 } from "path";
992
996
  import { parse as parseToml } from "smol-toml";
993
997
 
994
998
  // src/agents/user-mcp-config.ts
995
- import { existsSync as existsSync4, mkdirSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
996
- import { homedir as homedir2 } from "os";
997
- import { dirname as dirname2, join as join3 } from "path";
999
+ import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
1000
+ import { homedir as homedir3 } from "os";
1001
+ import { dirname as dirname2, join as join4 } from "path";
998
1002
 
999
1003
  // src/agents/injected-mcp.ts
1000
- import { existsSync as existsSync3, mkdtempSync, writeFileSync } from "fs";
1004
+ import { existsSync as existsSync3, mkdtempSync, writeFileSync as writeFileSync2 } from "fs";
1001
1005
  import { createRequire } from "module";
1002
1006
  import { tmpdir } from "os";
1003
- import { dirname, join as join2 } from "path";
1007
+ import { dirname, join as join3 } from "path";
1004
1008
  import { fileURLToPath } from "url";
1005
1009
 
1006
1010
  // src/mcp/profile.ts
@@ -1095,6 +1099,44 @@ function sideboardMcpProfile(env = process.env) {
1095
1099
  return env[SIDEBOARD_MCP_PROFILE_ENV]?.trim().toLowerCase() === "worktree" ? "worktree" : "orchestration";
1096
1100
  }
1097
1101
 
1102
+ // src/agents/codex-mcp-profile.ts
1103
+ import { randomBytes } from "crypto";
1104
+ import { mkdirSync, writeFileSync } from "fs";
1105
+ import { homedir as homedir2 } from "os";
1106
+ import { join as join2 } from "path";
1107
+ function isCodexSecretEnvKey(key) {
1108
+ return /token|secret|password|credential|oauth|api_key|_key$/i.test(key);
1109
+ }
1110
+ function tomlBasicString(value) {
1111
+ return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r")}"`;
1112
+ }
1113
+ function secretEnv(env) {
1114
+ if (!env) return void 0;
1115
+ const out = { ...env };
1116
+ delete out.ELECTRON_RUN_AS_NODE;
1117
+ return Object.keys(out).length > 0 ? out : void 0;
1118
+ }
1119
+ function writeCodexMcpSecretProfile(servers) {
1120
+ const blocks = [];
1121
+ for (const s of servers) {
1122
+ const env = secretEnv(s.env);
1123
+ if (!env) continue;
1124
+ const secrets = Object.entries(env).filter(([key]) => isCodexSecretEnvKey(key));
1125
+ if (secrets.length === 0) continue;
1126
+ const lines = [`[mcp_servers.${s.name}.env]`];
1127
+ for (const [key, value] of secrets) lines.push(`${key} = ${tomlBasicString(value)}`);
1128
+ blocks.push(lines.join("\n"));
1129
+ }
1130
+ if (blocks.length === 0) return null;
1131
+ const home = process.env.CODEX_HOME?.trim() || join2(homedir2(), ".codex");
1132
+ mkdirSync(home, { recursive: true, mode: 448 });
1133
+ const profile = `sideboard-${randomBytes(8).toString("hex")}`;
1134
+ const file = join2(home, `${profile}.config.toml`);
1135
+ writeFileSync(file, `${blocks.join("\n\n")}
1136
+ `, { mode: 384 });
1137
+ return { profile, file };
1138
+ }
1139
+
1098
1140
  // src/agents/injected-mcp.ts
1099
1141
  var SIDEBOARD_MCP_ALLOWED_TOOLS = [
1100
1142
  "mcp__sideboard",
@@ -1234,7 +1276,7 @@ function corePackageDir() {
1234
1276
  } catch {
1235
1277
  }
1236
1278
  try {
1237
- const req = createRequire(join2(process.cwd(), "package.json"));
1279
+ const req = createRequire(join3(process.cwd(), "package.json"));
1238
1280
  return dirname(req.resolve("@sideboard-ai/core"));
1239
1281
  } catch {
1240
1282
  return process.cwd();
@@ -1248,13 +1290,13 @@ function findSideboardMcpJsEntry() {
1248
1290
  let dir = corePackageDir();
1249
1291
  for (let i = 0; i < 10; i++) {
1250
1292
  const candidates = [
1251
- join2(dir, "mcp/run-stdio.js"),
1252
- join2(dir, "mcp/run-stdio.cjs"),
1253
- join2(dir, "dist/mcp/run-stdio.js"),
1254
- join2(dir, "dist/mcp/run-stdio.cjs"),
1255
- join2(dir, "packages/core/dist/mcp/run-stdio.js"),
1256
- join2(dir, "packages/cli/dist/index.js"),
1257
- join2(dir, "cli/dist/index.js")
1293
+ join3(dir, "mcp/run-stdio.js"),
1294
+ join3(dir, "mcp/run-stdio.cjs"),
1295
+ join3(dir, "dist/mcp/run-stdio.js"),
1296
+ join3(dir, "dist/mcp/run-stdio.cjs"),
1297
+ join3(dir, "packages/core/dist/mcp/run-stdio.js"),
1298
+ join3(dir, "packages/cli/dist/index.js"),
1299
+ join3(dir, "cli/dist/index.js")
1258
1300
  ];
1259
1301
  for (const p of candidates) {
1260
1302
  if (existsSync3(p) && !isAsarPath(p)) return p;
@@ -1362,6 +1404,7 @@ function toCodexMcpConfigArgs(servers) {
1362
1404
  const env = mcpSpawnEnv(s.env);
1363
1405
  if (env) {
1364
1406
  for (const [key, value] of Object.entries(env)) {
1407
+ if (isCodexSecretEnvKey(key)) continue;
1365
1408
  args.push("-c", `${prefix}.env.${key}=${JSON.stringify(value)}`);
1366
1409
  }
1367
1410
  }
@@ -1420,9 +1463,9 @@ function mcpServersRecord(servers, extraServers) {
1420
1463
  function writeMcpServersConfig(servers, extraServers) {
1421
1464
  const mcpServers = mcpServersRecord(servers, extraServers);
1422
1465
  if (Object.keys(mcpServers).length === 0) return null;
1423
- const dir = mkdtempSync(join2(tmpdir(), "sideboard-mcp-"));
1424
- const cfgPath = join2(dir, "mcp.json");
1425
- writeFileSync(cfgPath, JSON.stringify({ mcpServers }, null, 2));
1466
+ const dir = mkdtempSync(join3(tmpdir(), "sideboard-mcp-"));
1467
+ const cfgPath = join3(dir, "mcp.json");
1468
+ writeFileSync2(cfgPath, JSON.stringify({ mcpServers }, null, 2), { mode: 384 });
1426
1469
  return cfgPath;
1427
1470
  }
1428
1471
  async function writeInjectedMcpConfig(opts) {
@@ -1431,10 +1474,10 @@ async function writeInjectedMcpConfig(opts) {
1431
1474
 
1432
1475
  // src/agents/user-mcp-config.ts
1433
1476
  function userCursorMcpConfigPath() {
1434
- return join3(homedir2(), ".cursor", "mcp.json");
1477
+ return join4(homedir3(), ".cursor", "mcp.json");
1435
1478
  }
1436
1479
  function userClaudeMcpConfigPath() {
1437
- return join3(homedir2(), ".claude.json");
1480
+ return join4(homedir3(), ".claude.json");
1438
1481
  }
1439
1482
  function asObject(value) {
1440
1483
  if (!value || typeof value !== "object" || Array.isArray(value)) return {};
@@ -1469,8 +1512,8 @@ function writeMergedMcpServersJson(configPath, sideboard) {
1469
1512
  }
1470
1513
  }
1471
1514
  const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
1472
- mkdirSync(dirname2(configPath), { recursive: true });
1473
- writeFileSync2(configPath, `${JSON.stringify(next, null, 2)}
1515
+ mkdirSync2(dirname2(configPath), { recursive: true });
1516
+ writeFileSync3(configPath, `${JSON.stringify(next, null, 2)}
1474
1517
  `);
1475
1518
  }
1476
1519
  function launchFromResolved(server) {
@@ -1529,13 +1572,19 @@ function readText(path) {
1529
1572
  return "";
1530
1573
  }
1531
1574
  }
1532
- function userCodexConfigPaths(home = homedir3()) {
1533
- return [join4(home, ".codex", "config.toml"), join4(home, ".config", "codex", "config.toml")];
1575
+ function userCodexConfigPaths(home = homedir4()) {
1576
+ const paths = [
1577
+ join5(home, ".codex", "config.toml"),
1578
+ join5(home, ".config", "codex", "config.toml")
1579
+ ];
1580
+ const codexHome = process.env.CODEX_HOME?.trim();
1581
+ if (codexHome) paths.unshift(join5(codexHome, "config.toml"));
1582
+ return paths;
1534
1583
  }
1535
- function userOpencodeConfigPaths(home = homedir3()) {
1584
+ function userOpencodeConfigPaths(home = homedir4()) {
1536
1585
  return [
1537
- join4(home, ".config", "opencode", "opencode.json"),
1538
- join4(home, ".config", "opencode", "opencode.jsonc")
1586
+ join5(home, ".config", "opencode", "opencode.json"),
1587
+ join5(home, ".config", "opencode", "opencode.jsonc")
1539
1588
  ];
1540
1589
  }
1541
1590
  function userMcpNamesToDisable(opts) {
@@ -1554,7 +1603,7 @@ function userMcpNamesToDisable(opts) {
1554
1603
  }
1555
1604
  return out;
1556
1605
  }
1557
- function listUserCodexMcpNames(home = homedir3()) {
1606
+ function listUserCodexMcpNames(home = homedir4()) {
1558
1607
  const names = [];
1559
1608
  for (const path of userCodexConfigPaths(home)) {
1560
1609
  if (!existsSync5(path)) continue;
@@ -1562,7 +1611,7 @@ function listUserCodexMcpNames(home = homedir3()) {
1562
1611
  }
1563
1612
  return names;
1564
1613
  }
1565
- function listUserOpencodeMcpNames(home = homedir3()) {
1614
+ function listUserOpencodeMcpNames(home = homedir4()) {
1566
1615
  const names = [];
1567
1616
  for (const path of userOpencodeConfigPaths(home)) {
1568
1617
  if (!existsSync5(path)) continue;
@@ -1570,12 +1619,12 @@ function listUserOpencodeMcpNames(home = homedir3()) {
1570
1619
  }
1571
1620
  return names;
1572
1621
  }
1573
- function userClaudeMcpConfigObject(home = homedir3()) {
1574
- const claudePath = home === homedir3() ? userClaudeMcpConfigPath() : join4(home, ".claude.json");
1622
+ function userClaudeMcpConfigObject(home = homedir4()) {
1623
+ const claudePath = home === homedir4() ? userClaudeMcpConfigPath() : join5(home, ".claude.json");
1575
1624
  if (!existsSync5(claudePath)) return {};
1576
1625
  return asObject2(asObject2(readJsonObject(claudePath)).mcpServers);
1577
1626
  }
1578
- function listUserClaudeMcpServerEntries(home = homedir3(), projectDirs) {
1627
+ function listUserClaudeMcpServerEntries(home = homedir4(), projectDirs) {
1579
1628
  const out = {};
1580
1629
  for (const [name, entry] of Object.entries(
1581
1630
  listEnabledClaudePluginMcpServers({ home, projectDirs })
@@ -1613,7 +1662,7 @@ function toCodexUnattendedAppsArgs() {
1613
1662
  }
1614
1663
 
1615
1664
  // src/mcp-ui/proxy-http.ts
1616
- import { randomBytes, randomUUID } from "crypto";
1665
+ import { randomBytes as randomBytes2, randomUUID } from "crypto";
1617
1666
  import { createServer } from "http";
1618
1667
  import { Server as Server2 } from "@modelcontextprotocol/sdk/server/index.js";
1619
1668
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
@@ -1710,7 +1759,7 @@ function listedTool(tool) {
1710
1759
 
1711
1760
  // src/mcp-ui/proxy-http.ts
1712
1761
  async function listenMcpUiProxy(opts) {
1713
- const token = randomBytes(24).toString("hex");
1762
+ const token = randomBytes2(24).toString("hex");
1714
1763
  const transports = /* @__PURE__ */ new Map();
1715
1764
  const httpServer = createServer((req, res) => {
1716
1765
  void handle(req, res);
@@ -2083,7 +2132,7 @@ var singleton;
2083
2132
  function getMcpUiHost() {
2084
2133
  if (!singleton) {
2085
2134
  singleton = new McpUiHost({
2086
- entries: (projectDirs) => listUserClaudeMcpServerEntries(homedir4(), projectDirs)
2135
+ entries: (projectDirs) => listUserClaudeMcpServerEntries(homedir5(), projectDirs)
2087
2136
  });
2088
2137
  }
2089
2138
  return singleton;
@@ -2091,7 +2140,7 @@ function getMcpUiHost() {
2091
2140
  async function proxyClaudeUserMcp(orchestrator, projectDirs) {
2092
2141
  if (orchestrator) return {};
2093
2142
  const dirs = projectDirs.filter((d) => typeof d === "string" && d.length > 0);
2094
- return getMcpUiHost().proxyEntries(listUserClaudeMcpServerEntries(homedir4(), dirs), dirs);
2143
+ return getMcpUiHost().proxyEntries(listUserClaudeMcpServerEntries(homedir5(), dirs), dirs);
2095
2144
  }
2096
2145
  function closeMcpUiHost() {
2097
2146
  const host = singleton;
@@ -2110,16 +2159,6 @@ function planModeTurnInstruction(planMode) {
2110
2159
  return planMode ? PLAN_MODE_INSTRUCTION : PLAN_MODE_OFF_INSTRUCTION;
2111
2160
  }
2112
2161
  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
2162
  if (thread.planMode) {
2124
2163
  return {
2125
2164
  claude: "plan",
@@ -2131,6 +2170,18 @@ function permissionMode(thread) {
2131
2170
  codexSandbox: "read-only"
2132
2171
  };
2133
2172
  }
2173
+ if (thread.sourceType === "orchestration") {
2174
+ return {
2175
+ claude: "acceptEdits",
2176
+ // Unattended coordinators cannot answer permission prompts. Explicit
2177
+ // allows override the user's OpenCode denies for this process only.
2178
+ opencodePermission: JSON.stringify({
2179
+ edit: "allow",
2180
+ bash: { "*": "allow" }
2181
+ }),
2182
+ codexSandbox: "danger-full-access"
2183
+ };
2184
+ }
2134
2185
  if (thread.autonomy === "full") {
2135
2186
  return {
2136
2187
  claude: "bypassPermissions",
@@ -2140,10 +2191,7 @@ function permissionMode(thread) {
2140
2191
  }
2141
2192
  return {
2142
2193
  claude: "acceptEdits",
2143
- opencodePermission: JSON.stringify({
2144
- edit: "allow",
2145
- bash: { "*": "allow", "rm -rf *": "deny" }
2146
- }),
2194
+ opencodePermission: JSON.stringify({}),
2147
2195
  codexSandbox: "workspace-write"
2148
2196
  };
2149
2197
  }
@@ -2164,7 +2212,7 @@ function agentRpcChildEnv(rpc, cwd) {
2164
2212
  // src/agents/claude-host.ts
2165
2213
  import { existsSync as existsSync6 } from "fs";
2166
2214
  import { createRequire as createRequire2 } from "module";
2167
- import { dirname as dirname3, join as join5 } from "path";
2215
+ import { dirname as dirname3, join as join6 } from "path";
2168
2216
  import { fileURLToPath as fileURLToPath2 } from "url";
2169
2217
  function claudePilotSdkAllowedTools() {
2170
2218
  return PILOT_TOOL_NAMES.map(
@@ -2192,17 +2240,17 @@ function entryDir() {
2192
2240
  function claudeRunnerPath() {
2193
2241
  const packagedDir = packagedCursorRuntimeDir();
2194
2242
  if (packagedDir) {
2195
- const packaged = join5(packagedDir, "core-dist", "agents", "claude-runner.js");
2243
+ const packaged = join6(packagedDir, "core-dist", "agents", "claude-runner.js");
2196
2244
  if (existsSync6(packaged)) return packaged;
2197
2245
  }
2198
2246
  const root = entryDir();
2199
2247
  const candidates = [
2200
- join5(root, "agents", "claude-runner.js"),
2201
- join5(root, "agents", "claude-runner.cjs"),
2202
- join5(root, "dist", "agents", "claude-runner.js"),
2203
- join5(root, "dist", "agents", "claude-runner.cjs"),
2204
- join5(root, "claude-runner.ts"),
2205
- join5(root, "src", "agents", "claude-runner.ts")
2248
+ join6(root, "agents", "claude-runner.js"),
2249
+ join6(root, "agents", "claude-runner.cjs"),
2250
+ join6(root, "dist", "agents", "claude-runner.js"),
2251
+ join6(root, "dist", "agents", "claude-runner.cjs"),
2252
+ join6(root, "claude-runner.ts"),
2253
+ join6(root, "src", "agents", "claude-runner.ts")
2206
2254
  ];
2207
2255
  for (const candidate of candidates) {
2208
2256
  if (existsSync6(candidate)) return candidate;
@@ -2281,7 +2329,8 @@ function sessionCostUsdFromClaudeResult(obj) {
2281
2329
  function claudeResultErrorDetail(obj) {
2282
2330
  const isError = Boolean(obj.is_error) || typeof obj.subtype === "string" && /^error/i.test(obj.subtype);
2283
2331
  const fromResult = typeof obj.result === "string" ? obj.result.trim() : "";
2284
- if (fromResult && (isError || looksLikeAgentFailureMessage(fromResult))) {
2332
+ const shortFailure = fromResult.length > 0 && fromResult.length <= 300 && !fromResult.includes("\n") && looksLikeAgentFailureMessage(fromResult);
2333
+ if (fromResult && (isError || shortFailure)) {
2285
2334
  return fromResult;
2286
2335
  }
2287
2336
  if (!isError) return null;
@@ -2528,7 +2577,7 @@ function eventsFromClaudeSystem(obj) {
2528
2577
  data: `Context compressed${trigger}`,
2529
2578
  replace: true
2530
2579
  };
2531
- if (meta.postTokens != null && meta.postTokens > 0) {
2580
+ if (meta.postTokens != null && meta.postTokens > 0 && !parentId) {
2532
2581
  return [
2533
2582
  thinking,
2534
2583
  {
@@ -2609,7 +2658,7 @@ var claudeAdapter = {
2609
2658
  );
2610
2659
  }
2611
2660
  const mode = permissionMode(thread);
2612
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-5BWUTSPJ.js");
2661
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-Z2SURNHA.js");
2613
2662
  const isOrchestrator = isOrchestratorThread2(thread);
2614
2663
  const rpc = worktreeAgentRpc(isOrchestrator);
2615
2664
  const injectedServers = await buildInjectedMcpServers({
@@ -2709,6 +2758,7 @@ var claudeAdapter = {
2709
2758
  cwd: thread.worktreePath,
2710
2759
  stdin: useStdin ? `${promptText}
2711
2760
  ` : void 0,
2761
+ ...mcpConfigPath ? { cleanupDirs: [dirname4(mcpConfigPath)] } : {},
2712
2762
  // Nested Task/Agent thinking+text in stream-json (Claude Code 2.1.211+).
2713
2763
  // Raise the -p background-agent wait so long TaskOutput polls are not
2714
2764
  // abandoned at Claude Code’s 10-minute default.
@@ -2738,9 +2788,17 @@ var claudeAdapter = {
2738
2788
  Array.isArray(message?.content) ? message.content : void 0,
2739
2789
  parentId
2740
2790
  );
2741
- if (obj.type === "assistant") {
2791
+ if (obj.type === "assistant" && !parentId) {
2742
2792
  const usage = usageFromClaude(message?.usage);
2743
- if (usage) events.push({ type: "usage", data: usage, scope: "request" });
2793
+ const messageId = message && typeof message.id === "string" ? message.id : void 0;
2794
+ if (usage) {
2795
+ events.push({
2796
+ type: "usage",
2797
+ data: usage,
2798
+ scope: "request",
2799
+ ...messageId ? { messageId } : {}
2800
+ });
2801
+ }
2744
2802
  }
2745
2803
  if (events.length === 0) return null;
2746
2804
  return events.length === 1 ? events[0] : events;
@@ -2827,56 +2885,47 @@ var claudeAdapter = {
2827
2885
  return { file: claude, args, cwd: thread.worktreePath };
2828
2886
  },
2829
2887
  async listLinearIssues(_repoPath) {
2830
- const claude = resolveClaudeExecutable();
2831
- const prompt = "List my assigned Linear issues as JSON array only, no markdown. Each item: id, identifier, title, url, labels (string[]).";
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);
2888
+ const { listAssignedLinearIssues: listAssignedLinearIssues2 } = await import("./linear-list-63I7QUC6.js");
2889
+ return listAssignedLinearIssues2();
2848
2890
  }
2849
2891
  };
2850
- function parseIssuesJson(raw) {
2851
- const text = raw.trim();
2852
- const candidates = [text];
2853
- const match = text.match(/\[[\s\S]*\]/);
2854
- if (match) candidates.push(match[0]);
2855
- for (const c of candidates) {
2856
- try {
2857
- const parsed = JSON.parse(c);
2858
- if (Array.isArray(parsed)) {
2859
- return parsed.map((item) => ({
2860
- id: String(item.id ?? item.identifier ?? ""),
2861
- identifier: String(item.identifier ?? item.id ?? ""),
2862
- title: String(item.title ?? ""),
2863
- url: String(item.url ?? ""),
2864
- labels: Array.isArray(item.labels) ? item.labels.map(String) : []
2865
- }));
2866
- }
2867
- if (parsed && typeof parsed === "object" && typeof parsed.result === "string") {
2868
- return parseIssuesJson(parsed.result);
2869
- }
2870
- } catch {
2892
+
2893
+ // src/agents/codex.ts
2894
+ import { existsSync as existsSync8, statSync } from "fs";
2895
+ import { homedir as homedir6 } from "os";
2896
+ import { join as join7 } from "path";
2897
+
2898
+ // src/agents/codex-items.ts
2899
+ function eventsFromCodexItem(eventType, item) {
2900
+ const itemType = item.type ?? item.item_type;
2901
+ if (itemType === "reasoning" && typeof item.text === "string" && item.text) {
2902
+ return { type: "thinking", data: item.text };
2903
+ }
2904
+ if (itemType !== "file_change" || !item.id) return null;
2905
+ const changes = Array.isArray(item.changes) ? item.changes : [];
2906
+ const paths = changes.map((change) => typeof change?.path === "string" ? change.path : "").filter(Boolean);
2907
+ const added = changes.some((change) => change?.kind === "add");
2908
+ const events = [
2909
+ {
2910
+ type: "tool_use",
2911
+ id: item.id,
2912
+ name: added ? "Write" : "Edit",
2913
+ input: paths.length ? { paths } : void 0
2871
2914
  }
2915
+ ];
2916
+ const finished = eventType === "item.completed" || item.status === "completed" || item.status === "failed";
2917
+ if (finished) {
2918
+ events.push({
2919
+ type: "tool_result",
2920
+ id: item.id,
2921
+ content: paths.join("\n") || void 0,
2922
+ isError: item.status === "failed"
2923
+ });
2872
2924
  }
2873
- return [];
2925
+ return events.length === 1 ? events[0] : events;
2874
2926
  }
2875
2927
 
2876
2928
  // 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
2929
  var CODEX_PROMPT_ARG_MAX = 2e5;
2881
2930
  var FALLBACK_CODEX_MODELS = [
2882
2931
  { id: "gpt-5.6-sol", displayName: "GPT-5.6 Sol" },
@@ -2929,17 +2978,8 @@ function usageFromCodex(usage) {
2929
2978
  cachedInputTokens: Number(usage.cached_input_tokens ?? 0)
2930
2979
  });
2931
2980
  }
2932
- function codexConfigHasNetworkAccess() {
2933
- const candidates = [
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;
2981
+ function codexHomeDir() {
2982
+ return process.env.CODEX_HOME?.trim() || join7(homedir6(), ".codex");
2943
2983
  }
2944
2984
  function unwrapCodexMcpResult(result) {
2945
2985
  if (result == null) return void 0;
@@ -2968,7 +3008,7 @@ function asRecord3(value) {
2968
3008
  return void 0;
2969
3009
  }
2970
3010
  function codexLooksAuthenticated() {
2971
- const authPath = join6(homedir5(), ".codex", "auth.json");
3011
+ const authPath = join7(codexHomeDir(), "auth.json");
2972
3012
  if (!existsSync8(authPath)) return false;
2973
3013
  try {
2974
3014
  return statSync(authPath).size > 2;
@@ -3007,18 +3047,13 @@ var codexAdapter = {
3007
3047
  const authenticated = codexLooksAuthenticated();
3008
3048
  const linearMcp = false;
3009
3049
  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
3050
  return {
3016
3051
  agent: "codex",
3017
3052
  installed: true,
3018
3053
  authenticated,
3019
3054
  linearMcp,
3020
3055
  warnings,
3021
- reason: authenticated ? void 0 : "Codex auth not found \u2014 run `codex login` (expected ~/.codex/auth.json)"
3056
+ reason: authenticated ? void 0 : `Codex auth not found \u2014 run \`codex login\` (expected ${join7(codexHomeDir(), "auth.json")})`
3022
3057
  };
3023
3058
  },
3024
3059
  async buildTurn(thread, input) {
@@ -3043,6 +3078,12 @@ var codexAdapter = {
3043
3078
  threadId: thread.id
3044
3079
  });
3045
3080
  const isolatePlugins = isOrchestrator || Boolean(thread.isolateCodexPlugins) || Boolean(normalizeTurnInput(input).isolateCodexPlugins);
3081
+ const gitEnv = await resolveAgentGitAuthEnv(process.env, {
3082
+ cwd: thread.worktreePath
3083
+ });
3084
+ const writableRoots = mode.codexSandbox === "workspace-write" ? await resolveCodexGitWritableRoots(thread.worktreePath) : [];
3085
+ const secretProfile = writeCodexMcpSecretProfile(injected);
3086
+ const effort = thread.effort?.trim() ?? "";
3046
3087
  const mcpOverrides = [
3047
3088
  // Worktree first try keeps plugins (Claude connectors). Coordinators
3048
3089
  // isolate. After a fatal plugin MCP, the orchestrator retries with
@@ -3059,6 +3100,7 @@ var codexAdapter = {
3059
3100
  const execOpts = [
3060
3101
  // Global orchestration cwd is not a git repo; without this Codex ≥0.147
3061
3102
  // refuses to start ("Not inside a trusted directory").
3103
+ ...secretProfile ? ["-p", secretProfile.profile] : [],
3062
3104
  "--skip-git-repo-check",
3063
3105
  "--cd",
3064
3106
  thread.worktreePath,
@@ -3068,14 +3110,16 @@ var codexAdapter = {
3068
3110
  // `codex exec` rejects `--ask-for-approval` (global-only on newer CLIs).
3069
3111
  "-c",
3070
3112
  'approval_policy="never"',
3071
- // Seatbelt cannot use the login Keychain; inherit GH_CONFIG_DIR / GIT_CONFIG_*.
3072
- // Default policy also strips *TOKEN*. Linked worktrees need the main
3073
- // repo `.git` (+ `.git/worktrees/<name>`) as writable_roots so git commit
3074
- // can create index.lock.
3113
+ // Seatbelt cannot use the login Keychain. inherit=all keeps GH_CONFIG_DIR
3114
+ // and GIT_CONFIG_*. Default excludes still strip *TOKEN*/*SECRET*/*KEY*;
3115
+ // GIT_CONFIG_KEY_n is re-set because it matches *KEY*. Linked worktrees
3116
+ // need the main repo `.git` as writable_roots so git commit can lock.
3075
3117
  ...codexUnattendedGitConfigArgs(mode.codexSandbox, {
3076
- writableRoots: mode.codexSandbox === "workspace-write" ? await resolveCodexGitWritableRoots(thread.worktreePath) : []
3118
+ writableRoots,
3119
+ preserveEnv: gitEnv
3077
3120
  }),
3078
3121
  ...model ? ["--model", model] : [],
3122
+ ...effort ? ["-c", `model_reasoning_effort=${JSON.stringify(effort)}`] : [],
3079
3123
  ...mcpOverrides
3080
3124
  ];
3081
3125
  const args = sessionId ? ["exec", ...execOpts, "resume", sessionId, promptArg] : ["exec", ...execOpts, promptArg];
@@ -3084,7 +3128,8 @@ var codexAdapter = {
3084
3128
  args,
3085
3129
  cwd: thread.worktreePath,
3086
3130
  stdin: useStdin ? `${prompt}
3087
- ` : void 0
3131
+ ` : void 0,
3132
+ ...secretProfile ? { cleanupDirs: [secretProfile.file] } : {}
3088
3133
  };
3089
3134
  },
3090
3135
  parseEvent(line) {
@@ -3105,8 +3150,10 @@ var codexAdapter = {
3105
3150
  if (typeof obj.item === "object" && obj.item !== null) {
3106
3151
  const item = obj.item;
3107
3152
  const itemType = item.type ?? item.item_type;
3153
+ const mapped = eventsFromCodexItem(type, item);
3154
+ if (mapped) return mapped;
3108
3155
  if (itemType === "error") {
3109
- const detail = item.message?.trim() || extractJsonErrorMessage(obj) || "Codex item error";
3156
+ const detail = (typeof item.message === "string" ? item.message.trim() : "") || extractJsonErrorMessage(obj) || "Codex item error";
3110
3157
  return { type: "stderr", data: detail };
3111
3158
  }
3112
3159
  if (itemType === "agent_message" && item.text) {
@@ -3135,14 +3182,14 @@ var codexAdapter = {
3135
3182
  const events = [
3136
3183
  { type: "tool_use", id: item.id, name: "Bash", input }
3137
3184
  ];
3138
- const finished = type === "item.completed" || item.status === "completed" || item.status === "failed";
3185
+ const finished = type === "item.completed" || item.status === "completed" || item.status === "failed" || item.status === "declined";
3139
3186
  const output = typeof item.aggregated_output === "string" && item.aggregated_output ? item.aggregated_output : void 0;
3140
3187
  if (finished) {
3141
3188
  events.push({
3142
3189
  type: "tool_result",
3143
3190
  id: item.id,
3144
3191
  content: output,
3145
- isError: item.status === "failed"
3192
+ isError: item.status === "failed" || item.status === "declined"
3146
3193
  });
3147
3194
  } else if (output) {
3148
3195
  events.push({
@@ -3185,7 +3232,7 @@ var codexAdapter = {
3185
3232
  return events.length === 1 ? events[0] : events;
3186
3233
  }
3187
3234
  if (item.status === "failed") {
3188
- const detail = item.message?.trim() || extractJsonErrorMessage(item) || `Codex ${itemType ?? "item"} failed`;
3235
+ const detail = (typeof item.message === "string" ? item.message.trim() : "") || extractJsonErrorMessage(item) || `Codex ${itemType ?? "item"} failed`;
3189
3236
  return { type: "stderr", data: detail };
3190
3237
  }
3191
3238
  }
@@ -3194,7 +3241,8 @@ var codexAdapter = {
3194
3241
  return { type: "session_id", data: sid };
3195
3242
  }
3196
3243
  if (type === "turn.completed" || type === "turn_completed") {
3197
- const usage = usageFromCodex(obj.usage);
3244
+ const payload = obj;
3245
+ const usage = usageFromCodex(payload.last_token_usage ?? payload.usage);
3198
3246
  return usage ? { type: "usage", data: usage, scope: "turn" } : null;
3199
3247
  }
3200
3248
  if (typeof obj.content === "string" && obj.content.trim()) {
@@ -3217,7 +3265,7 @@ var codexAdapter = {
3217
3265
  if (sessionId) {
3218
3266
  return {
3219
3267
  file: codex,
3220
- args: ["exec", "--cd", thread.worktreePath, "resume", sessionId],
3268
+ args: ["resume", sessionId],
3221
3269
  cwd: thread.worktreePath
3222
3270
  };
3223
3271
  }
@@ -3228,36 +3276,14 @@ var codexAdapter = {
3228
3276
  };
3229
3277
  },
3230
3278
  async listLinearIssues(_repoPath) {
3231
- const prompt = "List my assigned Linear issues as JSON array only: id, identifier, title, url, labels.";
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
- }
3279
+ return listAssignedLinearIssues();
3254
3280
  }
3255
3281
  };
3256
3282
 
3257
3283
  // src/agents/cursor.ts
3258
3284
  import { existsSync as existsSync9 } from "fs";
3259
3285
  import { createRequire as createRequire3 } from "module";
3260
- import { dirname as dirname4, join as join7 } from "path";
3286
+ import { dirname as dirname5, join as join8 } from "path";
3261
3287
  import { fileURLToPath as fileURLToPath3 } from "url";
3262
3288
  var FALLBACK_CURSOR_MODELS = [
3263
3289
  { id: "default", displayName: "Auto" },
@@ -3309,11 +3335,11 @@ function entryDir2() {
3309
3335
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
3310
3336
  if (cjsDir) return cjsDir;
3311
3337
  try {
3312
- return dirname4(fileURLToPath3(import.meta.url));
3338
+ return dirname5(fileURLToPath3(import.meta.url));
3313
3339
  } catch {
3314
3340
  try {
3315
3341
  const req = createRequire3(process.cwd() + "/");
3316
- return dirname4(req.resolve("@sideboard-ai/core"));
3342
+ return dirname5(req.resolve("@sideboard-ai/core"));
3317
3343
  } catch {
3318
3344
  return process.cwd();
3319
3345
  }
@@ -3324,14 +3350,14 @@ function cursorRunnerPath() {
3324
3350
  if (packaged) return packaged;
3325
3351
  const root = entryDir2();
3326
3352
  const candidates = [
3327
- join7(root, "agents", "cursor-runner.js"),
3328
- join7(root, "agents", "cursor-runner.cjs"),
3353
+ join8(root, "agents", "cursor-runner.js"),
3354
+ join8(root, "agents", "cursor-runner.cjs"),
3329
3355
  // If somehow resolved from package root instead of dist/
3330
- join7(root, "dist", "agents", "cursor-runner.js"),
3331
- join7(root, "dist", "agents", "cursor-runner.cjs"),
3356
+ join8(root, "dist", "agents", "cursor-runner.js"),
3357
+ join8(root, "dist", "agents", "cursor-runner.cjs"),
3332
3358
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
3333
- join7(root, "cursor-runner.ts"),
3334
- join7(root, "src", "agents", "cursor-runner.ts")
3359
+ join8(root, "cursor-runner.ts"),
3360
+ join8(root, "src", "agents", "cursor-runner.ts")
3335
3361
  ];
3336
3362
  for (const candidate of candidates) {
3337
3363
  if (existsSync9(candidate)) return candidate;
@@ -3372,6 +3398,7 @@ var cursorAdapter = {
3372
3398
  },
3373
3399
  async buildTurn(thread, input) {
3374
3400
  const agentId = await this.resolveSessionId(thread.worktreePath, thread.sessionId);
3401
+ const fullPrompt = flattenTurnInput(input);
3375
3402
  const prompt = flattenTurnInput(dropCachedPrefixOnResume(input, agentId));
3376
3403
  const apiKey = resolveCursorApiKey() || void 0;
3377
3404
  const isOrchestrator = isOrchestratorThread(thread);
@@ -3388,6 +3415,7 @@ var cursorAdapter = {
3388
3415
  const mcpServers = toCursorMcpServers(injected);
3389
3416
  const req = {
3390
3417
  prompt,
3418
+ ...fullPrompt !== prompt ? { freshPrompt: fullPrompt } : {},
3391
3419
  cwd: thread.worktreePath,
3392
3420
  threadId: thread.id,
3393
3421
  agentId,
@@ -3414,8 +3442,9 @@ var cursorAdapter = {
3414
3442
  stdin: JSON.stringify(req),
3415
3443
  env: {
3416
3444
  ...launch.env,
3417
- ...cursorRipgrepEnv({ startFile: runner }),
3418
- ...apiKey ? { CURSOR_API_KEY: apiKey } : {}
3445
+ ...cursorRipgrepEnv({ startFile: runner })
3446
+ // API key stays on the stdin request. Do not copy it into the child env,
3447
+ // where `ps` and crash dumps can see it. The runner reads `req.apiKey`.
3419
3448
  }
3420
3449
  };
3421
3450
  },
@@ -3437,14 +3466,17 @@ var cursorAdapter = {
3437
3466
  };
3438
3467
 
3439
3468
  // src/agents/opencode.ts
3440
- import { existsSync as existsSync10 } from "fs";
3469
+ import { existsSync as existsSync11 } from "fs";
3470
+
3471
+ // src/agent-rpc/opencode-host.ts
3472
+ import { pathToFileURL } from "url";
3441
3473
 
3442
3474
  // src/agent-rpc/opencode-hook.ts
3443
- import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "fs";
3444
- import { join as join8 } from "path";
3475
+ import { existsSync as existsSync10, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync, writeFileSync as writeFileSync4 } from "fs";
3476
+ import { join as join9 } from "path";
3445
3477
  var OPENCODE_PLUGIN_SOURCE = `import { tool } from "@opencode-ai/plugin"
3446
3478
 
3447
- const URL = process.env[${JSON.stringify(AGENT_RPC_URL_ENV)}] || ""
3479
+ const RPC_URL = process.env[${JSON.stringify(AGENT_RPC_URL_ENV)}] || ""
3448
3480
  const TOKEN = process.env[${JSON.stringify(AGENT_RPC_TOKEN_ENV)}] || ""
3449
3481
  const CWD = process.env[${JSON.stringify(AGENT_RPC_CWD_ENV)}] || ""
3450
3482
 
@@ -3457,24 +3489,29 @@ function jsonError(err) {
3457
3489
  }
3458
3490
 
3459
3491
  function socketUrl() {
3460
- const u = new URL(URL)
3492
+ const u = new URL(RPC_URL)
3461
3493
  u.searchParams.set(${JSON.stringify(AGENT_RPC_TOKEN_QUERY)}, TOKEN)
3462
3494
  return u.toString()
3463
3495
  }
3464
3496
 
3465
3497
  function call(method, params) {
3466
- if (!URL || !TOKEN) {
3498
+ if (!RPC_URL || !TOKEN) {
3467
3499
  return Promise.resolve(jsonError(new Error("Agent RPC runtime is not running")))
3468
3500
  }
3501
+ const timeoutMs = method === "job.wait" ? 130000 : 30000
3469
3502
  return new Promise((resolve) => {
3470
3503
  let settled = false
3504
+ let ws
3505
+ let timer
3471
3506
  const done = (value) => {
3472
3507
  if (settled) return
3473
3508
  settled = true
3509
+ clearTimeout(timer)
3474
3510
  try { ws.close() } catch {}
3475
3511
  resolve(value)
3476
3512
  }
3477
- const ws = new WebSocket(socketUrl())
3513
+ timer = setTimeout(() => done(jsonError(new Error("Agent RPC timed out"))), timeoutMs)
3514
+ ws = new WebSocket(socketUrl())
3478
3515
  const id = Date.now()
3479
3516
  ws.addEventListener("open", () => {
3480
3517
  ws.send(JSON.stringify({ jsonrpc: "2.0", id, method, params, authToken: TOKEN }))
@@ -3546,12 +3583,19 @@ export const SideboardRpc = async (ctx) => {
3546
3583
  }
3547
3584
  `;
3548
3585
  function writeOpencodeRpcPlugin() {
3549
- const configDir = join8(appDataDir(), "agent-rpc", "opencode");
3550
- const pluginDir = join8(configDir, "plugins");
3551
- mkdirSync2(pluginDir, { recursive: true });
3552
- const pluginFile = join8(pluginDir, "sideboard-rpc.js");
3553
- writeFileSync3(pluginFile, OPENCODE_PLUGIN_SOURCE);
3554
- return { configDir, pluginFile };
3586
+ const pluginDir = join9(appDataDir(), "agent-rpc", "opencode");
3587
+ mkdirSync3(pluginDir, { recursive: true });
3588
+ const pluginFile = join9(pluginDir, "sideboard-rpc.js");
3589
+ if (existsSync10(pluginFile)) {
3590
+ try {
3591
+ if (readFileSync4(pluginFile, "utf8") === OPENCODE_PLUGIN_SOURCE) return pluginFile;
3592
+ } catch {
3593
+ }
3594
+ }
3595
+ const tmp = `${pluginFile}.${process.pid}.tmp`;
3596
+ writeFileSync4(tmp, OPENCODE_PLUGIN_SOURCE);
3597
+ renameSync(tmp, pluginFile);
3598
+ return pluginFile;
3555
3599
  }
3556
3600
 
3557
3601
  // src/agent-rpc/opencode-host.ts
@@ -3574,10 +3618,9 @@ async function buildOpencodeHostEnv(thread) {
3574
3618
  const config = injected.length > 0 || disableNames.length > 0 ? JSON.parse(toOpencodeMcpConfigContent(injected, { disableNames })) : {};
3575
3619
  const env = {};
3576
3620
  if (rpc) {
3577
- const { configDir, pluginFile } = writeOpencodeRpcPlugin();
3578
- env.OPENCODE_CONFIG_DIR = configDir;
3621
+ const pluginFile = writeOpencodeRpcPlugin();
3579
3622
  Object.assign(env, agentRpcChildEnv(rpc, thread.worktreePath));
3580
- config.plugin = [pluginFile];
3623
+ config.plugin = [pathToFileURL(pluginFile).href];
3581
3624
  }
3582
3625
  if (Object.keys(config).length > 0) {
3583
3626
  env.OPENCODE_CONFIG_CONTENT = JSON.stringify(config);
@@ -3644,7 +3687,7 @@ async function listOpencodeModels() {
3644
3687
  if (opencode === "opencode") {
3645
3688
  const which = await run("which", ["opencode"], { reject: false });
3646
3689
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
3647
- } else if (!existsSync10(opencode)) {
3690
+ } else if (!existsSync11(opencode)) {
3648
3691
  return FALLBACK_OPENCODE_MODELS;
3649
3692
  }
3650
3693
  const listed = await run(opencode, ["models"], { reject: false });
@@ -3679,7 +3722,7 @@ var opencodeAdapter = {
3679
3722
  async detect() {
3680
3723
  const opencode = resolveAgentExecutable("opencode");
3681
3724
  if (opencode !== "opencode") {
3682
- if (!existsSync10(opencode)) {
3725
+ if (!existsSync11(opencode)) {
3683
3726
  return {
3684
3727
  agent: "opencode",
3685
3728
  installed: false,
@@ -3733,6 +3776,11 @@ var opencodeAdapter = {
3733
3776
  if (model) {
3734
3777
  args.push("--model", model);
3735
3778
  }
3779
+ args.push("--thinking");
3780
+ const variant = thread.effort?.trim() ?? "";
3781
+ if (variant && /^(minimal|low|medium|high|max|xhigh)$/i.test(variant)) {
3782
+ args.push("--variant", variant);
3783
+ }
3736
3784
  const hostEnv = await buildOpencodeHostEnv(thread);
3737
3785
  return {
3738
3786
  file: resolveAgentExecutable("opencode"),
@@ -3765,6 +3813,10 @@ var opencodeAdapter = {
3765
3813
  const text = obj.part?.text ?? obj.text;
3766
3814
  if (text) return { type: "stdout", data: text };
3767
3815
  }
3816
+ if (obj.type === "reasoning" || obj.type === "thinking") {
3817
+ const text = obj.part?.text ?? obj.text;
3818
+ if (typeof text === "string" && text) return { type: "thinking", data: text };
3819
+ }
3768
3820
  if (obj.type === "tool_use") {
3769
3821
  const part = obj.part;
3770
3822
  const name = part?.tool ?? part?.name ?? obj.tool ?? obj.name ?? "tool";
@@ -3880,11 +3932,14 @@ var opencodeAdapter = {
3880
3932
  const listed = await run(
3881
3933
  resolveAgentExecutable("opencode"),
3882
3934
  ["session", "list", "--format", "json"],
3883
- { cwd: worktreePath, reject: false }
3935
+ { cwd: worktreePath, reject: false, timeoutMs: 8e3 }
3884
3936
  );
3885
- if (listed.exitCode === 0 && listed.stdout.trim()) {
3937
+ if (listed.exitCode === 0) {
3938
+ const raw = listed.stdout.trim();
3939
+ if (!raw) return null;
3886
3940
  try {
3887
- const sessions = JSON.parse(listed.stdout);
3941
+ const sessions = JSON.parse(raw);
3942
+ if (Array.isArray(sessions) && sessions.length === 0) return null;
3888
3943
  if (Array.isArray(sessions) && sessions.length > 0) {
3889
3944
  const norm = (p) => p.replace(/\/+$/, "");
3890
3945
  const wt = norm(worktreePath);
@@ -3918,34 +3973,8 @@ var opencodeAdapter = {
3918
3973
  };
3919
3974
  },
3920
3975
  async listLinearIssues(_repoPath) {
3921
- const prompt = "List my assigned Linear issues as JSON array only: id, identifier, title, url, labels.";
3922
- const { stdout, exitCode } = await run(
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
- }
3976
+ const { listAssignedLinearIssues: listAssignedLinearIssues2 } = await import("./linear-list-63I7QUC6.js");
3977
+ return listAssignedLinearIssues2();
3949
3978
  }
3950
3979
  };
3951
3980
 
@@ -4344,9 +4373,9 @@ function formatClaudeUsageOverLimitWait(windows, now = /* @__PURE__ */ new Date(
4344
4373
  }
4345
4374
 
4346
4375
  // src/agents/claude-usage-client.ts
4347
- import { existsSync as existsSync11, readFileSync as readFileSync5 } from "fs";
4348
- import { homedir as homedir6 } from "os";
4349
- import { join as join9 } from "path";
4376
+ import { existsSync as existsSync12, readFileSync as readFileSync5 } from "fs";
4377
+ import { homedir as homedir7 } from "os";
4378
+ import { join as join10 } from "path";
4350
4379
  var CLAUDE_OAUTH_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
4351
4380
  var CLAUDE_USAGE_TTL_MS = 9e4;
4352
4381
  var CLAUDE_USAGE_ERROR_TTL_MS = 5 * 6e4;
@@ -4386,12 +4415,12 @@ function accessTokenFromCredentialsJson(raw) {
4386
4415
  }
4387
4416
  }
4388
4417
  function claudeCredentialsPath(configDir) {
4389
- const root = configDir?.trim() || process.env.CLAUDE_CONFIG_DIR?.trim() || join9(homedir6(), ".claude");
4390
- return join9(root, ".credentials.json");
4418
+ const root = configDir?.trim() || process.env.CLAUDE_CONFIG_DIR?.trim() || join10(homedir7(), ".claude");
4419
+ return join10(root, ".credentials.json");
4391
4420
  }
4392
4421
  async function readFileAccessToken(configDir) {
4393
4422
  const path = claudeCredentialsPath(configDir);
4394
- if (!existsSync11(path)) return null;
4423
+ if (!existsSync12(path)) return null;
4395
4424
  try {
4396
4425
  return accessTokenFromCredentialsJson(readFileSync5(path, "utf8"));
4397
4426
  } catch {