@sideboard-ai/core 0.1.89 → 0.1.92

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 (30) hide show
  1. package/dist/agents/cursor-runner.cjs +129 -14
  2. package/dist/agents/cursor-runner.js +4 -1
  3. package/dist/{agents-LMUFTGKF.js → agents-JXQ5QHDU.js} +4 -4
  4. package/dist/{agents-ODBP7J6E.js → agents-TUV4NH7S.js} +5 -5
  5. package/dist/{chunk-RJLBSYUO.js → chunk-35LKGGOC.js} +45 -77
  6. package/dist/{chunk-WANQFU3S.js → chunk-6XBXVXX2.js} +2 -2
  7. package/dist/{chunk-7D27DD2X.js → chunk-CIRXAYWS.js} +260 -61
  8. package/dist/{chunk-B2KIO2SD.js → chunk-CLGO7TLO.js} +2 -2
  9. package/dist/{chunk-JE75QW2I.js → chunk-GJ2HJQIU.js} +236 -96
  10. package/dist/{chunk-CBJSPTBG.js → chunk-GXSYI7FH.js} +206 -5
  11. package/dist/{chunk-UHTNJKZX.js → chunk-NR6APJLD.js} +2 -2
  12. package/dist/{chunk-6EZRSCIT.js → chunk-QKYO6BHB.js} +2 -2
  13. package/dist/{chunk-ZXYWWSHZ.js → chunk-R7BQBSDT.js} +254 -61
  14. package/dist/{chunk-OB6IRIFV.js → chunk-XH2GS2LO.js} +2 -2
  15. package/dist/{chunk-VZ2L4AEJ.js → chunk-XUWDLRAE.js} +2 -2
  16. package/dist/{coordinator-prompt-UK5LYFN5.js → coordinator-prompt-AKEY4WSO.js} +2 -2
  17. package/dist/{coordinator-prompt-CI5SHONJ.js → coordinator-prompt-OQOOD5ET.js} +2 -2
  18. package/dist/{global-workspace-2YZ2V4I5.js → global-workspace-3GNPQCLE.js} +3 -3
  19. package/dist/{global-workspace-JQQLPJM5.js → global-workspace-M3OMVDDH.js} +3 -3
  20. package/dist/index.cjs +941 -455
  21. package/dist/index.d.cts +77 -19
  22. package/dist/index.d.ts +77 -19
  23. package/dist/index.js +166 -42
  24. package/dist/mcp/run-stdio.cjs +815 -428
  25. package/dist/mcp/run-stdio.js +77 -40
  26. package/dist/{workspaces-YWCC3WV4.js → workspaces-ERZC7ULY.js} +4 -4
  27. package/dist/{workspaces-FDO5L4NI.js → workspaces-J4WG6UFR.js} +4 -4
  28. package/dist/{worktree-7YNSJ224.js → worktree-DA4BOV7G.js} +7 -1
  29. package/dist/{worktree-4555QBQ7.js → worktree-EO5QAGJU.js} +7 -1
  30. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  listWorkspaces,
5
5
  removeWorkspace,
6
6
  syncWorkspacesFromThreads
7
- } from "./chunk-6EZRSCIT.js";
7
+ } from "./chunk-QKYO6BHB.js";
8
8
  import {
9
9
  BRIGHTSY_MCP_ALLOWED_TOOLS,
10
10
  CLAUDE_MODEL_CATALOG,
@@ -58,13 +58,14 @@ import {
58
58
  resolveCursorModelId,
59
59
  resolveLoginCommand,
60
60
  resolveQuotaFallbackAgent,
61
+ resolveSideboardMcpServer,
61
62
  sanitizeMcpServerName,
62
63
  shouldInjectBrightsyMcp,
63
64
  sideboardMcpProfile,
64
65
  threadRequestsBrightsyMcp,
65
66
  totalTokens,
66
67
  writeInjectedMcpConfig
67
- } from "./chunk-RJLBSYUO.js";
68
+ } from "./chunk-35LKGGOC.js";
68
69
  import {
69
70
  CLOUD_COORDINATOR_BUSY_REPLY,
70
71
  CLOUD_COORDINATOR_STOPPED_REPLY,
@@ -91,7 +92,7 @@ import {
91
92
  parseForceStopMessage,
92
93
  slackCoordinatorSourceRef,
93
94
  takenTeamSlugsForOrchestration
94
- } from "./chunk-B2KIO2SD.js";
95
+ } from "./chunk-CLGO7TLO.js";
95
96
  import {
96
97
  COORDINATOR_TOOL_PLAYBOOK,
97
98
  SLACK_REPLY_FORMATTING,
@@ -100,7 +101,7 @@ import {
100
101
  enrichWorkspacesWithGithub,
101
102
  ensureGlobalCoordinatorCwd,
102
103
  formatWorkspaceInventory
103
- } from "./chunk-VZ2L4AEJ.js";
104
+ } from "./chunk-XUWDLRAE.js";
104
105
  import {
105
106
  brightsyConfigPath,
106
107
  brightsyMcpServerName,
@@ -137,7 +138,7 @@ import {
137
138
  parseCursorRunnerLine,
138
139
  pushTurnStderr,
139
140
  summarizeTurnStderr
140
- } from "./chunk-CBJSPTBG.js";
141
+ } from "./chunk-GXSYI7FH.js";
141
142
  import {
142
143
  caffeinateHoldPath,
143
144
  getCaffeinateHold,
@@ -154,6 +155,7 @@ import {
154
155
  applyGithubGitAuthEnv,
155
156
  branchDisplayLabel,
156
157
  checkoutPrStackLayer,
158
+ codexSandboxWritableRootsArgs,
157
159
  codexUnattendedGitConfigArgs,
158
160
  collectTakenTeamSlugs,
159
161
  commitAll,
@@ -174,12 +176,14 @@ import {
174
176
  getPr,
175
177
  getPrChecks,
176
178
  getPrDetails,
179
+ getPrForHeadBranch,
177
180
  getPrMeta,
178
181
  getPrStack,
179
182
  ghHeadRef,
180
183
  ghRepoSelectArgs,
181
184
  githubAgentGitEnv,
182
185
  initPrStack,
186
+ isDefaultishSourceRef,
183
187
  isDirty,
184
188
  isGhRateLimitError,
185
189
  isInPrStack,
@@ -190,6 +194,7 @@ import {
190
194
  listPrs,
191
195
  listWorktrees,
192
196
  lookupSoccerTeam,
197
+ mergeAgentGitAuthEnv,
193
198
  mergePr,
194
199
  mergePrStack,
195
200
  nonInteractiveGitProcessEnv,
@@ -200,24 +205,29 @@ import {
200
205
  pushBranch,
201
206
  removeWorktree,
202
207
  resetGhStackDetectCache,
208
+ resetGithubAgentTokenMemo,
203
209
  resolveAgentGitAuthEnv,
210
+ resolveCodexGitWritableRoots,
204
211
  resolveDefaultBranch,
205
212
  resolveDiffBaseRef,
206
213
  resolveGithubAgentToken,
207
214
  resolveGithubRepoSlug,
208
215
  resolvePrSelector,
216
+ resolvePrSelectors,
209
217
  resolveRepoRoot,
210
218
  resolveWorktreeStartPoint,
219
+ scrubGithubTokensFromChildEnv,
211
220
  slugify,
212
221
  stackMergeReadiness,
213
222
  submitPrStack,
214
223
  suggestSlug,
215
224
  takenSlugsFromThread,
216
225
  threadDisplayLabel,
226
+ warmGithubAgentAuth,
217
227
  worktreeDisplayLabel,
218
228
  worktreeDisplayLabelForGroup,
219
229
  worktreeNameFromPath
220
- } from "./chunk-7D27DD2X.js";
230
+ } from "./chunk-CIRXAYWS.js";
221
231
  import {
222
232
  ATTACHMENTS_DIR,
223
233
  LEGACY_ATTACHMENTS_DIR,
@@ -1328,9 +1338,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
1328
1338
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
1329
1339
  );
1330
1340
  }
1331
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-JQQLPJM5.js");
1341
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-M3OMVDDH.js");
1332
1342
  if (isGlobalThread2(thread)) {
1333
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-UK5LYFN5.js");
1343
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-AKEY4WSO.js");
1334
1344
  ensureGlobalCoordinatorCwd2(
1335
1345
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
1336
1346
  );
@@ -1348,10 +1358,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
1348
1358
  const env = childEnvWithAppSettings(cmd.env);
1349
1359
  try {
1350
1360
  if (isOrchestratorThread(thread)) {
1351
- Object.assign(env, await resolveAgentGitAuthEnv(env));
1361
+ mergeAgentGitAuthEnv(env, await resolveAgentGitAuthEnv(env));
1352
1362
  } else {
1353
- const originEnv = await originGhRepoEnv(thread.worktreePath, { env });
1354
- Object.assign(env, originEnv);
1363
+ mergeAgentGitAuthEnv(env, await originGhRepoEnv(thread.worktreePath, { env }));
1355
1364
  }
1356
1365
  } catch (err) {
1357
1366
  const detail = err instanceof Error ? err.message : String(err);
@@ -1574,9 +1583,10 @@ function formatArtifactDirective() {
1574
1583
  "Files / media browser (CMS file manager column):",
1575
1584
  "4) Call Sideboard MCP `present_files` with optional title, path, and datasource (brightsy|memory).",
1576
1585
  " Opens the Files column for browse/upload/pick. Do NOT say a file manager UI is missing.",
1577
- "Multiple-choice questions (any mode \u2014 not only Plan):",
1578
- "5) Call Sideboard MCP `ask_user` when the user should pick from predefined options (approach forks, requirements, which API). First write a short chat message that explains the decision and what each option means (tradeoffs, when to pick it). Include a description on every option. After calling, stop and wait for their next message with answers. Do not ask multiple-choice questions as plain chat bullets \u2014 use ask_user so Sideboard shows the composer picker.",
1579
- "Never say artifacts, CMS UI, or the Files column are unavailable. Prefer present_schema for list/edit/publish; present_files for storage UI; html fences for standalone pages; ask_user for predefined-option questions."
1586
+ "Multiple-choice questions:",
1587
+ "5) Call Sideboard MCP `ask_user` only when work is blocked on choosing among a few concrete options (approach forks, which API, auth vs cookies). First write a short chat message that explains the decision and what each option means (tradeoffs, when to pick it). Include a description on every option. After calling, stop and wait for their next message with answers. If you are asking a real multiple-choice, use ask_user rather than chat bullets so Sideboard shows the composer picker.",
1588
+ "Do not call ask_user for greetings, check-ins, \u201Chello\u201D, open-ended how-can-I-help, or to invent a menu of possible next tasks \u2014 reply in chat. If one option is the obvious default, proceed without asking.",
1589
+ "Never say artifacts, CMS UI, or the Files column are unavailable. Prefer present_schema for list/edit/publish; present_files for storage UI; html fences for standalone pages; ask_user only for those blocked predefined-option questions."
1580
1590
  ].join("\n");
1581
1591
  }
1582
1592
  function formatUiReminder() {
@@ -1587,7 +1597,7 @@ function formatUiReminder() {
1587
1597
  "CMS forms/tables: MCP present_schema (Brightsy resource_id or inline schema+schemaUi).",
1588
1598
  "Files column: MCP present_files (brightsy account storage or memory).",
1589
1599
  "Do not say artifacts/CMS UI are unavailable.",
1590
- "Multiple-choice questions: MCP ask_user (composer picker, any mode). Explain options in chat first, then wait for answers."
1600
+ "ask_user: only when blocked on a real multiple-choice (approach fork, which API). Never for hellos, check-ins, or \u201Cwhat next?\u201D menus \u2014 reply in chat."
1591
1601
  ].join(" ");
1592
1602
  }
1593
1603
  var FILES_BY_AGENT = {
@@ -1874,7 +1884,10 @@ async function spawnWorkspaceScript(command, opts) {
1874
1884
  loginEnv
1875
1885
  );
1876
1886
  try {
1877
- Object.assign(env, await resolveAgentGitAuthEnv(env, { cwd: opts.worktreePath }));
1887
+ mergeAgentGitAuthEnv(
1888
+ env,
1889
+ await resolveAgentGitAuthEnv(env, { cwd: opts.worktreePath })
1890
+ );
1878
1891
  } catch {
1879
1892
  }
1880
1893
  const shell = process.platform === "darwin" ? "zsh" : "bash";
@@ -3759,6 +3772,7 @@ async function createThread(input, _onSetupLine) {
3759
3772
  let sourceRef = input.sourceRef;
3760
3773
  let sourceIsFork = false;
3761
3774
  let prUrl = null;
3775
+ let prTitle = null;
3762
3776
  if (input.sourceType === "pr") {
3763
3777
  const num = Number(input.sourceRef.replace(/^#/, ""));
3764
3778
  if (!Number.isFinite(num)) throw new Error(`Invalid PR number: ${input.sourceRef}`);
@@ -3774,6 +3788,12 @@ async function createThread(input, _onSetupLine) {
3774
3788
  } else if (input.sourceType === "branch") {
3775
3789
  if (!sourceRef || sourceRef === "HEAD" || sourceRef === "default") {
3776
3790
  sourceRef = await resolveDefaultBranch(repoPath);
3791
+ } else {
3792
+ const existing = await getPrForHeadBranch(repoPath, sourceRef);
3793
+ if (existing?.url) {
3794
+ prUrl = existing.url;
3795
+ prTitle = existing.title;
3796
+ }
3777
3797
  }
3778
3798
  } else if (input.sourceType === "adopt") {
3779
3799
  throw new Error("Use adoptThread() for adopt sources");
@@ -3804,14 +3824,15 @@ async function createThread(input, _onSetupLine) {
3804
3824
  sourceIsFork,
3805
3825
  parentThreadId: input.parentThreadId ?? null,
3806
3826
  status: "idle",
3807
- prUrl
3827
+ prUrl,
3828
+ prTitle
3808
3829
  });
3809
3830
  writeThread(thread);
3810
3831
  await ensureWorkspace(repoPath);
3811
3832
  return readThread(thread.id) ?? thread;
3812
3833
  }
3813
3834
  async function listLinearIssues(agent, repoPath) {
3814
- const { getAdapter: getAdapter2 } = await import("./agents-ODBP7J6E.js");
3835
+ const { getAdapter: getAdapter2 } = await import("./agents-TUV4NH7S.js");
3815
3836
  await requireAgent(agent, { requireLinear: true });
3816
3837
  const adapter = getAdapter2(agent);
3817
3838
  if (!adapter.listLinearIssues) {
@@ -4277,7 +4298,7 @@ import {
4277
4298
  } from "fs";
4278
4299
  import { tmpdir } from "os";
4279
4300
  import { join as join6 } from "path";
4280
- import Database from "better-sqlite3";
4301
+ import { createRequire } from "module";
4281
4302
  var CONDUCTOR_APP_SUPPORT = join6(
4282
4303
  process.env.HOME ?? "",
4283
4304
  "Library",
@@ -4286,6 +4307,11 @@ var CONDUCTOR_APP_SUPPORT = join6(
4286
4307
  );
4287
4308
  var CONDUCTOR_DB = join6(CONDUCTOR_APP_SUPPORT, "conductor.db");
4288
4309
  var CURSOR_SDK_STORE = join6(CONDUCTOR_APP_SUPPORT, "cursor-sdk-store");
4310
+ function openReadonlySqlite(file) {
4311
+ const req = createRequire(import.meta.url);
4312
+ const Database = req("better-sqlite3");
4313
+ return new Database(file, { readonly: true, fileMustExist: true });
4314
+ }
4289
4315
  function mapAgentType(raw) {
4290
4316
  if (!raw) return null;
4291
4317
  const v = raw.toLowerCase();
@@ -4354,7 +4380,7 @@ async function adoptThread(input) {
4354
4380
  messages: input.messages ?? []
4355
4381
  });
4356
4382
  writeThread(thread);
4357
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-YWCC3WV4.js");
4383
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ERZC7ULY.js");
4358
4384
  await ensureWorkspace2(repoPath);
4359
4385
  return thread;
4360
4386
  }
@@ -4378,7 +4404,7 @@ function listConductorWorkspaces() {
4378
4404
  }
4379
4405
  }
4380
4406
  }
4381
- const db = new Database(snapshot, { readonly: true, fileMustExist: true });
4407
+ const db = openReadonlySqlite(snapshot);
4382
4408
  try {
4383
4409
  const tables = db.prepare(`SELECT name FROM sqlite_master WHERE type='table'`).all();
4384
4410
  const names = new Set(tables.map((t) => t.name));
@@ -4469,7 +4495,7 @@ function importConductorWorkspace(workspaceId) {
4469
4495
  }
4470
4496
  }
4471
4497
  }
4472
- const db = new Database(snapshot, { readonly: true, fileMustExist: true });
4498
+ const db = openReadonlySqlite(snapshot);
4473
4499
  try {
4474
4500
  const row = db.prepare(
4475
4501
  `SELECT
@@ -6948,8 +6974,9 @@ var Orchestrator = class {
6948
6974
  return result;
6949
6975
  }
6950
6976
  async mergePr(threadRef) {
6951
- const { thread, selector, cwd } = await this.withPrSelector(threadRef);
6977
+ const { thread, selectors, cwd } = await this.withPrSelector(threadRef);
6952
6978
  this.assertNotGlobal(thread, "Merge PR");
6979
+ const selector = selectors[0];
6953
6980
  if (!selector) throw new Error("No pull request linked to this thread");
6954
6981
  const result = await mergePr(cwd, selector);
6955
6982
  const state = normalizePrState(result.state) || "MERGED";
@@ -6969,29 +6996,34 @@ var Orchestrator = class {
6969
6996
  await this.persistPrMetaAndMaybeArchive(thread, metaLike);
6970
6997
  return { url: metaLike.url, state };
6971
6998
  }
6972
- /** Resolve PR selector and optionally persist `prUrl` when found. */
6999
+ /** Resolve PR selectors and optionally persist `prUrl` when found. */
6973
7000
  async withPrSelector(threadRef) {
6974
7001
  const thread = this.requireThread(threadRef);
6975
- const selector = resolvePrSelector(thread);
7002
+ const selectors = resolvePrSelectors(thread);
6976
7003
  const cwd = thread.worktreePath;
6977
7004
  if (!cwd?.trim()) {
6978
7005
  throw new Error(`Thread ${threadRef} has no worktreePath`);
6979
7006
  }
6980
- return { thread, selector, cwd };
7007
+ return { thread, selectors, cwd };
6981
7008
  }
6982
7009
  async getPrChecks(threadRef) {
6983
- const { selector, cwd } = await this.withPrSelector(threadRef);
6984
- if (!selector) return null;
6985
- return getPrChecks(cwd, selector);
7010
+ const { selectors, cwd } = await this.withPrSelector(threadRef);
7011
+ for (const selector of selectors) {
7012
+ const checks = await getPrChecks(cwd, selector);
7013
+ if (checks) return checks;
7014
+ }
7015
+ return null;
6986
7016
  }
6987
7017
  async getPrMeta(threadRef) {
6988
- const { thread, selector, cwd } = await this.withPrSelector(threadRef);
6989
- if (!selector) return null;
6990
- const meta = await getPrMeta(cwd, selector);
6991
- if (meta) {
6992
- await this.persistPrMetaAndMaybeArchive(thread, meta);
7018
+ const { thread, selectors, cwd } = await this.withPrSelector(threadRef);
7019
+ for (const selector of selectors) {
7020
+ const meta = await getPrMeta(cwd, selector);
7021
+ if (meta) {
7022
+ await this.persistPrMetaAndMaybeArchive(thread, meta);
7023
+ return meta;
7024
+ }
6993
7025
  }
6994
- return meta;
7026
+ return null;
6995
7027
  }
6996
7028
  /**
6997
7029
  * Persist PR URL/title/state and Conductor-style auto-archive when the PR
@@ -7115,9 +7147,12 @@ var Orchestrator = class {
7115
7147
  return { stack: result.stack, threads: result.threads };
7116
7148
  }
7117
7149
  async getPrDetails(threadRef) {
7118
- const { thread, selector, cwd } = await this.withPrSelector(threadRef);
7119
- if (!selector) return null;
7120
- const details = await getPrDetails(cwd, selector);
7150
+ const { thread, selectors, cwd } = await this.withPrSelector(threadRef);
7151
+ let details = null;
7152
+ for (const selector of selectors) {
7153
+ details = await getPrDetails(cwd, selector);
7154
+ if (details) break;
7155
+ }
7121
7156
  if (details) {
7122
7157
  const patch = {};
7123
7158
  if (details.url && details.url !== thread.prUrl) patch.prUrl = details.url;
@@ -7302,7 +7337,7 @@ var Orchestrator = class {
7302
7337
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
7303
7338
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
7304
7339
  try {
7305
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-YWCC3WV4.js");
7340
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ERZC7ULY.js");
7306
7341
  await ensureWorkspace2(thread.repoPath);
7307
7342
  } catch {
7308
7343
  }
@@ -7345,7 +7380,7 @@ var Orchestrator = class {
7345
7380
  return restored2;
7346
7381
  }
7347
7382
  if (!existsSync14(thread.worktreePath)) {
7348
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-7YNSJ224.js");
7383
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-DA4BOV7G.js");
7349
7384
  const { execa: execa5 } = await import("execa");
7350
7385
  const slug = thread.worktreePath.split("/").pop();
7351
7386
  const dest = thread.worktreePath;
@@ -7454,7 +7489,7 @@ async function startOrchestration(opts) {
7454
7489
  sourceRef: "default",
7455
7490
  ...createOpts
7456
7491
  }).catch(async () => {
7457
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-7YNSJ224.js");
7492
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-DA4BOV7G.js");
7458
7493
  const repo = await resolveRepoRoot2(repoPath);
7459
7494
  const def = await resolveDefaultBranch2(repo);
7460
7495
  return orch.createThread({
@@ -8205,6 +8240,14 @@ function withTimeout(promise, ms, label) {
8205
8240
  }
8206
8241
  async function startMcpServer() {
8207
8242
  const orch = getOrchestrator();
8243
+ try {
8244
+ await warmGithubAgentAuth();
8245
+ } catch (err) {
8246
+ console.error(
8247
+ "[sideboard-mcp] GitHub agent auth warm skipped:",
8248
+ err instanceof Error ? err.message : err
8249
+ );
8250
+ }
8208
8251
  try {
8209
8252
  const { maxConcurrentAgents: maxConcurrentAgents2 } = await import("./app-settings-BRF7VKTQ.js");
8210
8253
  orch.setMaxConcurrent(maxConcurrentAgents2());
@@ -8311,7 +8354,7 @@ async function startMcpServer() {
8311
8354
  );
8312
8355
  server.tool(
8313
8356
  "ask_user",
8314
- "Ask the user clarifying multiple-choice questions in Sideboard\u2019s composer (any mode \u2014 not only Plan). Before calling, write a short chat message explaining the decision and what each option means. Include a description on every option. Use when the user should pick from predefined options (approach forks, requirements, which API) \u2014 not for \u201Cis the plan ready?\u201D. After calling, stop and wait for their next message with answers.",
8357
+ "Ask the user a clarifying multiple-choice question in Sideboard\u2019s composer. Call only when work is blocked on choosing among a few concrete options (approach fork, which API, auth vs cookies). Do not call for greetings, check-ins, \u201Chello\u201D, open-ended how-can-I-help, or to invent a menu of possible next tasks \u2014 reply in chat instead. If one option is the obvious default, proceed without asking. Before calling, write a short chat message explaining the decision and what each option means. Include a description on every option. After calling, stop and wait for answers. Not for \u201Cis the plan ready?\u201D.",
8315
8358
  {
8316
8359
  questions: z3.array(
8317
8360
  z3.object({
@@ -9540,6 +9583,74 @@ async function runCloudConnect(opts) {
9540
9583
  }
9541
9584
  }
9542
9585
 
9586
+ // src/agents/user-mcp-config.ts
9587
+ import { existsSync as existsSync15, mkdirSync as mkdirSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync4 } from "fs";
9588
+ import { homedir as homedir2 } from "os";
9589
+ import { dirname as dirname4, join as join13 } from "path";
9590
+ function userCursorMcpConfigPath() {
9591
+ return join13(homedir2(), ".cursor", "mcp.json");
9592
+ }
9593
+ function userClaudeMcpConfigPath() {
9594
+ return join13(homedir2(), ".claude.json");
9595
+ }
9596
+ function asObject(value) {
9597
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
9598
+ return { ...value };
9599
+ }
9600
+ function stripElectronSpawnEnv(env) {
9601
+ if (!env) return void 0;
9602
+ const next = { ...env };
9603
+ delete next.ELECTRON_RUN_AS_NODE;
9604
+ delete next.ELECTRON_RUN_AS_NODE;
9605
+ return Object.keys(next).length > 0 ? next : void 0;
9606
+ }
9607
+ function mergeSideboardIntoMcpServersJson(existing, sideboard) {
9608
+ const root = asObject(existing);
9609
+ const servers = asObject(root.mcpServers);
9610
+ const env = stripElectronSpawnEnv(sideboard.env);
9611
+ servers.sideboard = {
9612
+ command: sideboard.command,
9613
+ ...sideboard.args && sideboard.args.length > 0 ? { args: sideboard.args } : {},
9614
+ ...env ? { env } : {}
9615
+ };
9616
+ return { ...root, mcpServers: servers };
9617
+ }
9618
+ function writeMergedMcpServersJson(configPath, sideboard) {
9619
+ let existing = {};
9620
+ if (existsSync15(configPath)) {
9621
+ try {
9622
+ existing = JSON.parse(readFileSync10(configPath, "utf8"));
9623
+ } catch {
9624
+ existing = {};
9625
+ }
9626
+ }
9627
+ const next = mergeSideboardIntoMcpServersJson(existing, sideboard);
9628
+ mkdirSync5(dirname4(configPath), { recursive: true });
9629
+ writeFileSync4(configPath, `${JSON.stringify(next, null, 2)}
9630
+ `);
9631
+ }
9632
+ function launchFromResolved(server) {
9633
+ return {
9634
+ command: server.command,
9635
+ args: server.args,
9636
+ env: {
9637
+ ...server.env ?? {},
9638
+ SIDEBOARD_APP_DATA: appDataDir()
9639
+ }
9640
+ };
9641
+ }
9642
+ async function registerPackagedUserMcpClients() {
9643
+ const launch = launchFromResolved(await resolveSideboardMcpServer());
9644
+ const cursor = userCursorMcpConfigPath();
9645
+ writeMergedMcpServersJson(cursor, launch);
9646
+ const claude = userClaudeMcpConfigPath();
9647
+ if (existsSync15(claude)) {
9648
+ writeMergedMcpServersJson(claude, launch);
9649
+ return { cursor, claude };
9650
+ }
9651
+ return { cursor };
9652
+ }
9653
+
9543
9654
  // src/slack/oauth.ts
9544
9655
  import { randomBytes as randomBytes2 } from "crypto";
9545
9656
 
@@ -11238,6 +11349,7 @@ export {
11238
11349
  cleanupOrphanWorktrees,
11239
11350
  cloneRepoIntoSideboard,
11240
11351
  codexAdapter,
11352
+ codexSandboxWritableRootsArgs,
11241
11353
  codexUnattendedGitConfigArgs,
11242
11354
  coerceOrchestratorAgent,
11243
11355
  collectTakenTeamSlugs,
@@ -11354,6 +11466,7 @@ export {
11354
11466
  getPr,
11355
11467
  getPrChecks,
11356
11468
  getPrDetails,
11469
+ getPrForHeadBranch,
11357
11470
  getPrMeta,
11358
11471
  getPrStack,
11359
11472
  getRepoSetupInfo,
@@ -11390,6 +11503,7 @@ export {
11390
11503
  isCloudCoordinatorThread,
11391
11504
  isConductorBundledCli,
11392
11505
  isCursorAutoModel,
11506
+ isDefaultishSourceRef,
11393
11507
  isDirty,
11394
11508
  isGhRateLimitError,
11395
11509
  isGlobalRepoPath,
@@ -11456,8 +11570,10 @@ export {
11456
11570
  maybeCompactContext,
11457
11571
  mcpAllowTools,
11458
11572
  mcpAuthWarnings,
11573
+ mergeAgentGitAuthEnv,
11459
11574
  mergePr,
11460
11575
  mergePrStack,
11576
+ mergeSideboardIntoMcpServersJson,
11461
11577
  mergeUsage,
11462
11578
  nextPastedTextName,
11463
11579
  nextThinkingEffort,
@@ -11508,6 +11624,7 @@ export {
11508
11624
  recordSlackOutboundWatch,
11509
11625
  refreshGitHubAuth,
11510
11626
  refreshSlackReplyBadges,
11627
+ registerPackagedUserMcpClients,
11511
11628
  releaseCaffeinateHoldForThread,
11512
11629
  removeWorkspace,
11513
11630
  removeWorktree,
@@ -11516,9 +11633,11 @@ export {
11516
11633
  requestReview,
11517
11634
  requireAgent,
11518
11635
  resetGhStackDetectCache,
11636
+ resetGithubAgentTokenMemo,
11519
11637
  resolveAgentExecutable,
11520
11638
  resolveAgentGitAuthEnv,
11521
11639
  resolveClaudeExecutable,
11640
+ resolveCodexGitWritableRoots,
11522
11641
  resolveCommandBinarySync,
11523
11642
  resolveConductorCursorAgentId,
11524
11643
  resolveCursorModelId,
@@ -11535,6 +11654,7 @@ export {
11535
11654
  resolveNewThreadOptions,
11536
11655
  resolvePlanMarkdown,
11537
11656
  resolvePrSelector,
11657
+ resolvePrSelectors,
11538
11658
  resolveQuotaFallbackAgent,
11539
11659
  resolveRepoRoot,
11540
11660
  resolveReviewGuidelines,
@@ -11557,6 +11677,7 @@ export {
11557
11677
  sanitizeMcpServerName,
11558
11678
  saveAppSettings,
11559
11679
  saveLinearOAuth,
11680
+ scrubGithubTokensFromChildEnv,
11560
11681
  secureFileUnlocksWith,
11561
11682
  setCaffeinateHold,
11562
11683
  setHttpFetchImpl,
@@ -11627,7 +11748,10 @@ export {
11627
11748
  updateLinearIssue,
11628
11749
  updateOpencodeSettings,
11629
11750
  updateThread,
11751
+ userClaudeMcpConfigPath,
11752
+ userCursorMcpConfigPath,
11630
11753
  validateLinearApiKey,
11754
+ warmGithubAgentAuth,
11631
11755
  withAgentInstructions,
11632
11756
  withExportedPath,
11633
11757
  withThreadLock,