@sideboard-ai/core 0.1.218 → 0.1.220

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 (35) hide show
  1. package/dist/{agents-YABJUV3V.js → agents-6UOWJLXX.js} +4 -4
  2. package/dist/{agents-NWJ7DFJD.js → agents-DYSZ2JFY.js} +4 -4
  3. package/dist/{chunk-FSIJGLSV.js → chunk-3Y4FIARC.js} +39 -11
  4. package/dist/{chunk-JWBPSD7Q.js → chunk-ALDVGAIO.js} +8 -8
  5. package/dist/{chunk-SRFFIFW6.js → chunk-B73KKJQB.js} +9 -9
  6. package/dist/{chunk-OPYBLX4V.js → chunk-N2VST3NL.js} +49 -2
  7. package/dist/chunk-P2BSMNHB.js +179 -0
  8. package/dist/{chunk-MW57SKKR.js → chunk-P2EAAM3H.js} +49 -2
  9. package/dist/{chunk-IILG7DPX.js → chunk-QILV2BRW.js} +31 -18
  10. package/dist/chunk-ROPGQRPU.js +178 -0
  11. package/dist/{chunk-SVXIJ2IC.js → chunk-UNMMKZ4Q.js} +26 -13
  12. package/dist/{chunk-XRHTRXZN.js → chunk-YG2X34EF.js} +39 -11
  13. package/dist/{connected-teams-LX5DLL2I.js → connected-teams-PRHZS6B4.js} +2 -2
  14. package/dist/{connected-teams-PQETXUWV.js → connected-teams-YOIB42RB.js} +2 -2
  15. package/dist/{coordinator-prompt-5V7GEPBG.js → coordinator-prompt-JLMQVORO.js} +1 -1
  16. package/dist/{coordinator-prompt-J4QSNTKE.js → coordinator-prompt-VZ7OSRLD.js} +1 -1
  17. package/dist/{global-workspace-4TEMLESD.js → global-workspace-3FDAUNN2.js} +1 -1
  18. package/dist/{global-workspace-XPTFHMKL.js → global-workspace-QPSJEXGR.js} +1 -1
  19. package/dist/index.cjs +216 -43
  20. package/dist/index.d.cts +40 -2
  21. package/dist/index.d.ts +40 -2
  22. package/dist/index.js +17 -5
  23. package/dist/mcp/run-stdio.cjs +196 -41
  24. package/dist/mcp/run-stdio.js +5 -5
  25. package/dist/oauth-K6CWZEQO.js +23 -0
  26. package/dist/oauth-S3M7B475.js +21 -0
  27. package/dist/{orchestrator-SWRTYFHX.js → orchestrator-P4KNHFHG.js} +5 -5
  28. package/dist/{orchestrator-HKW3VLGX.js → orchestrator-Y5IDLJ7D.js} +5 -5
  29. package/dist/{workspaces-BCBBMMXB.js → workspaces-76W7IEKR.js} +3 -1
  30. package/dist/{workspaces-2HQP654Q.js → workspaces-TDBA64II.js} +3 -1
  31. package/package.json +1 -1
  32. package/dist/chunk-AN3THU7F.js +0 -103
  33. package/dist/chunk-Y4MIXGPA.js +0 -104
  34. package/dist/oauth-6ZQ4Q4XN.js +0 -11
  35. package/dist/oauth-O7UGLZOY.js +0 -13
@@ -1,10 +1,11 @@
1
1
  import {
2
2
  brightsyAccessTokenNeedsRefresh,
3
3
  ensureBrightsyLocalConfigFresh,
4
+ ensureBrightsyOAuthClientId,
4
5
  loadBrightsyConfig,
5
6
  refreshBrightsyAccessToken,
6
7
  saveBrightsyConfig
7
- } from "./chunk-AN3THU7F.js";
8
+ } from "./chunk-ROPGQRPU.js";
8
9
  import {
9
10
  appDataDir
10
11
  } from "./chunk-WFUDY6PC.js";
@@ -18,7 +19,7 @@ import { join } from "path";
18
19
 
19
20
  // src/brightsy/accounts.ts
20
21
  async function loadConnectedTeams() {
21
- const { listConnectedBrightsyTeams: listConnectedBrightsyTeams2 } = await import("./connected-teams-LX5DLL2I.js");
22
+ const { listConnectedBrightsyTeams: listConnectedBrightsyTeams2 } = await import("./connected-teams-PRHZS6B4.js");
22
23
  return listConnectedBrightsyTeams2();
23
24
  }
24
25
  async function runBrightsyTeamsJson(args) {
@@ -46,15 +47,15 @@ async function listBrightsyAccounts() {
46
47
  }
47
48
  async function getBrightsySession() {
48
49
  try {
49
- const { ensureBrightsyLocalConfigFresh: ensureBrightsyLocalConfigFresh2 } = await import("./oauth-6ZQ4Q4XN.js");
50
- const { ensureConnectedBrightsyTeamTokens: ensureConnectedBrightsyTeamTokens2 } = await import("./connected-teams-LX5DLL2I.js");
50
+ const { ensureBrightsyLocalConfigFresh: ensureBrightsyLocalConfigFresh2 } = await import("./oauth-S3M7B475.js");
51
+ const { ensureConnectedBrightsyTeamTokens: ensureConnectedBrightsyTeamTokens2 } = await import("./connected-teams-PRHZS6B4.js");
51
52
  await ensureBrightsyLocalConfigFresh2();
52
53
  await ensureConnectedBrightsyTeamTokens2();
53
54
  loadBrightsyConfig();
54
55
  const data = await runBrightsyTeamsJson([]);
55
56
  const accounts = Array.isArray(data.teams) ? data.teams : [];
56
57
  const active = data.active ?? accounts.find((a) => a.active) ?? null;
57
- const { ensureCliTeamTracked: ensureCliTeamTracked2 } = await import("./connected-teams-LX5DLL2I.js");
58
+ const { ensureCliTeamTracked: ensureCliTeamTracked2 } = await import("./connected-teams-PRHZS6B4.js");
58
59
  const connectedTeams = ensureCliTeamTracked2(
59
60
  active ? { id: active.id, slug: active.slug, name: active.name } : void 0
60
61
  );
@@ -94,7 +95,7 @@ async function performBrightsyAccountSwitch(accountIdOrSlug) {
94
95
  return { cfg, target: data.active };
95
96
  }
96
97
  async function switchBrightsyAccount(accountIdOrSlug) {
97
- const { connectBrightsyTeam: connectBrightsyTeam2 } = await import("./connected-teams-LX5DLL2I.js");
98
+ const { connectBrightsyTeam: connectBrightsyTeam2 } = await import("./connected-teams-PRHZS6B4.js");
98
99
  await connectBrightsyTeam2(accountIdOrSlug);
99
100
  return getBrightsySession();
100
101
  }
@@ -147,10 +148,10 @@ function applyConnectedTeamToCli(team) {
147
148
  account_id: team.id,
148
149
  account_slug: team.slug,
149
150
  endpoint: team.endpoint ?? base.endpoint ?? "https://brightsy.ai",
150
- oauth_client_id: base.oauth_client_id
151
+ oauth_client_id: team.oauth_client_id ?? base.oauth_client_id
151
152
  });
152
153
  }
153
- async function refreshTeamToken(team) {
154
+ async function refreshTeamToken(team, opts) {
154
155
  if (!team.refresh_token) return team;
155
156
  const cfg = (() => {
156
157
  try {
@@ -159,21 +160,31 @@ async function refreshTeamToken(team) {
159
160
  return null;
160
161
  }
161
162
  })();
163
+ const endpoint = team.endpoint || "https://brightsy.ai";
164
+ const clientId = await ensureBrightsyOAuthClientId({
165
+ endpoint,
166
+ clientId: team.oauth_client_id || cfg?.oauth_client_id,
167
+ fetchImpl: opts?.fetchImpl
168
+ });
162
169
  const grant = await refreshBrightsyAccessToken({
163
- endpoint: team.endpoint || "https://brightsy.ai",
170
+ endpoint,
164
171
  refreshToken: team.refresh_token,
165
- clientId: cfg?.oauth_client_id
172
+ clientId,
173
+ fetchImpl: opts?.fetchImpl
166
174
  });
167
- if (!grant) return team;
175
+ if (!grant) return { ...team, oauth_client_id: clientId || team.oauth_client_id };
168
176
  return {
169
177
  ...team,
170
178
  access_token: grant.access_token,
171
179
  refresh_token: grant.refresh_token || team.refresh_token,
172
- expires_at: grant.expires_at ?? team.expires_at
180
+ expires_at: grant.expires_at ?? team.expires_at,
181
+ oauth_client_id: clientId
173
182
  };
174
183
  }
175
- async function ensureConnectedBrightsyTeamTokens() {
176
- await ensureBrightsyLocalConfigFresh().catch(() => null);
184
+ async function ensureConnectedBrightsyTeamTokens(opts) {
185
+ await ensureBrightsyLocalConfigFresh({ fetchImpl: opts?.fetchImpl }).catch(
186
+ () => null
187
+ );
177
188
  const teams = readStore();
178
189
  if (teams.length === 0) return [];
179
190
  const next = [];
@@ -183,8 +194,8 @@ async function ensureConnectedBrightsyTeamTokens() {
183
194
  next.push(team);
184
195
  continue;
185
196
  }
186
- const refreshed = await refreshTeamToken(team);
187
- if (refreshed.access_token !== team.access_token || refreshed.refresh_token !== team.refresh_token || refreshed.expires_at !== team.expires_at) {
197
+ const refreshed = await refreshTeamToken(team, opts);
198
+ if (refreshed.access_token !== team.access_token || refreshed.refresh_token !== team.refresh_token || refreshed.expires_at !== team.expires_at || refreshed.oauth_client_id !== team.oauth_client_id) {
188
199
  changed = true;
189
200
  }
190
201
  next.push(refreshed);
@@ -214,7 +225,8 @@ function ensureCliTeamTracked(meta) {
214
225
  access_token: cfg.access_token,
215
226
  refresh_token: cfg.refresh_token,
216
227
  expires_at: cfg.expires_at,
217
- endpoint: cfg.endpoint
228
+ endpoint: cfg.endpoint,
229
+ oauth_client_id: cfg.oauth_client_id
218
230
  };
219
231
  writeStore([...existing, team]);
220
232
  } catch {
@@ -241,7 +253,8 @@ async function connectBrightsyTeam(accountIdOrSlug) {
241
253
  access_token: minted.access_token,
242
254
  refresh_token: minted.refresh_token,
243
255
  expires_at: minted.expires_at,
244
- endpoint: minted.endpoint
256
+ endpoint: minted.endpoint,
257
+ oauth_client_id: minted.oauth_client_id
245
258
  };
246
259
  writeStore([...existing, team]);
247
260
  return listConnectedBrightsyTeams();
@@ -0,0 +1,178 @@
1
+ import {
2
+ formatFetchError
3
+ } from "./chunk-N7WZ6NIN.js";
4
+
5
+ // src/brightsy/config.ts
6
+ import { existsSync, readFileSync, writeFileSync } from "fs";
7
+ import { homedir } from "os";
8
+ import { join } from "path";
9
+ function brightsyConfigPath() {
10
+ const override = process.env.BRIGHTSY_CONFIG?.trim();
11
+ if (override) return override;
12
+ return join(homedir(), ".brightsy", "config.json");
13
+ }
14
+ function loadBrightsyConfig() {
15
+ const path = brightsyConfigPath();
16
+ if (!existsSync(path)) {
17
+ throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
18
+ }
19
+ const raw = JSON.parse(readFileSync(path, "utf8"));
20
+ if (!raw.access_token || !raw.account_id) {
21
+ throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
22
+ }
23
+ return raw;
24
+ }
25
+ function saveBrightsyConfig(cfg) {
26
+ writeFileSync(brightsyConfigPath(), `${JSON.stringify(cfg, null, 2)}
27
+ `, {
28
+ mode: 384
29
+ });
30
+ }
31
+
32
+ // src/brightsy/oauth.ts
33
+ var REFRESH_SKEW_MS = 6e4;
34
+ var BRIGHTSY_OAUTH_CLIENT_ID = "sideboard";
35
+ var BRIGHTSY_OAUTH_REDIRECT = "http://127.0.0.1:19850/callback";
36
+ function defaultFetch(fetchImpl) {
37
+ return fetchImpl ?? globalThis.fetch.bind(globalThis);
38
+ }
39
+ function normalizeBrightsyEndpoint(endpoint) {
40
+ return (endpoint || "https://brightsy.ai").replace(/\/$/, "");
41
+ }
42
+ function brightsyAccessTokenNeedsRefresh(expiresAt, now = Date.now()) {
43
+ if (typeof expiresAt !== "number" || !Number.isFinite(expiresAt) || expiresAt <= 0) {
44
+ return true;
45
+ }
46
+ return now >= expiresAt - REFRESH_SKEW_MS;
47
+ }
48
+ function applyGrant(current, grant) {
49
+ return {
50
+ access_token: grant.access_token,
51
+ refresh_token: grant.refresh_token || current.refresh_token,
52
+ expires_at: grant.expires_at ?? current.expires_at
53
+ };
54
+ }
55
+ async function registerBrightsyOAuthClient(opts) {
56
+ const endpoint = normalizeBrightsyEndpoint(opts.endpoint);
57
+ const url = `${endpoint}/oauth/register`;
58
+ const clientId = (opts.clientId || BRIGHTSY_OAUTH_CLIENT_ID).trim();
59
+ const redirectUri = opts.redirectUri || BRIGHTSY_OAUTH_REDIRECT;
60
+ const fetchImpl = defaultFetch(opts.fetchImpl);
61
+ let res;
62
+ try {
63
+ res = await fetchImpl(url, {
64
+ method: "POST",
65
+ headers: { "Content-Type": "application/json" },
66
+ body: JSON.stringify({
67
+ client_id: clientId,
68
+ client_name: "Sideboard",
69
+ description: "Sideboard desktop Brightsy MCP client",
70
+ redirect_uris: [redirectUri],
71
+ scope: "brightsy:api",
72
+ grant_types: ["authorization_code", "refresh_token"],
73
+ response_types: ["code"],
74
+ token_endpoint_auth_method: "none"
75
+ })
76
+ });
77
+ } catch (err) {
78
+ throw new Error(formatFetchError(err, url));
79
+ }
80
+ if (!res.ok) return null;
81
+ const data = await res.json();
82
+ if (!data.client_id?.trim()) return null;
83
+ return {
84
+ client_id: data.client_id.trim(),
85
+ client_secret: data.client_secret?.trim() || void 0
86
+ };
87
+ }
88
+ async function ensureBrightsyOAuthClientId(opts) {
89
+ const existing = opts.clientId?.trim();
90
+ if (existing) return existing;
91
+ const registered = await registerBrightsyOAuthClient({
92
+ endpoint: opts.endpoint,
93
+ fetchImpl: opts.fetchImpl
94
+ });
95
+ return registered?.client_id || BRIGHTSY_OAUTH_CLIENT_ID;
96
+ }
97
+ async function refreshBrightsyAccessToken(opts) {
98
+ const endpoint = normalizeBrightsyEndpoint(opts.endpoint);
99
+ const url = `${endpoint}/oauth/token`;
100
+ const fetchImpl = defaultFetch(opts.fetchImpl);
101
+ const clientId = opts.clientId?.trim() || BRIGHTSY_OAUTH_CLIENT_ID;
102
+ let res;
103
+ try {
104
+ res = await fetchImpl(url, {
105
+ method: "POST",
106
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
107
+ body: new URLSearchParams({
108
+ grant_type: "refresh_token",
109
+ refresh_token: opts.refreshToken,
110
+ client_id: clientId
111
+ })
112
+ });
113
+ } catch (err) {
114
+ throw new Error(formatFetchError(err, url));
115
+ }
116
+ if (!res.ok) return null;
117
+ const data = await res.json();
118
+ if (!data.access_token) return null;
119
+ return {
120
+ access_token: data.access_token,
121
+ refresh_token: data.refresh_token,
122
+ expires_at: data.expires_in ? Date.now() + data.expires_in * 1e3 : void 0
123
+ };
124
+ }
125
+ var refreshInFlight = null;
126
+ async function ensureBrightsyLocalConfigFreshOnce(opts) {
127
+ let cfg;
128
+ try {
129
+ cfg = loadBrightsyConfig();
130
+ } catch {
131
+ return null;
132
+ }
133
+ const refreshToken = cfg.refresh_token;
134
+ if (!refreshToken || !brightsyAccessTokenNeedsRefresh(cfg.expires_at)) {
135
+ return cfg;
136
+ }
137
+ const endpoint = normalizeBrightsyEndpoint(cfg.endpoint);
138
+ const clientId = await ensureBrightsyOAuthClientId({
139
+ endpoint,
140
+ clientId: cfg.oauth_client_id,
141
+ fetchImpl: opts?.fetchImpl
142
+ });
143
+ if (clientId !== cfg.oauth_client_id) {
144
+ cfg = { ...cfg, oauth_client_id: clientId };
145
+ saveBrightsyConfig(cfg);
146
+ }
147
+ const grant = await refreshBrightsyAccessToken({
148
+ endpoint,
149
+ refreshToken,
150
+ clientId,
151
+ fetchImpl: opts?.fetchImpl
152
+ });
153
+ if (!grant) return cfg;
154
+ const next = { ...cfg, ...applyGrant(cfg, grant), oauth_client_id: clientId };
155
+ saveBrightsyConfig(next);
156
+ return next;
157
+ }
158
+ async function ensureBrightsyLocalConfigFresh(opts) {
159
+ if (refreshInFlight) return refreshInFlight;
160
+ refreshInFlight = ensureBrightsyLocalConfigFreshOnce(opts).finally(() => {
161
+ refreshInFlight = null;
162
+ });
163
+ return refreshInFlight;
164
+ }
165
+
166
+ export {
167
+ brightsyConfigPath,
168
+ loadBrightsyConfig,
169
+ saveBrightsyConfig,
170
+ BRIGHTSY_OAUTH_CLIENT_ID,
171
+ BRIGHTSY_OAUTH_REDIRECT,
172
+ normalizeBrightsyEndpoint,
173
+ brightsyAccessTokenNeedsRefresh,
174
+ registerBrightsyOAuthClient,
175
+ ensureBrightsyOAuthClientId,
176
+ refreshBrightsyAccessToken,
177
+ ensureBrightsyLocalConfigFresh
178
+ };
@@ -3,10 +3,11 @@
3
3
  import {
4
4
  brightsyAccessTokenNeedsRefresh,
5
5
  ensureBrightsyLocalConfigFresh,
6
+ ensureBrightsyOAuthClientId,
6
7
  loadBrightsyConfig,
7
8
  refreshBrightsyAccessToken,
8
9
  saveBrightsyConfig
9
- } from "./chunk-Y4MIXGPA.js";
10
+ } from "./chunk-P2BSMNHB.js";
10
11
  import {
11
12
  run
12
13
  } from "./chunk-ABOBTSO6.js";
@@ -106,10 +107,10 @@ function applyConnectedTeamToCli(team) {
106
107
  account_id: team.id,
107
108
  account_slug: team.slug,
108
109
  endpoint: team.endpoint ?? base.endpoint ?? "https://brightsy.ai",
109
- oauth_client_id: base.oauth_client_id
110
+ oauth_client_id: team.oauth_client_id ?? base.oauth_client_id
110
111
  });
111
112
  }
112
- async function refreshTeamToken(team) {
113
+ async function refreshTeamToken(team, opts) {
113
114
  if (!team.refresh_token) return team;
114
115
  const cfg = (() => {
115
116
  try {
@@ -118,21 +119,31 @@ async function refreshTeamToken(team) {
118
119
  return null;
119
120
  }
120
121
  })();
122
+ const endpoint = team.endpoint || "https://brightsy.ai";
123
+ const clientId = await ensureBrightsyOAuthClientId({
124
+ endpoint,
125
+ clientId: team.oauth_client_id || cfg?.oauth_client_id,
126
+ fetchImpl: opts?.fetchImpl
127
+ });
121
128
  const grant = await refreshBrightsyAccessToken({
122
- endpoint: team.endpoint || "https://brightsy.ai",
129
+ endpoint,
123
130
  refreshToken: team.refresh_token,
124
- clientId: cfg?.oauth_client_id
131
+ clientId,
132
+ fetchImpl: opts?.fetchImpl
125
133
  });
126
- if (!grant) return team;
134
+ if (!grant) return { ...team, oauth_client_id: clientId || team.oauth_client_id };
127
135
  return {
128
136
  ...team,
129
137
  access_token: grant.access_token,
130
138
  refresh_token: grant.refresh_token || team.refresh_token,
131
- expires_at: grant.expires_at ?? team.expires_at
139
+ expires_at: grant.expires_at ?? team.expires_at,
140
+ oauth_client_id: clientId
132
141
  };
133
142
  }
134
- async function ensureConnectedBrightsyTeamTokens() {
135
- await ensureBrightsyLocalConfigFresh().catch(() => null);
143
+ async function ensureConnectedBrightsyTeamTokens(opts) {
144
+ await ensureBrightsyLocalConfigFresh({ fetchImpl: opts?.fetchImpl }).catch(
145
+ () => null
146
+ );
136
147
  const teams = readStore();
137
148
  if (teams.length === 0) return [];
138
149
  const next = [];
@@ -142,8 +153,8 @@ async function ensureConnectedBrightsyTeamTokens() {
142
153
  next.push(team);
143
154
  continue;
144
155
  }
145
- const refreshed = await refreshTeamToken(team);
146
- if (refreshed.access_token !== team.access_token || refreshed.refresh_token !== team.refresh_token || refreshed.expires_at !== team.expires_at) {
156
+ const refreshed = await refreshTeamToken(team, opts);
157
+ if (refreshed.access_token !== team.access_token || refreshed.refresh_token !== team.refresh_token || refreshed.expires_at !== team.expires_at || refreshed.oauth_client_id !== team.oauth_client_id) {
147
158
  changed = true;
148
159
  }
149
160
  next.push(refreshed);
@@ -173,7 +184,8 @@ function ensureCliTeamTracked(meta) {
173
184
  access_token: cfg.access_token,
174
185
  refresh_token: cfg.refresh_token,
175
186
  expires_at: cfg.expires_at,
176
- endpoint: cfg.endpoint
187
+ endpoint: cfg.endpoint,
188
+ oauth_client_id: cfg.oauth_client_id
177
189
  };
178
190
  writeStore([...existing, team]);
179
191
  } catch {
@@ -200,7 +212,8 @@ async function connectBrightsyTeam(accountIdOrSlug) {
200
212
  access_token: minted.access_token,
201
213
  refresh_token: minted.refresh_token,
202
214
  expires_at: minted.expires_at,
203
- endpoint: minted.endpoint
215
+ endpoint: minted.endpoint,
216
+ oauth_client_id: minted.oauth_client_id
204
217
  };
205
218
  writeStore([...existing, team]);
206
219
  return listConnectedBrightsyTeams();
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isOrchestratorThread
3
- } from "./chunk-OPYBLX4V.js";
3
+ } from "./chunk-N2VST3NL.js";
4
4
  import {
5
5
  codexUnattendedGitConfigArgs,
6
6
  mergeAgentGitAuthEnv,
@@ -12,10 +12,10 @@ import {
12
12
  brightsyMcpServerName,
13
13
  ensureCliTeamTracked,
14
14
  ensureConnectedBrightsyTeamTokens
15
- } from "./chunk-IILG7DPX.js";
15
+ } from "./chunk-QILV2BRW.js";
16
16
  import {
17
17
  loadBrightsyConfig
18
- } from "./chunk-AN3THU7F.js";
18
+ } from "./chunk-ROPGQRPU.js";
19
19
  import {
20
20
  httpFetch
21
21
  } from "./chunk-N7WZ6NIN.js";
@@ -693,6 +693,7 @@ function teamEnv(team) {
693
693
  return {
694
694
  BRIGHTSY_API_TOKEN: team.access_token,
695
695
  ...team.refresh_token ? { BRIGHTSY_REFRESH_TOKEN: team.refresh_token } : {},
696
+ ...team.oauth_client_id ? { BRIGHTSY_OAUTH_CLIENT_ID: team.oauth_client_id } : {},
696
697
  BRIGHTSY_ACCOUNT_ID: team.id,
697
698
  BRIGHTSY_API_URL: endpoint
698
699
  };
@@ -876,8 +877,16 @@ function toOpencodeMcpConfigContent(servers, opts) {
876
877
  }
877
878
  return JSON.stringify({ mcp });
878
879
  }
879
- function writeMcpServersConfig(servers) {
880
- if (servers.length === 0) return null;
880
+ function stripElectronFromUserMcpEntry(entry) {
881
+ const next = { ...entry };
882
+ const env = next.env;
883
+ if (!env || typeof env !== "object" || Array.isArray(env)) return next;
884
+ const cleaned = { ...env };
885
+ delete cleaned.ELECTRON_RUN_AS_NODE;
886
+ next.env = cleaned;
887
+ return next;
888
+ }
889
+ function writeMcpServersConfig(servers, extraServers) {
881
890
  const mcpServers = {};
882
891
  for (const s of servers) {
883
892
  const env = mcpSpawnEnv(s.env);
@@ -887,6 +896,14 @@ function writeMcpServersConfig(servers) {
887
896
  ...env ? { env } : {}
888
897
  };
889
898
  }
899
+ if (extraServers) {
900
+ for (const [rawName, entry] of Object.entries(extraServers)) {
901
+ const name = rawName.trim();
902
+ if (!name || mcpServers[name] || !entry) continue;
903
+ mcpServers[name] = stripElectronFromUserMcpEntry(entry);
904
+ }
905
+ }
906
+ if (Object.keys(mcpServers).length === 0) return null;
890
907
  const dir = mkdtempSync(join(tmpdir(), "sideboard-mcp-"));
891
908
  const cfgPath = join(dir, "mcp.json");
892
909
  writeFileSync(cfgPath, JSON.stringify({ mcpServers }, null, 2));
@@ -1037,10 +1054,20 @@ function listUserOpencodeMcpNames(home = homedir2()) {
1037
1054
  }
1038
1055
  return names;
1039
1056
  }
1040
- function listUserClaudeMcpNames(home = homedir2()) {
1057
+ function userClaudeMcpConfigObject(home = homedir2()) {
1041
1058
  const claudePath = home === homedir2() ? userClaudeMcpConfigPath() : join3(home, ".claude.json");
1042
- if (!existsSync4(claudePath)) return [];
1043
- return listMcpNamesFromJsonMap(readJsonObject(claudePath), "mcpServers");
1059
+ if (!existsSync4(claudePath)) return {};
1060
+ return asObject2(asObject2(readJsonObject(claudePath)).mcpServers);
1061
+ }
1062
+ function listUserClaudeMcpServerEntries(home = homedir2()) {
1063
+ const out = {};
1064
+ for (const [rawName, value] of Object.entries(userClaudeMcpConfigObject(home))) {
1065
+ const name = rawName.trim();
1066
+ if (!name || isInjectedOrchMcpName(name)) continue;
1067
+ if (!value || typeof value !== "object" || Array.isArray(value)) continue;
1068
+ out[name] = value;
1069
+ }
1070
+ return out;
1044
1071
  }
1045
1072
  function toCodexDisableUserMcpArgs(names) {
1046
1073
  const args = [];
@@ -2077,7 +2104,7 @@ var claudeAdapter = {
2077
2104
  );
2078
2105
  }
2079
2106
  const mode = permissionMode(thread);
2080
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-4TEMLESD.js");
2107
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-3FDAUNN2.js");
2081
2108
  const isOrchestrator = isOrchestratorThread2(thread);
2082
2109
  const injectedServers = await buildInjectedMcpServers({
2083
2110
  includeSideboard: true,
@@ -2088,6 +2115,7 @@ var claudeAdapter = {
2088
2115
  });
2089
2116
  const injectedBrightsyNames = injectedServers.filter((s) => s.name === "brightsy" || s.name.startsWith("brightsy_")).map((s) => s.name);
2090
2117
  const chromeOn = claudeChromeEnabled();
2118
+ const userMcpEntries = isOrchestrator ? {} : listUserClaudeMcpServerEntries();
2091
2119
  let allowedTools;
2092
2120
  if (isOrchestrator) {
2093
2121
  allowedTools = [
@@ -2098,7 +2126,7 @@ var claudeAdapter = {
2098
2126
  } else {
2099
2127
  allowedTools = [
2100
2128
  ...BASE_ALLOWED_TOOLS,
2101
- ...mcpAllowToolsFromNames(userMcpNamesToDisable({ names: listUserClaudeMcpNames() })),
2129
+ ...mcpAllowToolsFromNames(Object.keys(userMcpEntries)),
2102
2130
  ...sideboardWorktreeAllowedTools({
2103
2131
  github: true,
2104
2132
  linear: isLinearConnected(),
@@ -2123,7 +2151,7 @@ var claudeAdapter = {
2123
2151
  if (systemPrompt) {
2124
2152
  args.push("--append-system-prompt", systemPrompt);
2125
2153
  }
2126
- const mcpConfigPath = writeMcpServersConfig(injectedServers);
2154
+ const mcpConfigPath = writeMcpServersConfig(injectedServers, userMcpEntries);
2127
2155
  if (mcpConfigPath) {
2128
2156
  args.push("--mcp-config", mcpConfigPath);
2129
2157
  args.push("--strict-mcp-config");
@@ -7,8 +7,8 @@ import {
7
7
  ensureConnectedBrightsyTeamTokens,
8
8
  getConnectedBrightsyTeamsRaw,
9
9
  listConnectedBrightsyTeams
10
- } from "./chunk-IILG7DPX.js";
11
- import "./chunk-AN3THU7F.js";
10
+ } from "./chunk-QILV2BRW.js";
11
+ import "./chunk-ROPGQRPU.js";
12
12
  import "./chunk-N7WZ6NIN.js";
13
13
  import "./chunk-WFUDY6PC.js";
14
14
  import "./chunk-HVUVQXZ2.js";
@@ -9,8 +9,8 @@ import {
9
9
  ensureConnectedBrightsyTeamTokens,
10
10
  getConnectedBrightsyTeamsRaw,
11
11
  listConnectedBrightsyTeams
12
- } from "./chunk-SVXIJ2IC.js";
13
- import "./chunk-Y4MIXGPA.js";
12
+ } from "./chunk-UNMMKZ4Q.js";
13
+ import "./chunk-P2BSMNHB.js";
14
14
  import "./chunk-VKQGAWHY.js";
15
15
  import "./chunk-ABOBTSO6.js";
16
16
  import "./chunk-EQNRWDLN.js";
@@ -7,7 +7,7 @@ import {
7
7
  enrichWorkspacesWithGithub,
8
8
  ensureGlobalCoordinatorCwd,
9
9
  formatWorkspaceInventory
10
- } from "./chunk-OPYBLX4V.js";
10
+ } from "./chunk-N2VST3NL.js";
11
11
  import "./chunk-KTZESHYH.js";
12
12
  import "./chunk-6K64FJDD.js";
13
13
  import "./chunk-PO4M4JAJ.js";
@@ -9,7 +9,7 @@ import {
9
9
  enrichWorkspacesWithGithub,
10
10
  ensureGlobalCoordinatorCwd,
11
11
  formatWorkspaceInventory
12
- } from "./chunk-MW57SKKR.js";
12
+ } from "./chunk-P2EAAM3H.js";
13
13
  import "./chunk-NFWPDEN4.js";
14
14
  import "./chunk-D6JWYJ4P.js";
15
15
  import "./chunk-HY2GFZ5S.js";
@@ -15,7 +15,7 @@ import {
15
15
  orchestratorSessionPoisonedByBuiltins,
16
16
  slackCoordinatorSourceRef,
17
17
  takenTeamSlugsForOrchestration
18
- } from "./chunk-OPYBLX4V.js";
18
+ } from "./chunk-N2VST3NL.js";
19
19
  import "./chunk-KTZESHYH.js";
20
20
  import "./chunk-6K64FJDD.js";
21
21
  import "./chunk-PO4M4JAJ.js";
@@ -17,7 +17,7 @@ import {
17
17
  orchestratorSessionPoisonedByBuiltins,
18
18
  slackCoordinatorSourceRef,
19
19
  takenTeamSlugsForOrchestration
20
- } from "./chunk-MW57SKKR.js";
20
+ } from "./chunk-P2EAAM3H.js";
21
21
  import "./chunk-NFWPDEN4.js";
22
22
  import "./chunk-D6JWYJ4P.js";
23
23
  import "./chunk-HY2GFZ5S.js";