@sideboard-ai/core 0.1.261 → 0.1.263

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/{abletime-OQ4PC52L.js → abletime-6AOJI2YZ.js} +4 -4
  2. package/dist/{abletime-CDGINDXG.js → abletime-U75ZGDIX.js} +5 -5
  3. package/dist/{abletime-oauth-KX2TDFTE.js → abletime-oauth-LOAHGG4X.js} +3 -3
  4. package/dist/{abletime-oauth-5A5EOH2A.js → abletime-oauth-TA2YDCYX.js} +4 -4
  5. package/dist/{abletime-rest-UEHOBLXD.js → abletime-rest-CTA5WV26.js} +4 -4
  6. package/dist/{abletime-rest-PUGKYTRR.js → abletime-rest-YZPFM6IY.js} +3 -3
  7. package/dist/agents/claude-runner.cjs +463 -0
  8. package/dist/agents/claude-runner.d.cts +1 -0
  9. package/dist/agents/claude-runner.d.ts +1 -0
  10. package/dist/agents/claude-runner.js +134 -0
  11. package/dist/agents/cursor-runner.cjs +388 -7
  12. package/dist/agents/cursor-runner.js +34 -7
  13. package/dist/{agents-J2P4KNEY.js → agents-3TUMFSMH.js} +10 -9
  14. package/dist/{agents-IKVUGW5H.js → agents-6FWDRVA2.js} +4 -4
  15. package/dist/{app-settings-OM7H64YM.js → app-settings-MVZPM6WW.js} +1 -1
  16. package/dist/{app-settings-VQEUCONM.js → app-settings-RKFFUIFQ.js} +2 -2
  17. package/dist/{chunk-6PFZ6XO7.js → chunk-2QUQH2SZ.js} +81 -6
  18. package/dist/{chunk-VIC6TDYT.js → chunk-36FOBJBF.js} +76 -3
  19. package/dist/{chunk-ABPNIYRS.js → chunk-3H7O27X2.js} +389 -102
  20. package/dist/{chunk-FSZ7YYFQ.js → chunk-4ALDX5IO.js} +5 -3
  21. package/dist/{chunk-5OKJDCBK.js → chunk-5PK53SAP.js} +5 -5
  22. package/dist/{chunk-U3AOJLH3.js → chunk-5ZPT5YAV.js} +8 -6
  23. package/dist/{chunk-YFTO7U2A.js → chunk-6YOXQVJ7.js} +3 -3
  24. package/dist/{chunk-J6ONZP74.js → chunk-6YY7XPPL.js} +5 -5
  25. package/dist/{chunk-WV7KJH2E.js → chunk-A5SAYFJ4.js} +1 -0
  26. package/dist/{chunk-B6XFBNYM.js → chunk-BOMSJUXW.js} +2 -2
  27. package/dist/{chunk-S7VDDJ34.js → chunk-CEOTK5GZ.js} +3 -3
  28. package/dist/{chunk-4F7J6UWD.js → chunk-EK3KVT7I.js} +515 -139
  29. package/dist/{chunk-HHEKVR6C.js → chunk-F5MFNUAA.js} +40 -2
  30. package/dist/{chunk-KVQX62XI.js → chunk-K7B25HO4.js} +3 -3
  31. package/dist/{chunk-JTNY5CK4.js → chunk-L5WGAIL2.js} +46 -46
  32. package/dist/chunk-NYBFYFK7.js +415 -0
  33. package/dist/{chunk-GIZQAOHZ.js → chunk-QX6QUZVD.js} +121 -91
  34. package/dist/{chunk-X2OTZ36G.js → chunk-RKPBIB2U.js} +52 -52
  35. package/dist/{chunk-W5PWGEKS.js → chunk-T3AYRQJZ.js} +107 -77
  36. package/dist/{chunk-D554YCHG.js → chunk-YKYEHDMX.js} +2 -2
  37. package/dist/connected-teams-RU6VATCM.js +1 -1
  38. package/dist/{coordinator-prompt-VQHQ3RIX.js → coordinator-prompt-HZCQZ6C5.js} +6 -6
  39. package/dist/{coordinator-prompt-TU6656OK.js → coordinator-prompt-J7DKHOCH.js} +3 -3
  40. package/dist/{global-workspace-PHF2MOGW.js → global-workspace-6LDUZ2NF.js} +3 -3
  41. package/dist/{global-workspace-47NZVA44.js → global-workspace-TI26K25J.js} +6 -6
  42. package/dist/index.cjs +1712 -721
  43. package/dist/index.d.cts +181 -41
  44. package/dist/index.d.ts +181 -41
  45. package/dist/index.js +693 -285
  46. package/dist/mcp/run-stdio.cjs +10469 -9896
  47. package/dist/mcp/run-stdio.js +193 -168
  48. package/dist/{orchestrator-VLTO5JBR.js → orchestrator-4JSG7BWC.js} +5 -5
  49. package/dist/{orchestrator-OCG4QVA5.js → orchestrator-5YU46YNS.js} +11 -10
  50. package/dist/{workspaces-I7TWFTJM.js → workspaces-QJ3XIPUJ.js} +6 -6
  51. package/dist/{workspaces-2XTDS7N2.js → workspaces-WOQHJFRQ.js} +3 -3
  52. package/dist/{worktree-DDDF3WHV.js → worktree-6U2FA5LO.js} +2 -2
  53. package/dist/{worktree-YASFE65H.js → worktree-KQA4ON2G.js} +5 -5
  54. package/package.json +4 -3
  55. /package/dist/{chunk-LDXSAVWO.js → chunk-GWFVCCJZ.js} +0 -0
@@ -1,18 +1,18 @@
1
+ import {
2
+ applyConnectedTeamToCli,
3
+ brightsyMcpServerName,
4
+ ensureCliTeamTracked,
5
+ ensureConnectedBrightsyTeamTokens
6
+ } from "./chunk-GWFVCCJZ.js";
1
7
  import {
2
8
  isOrchestratorThread
3
- } from "./chunk-X2OTZ36G.js";
9
+ } from "./chunk-RKPBIB2U.js";
4
10
  import {
5
11
  codexUnattendedGitConfigArgs,
6
12
  mergeAgentGitAuthEnv,
7
13
  resolveAgentGitAuthEnv,
8
14
  resolveCodexGitWritableRoots
9
- } from "./chunk-U3AOJLH3.js";
10
- import {
11
- applyConnectedTeamToCli,
12
- brightsyMcpServerName,
13
- ensureCliTeamTracked,
14
- ensureConnectedBrightsyTeamTokens
15
- } from "./chunk-LDXSAVWO.js";
15
+ } from "./chunk-5ZPT5YAV.js";
16
16
  import {
17
17
  loadBrightsyConfig
18
18
  } from "./chunk-ROPGQRPU.js";
@@ -33,10 +33,11 @@ import {
33
33
  looksLikeAgentFailureMessage,
34
34
  looksLikeBrightsyEmptyCompletion,
35
35
  packagedCursorRunnerPath,
36
+ packagedCursorRuntimeDir,
36
37
  packagedMcpStdioPath,
37
38
  parseCursorRunnerLine,
38
39
  resolveNodeLaunch
39
- } from "./chunk-WV7KJH2E.js";
40
+ } from "./chunk-A5SAYFJ4.js";
40
41
  import {
41
42
  enrichPathWithNpmGlobalBin,
42
43
  isConductorBundledCli,
@@ -44,6 +45,17 @@ import {
44
45
  run,
45
46
  withExportedPath
46
47
  } from "./chunk-QVN2WOKJ.js";
48
+ import {
49
+ AGENT_RPC_CLAUDE_SDK_SERVER,
50
+ AGENT_RPC_CWD_ENV,
51
+ AGENT_RPC_NATIVE_ENV,
52
+ AGENT_RPC_TOKEN_ENV,
53
+ AGENT_RPC_TOKEN_QUERY,
54
+ AGENT_RPC_URL_ENV,
55
+ PILOT_TOOL_DESCRIPTIONS,
56
+ PILOT_TOOL_NAMES,
57
+ agentRpcConnectFromMetadata
58
+ } from "./chunk-NYBFYFK7.js";
47
59
  import {
48
60
  claudeChromeEnabled,
49
61
  fromInclusiveInputUsage,
@@ -52,7 +64,7 @@ import {
52
64
  loadAppSettings,
53
65
  resolveAgentExecutable,
54
66
  resolveClaudeExecutable
55
- } from "./chunk-6PFZ6XO7.js";
67
+ } from "./chunk-2QUQH2SZ.js";
56
68
  import {
57
69
  isElectronLikeCommand,
58
70
  unwrapStrippedElectronLaunch
@@ -489,7 +501,7 @@ var brightsyAdapter = {
489
501
  };
490
502
 
491
503
  // src/agents/claude.ts
492
- import { existsSync as existsSync5 } from "fs";
504
+ import { existsSync as existsSync6 } from "fs";
493
505
 
494
506
  // src/agents/claude-mcp.ts
495
507
  function parseMcpList(text) {
@@ -536,6 +548,29 @@ function mcpAuthWarnings(servers) {
536
548
  `MCP needs login: ${needing.join(", ")}. Run: claude mcp login "<name>"`
537
549
  ];
538
550
  }
551
+ var BASE_ALLOWED_TOOLS = [
552
+ "Edit",
553
+ "Write",
554
+ "Bash",
555
+ "Read",
556
+ "Glob",
557
+ "Grep",
558
+ "WebFetch",
559
+ "WebSearch",
560
+ "Task",
561
+ "Agent",
562
+ "TaskOutput",
563
+ "TaskStop",
564
+ "EnterWorktree",
565
+ "ExitWorktree",
566
+ "Skill"
567
+ ];
568
+ var CLAUDE_PRINT_BG_WAIT_CEILING_MS = 72e5;
569
+ var CLAUDE_CHROME_ALLOWED_TOOLS = [
570
+ "mcp__claude-in-chrome",
571
+ "mcp__claude-in-chrome__*",
572
+ "Skill(claude-in-chrome)"
573
+ ];
539
574
 
540
575
  // src/agents/orch-mcp-isolation.ts
541
576
  import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
@@ -558,6 +593,34 @@ import { fileURLToPath } from "url";
558
593
  // src/mcp/profile.ts
559
594
  var SIDEBOARD_MCP_PROFILE_ENV = "SIDEBOARD_MCP_PROFILE";
560
595
  var SIDEBOARD_THREAD_ID_ENV = "SIDEBOARD_THREAD_ID";
596
+ function agentRpcOwnsPilotTools(env = process.env) {
597
+ return env[AGENT_RPC_NATIVE_ENV]?.trim() === "1";
598
+ }
599
+ function injectedSideboardMcpEnv(opts) {
600
+ const orchId = opts.orchestratorThreadId?.trim();
601
+ const threadId = opts.threadId?.trim() || orchId;
602
+ const env = {
603
+ SIDEBOARD_APP_DATA: appDataDir(),
604
+ [SIDEBOARD_MCP_PROFILE_ENV]: orchId ? "orchestration" : "worktree"
605
+ };
606
+ if (orchId) env.SIDEBOARD_ORCHESTRATOR_THREAD_ID = orchId;
607
+ if (threadId) env[SIDEBOARD_THREAD_ID_ENV] = threadId;
608
+ if (opts.rpcNativeTools) env[AGENT_RPC_NATIVE_ENV] = "1";
609
+ return env;
610
+ }
611
+ var AGENT_RPC_PILOT_MCP_TOOLS = [
612
+ "present_artifact",
613
+ "wait_for_job",
614
+ "stop_job"
615
+ ];
616
+ function shouldRegisterMcpWaitForTurn(env = process.env) {
617
+ return !agentRpcOwnsPilotTools(env);
618
+ }
619
+ function worktreeMcpToolNames(env = process.env) {
620
+ if (!agentRpcOwnsPilotTools(env)) return WORKTREE_MCP_TOOLS;
621
+ const omit = new Set(AGENT_RPC_PILOT_MCP_TOOLS);
622
+ return WORKTREE_MCP_TOOLS.filter((name) => !omit.has(name));
623
+ }
561
624
  var WORKTREE_MCP_TOOLS = [
562
625
  "present_artifact",
563
626
  "ask_user",
@@ -800,20 +863,10 @@ async function buildInjectedMcpServers(opts) {
800
863
  const servers = [];
801
864
  if (opts.includeSideboard) {
802
865
  const sideboard = await resolveSideboardMcpServer();
803
- const orchId = opts.orchestratorThreadId?.trim();
804
- const profile = orchId ? "orchestration" : "worktree";
805
- const threadId = opts.threadId?.trim() || orchId;
806
866
  sideboard.env = {
807
867
  ...sideboard.env ?? {},
808
- SIDEBOARD_APP_DATA: appDataDir(),
809
- [SIDEBOARD_MCP_PROFILE_ENV]: profile
868
+ ...injectedSideboardMcpEnv(opts)
810
869
  };
811
- if (orchId) {
812
- sideboard.env.SIDEBOARD_ORCHESTRATOR_THREAD_ID = orchId;
813
- }
814
- if (threadId) {
815
- sideboard.env[SIDEBOARD_THREAD_ID_ENV] = threadId;
816
- }
817
870
  try {
818
871
  mergeAgentGitAuthEnv(
819
872
  sideboard.env,
@@ -918,7 +971,7 @@ function stripElectronFromUserMcpEntry(entry) {
918
971
  next.env = cleaned;
919
972
  return next;
920
973
  }
921
- function writeMcpServersConfig(servers, extraServers) {
974
+ function mcpServersRecord(servers, extraServers) {
922
975
  const mcpServers = {};
923
976
  for (const s of servers) {
924
977
  const env = mcpSpawnEnv(s.env);
@@ -935,6 +988,10 @@ function writeMcpServersConfig(servers, extraServers) {
935
988
  mcpServers[name] = stripElectronFromUserMcpEntry(entry);
936
989
  }
937
990
  }
991
+ return mcpServers;
992
+ }
993
+ function writeMcpServersConfig(servers, extraServers) {
994
+ const mcpServers = mcpServersRecord(servers, extraServers);
938
995
  if (Object.keys(mcpServers).length === 0) return null;
939
996
  const dir = mkdtempSync(join(tmpdir(), "sideboard-mcp-"));
940
997
  const cfgPath = join(dir, "mcp.json");
@@ -2115,34 +2172,92 @@ function permissionMode(thread) {
2115
2172
  };
2116
2173
  }
2117
2174
 
2175
+ // src/agent-rpc/rpc-env.ts
2176
+ function worktreeAgentRpc(isOrchestrator) {
2177
+ return isOrchestrator ? null : agentRpcConnectFromMetadata();
2178
+ }
2179
+ function agentRpcChildEnv(rpc, cwd) {
2180
+ return {
2181
+ [AGENT_RPC_NATIVE_ENV]: "1",
2182
+ [AGENT_RPC_URL_ENV]: rpc.url,
2183
+ [AGENT_RPC_TOKEN_ENV]: rpc.authToken,
2184
+ [AGENT_RPC_CWD_ENV]: cwd
2185
+ };
2186
+ }
2187
+
2188
+ // src/agents/claude-host.ts
2189
+ import { existsSync as existsSync5 } from "fs";
2190
+ import { createRequire as createRequire2 } from "module";
2191
+ import { dirname as dirname3, join as join4 } from "path";
2192
+ import { fileURLToPath as fileURLToPath2 } from "url";
2193
+ function claudePilotSdkAllowedTools() {
2194
+ return PILOT_TOOL_NAMES.map(
2195
+ (name) => `mcp__${AGENT_RPC_CLAUDE_SDK_SERVER}__${name}`
2196
+ );
2197
+ }
2198
+ function withClaudePilotRpcTools(allowed) {
2199
+ const omit = new Set(PILOT_TOOL_NAMES.map((name) => `mcp__sideboard__${name}`));
2200
+ return [...allowed.filter((name) => !omit.has(name)), ...claudePilotSdkAllowedTools()];
2201
+ }
2202
+ function entryDir() {
2203
+ const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
2204
+ if (cjsDir) return cjsDir;
2205
+ try {
2206
+ return dirname3(fileURLToPath2(import.meta.url));
2207
+ } catch {
2208
+ try {
2209
+ const req = createRequire2(process.cwd() + "/");
2210
+ return dirname3(req.resolve("@sideboard-ai/core"));
2211
+ } catch {
2212
+ return process.cwd();
2213
+ }
2214
+ }
2215
+ }
2216
+ function claudeRunnerPath() {
2217
+ const packagedDir = packagedCursorRuntimeDir();
2218
+ if (packagedDir) {
2219
+ const packaged = join4(packagedDir, "core-dist", "agents", "claude-runner.js");
2220
+ if (existsSync5(packaged)) return packaged;
2221
+ }
2222
+ const root = entryDir();
2223
+ const candidates = [
2224
+ join4(root, "agents", "claude-runner.js"),
2225
+ join4(root, "agents", "claude-runner.cjs"),
2226
+ join4(root, "dist", "agents", "claude-runner.js"),
2227
+ join4(root, "dist", "agents", "claude-runner.cjs"),
2228
+ join4(root, "claude-runner.ts"),
2229
+ join4(root, "src", "agents", "claude-runner.ts")
2230
+ ];
2231
+ for (const candidate of candidates) {
2232
+ if (existsSync5(candidate)) return candidate;
2233
+ }
2234
+ return candidates[0];
2235
+ }
2236
+ async function buildClaudeRpcTurnCommand(req) {
2237
+ const runner = claudeRunnerPath();
2238
+ const isTs = runner.endsWith(".ts");
2239
+ const launch = applyNodeLaunch(
2240
+ await resolveNodeLaunch(runner),
2241
+ isTs ? ["--import", "tsx", runner] : [runner]
2242
+ );
2243
+ return {
2244
+ file: launch.file,
2245
+ args: launch.args,
2246
+ cwd: req.cwd,
2247
+ stdin: JSON.stringify(req),
2248
+ env: {
2249
+ ...launch.env,
2250
+ CLAUDE_CODE_FORWARD_SUBAGENT_TEXT: "1",
2251
+ CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS: process.env.CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS ?? "7200000",
2252
+ ...req.isolateClaudeAiMcp ? { ENABLE_CLAUDEAI_MCP_SERVERS: "false" } : {}
2253
+ }
2254
+ };
2255
+ }
2256
+
2118
2257
  // src/agents/claude.ts
2119
- var BASE_ALLOWED_TOOLS = [
2120
- "Edit",
2121
- "Write",
2122
- "Bash",
2123
- "Read",
2124
- "Glob",
2125
- "Grep",
2126
- "WebFetch",
2127
- "WebSearch",
2128
- // Subagents (Claude Code v2.1.63 renamed Task → Agent; allow both).
2129
- "Task",
2130
- "Agent",
2131
- "TaskOutput",
2132
- "TaskStop",
2133
- "EnterWorktree",
2134
- "ExitWorktree",
2135
- "Skill"
2136
- ];
2137
- var CLAUDE_PRINT_BG_WAIT_CEILING_MS = 72e5;
2138
2258
  function isLocalDevAppDataDir(dir = process.env.SIDEBOARD_APP_DATA) {
2139
2259
  return /[/\\]\.sideboard[/\\]dev-app-data(?:[/\\]|$)/.test(dir ?? "");
2140
2260
  }
2141
- var CLAUDE_CHROME_ALLOWED_TOOLS = [
2142
- "mcp__claude-in-chrome",
2143
- "mcp__claude-in-chrome__*",
2144
- "Skill(claude-in-chrome)"
2145
- ];
2146
2261
  var CLAUDE_PROMPT_ARG_MAX = 2e5;
2147
2262
  function usageFromClaude(usage) {
2148
2263
  if (!usage) return null;
@@ -2180,6 +2295,13 @@ function costUsdFromClaudeResult(obj) {
2180
2295
  }
2181
2296
  return void 0;
2182
2297
  }
2298
+ function sessionCostUsdFromClaudeResult(obj) {
2299
+ const totalCost = obj.total_cost_usd ?? obj.totalCostUsd;
2300
+ if (totalCost != null && Number.isFinite(Number(totalCost))) {
2301
+ return Number(totalCost);
2302
+ }
2303
+ return void 0;
2304
+ }
2183
2305
  function claudeResultErrorDetail(obj) {
2184
2306
  const isError = Boolean(obj.is_error) || typeof obj.subtype === "string" && /^error/i.test(obj.subtype);
2185
2307
  const fromResult = typeof obj.result === "string" ? obj.result.trim() : "";
@@ -2512,7 +2634,7 @@ var claudeAdapter = {
2512
2634
  async detect() {
2513
2635
  const claude = resolveClaudeExecutable();
2514
2636
  if (claude !== "claude") {
2515
- if (!existsSync5(claude)) {
2637
+ if (!existsSync6(claude)) {
2516
2638
  return {
2517
2639
  agent: "claude",
2518
2640
  installed: false,
@@ -2561,15 +2683,17 @@ var claudeAdapter = {
2561
2683
  );
2562
2684
  }
2563
2685
  const mode = permissionMode(thread);
2564
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-47NZVA44.js");
2686
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-TI26K25J.js");
2565
2687
  const isOrchestrator = isOrchestratorThread2(thread);
2688
+ const rpc = worktreeAgentRpc(isOrchestrator);
2566
2689
  const injectedServers = await buildInjectedMcpServers({
2567
2690
  includeSideboard: true,
2568
2691
  includeBrightsy: shouldInjectBrightsyMcp(thread, {
2569
2692
  orchestrator: isOrchestrator
2570
2693
  }),
2571
2694
  orchestratorThreadId: isOrchestrator ? thread.id : null,
2572
- threadId: thread.id
2695
+ threadId: thread.id,
2696
+ rpcNativeTools: Boolean(rpc)
2573
2697
  });
2574
2698
  const injectedBrightsyNames = injectedServers.filter((s) => s.name === "brightsy" || s.name.startsWith("brightsy_")).map((s) => s.name);
2575
2699
  const chromeOn = claudeChromeEnabled();
@@ -2597,6 +2721,23 @@ var claudeAdapter = {
2597
2721
  if (chromeOn) {
2598
2722
  allowedTools = [...allowedTools, ...CLAUDE_CHROME_ALLOWED_TOOLS];
2599
2723
  }
2724
+ if (rpc) {
2725
+ return buildClaudeRpcTurnCommand({
2726
+ prompt: promptText,
2727
+ cwd: thread.worktreePath,
2728
+ sessionId,
2729
+ model: thread.model,
2730
+ effort: thread.effort ?? (thread.fast ? "low" : "high"),
2731
+ permissionMode: mode.claude,
2732
+ systemPrompt,
2733
+ claudePath: claude,
2734
+ chrome: chromeOn,
2735
+ mcpServers: mcpServersRecord(injectedServers, userMcpEntries),
2736
+ allowedTools: withClaudePilotRpcTools(allowedTools),
2737
+ agentRpc: rpc,
2738
+ isolateClaudeAiMcp: isOrchestrator || isLocalDevAppDataDir()
2739
+ });
2740
+ }
2600
2741
  const args = [
2601
2742
  "-p",
2602
2743
  ...useStdin ? [] : [promptText],
@@ -2731,6 +2872,8 @@ var claudeAdapter = {
2731
2872
  if (usage) {
2732
2873
  const costUsd = costUsdFromClaudeResult(obj);
2733
2874
  if (costUsd != null) usage.costUsd = costUsd;
2875
+ const sessionCostUsd = sessionCostUsdFromClaudeResult(obj);
2876
+ if (sessionCostUsd != null) usage.sessionCostUsd = sessionCostUsd;
2734
2877
  events.push({ type: "usage", data: usage, scope: "turn" });
2735
2878
  }
2736
2879
  if (events.length === 0) return null;
@@ -2801,9 +2944,9 @@ function parseIssuesJson(raw) {
2801
2944
  }
2802
2945
 
2803
2946
  // src/agents/codex.ts
2804
- import { existsSync as existsSync6, readFileSync as readFileSync3, statSync } from "fs";
2947
+ import { existsSync as existsSync7, readFileSync as readFileSync3, statSync } from "fs";
2805
2948
  import { homedir as homedir3 } from "os";
2806
- import { join as join4 } from "path";
2949
+ import { join as join5 } from "path";
2807
2950
  var CODEX_PROMPT_ARG_MAX = 2e5;
2808
2951
  var FALLBACK_CODEX_MODELS = [
2809
2952
  { id: "gpt-5.6-sol", displayName: "GPT-5.6 Sol" },
@@ -2823,7 +2966,7 @@ async function listCodexModels() {
2823
2966
  if (codex === "codex") {
2824
2967
  const which = await run("which", ["codex"], { reject: false });
2825
2968
  if (which.exitCode !== 0) return FALLBACK_CODEX_MODELS;
2826
- } else if (!existsSync6(codex)) {
2969
+ } else if (!existsSync7(codex)) {
2827
2970
  return FALLBACK_CODEX_MODELS;
2828
2971
  }
2829
2972
  const listed = await run(codex, ["debug", "models"], { reject: false });
@@ -2858,11 +3001,11 @@ function usageFromCodex(usage) {
2858
3001
  }
2859
3002
  function codexConfigHasNetworkAccess() {
2860
3003
  const candidates = [
2861
- join4(homedir3(), ".codex", "config.toml"),
2862
- join4(homedir3(), ".config", "codex", "config.toml")
3004
+ join5(homedir3(), ".codex", "config.toml"),
3005
+ join5(homedir3(), ".config", "codex", "config.toml")
2863
3006
  ];
2864
3007
  for (const path of candidates) {
2865
- if (!existsSync6(path)) continue;
3008
+ if (!existsSync7(path)) continue;
2866
3009
  const text = readFileSync3(path, "utf8");
2867
3010
  if (/network_access\s*=\s*true/.test(text)) return true;
2868
3011
  }
@@ -2895,8 +3038,8 @@ function asRecord2(value) {
2895
3038
  return void 0;
2896
3039
  }
2897
3040
  function codexLooksAuthenticated() {
2898
- const authPath = join4(homedir3(), ".codex", "auth.json");
2899
- if (!existsSync6(authPath)) return false;
3041
+ const authPath = join5(homedir3(), ".codex", "auth.json");
3042
+ if (!existsSync7(authPath)) return false;
2900
3043
  try {
2901
3044
  return statSync(authPath).size > 2;
2902
3045
  } catch {
@@ -2908,7 +3051,7 @@ var codexAdapter = {
2908
3051
  async detect() {
2909
3052
  const codex = resolveAgentExecutable("codex");
2910
3053
  if (codex !== "codex") {
2911
- if (!existsSync6(codex)) {
3054
+ if (!existsSync7(codex)) {
2912
3055
  return {
2913
3056
  agent: "codex",
2914
3057
  installed: false,
@@ -3182,10 +3325,10 @@ var codexAdapter = {
3182
3325
  };
3183
3326
 
3184
3327
  // src/agents/cursor.ts
3185
- import { existsSync as existsSync7 } from "fs";
3186
- import { createRequire as createRequire2 } from "module";
3187
- import { dirname as dirname3, join as join5 } from "path";
3188
- import { fileURLToPath as fileURLToPath2 } from "url";
3328
+ import { existsSync as existsSync8 } from "fs";
3329
+ import { createRequire as createRequire3 } from "module";
3330
+ import { dirname as dirname4, join as join6 } from "path";
3331
+ import { fileURLToPath as fileURLToPath3 } from "url";
3189
3332
  var FALLBACK_CURSOR_MODELS = [
3190
3333
  { id: "default", displayName: "Auto" },
3191
3334
  { id: "composer-2.5", displayName: "Composer 2.5" },
@@ -3232,15 +3375,15 @@ async function listCursorModels() {
3232
3375
  return cachedModels?.models ?? FALLBACK_CURSOR_MODELS;
3233
3376
  }
3234
3377
  }
3235
- function entryDir() {
3378
+ function entryDir2() {
3236
3379
  const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
3237
3380
  if (cjsDir) return cjsDir;
3238
3381
  try {
3239
- return dirname3(fileURLToPath2(import.meta.url));
3382
+ return dirname4(fileURLToPath3(import.meta.url));
3240
3383
  } catch {
3241
3384
  try {
3242
- const req = createRequire2(process.cwd() + "/");
3243
- return dirname3(req.resolve("@sideboard-ai/core"));
3385
+ const req = createRequire3(process.cwd() + "/");
3386
+ return dirname4(req.resolve("@sideboard-ai/core"));
3244
3387
  } catch {
3245
3388
  return process.cwd();
3246
3389
  }
@@ -3249,19 +3392,19 @@ function entryDir() {
3249
3392
  function cursorRunnerPath() {
3250
3393
  const packaged = packagedCursorRunnerPath();
3251
3394
  if (packaged) return packaged;
3252
- const root = entryDir();
3395
+ const root = entryDir2();
3253
3396
  const candidates = [
3254
- join5(root, "agents", "cursor-runner.js"),
3255
- join5(root, "agents", "cursor-runner.cjs"),
3397
+ join6(root, "agents", "cursor-runner.js"),
3398
+ join6(root, "agents", "cursor-runner.cjs"),
3256
3399
  // If somehow resolved from package root instead of dist/
3257
- join5(root, "dist", "agents", "cursor-runner.js"),
3258
- join5(root, "dist", "agents", "cursor-runner.cjs"),
3400
+ join6(root, "dist", "agents", "cursor-runner.js"),
3401
+ join6(root, "dist", "agents", "cursor-runner.cjs"),
3259
3402
  // Source tree (dev): packages/core/src/agents/cursor-runner.ts
3260
- join5(root, "cursor-runner.ts"),
3261
- join5(root, "src", "agents", "cursor-runner.ts")
3403
+ join6(root, "cursor-runner.ts"),
3404
+ join6(root, "src", "agents", "cursor-runner.ts")
3262
3405
  ];
3263
3406
  for (const candidate of candidates) {
3264
- if (existsSync7(candidate)) return candidate;
3407
+ if (existsSync8(candidate)) return candidate;
3265
3408
  }
3266
3409
  return candidates[0];
3267
3410
  }
@@ -3302,13 +3445,15 @@ var cursorAdapter = {
3302
3445
  const prompt = flattenTurnInput(dropCachedPrefixOnResume(input, agentId));
3303
3446
  const apiKey = resolveCursorApiKey() || void 0;
3304
3447
  const isOrchestrator = isOrchestratorThread(thread);
3448
+ const rpc = agentRpcConnectFromMetadata();
3305
3449
  const injected = await buildInjectedMcpServers({
3306
3450
  includeSideboard: true,
3307
3451
  includeBrightsy: shouldInjectBrightsyMcp(thread, {
3308
3452
  orchestrator: isOrchestrator
3309
3453
  }),
3310
3454
  orchestratorThreadId: isOrchestrator ? thread.id : null,
3311
- threadId: thread.id
3455
+ threadId: thread.id,
3456
+ rpcNativeTools: Boolean(rpc)
3312
3457
  });
3313
3458
  const mcpServers = toCursorMcpServers(injected);
3314
3459
  const req = {
@@ -3322,6 +3467,8 @@ var cursorAdapter = {
3322
3467
  planMode: thread.planMode,
3323
3468
  apiKey,
3324
3469
  ...isOrchestrator ? { isolateAmbientMcp: true } : {},
3470
+ ...rpc ? { agentRpc: rpc } : {},
3471
+ ...isOrchestrator && rpc ? { rpcWaitForTurn: true } : {},
3325
3472
  ...Object.keys(mcpServers).length > 0 ? { mcpServers } : {}
3326
3473
  };
3327
3474
  const runner = cursorRunnerPath();
@@ -3360,7 +3507,155 @@ var cursorAdapter = {
3360
3507
  };
3361
3508
 
3362
3509
  // src/agents/opencode.ts
3363
- import { existsSync as existsSync8 } from "fs";
3510
+ import { existsSync as existsSync9 } from "fs";
3511
+
3512
+ // src/agent-rpc/opencode-hook.ts
3513
+ import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "fs";
3514
+ import { join as join7 } from "path";
3515
+ var OPENCODE_PLUGIN_SOURCE = `import { tool } from "@opencode-ai/plugin"
3516
+
3517
+ const URL = process.env[${JSON.stringify(AGENT_RPC_URL_ENV)}] || ""
3518
+ const TOKEN = process.env[${JSON.stringify(AGENT_RPC_TOKEN_ENV)}] || ""
3519
+ const CWD = process.env[${JSON.stringify(AGENT_RPC_CWD_ENV)}] || ""
3520
+
3521
+ function jsonResult(value) {
3522
+ return JSON.stringify(value)
3523
+ }
3524
+
3525
+ function jsonError(err) {
3526
+ return jsonResult({ ok: false, error: err instanceof Error ? err.message : String(err) })
3527
+ }
3528
+
3529
+ function socketUrl() {
3530
+ const u = new URL(URL)
3531
+ u.searchParams.set(${JSON.stringify(AGENT_RPC_TOKEN_QUERY)}, TOKEN)
3532
+ return u.toString()
3533
+ }
3534
+
3535
+ function call(method, params) {
3536
+ if (!URL || !TOKEN) {
3537
+ return Promise.resolve(jsonError(new Error("Agent RPC runtime is not running")))
3538
+ }
3539
+ return new Promise((resolve) => {
3540
+ let settled = false
3541
+ const done = (value) => {
3542
+ if (settled) return
3543
+ settled = true
3544
+ try { ws.close() } catch {}
3545
+ resolve(value)
3546
+ }
3547
+ const ws = new WebSocket(socketUrl())
3548
+ const id = Date.now()
3549
+ ws.addEventListener("open", () => {
3550
+ ws.send(JSON.stringify({ jsonrpc: "2.0", id, method, params, authToken: TOKEN }))
3551
+ })
3552
+ ws.addEventListener("message", (ev) => {
3553
+ let msg
3554
+ try { msg = JSON.parse(String(ev.data)) } catch { return }
3555
+ if (msg && msg.id === id) {
3556
+ if (msg.error) done(jsonError(new Error(msg.error.message || "Agent RPC error")))
3557
+ else done(jsonResult(msg.result))
3558
+ }
3559
+ })
3560
+ ws.addEventListener("error", () => done(jsonError(new Error("Agent RPC socket error"))))
3561
+ ws.addEventListener("close", () => {
3562
+ if (!settled) done(jsonError(new Error("Agent RPC socket closed")))
3563
+ })
3564
+ })
3565
+ }
3566
+
3567
+ function str(description) {
3568
+ return tool.schema.string().describe(description)
3569
+ }
3570
+
3571
+ function opt(description) {
3572
+ return tool.schema.string().optional().describe(description)
3573
+ }
3574
+
3575
+ export const SideboardRpc = async (ctx) => {
3576
+ const cwd = CWD || ctx.worktree || ctx.directory || ""
3577
+ const job = (method, args) => call(method, { ...args, cwd })
3578
+ return {
3579
+ tool: {
3580
+ present_artifact: tool({
3581
+ description: ${JSON.stringify(PILOT_TOOL_DESCRIPTIONS.present_artifact)},
3582
+ args: {
3583
+ title: str("Short title shown in the artifact pane header"),
3584
+ type: tool.schema.enum(["html", "svg", "markdown", "react", "log"]),
3585
+ content: str("html/svg/markdown/react: full document. log: only the new lines."),
3586
+ artifact_id: opt("Stable id. Required for type=log."),
3587
+ status: tool.schema.enum(["running", "ok", "failed", "idle"]).optional(),
3588
+ phase: opt("Progress phase"),
3589
+ mode: tool.schema.enum(["append", "replace"]).optional(),
3590
+ },
3591
+ async execute(args) {
3592
+ return call("ui.presentArtifact", args)
3593
+ },
3594
+ }),
3595
+ wait_for_job: tool({
3596
+ description: ${JSON.stringify(PILOT_TOOL_DESCRIPTIONS.wait_for_job)},
3597
+ args: {
3598
+ id: str("Detached job id (same kebab-case id passed to detached-job.cjs start)"),
3599
+ },
3600
+ async execute(args) {
3601
+ return job("job.wait", args)
3602
+ },
3603
+ }),
3604
+ stop_job: tool({
3605
+ description: ${JSON.stringify(PILOT_TOOL_DESCRIPTIONS.stop_job)},
3606
+ args: {
3607
+ id: str("Detached job id"),
3608
+ reason: opt("Why the job is being stopped"),
3609
+ },
3610
+ async execute(args) {
3611
+ return job("job.stop", args)
3612
+ },
3613
+ }),
3614
+ },
3615
+ }
3616
+ }
3617
+ `;
3618
+ function writeOpencodeRpcPlugin() {
3619
+ const configDir = join7(appDataDir(), "agent-rpc", "opencode");
3620
+ const pluginDir = join7(configDir, "plugins");
3621
+ mkdirSync2(pluginDir, { recursive: true });
3622
+ const pluginFile = join7(pluginDir, "sideboard-rpc.js");
3623
+ writeFileSync3(pluginFile, OPENCODE_PLUGIN_SOURCE);
3624
+ return { configDir, pluginFile };
3625
+ }
3626
+
3627
+ // src/agent-rpc/opencode-host.ts
3628
+ async function buildOpencodeHostEnv(thread) {
3629
+ const isOrchestrator = isOrchestratorThread(thread);
3630
+ const rpc = worktreeAgentRpc(isOrchestrator);
3631
+ const injected = await buildInjectedMcpServers({
3632
+ includeSideboard: true,
3633
+ includeBrightsy: shouldInjectBrightsyMcp(thread, {
3634
+ orchestrator: isOrchestrator
3635
+ }),
3636
+ orchestratorThreadId: isOrchestrator ? thread.id : null,
3637
+ threadId: thread.id,
3638
+ rpcNativeTools: Boolean(rpc)
3639
+ });
3640
+ const disableNames = isOrchestrator ? userMcpNamesToDisable({
3641
+ injectedNames: injected.map((s) => s.name),
3642
+ names: listUserOpencodeMcpNames()
3643
+ }) : [];
3644
+ const config = injected.length > 0 || disableNames.length > 0 ? JSON.parse(toOpencodeMcpConfigContent(injected, { disableNames })) : {};
3645
+ const env = {};
3646
+ if (rpc) {
3647
+ const { configDir, pluginFile } = writeOpencodeRpcPlugin();
3648
+ env.OPENCODE_CONFIG_DIR = configDir;
3649
+ Object.assign(env, agentRpcChildEnv(rpc, thread.worktreePath));
3650
+ config.plugin = [pluginFile];
3651
+ }
3652
+ if (Object.keys(config).length > 0) {
3653
+ env.OPENCODE_CONFIG_CONTENT = JSON.stringify(config);
3654
+ }
3655
+ return env;
3656
+ }
3657
+
3658
+ // src/agents/opencode.ts
3364
3659
  var FALLBACK_OPENCODE_MODELS = [
3365
3660
  { id: "opencode/big-pickle", displayName: "opencode \xB7 big-pickle" },
3366
3661
  {
@@ -3419,7 +3714,7 @@ async function listOpencodeModels() {
3419
3714
  if (opencode === "opencode") {
3420
3715
  const which = await run("which", ["opencode"], { reject: false });
3421
3716
  if (which.exitCode !== 0) return FALLBACK_OPENCODE_MODELS;
3422
- } else if (!existsSync8(opencode)) {
3717
+ } else if (!existsSync9(opencode)) {
3423
3718
  return FALLBACK_OPENCODE_MODELS;
3424
3719
  }
3425
3720
  const listed = await run(opencode, ["models"], { reject: false });
@@ -3454,7 +3749,7 @@ var opencodeAdapter = {
3454
3749
  async detect() {
3455
3750
  const opencode = resolveAgentExecutable("opencode");
3456
3751
  if (opencode !== "opencode") {
3457
- if (!existsSync8(opencode)) {
3752
+ if (!existsSync9(opencode)) {
3458
3753
  return {
3459
3754
  agent: "opencode",
3460
3755
  installed: false,
@@ -3508,20 +3803,7 @@ var opencodeAdapter = {
3508
3803
  if (model) {
3509
3804
  args.push("--model", model);
3510
3805
  }
3511
- const isOrchestrator = isOrchestratorThread(thread);
3512
- const injected = await buildInjectedMcpServers({
3513
- includeSideboard: true,
3514
- includeBrightsy: shouldInjectBrightsyMcp(thread, {
3515
- orchestrator: isOrchestrator
3516
- }),
3517
- orchestratorThreadId: isOrchestrator ? thread.id : null,
3518
- threadId: thread.id
3519
- });
3520
- const disableNames = isOrchestrator ? userMcpNamesToDisable({
3521
- injectedNames: injected.map((s) => s.name),
3522
- names: listUserOpencodeMcpNames()
3523
- }) : [];
3524
- const mcpContent = injected.length > 0 || disableNames.length > 0 ? toOpencodeMcpConfigContent(injected, { disableNames }) : null;
3806
+ const hostEnv = await buildOpencodeHostEnv(thread);
3525
3807
  return {
3526
3808
  file: resolveAgentExecutable("opencode"),
3527
3809
  args,
@@ -3531,7 +3813,7 @@ var opencodeAdapter = {
3531
3813
  stdin: prompt,
3532
3814
  env: {
3533
3815
  OPENCODE_PERMISSION: mode.opencodePermission,
3534
- ...mcpContent ? { OPENCODE_CONFIG_CONTENT: mcpContent } : {}
3816
+ ...hostEnv
3535
3817
  }
3536
3818
  };
3537
3819
  },
@@ -4132,9 +4414,9 @@ function formatClaudeUsageOverLimitWait(windows, now = /* @__PURE__ */ new Date(
4132
4414
  }
4133
4415
 
4134
4416
  // src/agents/claude-usage-client.ts
4135
- import { existsSync as existsSync9, readFileSync as readFileSync4 } from "fs";
4417
+ import { existsSync as existsSync10, readFileSync as readFileSync4 } from "fs";
4136
4418
  import { homedir as homedir4 } from "os";
4137
- import { join as join6 } from "path";
4419
+ import { join as join8 } from "path";
4138
4420
  var CLAUDE_OAUTH_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
4139
4421
  var CLAUDE_USAGE_TTL_MS = 9e4;
4140
4422
  var CLAUDE_USAGE_ERROR_TTL_MS = 5 * 6e4;
@@ -4174,12 +4456,12 @@ function accessTokenFromCredentialsJson(raw) {
4174
4456
  }
4175
4457
  }
4176
4458
  function claudeCredentialsPath(configDir) {
4177
- const root = configDir?.trim() || process.env.CLAUDE_CONFIG_DIR?.trim() || join6(homedir4(), ".claude");
4178
- return join6(root, ".credentials.json");
4459
+ const root = configDir?.trim() || process.env.CLAUDE_CONFIG_DIR?.trim() || join8(homedir4(), ".claude");
4460
+ return join8(root, ".credentials.json");
4179
4461
  }
4180
4462
  async function readFileAccessToken(configDir) {
4181
4463
  const path = claudeCredentialsPath(configDir);
4182
- if (!existsSync9(path)) return null;
4464
+ if (!existsSync10(path)) return null;
4183
4465
  try {
4184
4466
  return accessTokenFromCredentialsJson(readFileSync4(path, "utf8"));
4185
4467
  } catch {
@@ -4294,7 +4576,7 @@ async function getClaudePlanUsage(opts = {}) {
4294
4576
  }
4295
4577
 
4296
4578
  // src/agents/install.ts
4297
- import { existsSync as existsSync10 } from "fs";
4579
+ import { existsSync as existsSync11 } from "fs";
4298
4580
  var SETUP = {
4299
4581
  claude: {
4300
4582
  agent: "claude",
@@ -4475,7 +4757,7 @@ async function installNpmGlobalPackage(opts) {
4475
4757
  async function resolveExistingCli(agent) {
4476
4758
  if (agent === "cursor") return null;
4477
4759
  const exe = resolveAgentExecutable(agent);
4478
- if ((exe.includes("/") || exe.includes("\\")) && existsSync10(exe)) return exe;
4760
+ if ((exe.includes("/") || exe.includes("\\")) && existsSync11(exe)) return exe;
4479
4761
  enrichPathWithNpmGlobalBin();
4480
4762
  return whichOnPath(CLI_BIN[agent]);
4481
4763
  }
@@ -4549,7 +4831,7 @@ async function loginAgent(agent) {
4549
4831
  };
4550
4832
  }
4551
4833
  async function loginManagedAccount(accountId) {
4552
- const { loadAppSettings: loadAppSettings2 } = await import("./app-settings-VQEUCONM.js");
4834
+ const { loadAppSettings: loadAppSettings2 } = await import("./app-settings-RKFFUIFQ.js");
4553
4835
  const { loginEnvPrefix } = await import("./managed-accounts-2AK5RIAF.js");
4554
4836
  const account = loadAppSettings2().accounts.accounts.find((a) => a.id === accountId);
4555
4837
  if (!account) {
@@ -4646,8 +4928,13 @@ export {
4646
4928
  mcpAllowTools,
4647
4929
  mcpAllowToolsFromNames,
4648
4930
  mcpAuthWarnings,
4931
+ BASE_ALLOWED_TOOLS,
4932
+ CLAUDE_PRINT_BG_WAIT_CEILING_MS,
4933
+ CLAUDE_CHROME_ALLOWED_TOOLS,
4649
4934
  SIDEBOARD_MCP_PROFILE_ENV,
4650
4935
  SIDEBOARD_THREAD_ID_ENV,
4936
+ shouldRegisterMcpWaitForTurn,
4937
+ worktreeMcpToolNames,
4651
4938
  WORKTREE_MCP_TOOLS,
4652
4939
  WORKTREE_GITHUB_MCP_TOOLS,
4653
4940
  WORKTREE_LINEAR_MCP_TOOLS,