@sideboard-ai/core 0.1.319 → 0.1.321

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 (75) hide show
  1. package/dist/{abletime-L3ODNTBT.js → abletime-CRRLEYTE.js} +4 -4
  2. package/dist/{abletime-DVYO4IVS.js → abletime-ICW6Q2AB.js} +4 -4
  3. package/dist/{abletime-oauth-2VWQCXGT.js → abletime-oauth-P3KPPJE4.js} +3 -3
  4. package/dist/{abletime-oauth-6DTX7LB7.js → abletime-oauth-Q76XBSPG.js} +3 -3
  5. package/dist/{abletime-rest-PYQM234B.js → abletime-rest-DNFAYYLP.js} +3 -3
  6. package/dist/{abletime-rest-7NICZYOC.js → abletime-rest-DQ3PNKXP.js} +3 -3
  7. package/dist/agents/cursor-runner.js +2 -2
  8. package/dist/{agents-KABJUDPI.js → agents-PFVYC36J.js} +10 -10
  9. package/dist/{agents-2AR7I6B6.js → agents-ROFDNE7Z.js} +11 -11
  10. package/dist/{app-settings-CZVFMOI5.js → app-settings-KMPVI2B7.js} +1 -1
  11. package/dist/{app-settings-V6YPYY57.js → app-settings-P3H4SEIK.js} +1 -1
  12. package/dist/{chunk-QVN2WOKJ.js → chunk-2TUE6JKQ.js} +12 -0
  13. package/dist/{chunk-OO3R6CS2.js → chunk-45UB2J47.js} +537 -90
  14. package/dist/{chunk-DD67JWTN.js → chunk-4YXZOXMT.js} +1 -1
  15. package/dist/{chunk-5OM7UCTQ.js → chunk-56M6VEXI.js} +3 -3
  16. package/dist/{chunk-ZM43NTJJ.js → chunk-5OQONGHO.js} +5 -5
  17. package/dist/{chunk-V5BTGQ6M.js → chunk-6U6QRUHY.js} +1 -1
  18. package/dist/{chunk-QPLQXWND.js → chunk-72PUPPV2.js} +3 -3
  19. package/dist/{chunk-53OCOGND.js → chunk-7JV5QP5K.js} +3 -3
  20. package/dist/{chunk-HOLB6ZFZ.js → chunk-B4CDSSRN.js} +2 -0
  21. package/dist/{chunk-ST2UQBJT.js → chunk-BANN5HUX.js} +8 -8
  22. package/dist/{chunk-AESO2KJS.js → chunk-BPDVHB4U.js} +3 -3
  23. package/dist/{chunk-WLZHRNE6.js → chunk-BTIXTH4N.js} +3 -3
  24. package/dist/{chunk-AUJ4XB6H.js → chunk-DFUXW2IT.js} +2 -2
  25. package/dist/{chunk-I5TESHDN.js → chunk-EQ52JR3Q.js} +5 -5
  26. package/dist/{chunk-E52SQENB.js → chunk-FZKAAAEB.js} +3 -1
  27. package/dist/{chunk-YALFZKSC.js → chunk-H6GXYV5Q.js} +23 -20
  28. package/dist/{chunk-JD7CC6SW.js → chunk-HHPTGIKS.js} +2 -2
  29. package/dist/{chunk-GCHSJCCX.js → chunk-IFU4W4C4.js} +3 -1
  30. package/dist/{chunk-YEIHCSZS.js → chunk-IFWGG2M2.js} +9 -0
  31. package/dist/{chunk-IAPO7ZFG.js → chunk-JNEFEA2A.js} +8 -8
  32. package/dist/{chunk-U2N32EA6.js → chunk-LD2DXHBP.js} +543 -92
  33. package/dist/{chunk-7Q327QF2.js → chunk-QIC2JXHW.js} +5 -5
  34. package/dist/{chunk-2P4XKWV2.js → chunk-QKHEVSB5.js} +1 -1
  35. package/dist/{chunk-NRSC4N5X.js → chunk-RGUZPMTF.js} +8 -8
  36. package/dist/{chunk-AZ4GEEGL.js → chunk-RHJKZOPQ.js} +3 -3
  37. package/dist/{chunk-HH3VVTEC.js → chunk-S5CJUIPY.js} +5 -5
  38. package/dist/{chunk-A6C67DY5.js → chunk-SPMIZSKH.js} +16 -13
  39. package/dist/{chunk-FDXHNROD.js → chunk-TEFFR6PB.js} +2 -2
  40. package/dist/{chunk-TUJFCJJU.js → chunk-UWJUARFA.js} +546 -187
  41. package/dist/{chunk-MBYGWNLQ.js → chunk-UX6EDDGR.js} +1 -1
  42. package/dist/{chunk-LXBZQP2Q.js → chunk-V76MQ7MH.js} +5 -5
  43. package/dist/{chunk-GH7UMULC.js → chunk-XDQSHSL6.js} +8 -8
  44. package/dist/{chunk-2UG25RMK.js → chunk-YBTSZ2SW.js} +12 -0
  45. package/dist/{chunk-A46CIARU.js → chunk-YWBLQBSN.js} +549 -188
  46. package/dist/{chunk-Y3Y7SZBZ.js → chunk-ZHGMRBSC.js} +1 -1
  47. package/dist/{conductor-MG2RAQNT.js → conductor-CNT3VL3S.js} +8 -8
  48. package/dist/{conductor-NIUBJLTS.js → conductor-XLXJU24U.js} +8 -8
  49. package/dist/{connected-teams-IHK2WXUI.js → connected-teams-H4LZOJDC.js} +2 -2
  50. package/dist/{connected-teams-IFW3NQ6G.js → connected-teams-XYRZMQO4.js} +2 -2
  51. package/dist/{coordinator-prompt-X74F3JIC.js → coordinator-prompt-D5EE2YTV.js} +6 -6
  52. package/dist/{coordinator-prompt-3CT3D5UM.js → coordinator-prompt-TU24TQ4I.js} +6 -6
  53. package/dist/{global-workspace-BUWMRNW5.js → global-workspace-743TPQNF.js} +6 -6
  54. package/dist/{global-workspace-FTNJEML3.js → global-workspace-UPMXDQM7.js} +6 -6
  55. package/dist/index.cjs +2160 -867
  56. package/dist/index.d.cts +211 -74
  57. package/dist/index.d.ts +211 -74
  58. package/dist/index.js +496 -78
  59. package/dist/mcp/run-stdio.cjs +1377 -478
  60. package/dist/mcp/run-stdio.js +80 -32
  61. package/dist/{optional-cli-6GGESWGE.js → optional-cli-2YDQQCCD.js} +5 -5
  62. package/dist/{optional-cli-EMSZBYDE.js → optional-cli-USD6PROE.js} +4 -4
  63. package/dist/{orchestrator-NCA4LSCC.js → orchestrator-B4STIW4B.js} +14 -14
  64. package/dist/{orchestrator-H3DSZ5RM.js → orchestrator-VQ4HRYVB.js} +13 -13
  65. package/dist/{run-PCX5QWR4.js → run-7QMRYP3F.js} +3 -1
  66. package/dist/{run-TB7RBII2.js → run-UPNCCRCN.js} +3 -1
  67. package/dist/{thread-store-PLNIWFZ4.js → thread-store-3F7GR64A.js} +1 -1
  68. package/dist/{thread-store-7BBA63KV.js → thread-store-JRSL4HQY.js} +1 -1
  69. package/dist/{workspaces-MGKEAYNM.js → workspaces-47WQL5IG.js} +6 -6
  70. package/dist/{workspaces-2V5UYPYC.js → workspaces-75FD4QUR.js} +6 -6
  71. package/dist/{worktree-XJKLDYOL.js → worktree-G3E6WP66.js} +11 -9
  72. package/dist/{worktree-THAXW5U7.js → worktree-PDNPL5CQ.js} +11 -9
  73. package/dist/{worktree-exclude-RXZPTCNH.js → worktree-exclude-INRDQFWV.js} +2 -2
  74. package/dist/{worktree-exclude-5N2KTYIT.js → worktree-exclude-P5NJODWP.js} +2 -2
  75. package/package.json +1 -1
@@ -213,13 +213,13 @@ function toolDescription(name, input) {
213
213
  else if (/notify_orchestrator$/i.test(name)) return "Notify orchestrator";
214
214
  else if (/set_workspace_tags$/i.test(name)) return "Set workspace tags";
215
215
  if (/(?:list|set|delete)_env$/i.test(name)) return /list_env$/i.test(name) ? "List env vars" : /set_env$/i.test(name) ? "Set env var" : "Delete env var";
216
- if (/list_schedules$/i.test(name)) return "List schedules";
216
+ if (/list_schedules$/i.test(name)) return "List automations";
217
217
  if (/create_schedule$/i.test(name)) {
218
- return str(input?.name) ? `Schedule ${str(input?.name)}` : "Create schedule";
218
+ return str(input?.name) ? `Automation ${str(input?.name)}` : "Create automation";
219
219
  }
220
- if (/update_schedule$/i.test(name)) return "Update schedule";
221
- if (/delete_schedule$/i.test(name)) return "Delete schedule";
222
- if (/run_schedule$/i.test(name)) return "Run schedule";
220
+ if (/update_schedule$/i.test(name)) return "Update automation";
221
+ if (/delete_schedule$/i.test(name)) return "Delete automation";
222
+ if (/run_schedule$/i.test(name)) return "Run automation";
223
223
  if (isSkillToolName(name)) {
224
224
  const cmd = skillCommandFromInput(input);
225
225
  return cmd ? `Using /${cmd}` : "Using skill";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  git
3
- } from "./chunk-QVN2WOKJ.js";
3
+ } from "./chunk-2TUE6JKQ.js";
4
4
 
5
5
  // src/git/worktree-exclude.ts
6
6
  import { mkdirSync, readFileSync, writeFileSync } from "fs";
@@ -5,17 +5,17 @@ import {
5
5
  compactSummaryPart,
6
6
  isInternalAgentStatusText,
7
7
  lastAssistantMessageText
8
- } from "./chunk-I5TESHDN.js";
8
+ } from "./chunk-EQ52JR3Q.js";
9
9
  import {
10
10
  isCloudCoordinatorThread,
11
11
  isGlobalThread,
12
12
  isOrchestratorThread,
13
13
  isSlackCoordinatorThread
14
- } from "./chunk-A6C67DY5.js";
14
+ } from "./chunk-SPMIZSKH.js";
15
15
  import {
16
16
  mergeAgentGitAuthEnv,
17
17
  resolveAgentGitAuthEnv
18
- } from "./chunk-A46CIARU.js";
18
+ } from "./chunk-YWBLQBSN.js";
19
19
  import {
20
20
  ATTACHMENTS_DIR,
21
21
  DETACHED_JOBS_DIR,
@@ -24,15 +24,15 @@ import {
24
24
  } from "./chunk-N2WW62LF.js";
25
25
  import {
26
26
  ensureWorktreeSideboardIgnored
27
- } from "./chunk-DD67JWTN.js";
27
+ } from "./chunk-4YXZOXMT.js";
28
28
  import {
29
29
  ensureAgentPath,
30
30
  run
31
- } from "./chunk-2UG25RMK.js";
31
+ } from "./chunk-YBTSZ2SW.js";
32
32
  import {
33
33
  assertOrchestratorCapableAgent,
34
34
  contextTokens
35
- } from "./chunk-GCHSJCCX.js";
35
+ } from "./chunk-IFU4W4C4.js";
36
36
  import {
37
37
  stripNestedElectronEnv
38
38
  } from "./chunk-WWUABK6B.js";
@@ -47,7 +47,7 @@ import {
47
47
  updateThread,
48
48
  worktreeNameFromPath,
49
49
  writeThread
50
- } from "./chunk-HOLB6ZFZ.js";
50
+ } from "./chunk-B4CDSSRN.js";
51
51
  import {
52
52
  findConventionSetup,
53
53
  loadRepoSettings,
@@ -1678,7 +1678,7 @@ var PORT_RANGE_SIZE = 10;
1678
1678
  var RECLAIM_RETRY_DELAY_MS = 40;
1679
1679
  var RECLAIM_TRIES = 8;
1680
1680
  async function killReclaimable(ports, worktreePath, signal) {
1681
- const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-NIUBJLTS.js");
1681
+ const { killListenersOnPorts: killListenersOnPorts2, killStaleWorktreeListeners: killStaleWorktreeListeners2 } = await import("./conductor-XLXJU24U.js");
1682
1682
  if (worktreePath) killStaleWorktreeListeners2(ports, worktreePath, signal);
1683
1683
  else killListenersOnPorts2(ports);
1684
1684
  }
@@ -2,14 +2,14 @@ import {
2
2
  OPTIONAL_SERVICES,
3
3
  isOptionalServiceId,
4
4
  optionalServiceSpec
5
- } from "./chunk-FDXHNROD.js";
5
+ } from "./chunk-TEFFR6PB.js";
6
6
  import {
7
7
  installNpmGlobalPackage,
8
8
  whichOnPath
9
- } from "./chunk-AESO2KJS.js";
9
+ } from "./chunk-BPDVHB4U.js";
10
10
  import {
11
11
  enrichPathWithNpmGlobalBin
12
- } from "./chunk-QVN2WOKJ.js";
12
+ } from "./chunk-2TUE6JKQ.js";
13
13
 
14
14
  // src/integrations/optional-cli.ts
15
15
  async function detectOptionalServiceClis() {
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-RSA47QYR.js";
9
9
  import {
10
10
  run
11
- } from "./chunk-QVN2WOKJ.js";
11
+ } from "./chunk-2TUE6JKQ.js";
12
12
  import {
13
13
  appDataDir
14
14
  } from "./chunk-H4UEFJRI.js";
@@ -19,7 +19,7 @@ import { join } from "path";
19
19
 
20
20
  // src/brightsy/accounts.ts
21
21
  async function loadConnectedTeams() {
22
- const { listConnectedBrightsyTeams: listConnectedBrightsyTeams2 } = await import("./connected-teams-IHK2WXUI.js");
22
+ const { listConnectedBrightsyTeams: listConnectedBrightsyTeams2 } = await import("./connected-teams-H4LZOJDC.js");
23
23
  return listConnectedBrightsyTeams2();
24
24
  }
25
25
  async function runBrightsyTeamsJson(args) {
@@ -48,14 +48,14 @@ async function listBrightsyAccounts() {
48
48
  async function getBrightsySession() {
49
49
  try {
50
50
  const { ensureBrightsyLocalConfigFresh: ensureBrightsyLocalConfigFresh2 } = await import("./oauth-CR5FY4CJ.js");
51
- const { ensureConnectedBrightsyTeamTokens: ensureConnectedBrightsyTeamTokens2 } = await import("./connected-teams-IHK2WXUI.js");
51
+ const { ensureConnectedBrightsyTeamTokens: ensureConnectedBrightsyTeamTokens2 } = await import("./connected-teams-H4LZOJDC.js");
52
52
  await ensureBrightsyLocalConfigFresh2();
53
53
  await ensureConnectedBrightsyTeamTokens2();
54
54
  loadBrightsyConfig();
55
55
  const data = await runBrightsyTeamsJson([]);
56
56
  const accounts = Array.isArray(data.teams) ? data.teams : [];
57
57
  const active = data.active ?? accounts.find((a) => a.active) ?? null;
58
- const { ensureCliTeamTracked: ensureCliTeamTracked2 } = await import("./connected-teams-IHK2WXUI.js");
58
+ const { ensureCliTeamTracked: ensureCliTeamTracked2 } = await import("./connected-teams-H4LZOJDC.js");
59
59
  const connectedTeams = ensureCliTeamTracked2(
60
60
  active ? { id: active.id, slug: active.slug, name: active.name } : void 0
61
61
  );
@@ -95,7 +95,7 @@ async function performBrightsyAccountSwitch(accountIdOrSlug) {
95
95
  return { cfg, target: data.active };
96
96
  }
97
97
  async function switchBrightsyAccount(accountIdOrSlug) {
98
- const { connectBrightsyTeam: connectBrightsyTeam2 } = await import("./connected-teams-IHK2WXUI.js");
98
+ const { connectBrightsyTeam: connectBrightsyTeam2 } = await import("./connected-teams-H4LZOJDC.js");
99
99
  await connectBrightsyTeam2(accountIdOrSlug);
100
100
  return getBrightsySession();
101
101
  }
@@ -3,9 +3,11 @@
3
3
  import {
4
4
  canonicalizeRepoPath,
5
5
  ensureGhPreferOrigin,
6
+ formatRemoteTag,
6
7
  resolveGithubRepoSlug,
8
+ resolveOriginRemote,
7
9
  resolveRepoRoot
8
- } from "./chunk-A46CIARU.js";
10
+ } from "./chunk-YWBLQBSN.js";
9
11
  import {
10
12
  ATTACHMENTS_DIR,
11
13
  attachmentsGitignoreBody
@@ -22,7 +24,7 @@ import {
22
24
  resolveThreadDefaults,
23
25
  resolveViewerProfile,
24
26
  resolveViewerProfileForRepo
25
- } from "./chunk-GCHSJCCX.js";
27
+ } from "./chunk-IFU4W4C4.js";
26
28
  import {
27
29
  allocateTeamName,
28
30
  createEmptyThread,
@@ -31,7 +33,7 @@ import {
31
33
  teamSlugFromName,
32
34
  updateThread,
33
35
  writeThread
34
- } from "./chunk-HOLB6ZFZ.js";
36
+ } from "./chunk-B4CDSSRN.js";
35
37
  import {
36
38
  appDataDir,
37
39
  globalAgentCwd,
@@ -309,7 +311,7 @@ import { join as join2 } from "path";
309
311
  function formatWorkspaceInventory(workspaces) {
310
312
  if (workspaces.length === 0) return "(no registered workspaces)";
311
313
  return workspaces.map((w) => {
312
- const slug = w.githubSlug?.trim() ? ` github:${w.githubSlug.trim()}` : "";
314
+ const slug = w.originRemote ? ` ${formatRemoteTag(w.originRemote)}` : w.githubSlug?.trim() ? ` github:${w.githubSlug.trim()}` : "";
313
315
  const profile = formatWorkspaceProfileSuffix(safeViewerProfile(w.path));
314
316
  return `- ${w.name}: ${w.path}${slug}${profile}`;
315
317
  }).join("\n");
@@ -317,8 +319,9 @@ function formatWorkspaceInventory(workspaces) {
317
319
  async function enrichWorkspacesWithGithub(workspaces) {
318
320
  return Promise.all(
319
321
  workspaces.map(async (w) => {
320
- const githubSlug = await resolveGithubRepoSlug(w.path).catch(() => null);
321
- return { ...w, githubSlug };
322
+ const originRemote = await resolveOriginRemote(w.path).catch(() => null);
323
+ const githubSlug = originRemote ? originRemote.forge === "github" ? originRemote.slug : null : await resolveGithubRepoSlug(w.path).catch(() => null);
324
+ return { ...w, githubSlug, originRemote };
322
325
  })
323
326
  );
324
327
  }
@@ -329,8 +332,8 @@ function coordinatorGreenfieldPlaybook(reposDir) {
329
332
  "- Examples:",
330
333
  ` - Clone: \`git clone <url> ${reposDir}/<name>\``,
331
334
  ` - New GitHub repo: \`gh repo create <owner>/<name> --private --clone -- ${reposDir}/<name>\` (or mkdir + git init + gh repo create + remote add + push)`,
332
- "- Then: add_project with that absolute path \u2192 create_workspace (repoPath + parentChatId) \u2192 send_to_chat (build) \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft (or send_to_chat `gh pr create --draft --assignee @me -R <origin-owner/name>`).",
333
- "- Always target the child worktree's **origin** (`github:` slug from list_projects / `git remote get-url origin` in that worktree). Never open PRs against `upstream`.",
335
+ "- Then: add_project with that absolute path \u2192 create_workspace (repoPath + parentChatId) \u2192 send_to_chat (build) \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft (GitHub: `gh pr create --draft --assignee @me -R <slug>`; Cursor: `origin pr create --draft --push -R <slug>`; Entire: `entire trail create --title`).",
336
+ "- Always target the child worktree's **origin** (`github:`, `cursor:`, or `entire:` from list_projects / `git remote get-url origin` in that worktree). Never open PRs against `upstream`.",
334
337
  "- Do coding work in the child worktree thread, not by editing files in this home cwd."
335
338
  ].join("\n");
336
339
  }
@@ -338,9 +341,9 @@ var COORDINATOR_TOOL_PLAYBOOK = [
338
341
  "Role: you oversee Sideboard workspaces across registered repos. A workspace is one isolated checkout and can have many agent chats on those same files. You do not live inside one of those worktrees. Do not treat a workspace as one agent.",
339
342
  "Sideboard MCP (fleet control \u2014 prefer these for status and orchestration):",
340
343
  "Discover:",
341
- "- 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.",
344
+ "- list_projects \u2014 registered repos (path + that repo's origin host:owner/repo, such as github:, cursor:, or entire:, and project context when set). Projects do not share one git host. Use account / project context to pick the right repo for tickets or reviews.",
342
345
  "- 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.",
343
- `- 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).`,
346
+ '- 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. Cursor Origin has no issues; a Cursor repo uses Linear or AbleTime (unavailableReason otherwise) \u2014 do not use it for that review-inbox ask. Entire tickets are Trails (`entire trail`), not GitHub Issues. When they ask for tickets to work on, follow their context (assignee=me or unassigned as it says).',
344
347
  "- 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.",
345
348
  "- 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.",
346
349
  "- 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.",
@@ -354,7 +357,7 @@ var COORDINATOR_TOOL_PLAYBOOK = [
354
357
  "- get_viewer_context / update_viewer_context \u2014 read or replace Settings \u2192 Agents (account) and Settings \u2192 Projects (per-repo) context. You can update a project: pass scope=project and repoPath from list_projects (this cwd is not a project). update_viewer_context requires confirmed=true after ask_user. Never write context unprompted.",
355
358
  "- list_env / set_env / delete_env \u2014 Settings \u2192 Environment. scope=project requires repoPath from list_projects and stores the key under that project prefix (the project name, uppercased, plus _). APPLE_ID for sideboard is SIDEBOARD_APPLE_ID. scope=account is shared by every project and is not prefixed. list_env returns names only.",
356
359
  "- set_caffeinate \u2014 keep this Mac awake across turns (macOS caffeinate). Turn on for phone remote / away-from-keyboard work, overnight schedules, or when the user will be away. Turn OFF when they say they are done, wrapping up, going to sleep, or no longer need the machine awake. Closing this chat also releases it.",
357
- "- list_schedules / create_schedule / update_schedule / delete_schedule / run_schedule \u2014 local jobs that send a prompt to a chat (chatId or self) or start a new Global chat (omit chatId). One-shot `at`, interval `every` (15m/1h/6h/1d), or 5-field `cron`. Recurring jobs without chatId open a new chat each run. Worktree agents have the same tools (`chatId=self` continues that coding chat). Jobs fire only while Sideboard.app is running; sleep skips until wake. Creating or enabling a future job turns on Settings \u2192 Advanced \u2192 Caffeinate while schedules are enabled (or call set_caffeinate).",
360
+ "- list_schedules / create_schedule / update_schedule / delete_schedule / run_schedule \u2014 automations that send a prompt to a chat (chatId or self) or start a new Global chat (omit chatId). One-shot `at`, interval `every` (15m/1h/6h/1d), or 5-field `cron`. Recurring jobs without chatId open a new chat each run and archive it when that run finishes (History keeps the latest run for that automation). Worktree agents have the same tools (`chatId=self` continues that coding chat). Jobs fire only while Sideboard.app is running; sleep skips until wake. Creating or enabling a future job turns on Settings \u2192 Advanced \u2192 Caffeinate while automations are enabled (or call set_caffeinate). The desktop lists them in the sidebar after Board.",
358
361
  "Projects:",
359
362
  "- add_project / remove_project \u2014 register or unregister a git repo",
360
363
  "Workspaces and chats:",
@@ -377,11 +380,11 @@ var COORDINATOR_TOOL_PLAYBOOK = [
377
380
  "- list_run_scripts / run_dev_script / stop_dev_script / get_run_log \u2014 start/stop named run scripts and read the Run-tab terminal (tail). Pass name so desktop and mobile (or any pair) can run at once; each gets its own port. run_dev_script returns {url, port, preview} (SIDEBOARD_PORT). preview=url \u2192 tell the worktree agent to open that URL; preview=window \u2192 Electron: the native window is the app (url is renderer/HMR only). Never localhost:3000. list_run_scripts active[].url if already running.",
378
381
  "Inspect / review / PRs:",
379
382
  "- get_diff \u2014 compact diff summary",
380
- "- get_pr_checks \u2014 snapshot of a worktree thread's PR checks (null = no PR). Use this to inspect status. If the user gave a goal, the worktree agent watches with `gh pr checks --watch` \u2014 do not poll for the human.",
383
+ "- get_pr_checks \u2014 snapshot of a worktree thread's PR checks (null = no PR). Use this to inspect status. If the user gave a goal, the worktree agent watches with `gh pr checks --watch` on GitHub, `origin pr watch` on Cursor, or `entire trail watch` on Entire \u2014 do not poll for the human.",
381
384
  '- request_review \u2014 run a Review on a worktree thread. Reuses the only unused idle agent when the checkout has a single chat with no messages; otherwise opens a Review tab (attaches .claude/skills/review/SKILL.md when present, else .context/review.md copied from .sideboard/review.md / stock; sends "Review changes in this workspace."); then wait_for_turn (loop while stillRunning) / get_turn_result on the returned id. The review stays in that chat so they can read it and type next steps \u2014 do not tell the child to comment or update the PR or ticket.',
382
385
  "- ask_git \u2014 commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge \u2014 same prompts as the desktop git buttons (Resolve, Create PR, \u2026). Always steers the worktree agent; then wait_for_turn (loop while stillRunning). Prefer this over paraphrasing. If the user gave a goal (Greptile 5/5, CI green), send_to_chat that goal so the worktree agent enters the watch-fix-push loop \u2014 do not tell the human to poll.",
383
386
  '- Merge (`ask_git` action=merge / send_to_chat "Merge PR.") only when the user explicitly asked to merge that PR. Do not merge because the work looks done, CI is green, or a typical flow includes it.',
384
- '- Or send_to_chat with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Ready for review.", "Merge PR." Prefer ask_git resolve-conflicts (it names the actual PR base \u2014 not always main) over paraphrasing. (draft PRs: `gh pr create --draft --assignee @me -R <origin-owner/name>` using the workspace `github:` slug \u2014 never upstream). Never run git/gh from this orchestration cwd, and never merge the PR yourself.',
387
+ '- Or send_to_chat with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Ready for review.", "Merge PR." Prefer ask_git resolve-conflicts (it names the actual PR base \u2014 not always main) over paraphrasing. Draft PRs follow that workspace origin: GitHub (`github:`) uses `gh pr create --draft --assignee @me -R <slug>`; Cursor (`cursor:`) uses `origin pr create --draft --push -R <slug>`; Entire (`entire:`) uses `entire trail create --title` (Trails have no draft state). Never upstream. Never run git, gh, origin, or entire from this orchestration cwd, and never merge the PR yourself.',
385
388
  "Process guides:",
386
389
  "- Long child jobs (pack, test, deploy, anything that may run more than ~30s): workers always have `/long-running` (Sideboard product skill). Tell them to detach and wait; they may `stop_job` if it hangs or is doing the wrong thing; do not ask the human to poll.",
387
390
  "- Recurring multi-item / fan-out: if the child worktree has `.claude/skills/graph-engineering/SKILL.md`, tell the worker to follow it (`/graph-engineering`). Judge first; state on disk; grow the rulebook; do not patch three threads.",
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  loadAppSettings,
6
6
  saveAppSettings
7
- } from "./chunk-E52SQENB.js";
7
+ } from "./chunk-FZKAAAEB.js";
8
8
 
9
9
  // src/integrations/optional-services.ts
10
10
  var OPTIONAL_SERVICE_IDS = ["vercel", "supabase", "posthog", "sentry"];
@@ -273,7 +273,7 @@ async function connectedCliPresence(integrations) {
273
273
  const ids = connectedOptionalServices(integrations).filter((spec) => spec.cli).map((spec) => spec.id);
274
274
  if (ids.length === 0) return void 0;
275
275
  try {
276
- const { optionalCliPresence } = await import("./optional-cli-6GGESWGE.js");
276
+ const { optionalCliPresence } = await import("./optional-cli-2YDQQCCD.js");
277
277
  return await optionalCliPresence(ids);
278
278
  } catch {
279
279
  return void 0;