@sideboard-ai/core 0.1.299 → 0.1.301

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 (38) hide show
  1. package/dist/agents/claude-runner.cjs +36 -0
  2. package/dist/agents/claude-runner.js +17 -0
  3. package/dist/{agents-JCCJJMA7.js → agents-ETD2LWP4.js} +4 -4
  4. package/dist/{agents-IVKPCK56.js → agents-V2SRC2LH.js} +5 -4
  5. package/dist/{chunk-EB7B4D2Z.js → chunk-2KJE53ZJ.js} +15 -88
  6. package/dist/{chunk-3IXGI2FP.js → chunk-3XDU7RIE.js} +1 -1
  7. package/dist/{chunk-QB4UQA5L.js → chunk-7SEWZXPT.js} +2 -2
  8. package/dist/{chunk-F3JYJ4UB.js → chunk-EP4IIKP4.js} +4 -4
  9. package/dist/{chunk-HTL4FBTP.js → chunk-FBZODCO4.js} +65 -0
  10. package/dist/chunk-FO3NKZVJ.js +104 -0
  11. package/dist/{chunk-YAILSKW3.js → chunk-FPJFK4LB.js} +11 -11
  12. package/dist/{chunk-EB3F5AWV.js → chunk-FUXOZHHF.js} +15 -54
  13. package/dist/{chunk-NF3WDI7F.js → chunk-JTW4CZEQ.js} +41 -48
  14. package/dist/{chunk-G52HLBQR.js → chunk-KIWICTLW.js} +1 -1
  15. package/dist/{chunk-UMALFEDS.js → chunk-LZ744H2I.js} +2 -2
  16. package/dist/{chunk-MMIDAD6J.js → chunk-OJKSDRZU.js} +4 -4
  17. package/dist/{chunk-K5EACGG2.js → chunk-WV33I2GC.js} +13 -0
  18. package/dist/{conductor-UQDDDW35.js → conductor-57KZLWTB.js} +5 -4
  19. package/dist/{conductor-JLHXMMKR.js → conductor-57UKACQA.js} +4 -4
  20. package/dist/{coordinator-prompt-SSUYZSJO.js → coordinator-prompt-2TBRFJZ5.js} +3 -3
  21. package/dist/{coordinator-prompt-HKLVS26O.js → coordinator-prompt-VOWUJRVJ.js} +4 -3
  22. package/dist/{global-workspace-MHE6FCUZ.js → global-workspace-T5C7EMVV.js} +3 -3
  23. package/dist/{global-workspace-I32EWKX3.js → global-workspace-V6SOEETA.js} +4 -3
  24. package/dist/index.cjs +164 -120
  25. package/dist/index.d.cts +29 -18
  26. package/dist/index.d.ts +29 -18
  27. package/dist/index.js +43 -19
  28. package/dist/mcp/run-stdio.cjs +72 -57
  29. package/dist/mcp/run-stdio.js +6 -6
  30. package/dist/{orchestrator-SX4SGZHF.js → orchestrator-C43M3JDK.js} +6 -6
  31. package/dist/{orchestrator-ESLNXVOX.js → orchestrator-JEF7JC3S.js} +7 -6
  32. package/dist/{thread-store-5XXHSWMN.js → thread-store-BMNJEJUH.js} +1 -1
  33. package/dist/{thread-store-WXLXKDVN.js → thread-store-POAYB2ID.js} +2 -1
  34. package/dist/{workspaces-O3L32CDO.js → workspaces-7ZYTTB4A.js} +3 -3
  35. package/dist/{workspaces-ATMIKXLK.js → workspaces-EWVIEJ4O.js} +4 -3
  36. package/dist/{worktree-RMYXBTJG.js → worktree-2Q6J2VWZ.js} +3 -2
  37. package/dist/{worktree-6G5X4ABY.js → worktree-ZAJGYKCB.js} +2 -2
  38. package/package.json +1 -1
@@ -384,6 +384,29 @@ function createClaudePilotSdkServer(createSdkMcpServer, tool, opts) {
384
384
  return { server, exec };
385
385
  }
386
386
 
387
+ // src/agents/claude-mcp.ts
388
+ function sanitizeMcpServerName(name) {
389
+ return name.replace(/[^A-Za-z0-9_-]/g, "_");
390
+ }
391
+ function mcpServerIdForPermission(toolName, serverName) {
392
+ if (toolName.startsWith("mcp__")) {
393
+ const rest = toolName.slice("mcp__".length);
394
+ const split = rest.indexOf("__");
395
+ const id = (split === -1 ? rest : rest.slice(0, split)).trim();
396
+ if (id && id !== "*") return id;
397
+ }
398
+ const sanitized = sanitizeMcpServerName((serverName ?? "").trim());
399
+ return sanitized || null;
400
+ }
401
+ function mcpServerPermissionUpdate(serverId) {
402
+ return {
403
+ type: "addRules",
404
+ behavior: "allow",
405
+ destination: "session",
406
+ rules: [{ toolName: `mcp__${serverId}` }, { toolName: `mcp__${serverId}__*` }]
407
+ };
408
+ }
409
+
387
410
  // src/agents/claude-permission.ts
388
411
  function deny(message) {
389
412
  return { behavior: "deny", message, decisionClassification: "user_reject" };
@@ -405,6 +428,16 @@ async function claudePermissionResult(input) {
405
428
  if (input.permissionMode === "plan") {
406
429
  return deny("Plan mode is on, so this action stays blocked.");
407
430
  }
431
+ if (input.permissionMode === "bypassPermissions") {
432
+ const serverId = mcpServerIdForPermission(input.toolName, input.mcpServer);
433
+ if (serverId) {
434
+ return {
435
+ behavior: "allow",
436
+ updatedPermissions: [mcpServerPermissionUpdate(serverId)],
437
+ decisionClassification: "user_permanent"
438
+ };
439
+ }
440
+ }
408
441
  const threadId = input.threadId.trim();
409
442
  if (!threadId) return deny("Sideboard could not tell which chat to ask.");
410
443
  if (input.options.signal?.aborted) return deny("The turn was cancelled.");
@@ -420,6 +453,7 @@ async function claudePermissionResult(input) {
420
453
  description: input.options.description,
421
454
  displayName: input.options.displayName,
422
455
  suggestions: input.options.suggestions,
456
+ ...input.mcpServer ? { mcpServer: input.mcpServer } : {},
423
457
  suppressAlwaysAllow: input.options.suppressAlwaysAllowRule === true,
424
458
  defaultToNo: input.options.defaultToNo === true
425
459
  });
@@ -484,6 +518,7 @@ async function main() {
484
518
  cwd: req.cwd,
485
519
  pathToClaudeCodeExecutable: req.claudePath,
486
520
  permissionMode: req.permissionMode,
521
+ ...req.permissionMode === "bypassPermissions" ? { allowDangerouslySkipPermissions: true } : {},
487
522
  allowedTools: req.allowedTools,
488
523
  mcpServers,
489
524
  includePartialMessages: true
@@ -498,6 +533,7 @@ async function main() {
498
533
  threadId: process.env.SIDEBOARD_THREAD_ID?.trim() || "",
499
534
  toolName,
500
535
  toolInput,
536
+ mcpServer: toolOpts.mcpServer?.name,
501
537
  options: toolOpts,
502
538
  rpc: req.agentRpc
503
539
  });
@@ -1,4 +1,8 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ mcpServerIdForPermission,
4
+ mcpServerPermissionUpdate
5
+ } from "../chunk-FO3NKZVJ.js";
2
6
  import {
3
7
  AGENT_RPC_CLAUDE_SDK_SERVER,
4
8
  AgentRpcClient,
@@ -77,6 +81,16 @@ async function claudePermissionResult(input) {
77
81
  if (input.permissionMode === "plan") {
78
82
  return deny("Plan mode is on, so this action stays blocked.");
79
83
  }
84
+ if (input.permissionMode === "bypassPermissions") {
85
+ const serverId = mcpServerIdForPermission(input.toolName, input.mcpServer);
86
+ if (serverId) {
87
+ return {
88
+ behavior: "allow",
89
+ updatedPermissions: [mcpServerPermissionUpdate(serverId)],
90
+ decisionClassification: "user_permanent"
91
+ };
92
+ }
93
+ }
80
94
  const threadId = input.threadId.trim();
81
95
  if (!threadId) return deny("Sideboard could not tell which chat to ask.");
82
96
  if (input.options.signal?.aborted) return deny("The turn was cancelled.");
@@ -92,6 +106,7 @@ async function claudePermissionResult(input) {
92
106
  description: input.options.description,
93
107
  displayName: input.options.displayName,
94
108
  suggestions: input.options.suggestions,
109
+ ...input.mcpServer ? { mcpServer: input.mcpServer } : {},
95
110
  suppressAlwaysAllow: input.options.suppressAlwaysAllowRule === true,
96
111
  defaultToNo: input.options.defaultToNo === true
97
112
  });
@@ -156,6 +171,7 @@ async function main() {
156
171
  cwd: req.cwd,
157
172
  pathToClaudeCodeExecutable: req.claudePath,
158
173
  permissionMode: req.permissionMode,
174
+ ...req.permissionMode === "bypassPermissions" ? { allowDangerouslySkipPermissions: true } : {},
159
175
  allowedTools: req.allowedTools,
160
176
  mcpServers,
161
177
  includePartialMessages: true
@@ -170,6 +186,7 @@ async function main() {
170
186
  threadId: process.env.SIDEBOARD_THREAD_ID?.trim() || "",
171
187
  toolName,
172
188
  toolInput,
189
+ mcpServer: toolOpts.mcpServer?.name,
173
190
  options: toolOpts,
174
191
  rpc: req.agentRpc
175
192
  });
@@ -46,7 +46,7 @@ import {
46
46
  resolveCursorSdkRoot,
47
47
  resolveQuotaFallbackAgent,
48
48
  turnCostUsdFromCursorUsage
49
- } from "./chunk-EB3F5AWV.js";
49
+ } from "./chunk-FUXOZHHF.js";
50
50
  import {
51
51
  getAgentSetupInfo,
52
52
  installAgent,
@@ -63,8 +63,8 @@ import "./chunk-7IAMHN2N.js";
63
63
  import "./chunk-PXMLMBMI.js";
64
64
  import "./chunk-2GPQZZLY.js";
65
65
  import "./chunk-5XQ43YZU.js";
66
- import "./chunk-UMALFEDS.js";
67
- import "./chunk-3IXGI2FP.js";
66
+ import "./chunk-LZ744H2I.js";
67
+ import "./chunk-3XDU7RIE.js";
68
68
  import "./chunk-N2WW62LF.js";
69
69
  import "./chunk-DD67JWTN.js";
70
70
  import {
@@ -88,7 +88,7 @@ import "./chunk-NSTQ6QKD.js";
88
88
  import "./chunk-WWUABK6B.js";
89
89
  import "./chunk-FJZWM2ON.js";
90
90
  import "./chunk-UN5Q7POQ.js";
91
- import "./chunk-HTL4FBTP.js";
91
+ import "./chunk-FBZODCO4.js";
92
92
  import "./chunk-4RZRHTSZ.js";
93
93
  import "./chunk-KGZBYWZ3.js";
94
94
  import "./chunk-H5XL4KUS.js";
@@ -37,7 +37,7 @@ import {
37
37
  planModeTurnInstruction,
38
38
  resolveCursorModelId,
39
39
  resolveQuotaFallbackAgent
40
- } from "./chunk-EB7B4D2Z.js";
40
+ } from "./chunk-2KJE53ZJ.js";
41
41
  import "./chunk-VGNLMGBK.js";
42
42
  import "./chunk-F36QRDM4.js";
43
43
  import {
@@ -52,12 +52,13 @@ import {
52
52
  resolveLoginCommand,
53
53
  whichOnPath
54
54
  } from "./chunk-B42H6GJR.js";
55
- import "./chunk-QB4UQA5L.js";
56
- import "./chunk-G52HLBQR.js";
57
- import "./chunk-K5EACGG2.js";
55
+ import "./chunk-7SEWZXPT.js";
56
+ import "./chunk-KIWICTLW.js";
57
+ import "./chunk-WV33I2GC.js";
58
58
  import "./chunk-2P4XKWV2.js";
59
59
  import "./chunk-33KDPEK4.js";
60
60
  import "./chunk-JAT3JFOS.js";
61
+ import "./chunk-FO3NKZVJ.js";
61
62
  import {
62
63
  CURSOR_SDK_INSTALL_HINT,
63
64
  cursorSdkMessageToEvents,
@@ -12,19 +12,26 @@ import {
12
12
  } from "./chunk-F36QRDM4.js";
13
13
  import {
14
14
  isOrchestratorThread
15
- } from "./chunk-QB4UQA5L.js";
15
+ } from "./chunk-7SEWZXPT.js";
16
16
  import {
17
17
  codexUnattendedGitConfigArgs,
18
18
  mergeAgentGitAuthEnv,
19
19
  resolveAgentGitAuthEnv,
20
20
  resolveCodexGitWritableRoots
21
- } from "./chunk-G52HLBQR.js";
21
+ } from "./chunk-KIWICTLW.js";
22
22
  import {
23
23
  loadBrightsyConfig
24
24
  } from "./chunk-33KDPEK4.js";
25
25
  import {
26
26
  httpFetch
27
27
  } from "./chunk-JAT3JFOS.js";
28
+ import {
29
+ BASE_ALLOWED_TOOLS,
30
+ CLAUDE_CHROME_ALLOWED_TOOLS,
31
+ CLAUDE_POSTHOG_CONNECTOR_ALLOWED_TOOLS,
32
+ CLAUDE_PRINT_BG_WAIT_CEILING_MS,
33
+ mcpAllowToolsFromNames
34
+ } from "./chunk-FO3NKZVJ.js";
28
35
  import {
29
36
  CURSOR_SDK_INSTALL_HINT,
30
37
  applyAgentRunnerHeapEnv,
@@ -507,79 +514,6 @@ var brightsyAdapter = {
507
514
  // src/agents/claude.ts
508
515
  import { existsSync as existsSync6 } from "fs";
509
516
 
510
- // src/agents/claude-mcp.ts
511
- function parseMcpList(text) {
512
- const servers = [];
513
- const seen = /* @__PURE__ */ new Set();
514
- for (const raw of text.split("\n")) {
515
- const line = raw.trim();
516
- if (!line || /^Checking MCP/i.test(line)) continue;
517
- const m = line.match(/^(.+?):\s+\S+/);
518
- if (!m) continue;
519
- const name = m[1].trim();
520
- if (!name || seen.has(name)) continue;
521
- const needsAuth = /Needs authentication/i.test(line);
522
- const connected = !needsAuth && /Connected/i.test(line);
523
- if (!needsAuth && !connected) continue;
524
- seen.add(name);
525
- servers.push({ name, connected, needsAuth });
526
- }
527
- return servers;
528
- }
529
- function sanitizeMcpServerName(name) {
530
- return name.replace(/[^A-Za-z0-9_-]/g, "_");
531
- }
532
- function mcpAllowTools(servers) {
533
- const out = [];
534
- for (const s of servers) {
535
- if (!s.connected) continue;
536
- const id = sanitizeMcpServerName(s.name);
537
- if (!id) continue;
538
- out.push(`mcp__${id}`);
539
- out.push(`mcp__${id}__*`);
540
- }
541
- return out;
542
- }
543
- function mcpAllowToolsFromNames(names) {
544
- return mcpAllowTools(
545
- [...names].map((name) => name.trim()).filter(Boolean).map((name) => ({ name, connected: true, needsAuth: false }))
546
- );
547
- }
548
- function mcpAuthWarnings(servers) {
549
- const needing = servers.filter((s) => s.needsAuth).map((s) => s.name);
550
- if (needing.length === 0) return [];
551
- return [
552
- `MCP needs login: ${needing.join(", ")}. Run: claude mcp login "<name>"`
553
- ];
554
- }
555
- var BASE_ALLOWED_TOOLS = [
556
- "Edit",
557
- "Write",
558
- "Bash",
559
- "Read",
560
- "Glob",
561
- "Grep",
562
- "WebFetch",
563
- "WebSearch",
564
- "Task",
565
- "Agent",
566
- "TaskOutput",
567
- "TaskStop",
568
- "EnterWorktree",
569
- "ExitWorktree",
570
- "Skill"
571
- ];
572
- var CLAUDE_PRINT_BG_WAIT_CEILING_MS = 72e5;
573
- var CLAUDE_CHROME_ALLOWED_TOOLS = [
574
- "mcp__claude-in-chrome",
575
- "mcp__claude-in-chrome__*",
576
- "Skill(claude-in-chrome)"
577
- ];
578
- var CLAUDE_POSTHOG_CONNECTOR_ALLOWED_TOOLS = [
579
- "mcp__claude_ai_PostHog",
580
- "mcp__claude_ai_PostHog__*"
581
- ];
582
-
583
517
  // src/agents/orch-mcp-isolation.ts
584
518
  import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
585
519
  import { homedir as homedir2 } from "os";
@@ -1757,7 +1691,7 @@ var claudeAdapter = {
1757
1691
  );
1758
1692
  }
1759
1693
  const mode = permissionMode(thread);
1760
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-I32EWKX3.js");
1694
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-V6SOEETA.js");
1761
1695
  const isOrchestrator = isOrchestratorThread2(thread);
1762
1696
  const rpc = worktreeAgentRpc(isOrchestrator);
1763
1697
  const injectedServers = await buildInjectedMcpServers({
@@ -1777,12 +1711,13 @@ var claudeAdapter = {
1777
1711
  allowedTools = [
1778
1712
  ...BASE_ALLOWED_TOOLS,
1779
1713
  ...SIDEBOARD_MCP_ALLOWED_TOOLS,
1780
- ...brightsyMcpAllowedTools(injectedBrightsyNames)
1714
+ ...brightsyMcpAllowedTools(injectedBrightsyNames),
1715
+ ...mcpAllowToolsFromNames(thread.approvedMcpServers ?? [])
1781
1716
  ];
1782
1717
  } else {
1783
1718
  allowedTools = [
1784
1719
  ...BASE_ALLOWED_TOOLS,
1785
- ...mcpAllowToolsFromNames(Object.keys(userMcpEntries)),
1720
+ ...mcpAllowToolsFromNames([...Object.keys(userMcpEntries), ...thread.approvedMcpServers ?? []]),
1786
1721
  ...sideboardWorktreeAllowedTools({
1787
1722
  github: true,
1788
1723
  linear: isLinearConnected(),
@@ -1822,7 +1757,8 @@ var claudeAdapter = {
1822
1757
  "--verbose",
1823
1758
  "--include-partial-messages",
1824
1759
  "--permission-mode",
1825
- mode.claude
1760
+ mode.claude,
1761
+ ...mode.claude === "bypassPermissions" ? ["--dangerously-skip-permissions"] : []
1826
1762
  ];
1827
1763
  if (systemPrompt) {
1828
1764
  args.push("--append-system-prompt", systemPrompt);
@@ -3682,15 +3618,6 @@ export {
3682
3618
  adjustBrightsyTurnExit,
3683
3619
  listBrightsyChatTargets,
3684
3620
  brightsyAdapter,
3685
- parseMcpList,
3686
- sanitizeMcpServerName,
3687
- mcpAllowTools,
3688
- mcpAllowToolsFromNames,
3689
- mcpAuthWarnings,
3690
- BASE_ALLOWED_TOOLS,
3691
- CLAUDE_PRINT_BG_WAIT_CEILING_MS,
3692
- CLAUDE_CHROME_ALLOWED_TOOLS,
3693
- CLAUDE_POSTHOG_CONNECTOR_ALLOWED_TOOLS,
3694
3621
  SIDEBOARD_MCP_PROFILE_ENV,
3695
3622
  SIDEBOARD_THREAD_ID_ENV,
3696
3623
  shouldRegisterMcpWaitForTurn,
@@ -26,7 +26,7 @@ import {
26
26
  normalizeTakenSlug,
27
27
  normalizeWorktreePath,
28
28
  takenSlugsFromThread
29
- } from "./chunk-HTL4FBTP.js";
29
+ } from "./chunk-FBZODCO4.js";
30
30
  import {
31
31
  worktreesRoot
32
32
  } from "./chunk-H5XL4KUS.js";
@@ -3,7 +3,7 @@ import {
3
3
  ensureGhPreferOrigin,
4
4
  resolveGithubRepoSlug,
5
5
  resolveRepoRoot
6
- } from "./chunk-G52HLBQR.js";
6
+ } from "./chunk-KIWICTLW.js";
7
7
  import {
8
8
  allocateTeamName,
9
9
  createEmptyThread,
@@ -12,7 +12,7 @@ import {
12
12
  teamSlugFromName,
13
13
  updateThread,
14
14
  writeThread
15
- } from "./chunk-K5EACGG2.js";
15
+ } from "./chunk-WV33I2GC.js";
16
16
  import {
17
17
  ATTACHMENTS_DIR,
18
18
  attachmentsGitignoreBody
@@ -11,11 +11,11 @@ import {
11
11
  isGlobalThread,
12
12
  isOrchestratorThread,
13
13
  isSlackCoordinatorThread
14
- } from "./chunk-UMALFEDS.js";
14
+ } from "./chunk-LZ744H2I.js";
15
15
  import {
16
16
  mergeAgentGitAuthEnv,
17
17
  resolveAgentGitAuthEnv
18
- } from "./chunk-3IXGI2FP.js";
18
+ } from "./chunk-3XDU7RIE.js";
19
19
  import {
20
20
  ATTACHMENTS_DIR,
21
21
  DETACHED_JOBS_DIR,
@@ -46,7 +46,7 @@ import {
46
46
  updateThread,
47
47
  worktreeNameFromPath,
48
48
  writeThread
49
- } from "./chunk-HTL4FBTP.js";
49
+ } from "./chunk-FBZODCO4.js";
50
50
  import {
51
51
  findConventionSetup,
52
52
  loadRepoSettings,
@@ -1674,7 +1674,7 @@ var PORT_RANGE_SIZE = 10;
1674
1674
  var RECLAIM_RETRY_DELAY_MS = 40;
1675
1675
  var RECLAIM_TRIES = 8;
1676
1676
  async function killReclaimable(ports, worktreePath, signal) {
1677
- const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-JLHXMMKR.js");
1677
+ const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-57UKACQA.js");
1678
1678
  if (worktreePath) killStaleWorktreeListeners2(ports, worktreePath, signal);
1679
1679
  else killListenersOnPorts2(ports);
1680
1680
  }
@@ -945,6 +945,56 @@ import {
945
945
  } from "fs";
946
946
  import { basename } from "path";
947
947
  import lockfile from "proper-lockfile";
948
+
949
+ // src/agents/claude-mcp.ts
950
+ function sanitizeMcpServerName(name) {
951
+ return name.replace(/[^A-Za-z0-9_-]/g, "_");
952
+ }
953
+ function mcpAllowTools(servers) {
954
+ const out = [];
955
+ for (const s of servers) {
956
+ if (!s.connected) continue;
957
+ const id = sanitizeMcpServerName(s.name);
958
+ if (!id) continue;
959
+ out.push(`mcp__${id}`);
960
+ out.push(`mcp__${id}__*`);
961
+ }
962
+ return out;
963
+ }
964
+ function mcpAllowToolsFromNames(names) {
965
+ return mcpAllowTools(
966
+ [...names].map((name) => name.trim()).filter(Boolean).map((name) => ({ name, connected: true, needsAuth: false }))
967
+ );
968
+ }
969
+ var BASE_ALLOWED_TOOLS = [
970
+ "Edit",
971
+ "Write",
972
+ "Bash",
973
+ "Read",
974
+ "Glob",
975
+ "Grep",
976
+ "WebFetch",
977
+ "WebSearch",
978
+ "Task",
979
+ "Agent",
980
+ "TaskOutput",
981
+ "TaskStop",
982
+ "EnterWorktree",
983
+ "ExitWorktree",
984
+ "Skill"
985
+ ];
986
+ var CLAUDE_PRINT_BG_WAIT_CEILING_MS = 72e5;
987
+ var CLAUDE_CHROME_ALLOWED_TOOLS = [
988
+ "mcp__claude-in-chrome",
989
+ "mcp__claude-in-chrome__*",
990
+ "Skill(claude-in-chrome)"
991
+ ];
992
+ var CLAUDE_POSTHOG_CONNECTOR_ALLOWED_TOOLS = [
993
+ "mcp__claude_ai_PostHog",
994
+ "mcp__claude_ai_PostHog__*"
995
+ ];
996
+
997
+ // src/store/thread-store.ts
948
998
  function nowIso() {
949
999
  return (/* @__PURE__ */ new Date()).toISOString();
950
1000
  }
@@ -954,6 +1004,15 @@ function resolveThreadEffort(raw) {
954
1004
  if (raw.fast) return "low";
955
1005
  return "high";
956
1006
  }
1007
+ function normalizeApprovedMcpServers(raw) {
1008
+ if (!Array.isArray(raw)) return void 0;
1009
+ const ids = [
1010
+ ...new Set(
1011
+ raw.map((value) => typeof value === "string" ? sanitizeMcpServerName(value.trim()) : "").filter(Boolean)
1012
+ )
1013
+ ];
1014
+ return ids.length > 0 ? ids : void 0;
1015
+ }
957
1016
  function normalizeRunScriptRequest(raw) {
958
1017
  if (!raw || typeof raw !== "object") return void 0;
959
1018
  const req = raw;
@@ -979,6 +1038,7 @@ function normalizeThread(raw) {
979
1038
  planMode: Boolean(raw.planMode),
980
1039
  isolateCodexPlugins: raw.isolateCodexPlugins === true ? true : void 0,
981
1040
  autonomy: raw.autonomy ?? "default",
1041
+ approvedMcpServers: normalizeApprovedMcpServers(raw.approvedMcpServers),
982
1042
  lastError: raw.lastError ?? null,
983
1043
  agentPid: raw.agentPid ?? null,
984
1044
  attachments: Array.isArray(raw.attachments) ? raw.attachments : [],
@@ -1231,6 +1291,11 @@ export {
1231
1291
  agentNicknameFromWorktreePath,
1232
1292
  worktreeIdentityTitles,
1233
1293
  isWorktreeIdentityTitle,
1294
+ mcpAllowToolsFromNames,
1295
+ BASE_ALLOWED_TOOLS,
1296
+ CLAUDE_PRINT_BG_WAIT_CEILING_MS,
1297
+ CLAUDE_CHROME_ALLOWED_TOOLS,
1298
+ CLAUDE_POSTHOG_CONNECTOR_ALLOWED_TOOLS,
1234
1299
  resolveThreadEffort,
1235
1300
  normalizeThread,
1236
1301
  createEmptyThread,
@@ -0,0 +1,104 @@
1
+ // src/agents/claude-mcp.ts
2
+ function parseMcpList(text) {
3
+ const servers = [];
4
+ const seen = /* @__PURE__ */ new Set();
5
+ for (const raw of text.split("\n")) {
6
+ const line = raw.trim();
7
+ if (!line || /^Checking MCP/i.test(line)) continue;
8
+ const m = line.match(/^(.+?):\s+\S+/);
9
+ if (!m) continue;
10
+ const name = m[1].trim();
11
+ if (!name || seen.has(name)) continue;
12
+ const needsAuth = /Needs authentication/i.test(line);
13
+ const connected = !needsAuth && /Connected/i.test(line);
14
+ if (!needsAuth && !connected) continue;
15
+ seen.add(name);
16
+ servers.push({ name, connected, needsAuth });
17
+ }
18
+ return servers;
19
+ }
20
+ function sanitizeMcpServerName(name) {
21
+ return name.replace(/[^A-Za-z0-9_-]/g, "_");
22
+ }
23
+ function mcpServerIdForPermission(toolName, serverName) {
24
+ if (toolName.startsWith("mcp__")) {
25
+ const rest = toolName.slice("mcp__".length);
26
+ const split = rest.indexOf("__");
27
+ const id = (split === -1 ? rest : rest.slice(0, split)).trim();
28
+ if (id && id !== "*") return id;
29
+ }
30
+ const sanitized = sanitizeMcpServerName((serverName ?? "").trim());
31
+ return sanitized || null;
32
+ }
33
+ function mcpServerPermissionUpdate(serverId) {
34
+ return {
35
+ type: "addRules",
36
+ behavior: "allow",
37
+ destination: "session",
38
+ rules: [{ toolName: `mcp__${serverId}` }, { toolName: `mcp__${serverId}__*` }]
39
+ };
40
+ }
41
+ function mcpAllowTools(servers) {
42
+ const out = [];
43
+ for (const s of servers) {
44
+ if (!s.connected) continue;
45
+ const id = sanitizeMcpServerName(s.name);
46
+ if (!id) continue;
47
+ out.push(`mcp__${id}`);
48
+ out.push(`mcp__${id}__*`);
49
+ }
50
+ return out;
51
+ }
52
+ function mcpAllowToolsFromNames(names) {
53
+ return mcpAllowTools(
54
+ [...names].map((name) => name.trim()).filter(Boolean).map((name) => ({ name, connected: true, needsAuth: false }))
55
+ );
56
+ }
57
+ function mcpAuthWarnings(servers) {
58
+ const needing = servers.filter((s) => s.needsAuth).map((s) => s.name);
59
+ if (needing.length === 0) return [];
60
+ return [
61
+ `MCP needs login: ${needing.join(", ")}. Run: claude mcp login "<name>"`
62
+ ];
63
+ }
64
+ var BASE_ALLOWED_TOOLS = [
65
+ "Edit",
66
+ "Write",
67
+ "Bash",
68
+ "Read",
69
+ "Glob",
70
+ "Grep",
71
+ "WebFetch",
72
+ "WebSearch",
73
+ "Task",
74
+ "Agent",
75
+ "TaskOutput",
76
+ "TaskStop",
77
+ "EnterWorktree",
78
+ "ExitWorktree",
79
+ "Skill"
80
+ ];
81
+ var CLAUDE_PRINT_BG_WAIT_CEILING_MS = 72e5;
82
+ var CLAUDE_CHROME_ALLOWED_TOOLS = [
83
+ "mcp__claude-in-chrome",
84
+ "mcp__claude-in-chrome__*",
85
+ "Skill(claude-in-chrome)"
86
+ ];
87
+ var CLAUDE_POSTHOG_CONNECTOR_ALLOWED_TOOLS = [
88
+ "mcp__claude_ai_PostHog",
89
+ "mcp__claude_ai_PostHog__*"
90
+ ];
91
+
92
+ export {
93
+ parseMcpList,
94
+ sanitizeMcpServerName,
95
+ mcpServerIdForPermission,
96
+ mcpServerPermissionUpdate,
97
+ mcpAllowTools,
98
+ mcpAllowToolsFromNames,
99
+ mcpAuthWarnings,
100
+ BASE_ALLOWED_TOOLS,
101
+ CLAUDE_PRINT_BG_WAIT_CEILING_MS,
102
+ CLAUDE_CHROME_ALLOWED_TOOLS,
103
+ CLAUDE_POSTHOG_CONNECTOR_ALLOWED_TOOLS
104
+ };
@@ -27,7 +27,7 @@ import {
27
27
  parseSessionQuotaResetAt,
28
28
  planModeTurnInstruction,
29
29
  resolveQuotaFallbackAgent
30
- } from "./chunk-EB3F5AWV.js";
30
+ } from "./chunk-FUXOZHHF.js";
31
31
  import {
32
32
  REVIEW_TAB_TITLE,
33
33
  applyWorktreePkgCacheEnv,
@@ -66,7 +66,7 @@ import {
66
66
  worktreeDevProcessKey,
67
67
  worktreeRunProcessKey,
68
68
  worktreeSetupProcessKey
69
- } from "./chunk-F3JYJ4UB.js";
69
+ } from "./chunk-EP4IIKP4.js";
70
70
  import {
71
71
  applyAgentEvent,
72
72
  clipAgentEventForPaint,
@@ -118,7 +118,7 @@ import {
118
118
  stageAbsolutePathsAsAttachments,
119
119
  stageBuffersAsAttachments,
120
120
  syncWorkspacesFromThreads
121
- } from "./chunk-UMALFEDS.js";
121
+ } from "./chunk-LZ744H2I.js";
122
122
  import {
123
123
  addPrStackLayer,
124
124
  allocateTeamSlug,
@@ -160,7 +160,7 @@ import {
160
160
  resolveRepoRoot,
161
161
  switchWorktreeBranch,
162
162
  withRepoGitLock
163
- } from "./chunk-3IXGI2FP.js";
163
+ } from "./chunk-3XDU7RIE.js";
164
164
  import {
165
165
  clearStaleIndexLocks,
166
166
  enrichPathWithNpmGlobalBin,
@@ -238,7 +238,7 @@ import {
238
238
  worktreeNameFromPath,
239
239
  worktreeSlugForTicket,
240
240
  writeThread
241
- } from "./chunk-HTL4FBTP.js";
241
+ } from "./chunk-FBZODCO4.js";
242
242
  import {
243
243
  annotateDevAccessRuns,
244
244
  appDataDir,
@@ -503,9 +503,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
503
503
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
504
504
  );
505
505
  }
506
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-MHE6FCUZ.js");
506
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-T5C7EMVV.js");
507
507
  if (isGlobalThread2(thread)) {
508
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-SSUYZSJO.js");
508
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-2TBRFJZ5.js");
509
509
  ensureGlobalCoordinatorCwd2(
510
510
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
511
511
  );
@@ -3444,7 +3444,7 @@ async function adoptThread(input) {
3444
3444
  messages: input.messages ?? []
3445
3445
  });
3446
3446
  writeThread(thread);
3447
- const { addWorkspace: addWorkspace2 } = await import("./workspaces-O3L32CDO.js");
3447
+ const { addWorkspace: addWorkspace2 } = await import("./workspaces-7ZYTTB4A.js");
3448
3448
  await addWorkspace2(repoPath);
3449
3449
  const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-5N2KTYIT.js");
3450
3450
  await ensureWorktreeSideboardIgnored(input.worktreePath);
@@ -6329,7 +6329,7 @@ function formatScheduledPrompt(name, prompt) {
6329
6329
  ${prompt}`;
6330
6330
  }
6331
6331
  async function defaultDeps() {
6332
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-SX4SGZHF.js");
6332
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-C43M3JDK.js");
6333
6333
  const orch = getOrchestrator2();
6334
6334
  return {
6335
6335
  findThread: (id) => findThreadByRef(id),
@@ -9204,7 +9204,7 @@ async function startOrchestration(opts) {
9204
9204
  sourceRef: "default",
9205
9205
  ...createOpts
9206
9206
  }).catch(async () => {
9207
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-6G5X4ABY.js");
9207
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-ZAJGYKCB.js");
9208
9208
  const repo = await resolveRepoRoot2(repoPath);
9209
9209
  const def = await resolveDefaultBranch2(repo);
9210
9210
  return orch.createThread({
@@ -9214,7 +9214,7 @@ async function startOrchestration(opts) {
9214
9214
  repoPath: repo
9215
9215
  });
9216
9216
  });
9217
- const { updateThread: upd } = await import("./thread-store-5XXHSWMN.js");
9217
+ const { updateThread: upd } = await import("./thread-store-BMNJEJUH.js");
9218
9218
  const updated = upd(thread.id, {
9219
9219
  sourceType: "orchestration",
9220
9220
  sourceRef: goal