@sideboard-ai/core 0.1.313 → 0.1.314

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 (32) hide show
  1. package/dist/{agents-OHIE3Z7L.js → agents-KIC6CNXF.js} +2 -2
  2. package/dist/{agents-PSNWJMEC.js → agents-S7VBS5JL.js} +2 -2
  3. package/dist/{chunk-ZW7RSQHY.js → chunk-5QYCCXXQ.js} +2 -2
  4. package/dist/{chunk-U3J2YY4T.js → chunk-6EGQPMSR.js} +11 -11
  5. package/dist/{chunk-TDXORDN6.js → chunk-7DBL5AF4.js} +117 -53
  6. package/dist/{chunk-QC2TQMPJ.js → chunk-7UP4D5XI.js} +2 -2
  7. package/dist/{chunk-2JOBQUUS.js → chunk-A45QMSVB.js} +117 -53
  8. package/dist/{chunk-WRZRX4Q7.js → chunk-NMPQ7GIS.js} +3 -3
  9. package/dist/{chunk-X3FSWWW2.js → chunk-S3KYDK6W.js} +4 -4
  10. package/dist/{chunk-62ESCTJ4.js → chunk-TO5UL7VN.js} +3 -3
  11. package/dist/{chunk-E2NJ6RH7.js → chunk-YK77HB3W.js} +10 -10
  12. package/dist/{chunk-RU6DTCCV.js → chunk-ZQLZ2A3I.js} +1 -1
  13. package/dist/{chunk-5QX2NYXL.js → chunk-ZSVKUOFH.js} +4 -4
  14. package/dist/{conductor-CTWR6NH4.js → conductor-G6TKCMIW.js} +2 -2
  15. package/dist/{conductor-YOBSYPLT.js → conductor-IIDQ2U24.js} +2 -2
  16. package/dist/{coordinator-prompt-YAZRQ4BI.js → coordinator-prompt-5USNNCG6.js} +1 -1
  17. package/dist/{coordinator-prompt-GZCWQAAV.js → coordinator-prompt-EXJSULAR.js} +1 -1
  18. package/dist/{global-workspace-H6X32IJZ.js → global-workspace-UDRTONQE.js} +1 -1
  19. package/dist/{global-workspace-BZAVBOH3.js → global-workspace-ZGPIGJ6J.js} +1 -1
  20. package/dist/index.cjs +130 -58
  21. package/dist/index.d.cts +13 -8
  22. package/dist/index.d.ts +13 -8
  23. package/dist/index.js +9 -9
  24. package/dist/mcp/run-stdio.cjs +130 -58
  25. package/dist/mcp/run-stdio.js +5 -5
  26. package/dist/{optional-cli-QDIT57VD.js → optional-cli-MLZSE6KW.js} +1 -1
  27. package/dist/{optional-cli-QY6V5S5N.js → optional-cli-SI4BCPRH.js} +2 -2
  28. package/dist/{orchestrator-RRHB7RNN.js → orchestrator-AM7VT2BD.js} +5 -5
  29. package/dist/{orchestrator-BF7TKSA2.js → orchestrator-V6NLIPLH.js} +5 -5
  30. package/dist/{workspaces-BQUDYTBX.js → workspaces-3TTODHKN.js} +1 -1
  31. package/dist/{workspaces-AGOLRBYZ.js → workspaces-TATO466L.js} +1 -1
  32. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -202,7 +202,7 @@ import {
202
202
  worktreeCleanupSettings,
203
203
  writeAgentBlock,
204
204
  writeWorktreeFile
205
- } from "./chunk-U3J2YY4T.js";
205
+ } from "./chunk-6EGQPMSR.js";
206
206
  import {
207
207
  LEGACY_PLAN_FILE_REL,
208
208
  PLAN_FILE_NAME,
@@ -292,7 +292,7 @@ import {
292
292
  userMcpNamesToDisable,
293
293
  worktreeMcpToolNames,
294
294
  writeInjectedMcpConfig
295
- } from "./chunk-TDXORDN6.js";
295
+ } from "./chunk-7DBL5AF4.js";
296
296
  import {
297
297
  brightsyMcpServerName,
298
298
  connectBrightsyTeam,
@@ -423,7 +423,7 @@ import {
423
423
  workspaceAgentChatSummaries,
424
424
  worktreeRunPortsPath,
425
425
  wrapReviewSkillMarkdown
426
- } from "./chunk-QC2TQMPJ.js";
426
+ } from "./chunk-7UP4D5XI.js";
427
427
  import {
428
428
  STDERR_EVENT_MAX_CHARS,
429
429
  STDOUT_EVENT_MAX_CHARS,
@@ -542,7 +542,7 @@ import {
542
542
  detectOptionalServiceClis,
543
543
  installOptionalServiceCli,
544
544
  optionalCliPresence
545
- } from "./chunk-RU6DTCCV.js";
545
+ } from "./chunk-ZQLZ2A3I.js";
546
546
  import {
547
547
  OPTIONAL_SERVICES,
548
548
  OPTIONAL_SERVICE_IDS,
@@ -558,7 +558,7 @@ import {
558
558
  optionalServiceConnected,
559
559
  optionalServiceSpec,
560
560
  verifyOptionalService
561
- } from "./chunk-WRZRX4Q7.js";
561
+ } from "./chunk-NMPQ7GIS.js";
562
562
  import {
563
563
  getAgentSetupInfo,
564
564
  installAgent,
@@ -623,7 +623,7 @@ import {
623
623
  stageBuffersAsAttachments,
624
624
  syncWorkspacesFromThreads,
625
625
  takenTeamSlugsForOrchestration
626
- } from "./chunk-5QX2NYXL.js";
626
+ } from "./chunk-ZSVKUOFH.js";
627
627
  import {
628
628
  GITHUB_PR_BODY_MAX_CHARS,
629
629
  GITHUB_PR_BODY_SAFE_CHARS,
@@ -8727,7 +8727,7 @@ async function startHeadlessHost(opts) {
8727
8727
  };
8728
8728
  const refreshRunning = async () => {
8729
8729
  try {
8730
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-BF7TKSA2.js");
8730
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-V6NLIPLH.js");
8731
8731
  agentsRunning = getOrchestrator2().getRuntime().running;
8732
8732
  } catch {
8733
8733
  agentsRunning = 0;
@@ -10659,7 +10659,7 @@ async function handleJobStop(params, _ctx) {
10659
10659
  return stopDetachedJob(jobCwd(rec), id, reason ? { reason } : void 0);
10660
10660
  }
10661
10661
  async function defaultTurnWait(ref, timeoutMs) {
10662
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-BF7TKSA2.js");
10662
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-V6NLIPLH.js");
10663
10663
  const orch = getOrchestrator2();
10664
10664
  const thread = await orch.waitForTurn(ref, timeoutMs, {
10665
10665
  resolveIfStillRunning: true
@@ -14035,7 +14035,7 @@ async function continueSourceThread(threadId, prompt) {
14035
14035
  await continueOnReply(threadId, prompt);
14036
14036
  return;
14037
14037
  }
14038
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-BF7TKSA2.js");
14038
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-V6NLIPLH.js");
14039
14039
  await getOrchestrator2().send(threadId, prompt);
14040
14040
  } catch {
14041
14041
  }
@@ -10147,12 +10147,12 @@ var init_coordinator_prompt = __esm({
10147
10147
  "- list_projects \u2014 registered repos (path + github slug + project context when set). Use account / project context to pick the right repo for tickets or reviews.",
10148
10148
  "- list_board \u2014 Home Kanban of workspaces (New / Draft / Review / Approved / Merged; one card per checkout). Sibling chats on a card are separate agents, not one agent. Path to merge: no PR \u2192 draft PR \u2192 open PR \u2192 approved \u2192 merged. Archive removes the card to Settings \u2192 History (list_archive to browse, restore_workspace to bring it back). Queued/running are activity on the card, not columns. Orchestration chats are not on the board. Filters: query, repoPath, kind, column, limit.",
10149
10149
  `- list_branches / list_prs / list_issues \u2014 pass repoPath from list_projects. Review is PRs (the surface for assigned ticket work), not the tickets: "Get me N tickets to review" \u2192 list_prs(queue=review, limit=N) then create_workspace sourceType=pr. That is open non-draft PRs labeled with this project's ready-for-review GitHub label (Settings \u2192 Projects; default eng-review) with no individual user reviewer yet. A team request (engineering-team) is not a claim \u2014 the viewer is on that team and can pick it up; claimed means an individual account is the reviewer. Bots ignored. Use Settings \u2192 Agents / Projects context (roles, teams, labels \u2014 freeform text; project adds to account) to prefer the right queues. queue=mine is review-requested:@me; queue=approved|changes uses those labels. Also: state, label, reviewer=me|unassigned|login, query, limit default 40 max 250; raise limit or tighten when truncated. list_issues (query, assignee=me|unassigned|all|user, limit default 40 max 250) lists Linear, AbleTime, or GitHub tickets \u2014 do not use it for that review-inbox ask. When they ask for tickets to work on, follow their context (assignee=me or unassigned as it says).`,
10150
- "- Find work: when they ask to find work, pick up tickets, or list reviews, use Settings \u2192 Agents (account) plus Settings \u2192 Projects (per-repo) context. Tickets \u2192 Sideboard list_issues / linear_* (Account Linear). Reviews \u2192 list_prs(queue=review). Do not call Claude Linear MCP or any other vendor Linear MCP \u2014 those HTTP connectors hang or flap on the first turn. If a vendor MCP is down or reconnecting, ignore it and keep going with Sideboard tools. Show the options \u2014 do not create_workspace or start unless they also asked to start (e.g. \u201Cfind me work and start it\u201D). Do not start this unprompted. To change that context, show the proposed text, ask_user (Save this context / Do not save), wait, then update_viewer_context with confirmed=true. Never write it without confirmation.",
10150
+ "- Find work: when they ask to find work, pick up tickets, or list reviews, use Settings \u2192 Agents (account) plus Settings \u2192 Projects (per-repo) context. Tickets \u2192 Sideboard list_issues / linear_* (Account Linear). Reviews \u2192 list_prs(queue=review). Do not call Claude Linear MCP or any other vendor Linear MCP \u2014 those HTTP connectors hang or flap on the first turn. If a vendor MCP is down or reconnecting, ignore it and keep going with Sideboard tools. A failed Claude connector is not a Sideboard outage \u2014 do not mention it when the Account connection works. Show the options \u2014 do not create_workspace or start unless they also asked to start (e.g. \u201Cfind me work and start it\u201D). Do not start this unprompted. To change that context, show the proposed text, ask_user (Save this context / Do not save), wait, then update_viewer_context with confirmed=true. Never write it without confirmation.",
10151
10151
  "- Ticket updates: list_issues / linear_search_issues / github_search_issues with updatedSince (yesterday, 2d, or ISO). One call returns new assignments, ticket edits, and new comments \u2014 do not get_issue every ticket just to check for comments. kind=created vs updated distinguishes new tickets from existing ones.",
10152
- "- linear_* (when Linear is connected) \u2014 list_teams for team key/states; linear_list_projects for project names; get/search include the project a ticket is on; get/create/update/comment with ENG-123. Worktree agents have the same Account tools \u2014 prefer they comment, update status, and create spin-offs (parent=) on their own ticket when they were asked to do the work. When reviewing a PR or ticket, do not comment or update until the user types a next step \u2014 they should work through the feedback in chat first. Do not tell the child to ask_user after the review. Scope errors: reconnect Linear in Account settings. Prefer these over any Linear MCP the CLI may still list.",
10153
- "- github_* \u2014 get/comment/update/create GitHub issues via Account `gh` (#123). github_list_projects and get/search include GitHub Projects. projectsError or a missing read:project scope \u2192 `gh auth refresh -s read:project`. Worktree agents have these too. Prefer over any vendor GitHub MCP. Pass parent= for spin-offs. When reviewing a PR or ticket, do not comment, submit `gh pr review`, or update the PR/ticket until the user types a next step.",
10152
+ "- linear_* (when Linear is connected) \u2014 list_teams for team key/states; linear_list_projects for project names; get/search include the project a ticket is on; get/create/update/comment with ENG-123. Worktree agents have the same Account tools \u2014 prefer they comment, update status, and create spin-offs (parent=) on their own ticket when they were asked to do the work. When reviewing a PR or ticket, do not comment or update until the user types a next step \u2014 they should work through the feedback in chat first. Do not tell the child to ask_user after the review. Scope errors: reconnect Linear in Account settings. Prefer these over any Linear MCP the CLI may still list. Worktree agents use the Claude Linear connector only when Account Linear is not set or the Sideboard call fails, and they do not mention that connector startup failure when Sideboard works.",
10153
+ "- github_* \u2014 get/comment/update/create GitHub issues via Account `gh` (#123). github_list_projects and get/search include GitHub Projects. projectsError or a missing read:project scope \u2192 `gh auth refresh -s read:project`. Worktree agents have these too. Prefer Sideboard `github_*` while Account `gh` works. A failed Claude GitHub connector (`mcp_github_github`) is not a Sideboard outage \u2014 do not mention it. Use that connector only when `gh` is not set up or the Sideboard call fails. Pass parent= for spin-offs. When reviewing a PR or ticket, do not comment, submit `gh pr review`, or update the PR/ticket until the user types a next step.",
10154
10154
  "- abletime_* (when AbleTime is connected) \u2014 orientation first; abletime_list_projects lists projects; get/list include the project a task is on; get/comment/update/create (parent= for spin-offs); ensure_task when work has no ticket (or create_workspace from the default branch auto-creates one). Worktree agents have the same Account tools. Same review-write gate as Linear/GitHub.",
10155
- "- Optional connectors (Vercel, Supabase, Sentry) in Settings \u2192 Connectors inject tokens into worktree agent env when connected. Prefer official CLIs (`vercel`, `supabase`, `sentry-cli`). When Settings \u2192 Connectors has a PostHog personal API key, PostHog is the Sideboard tool `posthog_api` (GET by default; POST `/api/projects/:id/query/` or `/api/environments/:id/query/` is a read and does not need write=true; other POST and PATCH need write=true only when the user asked to change data). The PostHog key stays in the vault \u2014 do not read it from the environment, and do not sign in to a PostHog MCP. When no PostHog API key is set, leave the Claude PostHog connector alone. If a Vercel, Supabase, or Sentry MCP needsAuth or is unauthorized, do not sign in \u2014 use the native CLI. Tell any worktree agent (Claude / Cursor / Codex / OpenCode) to write CLI output to `.context/cli/` and read a slice. If a CLI is missing, the user presses Install CLI on that row. Do not add vendor MCPs. Git (`gh`) stays Settings \u2192 Git; issue tracking stays Settings \u2192 Issues. The phone remote is Settings \u2192 Remote \u2014 do not look up Slack users.",
10155
+ "- Optional connectors (Vercel, Supabase, Sentry) in Settings \u2192 Connectors inject tokens into worktree agent env when connected. Prefer official CLIs (`vercel`, `supabase`, `sentry-cli`). When Settings \u2192 Connectors has a PostHog personal API key, PostHog is the Sideboard tool `posthog_api` (GET by default; POST `/api/projects/:id/query/` or `/api/environments/:id/query/` is a read and does not need write=true; other POST and PATCH need write=true only when the user asked to change data). The PostHog key stays in the vault \u2014 do not read it from the environment, and do not sign in to a PostHog MCP. When no PostHog API key is set, use the Claude PostHog connector. When a key is set, ignore a failed Claude PostHog connector and do not sign in to a PostHog MCP. If a Vercel, Supabase, or Sentry MCP needsAuth or is unauthorized while that Sideboard token is set, do not sign in \u2014 use the native CLI. When that token is not set or the CLI call fails, the Claude connector is the fallback. Do not mention a Claude connector startup failure when the Sideboard connection works. Tell any worktree agent (Claude / Cursor / Codex / OpenCode) to write CLI output to `.context/cli/` and read a slice. If a CLI is missing, the user presses Install CLI on that row. Do not add vendor MCPs. Git (`gh`) stays Settings \u2192 Git; issue tracking stays Settings \u2192 Issues. The phone remote is Settings \u2192 Remote \u2014 do not look up Slack users.",
10156
10156
  "- get_pr_stack / open_pr_stack_layers / add_stack_layer / create_pr_stack \u2014 GitHub stacked PRs (`gh stack`); one worktree per layer",
10157
10157
  "- list_models \u2014 only when you need a specific model (rare); otherwise omit model so Account defaults apply",
10158
10158
  "- list_chats / get_chat \u2014 live thread list (parent id + last message preview). get_chat on this orchestration chat lists child worktree agents (status + lastText). blockedReason is why that agent is waiting on a person. Also includes usage / lastTurnUsage. Archived workspaces and agents are list_archive, not this list.",
@@ -11385,6 +11385,127 @@ var init_brightsy = __esm({
11385
11385
  }
11386
11386
  });
11387
11387
 
11388
+ // src/agents/claude-mcp-status.ts
11389
+ function mcpStatusThinkingFromClaudeInit(obj) {
11390
+ const raw = obj.mcp_servers ?? obj.mcpServers;
11391
+ const servers = [];
11392
+ if (Array.isArray(raw)) {
11393
+ for (const item of raw) {
11394
+ if (!item || typeof item !== "object" || Array.isArray(item)) continue;
11395
+ const rec = item;
11396
+ const name = typeof rec.name === "string" && rec.name.trim() || typeof rec.server === "string" && rec.server.trim() || "";
11397
+ const status = typeof rec.status === "string" && rec.status.trim() || typeof rec.state === "string" && rec.state.trim() || "";
11398
+ if (name) servers.push({ name, status: status || "unknown" });
11399
+ }
11400
+ } else if (raw && typeof raw === "object") {
11401
+ for (const [name, value] of Object.entries(raw)) {
11402
+ if (!name.trim()) continue;
11403
+ if (typeof value === "string" && value.trim()) {
11404
+ servers.push({ name, status: value.trim() });
11405
+ continue;
11406
+ }
11407
+ if (value && typeof value === "object" && !Array.isArray(value)) {
11408
+ const rec = value;
11409
+ const status = typeof rec.status === "string" && rec.status.trim() || typeof rec.state === "string" && rec.state.trim() || "unknown";
11410
+ servers.push({ name, status });
11411
+ }
11412
+ }
11413
+ }
11414
+ const coverage = claudeConnectorCoverage();
11415
+ const sideboardOk = sideboardMcpOk(servers);
11416
+ const notable = servers.filter(
11417
+ (server) => isNotableMcpInitStatus(server, sideboardOk, coverage)
11418
+ );
11419
+ if (notable.length === 0) return null;
11420
+ return `MCP: ${notable.map((s) => `${s.name} ${s.status}`).join(", ")}`;
11421
+ }
11422
+ function isCleanMcpConnect(status) {
11423
+ return /^(connected|ok|ready|success)$/i.test(status.trim());
11424
+ }
11425
+ function isMcpAuthStatus(status) {
11426
+ return /needs[_-]?auth|needs authentication|unauthorized|not authenticated|authrequired/i.test(
11427
+ status
11428
+ );
11429
+ }
11430
+ function isSideboardMcpName(name) {
11431
+ return /^sideboard$/i.test(name.trim()) || /^mcp__sideboard$/i.test(name.trim());
11432
+ }
11433
+ function isVendorClaudeAiMcpName(name) {
11434
+ return /^claude\.ai\b/i.test(name.trim()) || /^mcp__claude_ai_/i.test(name.trim());
11435
+ }
11436
+ function sideboardMcpOk(servers) {
11437
+ const row = servers.find((server) => isSideboardMcpName(server.name));
11438
+ return Boolean(row && isCleanMcpConnect(row.status));
11439
+ }
11440
+ function sideboardServiceForClaudeConnector(name) {
11441
+ const raw = name.trim();
11442
+ if (!raw || isSideboardMcpName(raw)) return null;
11443
+ const pluginLike = /^(?:plugin[:_]|mcp__plugin_|claude\.ai\s|(?:mcp__)?claude_ai_)/i.test(raw);
11444
+ const doubled = raw.match(/^mcp_([a-z0-9]+)_([a-z0-9]+)$/i);
11445
+ if (!pluginLike && !(doubled && doubled[1].toLowerCase() === doubled[2].toLowerCase())) {
11446
+ return null;
11447
+ }
11448
+ let body = raw;
11449
+ if (/^claude\.ai\s+/i.test(body)) body = body.replace(/^claude\.ai\s+/i, "");
11450
+ else if (/^(?:mcp__)?claude_ai_/i.test(body)) body = body.replace(/^(?:mcp__)?claude_ai_/i, "");
11451
+ else if (/^mcp__plugin_/i.test(body)) body = body.slice("mcp__plugin_".length);
11452
+ else if (/^plugin_/i.test(body)) body = body.slice("plugin_".length);
11453
+ else if (/^plugin:/i.test(body)) body = body.slice("plugin:".length);
11454
+ else if (/^mcp_/i.test(body)) body = body.slice("mcp_".length);
11455
+ const head = body.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean)[0];
11456
+ if (!head || !SIDEBOARD_CONNECTOR_SERVICES.includes(head)) return null;
11457
+ return head;
11458
+ }
11459
+ function claudeConnectorCoverage() {
11460
+ let github = false;
11461
+ try {
11462
+ github = githubAgentAuthReady();
11463
+ } catch {
11464
+ github = false;
11465
+ }
11466
+ let linear = false;
11467
+ let posthog = false;
11468
+ let vercel = false;
11469
+ let supabase = false;
11470
+ let sentry = false;
11471
+ try {
11472
+ linear = isLinearConnected();
11473
+ posthog = isPosthogConnected();
11474
+ const integrations = loadAppSettings().integrations ?? {};
11475
+ if (integrations.githubPat?.trim()) github = true;
11476
+ vercel = Boolean(integrations.vercelToken?.trim());
11477
+ supabase = Boolean(integrations.supabaseAccessToken?.trim());
11478
+ sentry = Boolean(integrations.sentryAuthToken?.trim());
11479
+ } catch {
11480
+ }
11481
+ return { github, linear, posthog, vercel, supabase, sentry };
11482
+ }
11483
+ function isNotableMcpInitStatus(server, sideboardOk, coverage) {
11484
+ if (isCleanMcpConnect(server.status)) return false;
11485
+ if (isSideboardMcpName(server.name)) return true;
11486
+ if (isMcpAuthStatus(server.status)) return false;
11487
+ const service = sideboardServiceForClaudeConnector(server.name);
11488
+ if (service) return !(sideboardOk && coverage[service]);
11489
+ if (isVendorClaudeAiMcpName(server.name)) return false;
11490
+ return true;
11491
+ }
11492
+ var SIDEBOARD_CONNECTOR_SERVICES;
11493
+ var init_claude_mcp_status = __esm({
11494
+ "src/agents/claude-mcp-status.ts"() {
11495
+ "use strict";
11496
+ init_github_agent_auth();
11497
+ init_app_settings();
11498
+ SIDEBOARD_CONNECTOR_SERVICES = [
11499
+ "github",
11500
+ "linear",
11501
+ "posthog",
11502
+ "vercel",
11503
+ "supabase",
11504
+ "sentry"
11505
+ ];
11506
+ }
11507
+ });
11508
+
11388
11509
  // src/mcp-ui/meta.ts
11389
11510
  function matchClaudeMcpTool(toolName, serverNames) {
11390
11511
  const name = toolName.trim();
@@ -13552,56 +13673,6 @@ function claudeString(obj, key) {
13552
13673
  const v = obj[key];
13553
13674
  return typeof v === "string" && v.trim() ? v.trim() : void 0;
13554
13675
  }
13555
- function mcpStatusThinkingFromClaudeInit(obj) {
13556
- const raw = obj.mcp_servers ?? obj.mcpServers;
13557
- const servers = [];
13558
- if (Array.isArray(raw)) {
13559
- for (const item of raw) {
13560
- if (!item || typeof item !== "object" || Array.isArray(item)) continue;
13561
- const rec = item;
13562
- const name = typeof rec.name === "string" && rec.name.trim() || typeof rec.server === "string" && rec.server.trim() || "";
13563
- const status = typeof rec.status === "string" && rec.status.trim() || typeof rec.state === "string" && rec.state.trim() || "";
13564
- if (name) servers.push({ name, status: status || "unknown" });
13565
- }
13566
- } else if (raw && typeof raw === "object") {
13567
- for (const [name, value] of Object.entries(raw)) {
13568
- if (!name.trim()) continue;
13569
- if (typeof value === "string" && value.trim()) {
13570
- servers.push({ name, status: value.trim() });
13571
- continue;
13572
- }
13573
- if (value && typeof value === "object" && !Array.isArray(value)) {
13574
- const rec = value;
13575
- const status = typeof rec.status === "string" && rec.status.trim() || typeof rec.state === "string" && rec.state.trim() || "unknown";
13576
- servers.push({ name, status });
13577
- }
13578
- }
13579
- }
13580
- const notable = servers.filter(isNotableMcpInitStatus);
13581
- if (notable.length === 0) return null;
13582
- return `MCP: ${notable.map((s) => `${s.name} ${s.status}`).join(", ")}`;
13583
- }
13584
- function isCleanMcpConnect(status) {
13585
- return /^(connected|ok|ready|success)$/i.test(status.trim());
13586
- }
13587
- function isMcpAuthStatus(status) {
13588
- return /needs[_-]?auth|needs authentication|unauthorized|not authenticated|authrequired/i.test(
13589
- status
13590
- );
13591
- }
13592
- function isSideboardMcpName(name) {
13593
- return /^sideboard$/i.test(name.trim()) || /^mcp__sideboard$/i.test(name.trim());
13594
- }
13595
- function isVendorClaudeAiMcpName(name) {
13596
- return /^claude\.ai\b/i.test(name.trim()) || /^mcp__claude_ai_/i.test(name.trim());
13597
- }
13598
- function isNotableMcpInitStatus(server) {
13599
- if (isCleanMcpConnect(server.status)) return false;
13600
- if (isSideboardMcpName(server.name)) return true;
13601
- if (isVendorClaudeAiMcpName(server.name)) return false;
13602
- if (isMcpAuthStatus(server.status)) return false;
13603
- return true;
13604
- }
13605
13676
  function eventsFromClaudeSystem(obj) {
13606
13677
  const subtype = claudeString(obj, "subtype") ?? "";
13607
13678
  const parentId = claudeParentToolUseId(obj);
@@ -13749,6 +13820,7 @@ var init_claude = __esm({
13749
13820
  import_node_fs34 = require("fs");
13750
13821
  init_run();
13751
13822
  init_app_settings();
13823
+ init_claude_mcp_status();
13752
13824
  init_claude_mcp();
13753
13825
  init_host();
13754
13826
  init_error_detail();
@@ -25693,7 +25765,7 @@ function formatIssueToolsDirective(opts) {
25693
25765
  if (!opts.linear && !opts.abletime && !github) return null;
25694
25766
  const lines = [
25695
25767
  "Issue tracking (Settings \u2192 Issues / Git \u2014 already signed in):",
25696
- "- Use Sideboard `linear_*` / `github_*` / `abletime_*` tools. Do not call Claude Linear MCP, vendor GitHub MCP, or any other vendor issue MCP \u2014 those need a separate login and hang. If a vendor namespace shows needsAuth, ignore it and keep going with Sideboard tools."
25768
+ "- Use Sideboard `linear_*` / `github_*` / `abletime_*` when that Account connection is set and the call works. If it is not set, or the Sideboard call fails because the connection is down, use the Claude connector for that service. Do not mention a Claude connector that failed to start (for example `mcp_github_github` or `plugin:github:github`) when the Sideboard connection is working. A vendor issue MCP that only needsAuth is noise \u2014 do not sign in to it while Sideboard covers that service."
25697
25769
  ];
25698
25770
  if (opts.linear) {
25699
25771
  lines.push(
@@ -25733,7 +25805,7 @@ function formatIssueToolsReminder(opts) {
25733
25805
  ].filter(Boolean);
25734
25806
  const ticket = opts.ticketId?.trim();
25735
25807
  const ticketBit = ticket ? ` This ticket: ${ticket}${opts.ticketProvider ? ` (${opts.ticketProvider})` : ""} \u2014 get; comment/update review findings only after they ask. Spin-offs use parent=.` : " get/comment/update/create (parent= for spin-offs).";
25736
- return `Issues: Sideboard ${names.join(" / ")} (Account). Ignore vendor issue MCP auth.${ticketBit} Review stays in chat \u2014 do not ask_user after it; they type next steps. Authors see comments immediately.`;
25808
+ return `Issues: Sideboard ${names.join(" / ")} when that Account connection works. If it is not set or the call fails, use the Claude connector. Do not mention a Claude connector startup failure when Sideboard covers it.${ticketBit} Review stays in chat \u2014 do not ask_user after it; they type next steps. Authors see comments immediately.`;
25737
25809
  }
25738
25810
  function formatPrGateDirective() {
25739
25811
  return [
@@ -25934,7 +26006,7 @@ function connectorAuthCaution(posthog, cliConnected) {
25934
26006
  const signIn = posthog ? "If a connector MCP is listed but needsAuth or returns unauthorized, do not sign in to that MCP." : "If a Vercel, Supabase, or Sentry MCP is listed but needsAuth or returns unauthorized, do not sign in to that MCP.";
25935
26007
  const token = cliConnected ? " CLI tokens are already in this process." : "";
25936
26008
  const key = posthog ? " Do not read a PostHog key from the environment." : "";
25937
- return `${signIn}${token}${key}`;
26009
+ return `${signIn}${token}${key} When this Sideboard connection works, ignore a Claude connector that failed to start. Use the Claude connector only when this connection is not set or the CLI call fails.`;
25938
26010
  }
25939
26011
  function connectorReminderBit(spec, cli) {
25940
26012
  if (!spec.cli) return `${spec.label}: \`posthog_api\``;
@@ -25961,7 +26033,7 @@ function formatOptionalServicesReminder(integrations, cli) {
25961
26033
  const bits = connected.map((spec) => connectorReminderBit(spec, cli)).join(". ");
25962
26034
  const tokenBit = connected.some((spec) => spec.cli) ? "CLI tokens are already in this process. " : "";
25963
26035
  const posthog = connected.some((spec) => spec.id === "posthog");
25964
- const auth = posthog ? "If a connector MCP needsAuth or is unauthorized, ignore it and use the CLI or `posthog_api`. Do not read a PostHog key from the environment." : "If a Vercel, Supabase, or Sentry MCP needsAuth or is unauthorized, ignore it and use the CLI.";
26036
+ const auth = posthog ? "If a connector MCP needsAuth or is unauthorized, ignore it and use the CLI or `posthog_api` while this Sideboard connection works. Use the Claude connector only when it is not set or the call fails. Do not read a PostHog key from the environment." : "If a Vercel, Supabase, or Sentry MCP needsAuth or is unauthorized, ignore it and use the CLI while this Sideboard connection works. Use the Claude connector only when it is not set or the CLI call fails.";
25965
26037
  return `Settings \u2192 Connectors: ${tokenBit}${bits}. ${auth} Do not add vendor MCPs. Shell dumps from those CLIs go in \`.context/cli/\` \u2014 read a slice.`;
25966
26038
  }
25967
26039
  async function connectedCliPresence(integrations) {
@@ -56,7 +56,7 @@ import {
56
56
  updateSchedule,
57
57
  workspaceTagTargetRef,
58
58
  writeAgentBlock
59
- } from "../chunk-E2NJ6RH7.js";
59
+ } from "../chunk-YK77HB3W.js";
60
60
  import "../chunk-LX5R5JOR.js";
61
61
  import {
62
62
  commentAbleTimeTask,
@@ -81,7 +81,7 @@ import "../chunk-6424BACS.js";
81
81
  import "../chunk-CFTOKVQN.js";
82
82
  import {
83
83
  normalizeServiceOrigin
84
- } from "../chunk-62ESCTJ4.js";
84
+ } from "../chunk-TO5UL7VN.js";
85
85
  import {
86
86
  PRESENT_PLAN_REQUIRES_PLAN_MODE,
87
87
  PRESENT_PLAN_TOOL_DESCRIPTION,
@@ -97,7 +97,7 @@ import {
97
97
  shouldRegisterMcpWaitForTurn,
98
98
  sideboardMcpProfile,
99
99
  worktreeMcpToolNames
100
- } from "../chunk-2JOBQUUS.js";
100
+ } from "../chunk-A45QMSVB.js";
101
101
  import "../chunk-EGTCXNQM.js";
102
102
  import "../chunk-V5BTGQ6M.js";
103
103
  import "../chunk-E63AM3PW.js";
@@ -114,7 +114,7 @@ import {
114
114
  waitForDetachedJob,
115
115
  waitForTurnToolResult,
116
116
  workspaceAgentChatSummaries
117
- } from "../chunk-ZW7RSQHY.js";
117
+ } from "../chunk-5QYCCXXQ.js";
118
118
  import {
119
119
  HUGE_TOOL_RESULT_SUMMARY,
120
120
  clipToolResultForStore,
@@ -125,7 +125,7 @@ import {
125
125
  import {
126
126
  GLOBAL_WORKSPACE_ID,
127
127
  isCloudCoordinatorThread
128
- } from "../chunk-X3FSWWW2.js";
128
+ } from "../chunk-S3KYDK6W.js";
129
129
  import {
130
130
  canonicalizeRepoPath,
131
131
  formatGhLandError,
@@ -4,7 +4,7 @@ import {
4
4
  OPTIONAL_SERVICES,
5
5
  isOptionalServiceId,
6
6
  optionalServiceSpec
7
- } from "./chunk-62ESCTJ4.js";
7
+ } from "./chunk-TO5UL7VN.js";
8
8
  import {
9
9
  installNpmGlobalPackage,
10
10
  whichOnPath
@@ -3,8 +3,8 @@ import {
3
3
  detectOptionalServiceClis,
4
4
  installOptionalServiceCli,
5
5
  optionalCliPresence
6
- } from "./chunk-RU6DTCCV.js";
7
- import "./chunk-WRZRX4Q7.js";
6
+ } from "./chunk-ZQLZ2A3I.js";
7
+ import "./chunk-NMPQ7GIS.js";
8
8
  import "./chunk-U4WACWBC.js";
9
9
  import "./chunk-JAT3JFOS.js";
10
10
  import "./chunk-QVN2WOKJ.js";
@@ -11,19 +11,19 @@ import {
11
11
  resolveSendFollowUp,
12
12
  startOrchestration,
13
13
  waitForPidExit
14
- } from "./chunk-E2NJ6RH7.js";
14
+ } from "./chunk-YK77HB3W.js";
15
15
  import "./chunk-LX5R5JOR.js";
16
- import "./chunk-62ESCTJ4.js";
16
+ import "./chunk-TO5UL7VN.js";
17
17
  import "./chunk-4GK32AYX.js";
18
18
  import "./chunk-DC3VZXMA.js";
19
- import "./chunk-2JOBQUUS.js";
19
+ import "./chunk-A45QMSVB.js";
20
20
  import "./chunk-EGTCXNQM.js";
21
21
  import "./chunk-V5BTGQ6M.js";
22
22
  import "./chunk-E63AM3PW.js";
23
23
  import "./chunk-2GPQZZLY.js";
24
- import "./chunk-ZW7RSQHY.js";
24
+ import "./chunk-5QYCCXXQ.js";
25
25
  import "./chunk-I5TESHDN.js";
26
- import "./chunk-X3FSWWW2.js";
26
+ import "./chunk-S3KYDK6W.js";
27
27
  import "./chunk-DLGGLV2M.js";
28
28
  import "./chunk-N2WW62LF.js";
29
29
  import "./chunk-DD67JWTN.js";
@@ -9,16 +9,16 @@ import {
9
9
  resolveSendFollowUp,
10
10
  startOrchestration,
11
11
  waitForPidExit
12
- } from "./chunk-U3J2YY4T.js";
12
+ } from "./chunk-6EGQPMSR.js";
13
13
  import "./chunk-PGPSIEMW.js";
14
- import "./chunk-TDXORDN6.js";
14
+ import "./chunk-7DBL5AF4.js";
15
15
  import "./chunk-HH3VVTEC.js";
16
- import "./chunk-QC2TQMPJ.js";
16
+ import "./chunk-7UP4D5XI.js";
17
17
  import "./chunk-7Q327QF2.js";
18
18
  import "./chunk-7H655NEW.js";
19
- import "./chunk-WRZRX4Q7.js";
19
+ import "./chunk-NMPQ7GIS.js";
20
20
  import "./chunk-U4WACWBC.js";
21
- import "./chunk-5QX2NYXL.js";
21
+ import "./chunk-ZSVKUOFH.js";
22
22
  import "./chunk-BIPXOHZI.js";
23
23
  import "./chunk-HG25AYBV.js";
24
24
  import "./chunk-2P4XKWV2.js";
@@ -9,7 +9,7 @@ import {
9
9
  removeWorkspace,
10
10
  sameWorkspacePath,
11
11
  syncWorkspacesFromThreads
12
- } from "./chunk-5QX2NYXL.js";
12
+ } from "./chunk-ZSVKUOFH.js";
13
13
  import "./chunk-BIPXOHZI.js";
14
14
  import "./chunk-HG25AYBV.js";
15
15
  import "./chunk-2P4XKWV2.js";
@@ -11,7 +11,7 @@ import {
11
11
  removeWorkspace,
12
12
  sameWorkspacePath,
13
13
  syncWorkspacesFromThreads
14
- } from "./chunk-X3FSWWW2.js";
14
+ } from "./chunk-S3KYDK6W.js";
15
15
  import "./chunk-DLGGLV2M.js";
16
16
  import "./chunk-N2WW62LF.js";
17
17
  import "./chunk-DD67JWTN.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sideboard-ai/core",
3
- "version": "0.1.313",
3
+ "version": "0.1.314",
4
4
  "description": "Sideboard core — orchestration, agents, git worktrees, MCP server",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",