@sideboard-ai/core 0.1.79 → 0.1.83

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 (34) hide show
  1. package/dist/agents/cursor-runner.cjs +18 -0
  2. package/dist/agents/cursor-runner.js +4 -0
  3. package/dist/{agents-EWPHOM6Y.js → agents-3YPUZME7.js} +6 -5
  4. package/dist/{agents-GRAPUXWW.js → agents-4KRD46KG.js} +5 -5
  5. package/dist/{app-settings-NILNWNNQ.js → app-settings-GVSOIJLZ.js} +1 -1
  6. package/dist/{app-settings-6IOQYGBK.js → app-settings-MQXL7OUF.js} +2 -1
  7. package/dist/{chunk-6T2SKGCS.js → chunk-DJFGX4RT.js} +3 -3
  8. package/dist/{chunk-HCGEFU3J.js → chunk-E2MIA7DO.js} +13 -14
  9. package/dist/{chunk-HSLQXL6M.js → chunk-ERJS3ZDP.js} +13 -14
  10. package/dist/{chunk-YVVXWWCC.js → chunk-GD2FM6FN.js} +81 -49
  11. package/dist/{chunk-FUUVPN4A.js → chunk-HBBXS2FR.js} +78 -49
  12. package/dist/chunk-IZ7RPF54.js +36 -0
  13. package/dist/{chunk-P33ZQ7ZC.js → chunk-JMRJ4F5B.js} +70 -25
  14. package/dist/{chunk-SHCR6RPU.js → chunk-JW6YFPQE.js} +83 -24
  15. package/dist/{chunk-PW5YHHP3.js → chunk-LVTNWH7B.js} +2 -2
  16. package/dist/{chunk-5LXWTU3J.js → chunk-NXXT5SE3.js} +3 -3
  17. package/dist/{chunk-5VTWBI3I.js → chunk-RS54WYYH.js} +2 -2
  18. package/dist/{chunk-XKNBSYA7.js → chunk-UHGN4KCL.js} +35 -1
  19. package/dist/{chunk-IFPN6TER.js → chunk-YO3CYL6B.js} +4 -1
  20. package/dist/{coordinator-prompt-2OVON2LQ.js → coordinator-prompt-46JE4NQR.js} +4 -3
  21. package/dist/{coordinator-prompt-K2R34A5T.js → coordinator-prompt-6ICA54JR.js} +3 -3
  22. package/dist/{global-workspace-VG44RZUH.js → global-workspace-GSLCEB5E.js} +5 -4
  23. package/dist/{global-workspace-RI367AM6.js → global-workspace-OBRWUPZG.js} +4 -4
  24. package/dist/index.cjs +268 -151
  25. package/dist/index.d.cts +52 -11
  26. package/dist/index.d.ts +52 -11
  27. package/dist/index.js +87 -87
  28. package/dist/mcp/run-stdio.cjs +249 -141
  29. package/dist/mcp/run-stdio.js +66 -76
  30. package/dist/{workspaces-TYPJNUSM.js → workspaces-7B3PTEF4.js} +6 -5
  31. package/dist/{workspaces-BQWQEZWE.js → workspaces-RJIWQB6J.js} +5 -5
  32. package/dist/{worktree-5VLLFI5W.js → worktree-HSN5LWY6.js} +3 -2
  33. package/dist/{worktree-UNSOCYZU.js → worktree-U3UIID2K.js} +2 -2
  34. 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-PW5YHHP3.js";
7
+ } from "./chunk-LVTNWH7B.js";
8
8
  import {
9
9
  BRIGHTSY_MCP_ALLOWED_TOOLS,
10
10
  CLAUDE_MODEL_CATALOG,
@@ -13,12 +13,14 @@ import {
13
13
  SIDEBOARD_MCP_ALLOWED_TOOLS,
14
14
  SIDEBOARD_MCP_PROFILE_ENV,
15
15
  allAdapters,
16
+ applyTurnUsage,
16
17
  brightsyAdapter,
17
18
  brightsyMcpAllowedTools,
18
19
  buildCachedUserContent,
19
20
  buildClaudeStreamJsonUserMessage,
20
21
  claudeAdapter,
21
22
  codexAdapter,
23
+ contextTokens,
22
24
  countCacheControlBlocks,
23
25
  cursorAdapter,
24
26
  decodeBrightsyTarget,
@@ -26,6 +28,7 @@ import {
26
28
  encodeBrightsyTarget,
27
29
  findInvalidCacheControlTtlOrder,
28
30
  flattenTurnInput,
31
+ fromInclusiveInputUsage,
29
32
  getAdapter,
30
33
  getAgentSetupInfo,
31
34
  installAgent,
@@ -41,6 +44,7 @@ import {
41
44
  loginAgent,
42
45
  mcpAllowTools,
43
46
  mcpAuthWarnings,
47
+ mergeUsage,
44
48
  normalizeTurnInput,
45
49
  openInSystemTerminal,
46
50
  opencodeAdapter,
@@ -50,6 +54,7 @@ import {
50
54
  permissionMode,
51
55
  prepareTerminalCommand,
52
56
  promptMentionsBrightsy,
57
+ requestOccupancy,
53
58
  resolveCursorModelId,
54
59
  resolveLoginCommand,
55
60
  resolveQuotaFallbackAgent,
@@ -57,8 +62,9 @@ import {
57
62
  shouldInjectBrightsyMcp,
58
63
  sideboardMcpProfile,
59
64
  threadRequestsBrightsyMcp,
65
+ totalTokens,
60
66
  writeInjectedMcpConfig
61
- } from "./chunk-SHCR6RPU.js";
67
+ } from "./chunk-JW6YFPQE.js";
62
68
  import {
63
69
  CLOUD_COORDINATOR_BUSY_REPLY,
64
70
  CLOUD_COORDINATOR_STOPPED_REPLY,
@@ -85,7 +91,7 @@ import {
85
91
  parseForceStopMessage,
86
92
  slackCoordinatorSourceRef,
87
93
  takenTeamSlugsForOrchestration
88
- } from "./chunk-5LXWTU3J.js";
94
+ } from "./chunk-NXXT5SE3.js";
89
95
  import {
90
96
  COORDINATOR_TOOL_PLAYBOOK,
91
97
  SLACK_REPLY_FORMATTING,
@@ -94,7 +100,7 @@ import {
94
100
  enrichWorkspacesWithGithub,
95
101
  ensureGlobalCoordinatorCwd,
96
102
  formatWorkspaceInventory
97
- } from "./chunk-HCGEFU3J.js";
103
+ } from "./chunk-E2MIA7DO.js";
98
104
  import {
99
105
  brightsyConfigPath,
100
106
  brightsyMcpServerName,
@@ -159,6 +165,7 @@ import {
159
165
  formatGhLandError,
160
166
  formatGitAuthModeDirective,
161
167
  formatIpcInvokeError,
168
+ formatMergePrError,
162
169
  formatRateLimitResetHint,
163
170
  getPr,
164
171
  getPrChecks,
@@ -173,6 +180,7 @@ import {
173
180
  isGhRateLimitError,
174
181
  isInPrStack,
175
182
  isPlaceholderBranch,
183
+ isPrNotMergeableError,
176
184
  isSideboardScratchPath,
177
185
  listBranches,
178
186
  listPrs,
@@ -202,7 +210,7 @@ import {
202
210
  worktreeDisplayLabel,
203
211
  worktreeDisplayLabelForGroup,
204
212
  worktreeNameFromPath
205
- } from "./chunk-YVVXWWCC.js";
213
+ } from "./chunk-GD2FM6FN.js";
206
214
  import {
207
215
  ATTACHMENTS_DIR,
208
216
  LEGACY_ATTACHMENTS_DIR,
@@ -271,7 +279,10 @@ import {
271
279
  updateIntegrationsSettings,
272
280
  updateOpencodeSettings,
273
281
  writeSecureJson
274
- } from "./chunk-IFPN6TER.js";
282
+ } from "./chunk-YO3CYL6B.js";
283
+ import {
284
+ stripNestedElectronEnv
285
+ } from "./chunk-IZ7RPF54.js";
275
286
  import {
276
287
  writePrivateFile
277
288
  } from "./chunk-JT7R45JB.js";
@@ -351,7 +362,8 @@ function agentGitPrompt(action, opts) {
351
362
  return "Commit, push, and open a PR in the browser.";
352
363
  case "resolve-conflicts": {
353
364
  const base = opts?.prBase?.trim().replace(/^refs\/heads\//, "");
354
- return base ? `Merge origin/${base} into this branch. Then push.` : "Fix merge conflicts.";
365
+ const named = base ? ` (${base})` : "";
366
+ return `Merge the remote branch${named} into your branch and resolve conflicts. Then, commit and push your changes.`;
355
367
  }
356
368
  case "merge":
357
369
  return "Merge PR.";
@@ -1296,41 +1308,6 @@ function normalizeParseResult(parsed) {
1296
1308
  return Array.isArray(parsed) ? parsed : [parsed];
1297
1309
  }
1298
1310
 
1299
- // src/agents/usage.ts
1300
- function sumOptional(a, b) {
1301
- if (a == null && b == null) return void 0;
1302
- return (a ?? 0) + (b ?? 0);
1303
- }
1304
- function requestOccupancy(u) {
1305
- return u.inputTokens + (u.cacheReadTokens ?? 0) + (u.cacheWriteTokens ?? 0);
1306
- }
1307
- function mergeUsage(a, b) {
1308
- return {
1309
- inputTokens: (a?.inputTokens ?? 0) + b.inputTokens,
1310
- outputTokens: (a?.outputTokens ?? 0) + b.outputTokens,
1311
- cacheReadTokens: sumOptional(a?.cacheReadTokens, b.cacheReadTokens),
1312
- cacheWriteTokens: sumOptional(a?.cacheWriteTokens, b.cacheWriteTokens),
1313
- lastRequestTokens: b.lastRequestTokens ?? a?.lastRequestTokens
1314
- };
1315
- }
1316
- function applyTurnUsage(current, incoming, scope = "request") {
1317
- if (scope === "turn") {
1318
- return {
1319
- ...incoming,
1320
- lastRequestTokens: current?.lastRequestTokens ?? requestOccupancy(incoming)
1321
- };
1322
- }
1323
- const merged = mergeUsage(current, incoming);
1324
- return { ...merged, lastRequestTokens: requestOccupancy(incoming) };
1325
- }
1326
- function totalTokens(u) {
1327
- return u.inputTokens + u.outputTokens + (u.cacheReadTokens ?? 0) + (u.cacheWriteTokens ?? 0);
1328
- }
1329
- function contextTokens(u) {
1330
- if (u.lastRequestTokens != null && u.lastRequestTokens > 0) return u.lastRequestTokens;
1331
- return requestOccupancy(u);
1332
- }
1333
-
1334
1311
  // src/agents/spawn.ts
1335
1312
  async function spawnAgentTurn(thread, input, onEvent) {
1336
1313
  ensureAgentPath();
@@ -1339,9 +1316,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
1339
1316
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
1340
1317
  );
1341
1318
  }
1342
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-VG44RZUH.js");
1319
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-GSLCEB5E.js");
1343
1320
  if (isGlobalThread2(thread)) {
1344
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-2OVON2LQ.js");
1321
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-46JE4NQR.js");
1345
1322
  ensureGlobalCoordinatorCwd2(
1346
1323
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
1347
1324
  );
@@ -1508,7 +1485,7 @@ function formatWorktreeDirective(thread, opts) {
1508
1485
  "- Prefer a concise imperative title (Conventional Commits style when it fits: feat:/fix:/chore:/docs:). Body should summarize intent, key changes, and test notes."
1509
1486
  );
1510
1487
  lines.push(
1511
- "- Commit with messages that state the purpose of the change (same standard as the PR). Stay on this thread branch. Never push directly to main/master or merge locally into the main checkout. When asked to merge the PR, use GitHub from this worktree (`gh pr merge` / `gh stack merge`)."
1488
+ "- Commit with messages that state the purpose of the change (same standard as the PR). Stay on this thread branch. Never push directly to main/master or merge locally into the main checkout. Do not merge the PR unless this turn is a Merge PR request or the user explicitly asked. When merging, use GitHub from this worktree (`gh pr merge` / `gh stack merge`)."
1512
1489
  );
1513
1490
  if (thread.prUrl) {
1514
1491
  lines.push(
@@ -1540,19 +1517,30 @@ function formatWorktreeDirective(thread, opts) {
1540
1517
  '- "Fix CI: <name>." \u2192 investigate that failing check, fix it, commit, and push.'
1541
1518
  );
1542
1519
  lines.push(
1543
- '- "Update the branch." / "Fix merge conflicts." / "Merge origin/<base> into this branch. Then push." \u2192 sync with the PR base (merge or rebase), resolve conflicts carefully, commit, and push until the PR is mergeable.'
1520
+ '- "Merge the remote branch (<base>) into your branch and resolve conflicts. Then, commit and push your changes." \u2192 fetch the PR base, merge it into this branch, resolve conflicts carefully, commit, and push until the PR is mergeable.'
1544
1521
  );
1545
1522
  lines.push(
1546
1523
  '- "Address review comments." \u2192 read PR review feedback, make the requested changes, commit, and push.'
1547
1524
  );
1548
1525
  lines.push(
1549
- '- "Merge PR." \u2192 merge this thread\'s open pull request on GitHub. If `gh stack view` shows a stack, use `gh stack merge`; otherwise `gh pr merge` (respect repo defaults / squash vs merge). Do not force-push main/master or merge locally into the main checkout.'
1526
+ '- "Merge PR." \u2192 merge this thread\'s open pull request on GitHub (this phrase is the explicit ask). If `gh stack view` shows a stack, use `gh stack merge`; otherwise `gh pr merge` (respect repo defaults / squash vs merge). Do not force-push main/master or merge locally into the main checkout.'
1550
1527
  );
1528
+ lines.push("");
1529
+ lines.push(formatProcessGuideDirective());
1551
1530
  return lines.join("\n");
1552
1531
  }
1553
1532
  function formatWorktreeReminder() {
1554
1533
  return "Sideboard worktree: stay in this cwd for all file and git work. Push and open PRs against origin, never upstream. Do not edit the main repo checkout.";
1555
1534
  }
1535
+ function formatProcessGuideDirective() {
1536
+ return [
1537
+ "Process guides (recurring work only):",
1538
+ "- If `.claude/skills/graph-engineering/SKILL.md` exists, follow it (`/graph-engineering`) for migrations, ports, batch fixes, and other fan-out. Judge first; state on disk; grow the rulebook; do not patch around it.",
1539
+ "- If this same shape of work will happen again, write `.claude/skills/<kebab-name>/SKILL.md` in this worktree (Claude Code project skill). Sideboard `/name`, Claude Code, and `attach` all load that path. Do not leave the method only in chat.",
1540
+ "- Do not write new skills under `.sideboard/skills` \u2014 native agents do not scan it. Point Codex/OpenCode at the file from `AGENTS.md`. Optional: symlink `.cursor/skills/<name>` to the Claude skill.",
1541
+ "- Skip a guide for a one-off. If a matching skill exists, follow it. Same miss twice \u2192 edit the skill (or `.sideboard/review.md`), do not patch around it."
1542
+ ].join("\n");
1543
+ }
1556
1544
  function formatArtifactDirective() {
1557
1545
  return [
1558
1546
  "Sideboard side column (desktop UI):",
@@ -1570,9 +1558,22 @@ function formatArtifactDirective() {
1570
1558
  "Files / media browser (CMS file manager column):",
1571
1559
  "4) Call Sideboard MCP `present_files` with optional title, path, and datasource (brightsy|memory).",
1572
1560
  " Opens the Files column for browse/upload/pick. Do NOT say a file manager UI is missing.",
1573
- "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."
1561
+ "Multiple-choice questions (any mode \u2014 not only Plan):",
1562
+ "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.",
1563
+ "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."
1574
1564
  ].join("\n");
1575
1565
  }
1566
+ function formatUiReminder() {
1567
+ return [
1568
+ "Sideboard side column (important):",
1569
+ "There is no claude.ai Artifact tool here \u2014 that is normal.",
1570
+ "HTML/SVG/markdown: ```html fence or MCP present_artifact.",
1571
+ "CMS forms/tables: MCP present_schema (Brightsy resource_id or inline schema+schemaUi).",
1572
+ "Files column: MCP present_files (brightsy account storage or memory).",
1573
+ "Do not say artifacts/CMS UI are unavailable.",
1574
+ "Multiple-choice questions: MCP ask_user (composer picker, any mode). Explain options in chat first, then wait for answers."
1575
+ ].join(" ");
1576
+ }
1576
1577
  var FILES_BY_AGENT = {
1577
1578
  claude: [
1578
1579
  "CLAUDE.md",
@@ -1589,10 +1590,11 @@ var FILES_BY_AGENT = {
1589
1590
  var MAX_CHARS_PER_FILE = 48e3;
1590
1591
  function loadAgentInstructions(worktreePath, agent) {
1591
1592
  const candidates = FILES_BY_AGENT[agent] ?? FILES_BY_AGENT.claude;
1592
- const seen = /* @__PURE__ */ new Set();
1593
+ const seenPaths = /* @__PURE__ */ new Set();
1594
+ const seenBodies = /* @__PURE__ */ new Set();
1593
1595
  const out = [];
1594
1596
  for (const rel of candidates) {
1595
- if (seen.has(rel)) continue;
1597
+ if (seenPaths.has(rel)) continue;
1596
1598
  const abs = join(worktreePath, rel);
1597
1599
  if (!existsSync(abs)) continue;
1598
1600
  try {
@@ -1604,7 +1606,10 @@ function loadAgentInstructions(worktreePath, agent) {
1604
1606
 
1605
1607
  \u2026(truncated)`;
1606
1608
  }
1607
- seen.add(rel);
1609
+ const body = content.trim().replace(/\r\n/g, "\n");
1610
+ if (seenBodies.has(body)) continue;
1611
+ seenPaths.add(rel);
1612
+ seenBodies.add(body);
1608
1613
  out.push({ relativePath: rel, content });
1609
1614
  } catch {
1610
1615
  }
@@ -1763,16 +1768,6 @@ async function captureLoginEnv() {
1763
1768
  cachedLoginEnv = { ...process.env };
1764
1769
  return { ...cachedLoginEnv };
1765
1770
  }
1766
- var NESTED_ELECTRON_ENV_PREFIXES = ["ELECTRON_", "CHROME_"];
1767
- function stripNestedElectronEnv(env) {
1768
- const out = { ...env };
1769
- for (const key of Object.keys(out)) {
1770
- if (NESTED_ELECTRON_ENV_PREFIXES.some((prefix) => key.startsWith(prefix))) {
1771
- delete out[key];
1772
- }
1773
- }
1774
- return out;
1775
- }
1776
1771
  function buildWorkspaceScriptEnv(opts, baseEnv) {
1777
1772
  const env = stripNestedElectronEnv({
1778
1773
  ...baseEnv ?? process.env
@@ -3838,7 +3833,7 @@ async function createThread(input, _onSetupLine) {
3838
3833
  return readThread(thread.id) ?? thread;
3839
3834
  }
3840
3835
  async function listLinearIssues(agent, repoPath) {
3841
- const { getAdapter: getAdapter2 } = await import("./agents-EWPHOM6Y.js");
3836
+ const { getAdapter: getAdapter2 } = await import("./agents-3YPUZME7.js");
3842
3837
  await requireAgent(agent, { requireLinear: true });
3843
3838
  const adapter = getAdapter2(agent);
3844
3839
  if (!adapter.listLinearIssues) {
@@ -4381,7 +4376,7 @@ async function adoptThread(input) {
4381
4376
  messages: input.messages ?? []
4382
4377
  });
4383
4378
  writeThread(thread);
4384
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-TYPJNUSM.js");
4379
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-7B3PTEF4.js");
4385
4380
  await ensureWorkspace2(repoPath);
4386
4381
  return thread;
4387
4382
  }
@@ -5514,6 +5509,10 @@ File: src/client/frontends/desktop/core/UserData.ts
5514
5509
 
5515
5510
  **Approve** \u2014 Diff is scoped, behavior looks correct, and there are no blocking issues. Safe to merge.
5516
5511
  </example>
5512
+
5513
+ ## Growing the rules
5514
+
5515
+ If a blocking issue is a missing or ambiguous repo rule that will recur, say so and propose one sentence for \`.sideboard/review.md\` or a \`.claude/skills/<name>/SKILL.md\`. Do not only patch this diff when the same miss will happen again. New skills go under \`.claude/skills\` (Claude Code / attach) \u2014 not \`.sideboard/skills\`.
5517
5516
  `;
5518
5517
 
5519
5518
  // src/review/request-review.ts
@@ -5898,7 +5897,7 @@ var Orchestrator = class {
5898
5897
  orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
5899
5898
  });
5900
5899
  }
5901
- const { autoCleanupOrphansEnabled: autoCleanupOrphansEnabled2 } = await import("./app-settings-6IOQYGBK.js");
5900
+ const { autoCleanupOrphansEnabled: autoCleanupOrphansEnabled2 } = await import("./app-settings-MQXL7OUF.js");
5902
5901
  if (autoCleanupOrphansEnabled2() && shouldRunWorktreeCleanup() && orphans.length > 0) {
5903
5902
  await cleanupOrphanWorktrees({ repoPaths });
5904
5903
  }
@@ -6055,7 +6054,7 @@ var Orchestrator = class {
6055
6054
  }
6056
6055
  async finishCreateThread(threadId, prompt) {
6057
6056
  await this.runSetupAfterCreate(threadId);
6058
- const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await import("./app-settings-6IOQYGBK.js");
6057
+ const { autoRunAfterSetupEnabled: autoRunAfterSetupEnabled2 } = await import("./app-settings-MQXL7OUF.js");
6059
6058
  if (autoRunAfterSetupEnabled2()) {
6060
6059
  try {
6061
6060
  await this.startDev(threadId);
@@ -6297,14 +6296,7 @@ var Orchestrator = class {
6297
6296
  SLACK_REPLY_FORMATTING
6298
6297
  ].join("\n") : null
6299
6298
  ].filter(Boolean).join("\n") : null;
6300
- const artifactReminder = thread.agent !== "brightsy" ? [
6301
- "Sideboard side column (important):",
6302
- "There is no claude.ai Artifact tool here \u2014 that is normal.",
6303
- "HTML/SVG/markdown: ```html fence or MCP present_artifact.",
6304
- "CMS forms/tables: MCP present_schema (Brightsy resource_id or inline schema+schemaUi).",
6305
- "Files column: MCP present_files (brightsy account storage or memory).",
6306
- "Do not say artifacts/CMS UI are unavailable."
6307
- ].join(" ") : null;
6299
+ const artifactReminder = thread.agent !== "brightsy" ? formatUiReminder() : null;
6308
6300
  const worktreeReminder = thread.agent !== "brightsy" && !isOrchestratorThread(thread) ? formatWorktreeReminder() : null;
6309
6301
  const slackReplyContext = formatSlackRepliesForTurn(
6310
6302
  pendingSlackExternalReplies(thread.messages)
@@ -6333,7 +6325,7 @@ var Orchestrator = class {
6333
6325
  }
6334
6326
  const isBrightsy = fresh.agent === "brightsy";
6335
6327
  const isOrchestration = isOrchestratorThread(fresh);
6336
- const { autoRenameBranchEnabled: autoRenameBranchEnabled2, getGithubGitAuthMode: getGithubGitAuthMode2 } = await import("./app-settings-6IOQYGBK.js");
6328
+ const { autoRenameBranchEnabled: autoRenameBranchEnabled2, getGithubGitAuthMode: getGithubGitAuthMode2 } = await import("./app-settings-MQXL7OUF.js");
6337
6329
  const gitAuthMode = getGithubGitAuthMode2();
6338
6330
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
6339
6331
  githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
@@ -6998,7 +6990,9 @@ var Orchestrator = class {
6998
6990
  reviewDecision: null,
6999
6991
  baseRefName: "",
7000
6992
  headRefName: "",
7001
- isInMergeQueue: false
6993
+ isInMergeQueue: false,
6994
+ mergeable: null,
6995
+ mergeStateStatus: null
7002
6996
  };
7003
6997
  await this.persistPrMetaAndMaybeArchive(thread, metaLike);
7004
6998
  return { url: metaLike.url, state };
@@ -7048,7 +7042,7 @@ var Orchestrator = class {
7048
7042
  updateThread(thread.id, { title: meta.title });
7049
7043
  }
7050
7044
  }
7051
- const { autoArchiveOnMergeEnabled: autoArchiveOnMergeEnabled2 } = await import("./app-settings-6IOQYGBK.js");
7045
+ const { autoArchiveOnMergeEnabled: autoArchiveOnMergeEnabled2 } = await import("./app-settings-MQXL7OUF.js");
7052
7046
  const latest = this.requireThread(thread.id);
7053
7047
  if (!shouldAutoArchiveOnPrMerge({
7054
7048
  previousPrState: prevState || null,
@@ -7336,7 +7330,7 @@ var Orchestrator = class {
7336
7330
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
7337
7331
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
7338
7332
  try {
7339
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-TYPJNUSM.js");
7333
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-7B3PTEF4.js");
7340
7334
  await ensureWorkspace2(thread.repoPath);
7341
7335
  } catch {
7342
7336
  }
@@ -7358,7 +7352,7 @@ var Orchestrator = class {
7358
7352
  await runArchiveScript(thread.repoPath, thread.worktreePath);
7359
7353
  } catch {
7360
7354
  }
7361
- const { deleteBranchOnPurgeEnabled: deleteBranchOnPurgeEnabled2 } = await import("./app-settings-6IOQYGBK.js");
7355
+ const { deleteBranchOnPurgeEnabled: deleteBranchOnPurgeEnabled2 } = await import("./app-settings-MQXL7OUF.js");
7362
7356
  const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled2();
7363
7357
  await removeWorktree(thread.repoPath, thread.worktreePath, {
7364
7358
  deleteBranch: deleteBranch ? thread.branchName : void 0
@@ -7379,7 +7373,7 @@ var Orchestrator = class {
7379
7373
  return restored2;
7380
7374
  }
7381
7375
  if (!existsSync15(thread.worktreePath)) {
7382
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-5VLLFI5W.js");
7376
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-HSN5LWY6.js");
7383
7377
  const { execa: execa6 } = await import("execa");
7384
7378
  const slug = thread.worktreePath.split("/").pop();
7385
7379
  const dest = thread.worktreePath;
@@ -7488,7 +7482,7 @@ async function startOrchestration(opts) {
7488
7482
  sourceRef: "default",
7489
7483
  ...createOpts
7490
7484
  }).catch(async () => {
7491
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-5VLLFI5W.js");
7485
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-HSN5LWY6.js");
7492
7486
  const repo = await resolveRepoRoot2(repoPath);
7493
7487
  const def = await resolveDefaultBranch2(repo);
7494
7488
  return createThread({
@@ -8240,7 +8234,7 @@ function withTimeout(promise, ms, label) {
8240
8234
  async function startMcpServer() {
8241
8235
  const orch = getOrchestrator();
8242
8236
  try {
8243
- const { maxConcurrentAgents: maxConcurrentAgents2 } = await import("./app-settings-6IOQYGBK.js");
8237
+ const { maxConcurrentAgents: maxConcurrentAgents2 } = await import("./app-settings-MQXL7OUF.js");
8244
8238
  orch.setMaxConcurrent(maxConcurrentAgents2());
8245
8239
  } catch {
8246
8240
  }
@@ -8345,7 +8339,7 @@ async function startMcpServer() {
8345
8339
  );
8346
8340
  server.tool(
8347
8341
  "ask_user",
8348
- "Ask the user clarifying multiple-choice questions in Sideboard\u2019s composer (plan mode). Before calling, write a short chat message explaining the decision and what each option means. Include a description on every option. Use for approach forks and requirements \u2014 not for \u201Cis the plan ready?\u201D. After calling, stop and wait for their next message with answers.",
8342
+ "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.",
8349
8343
  {
8350
8344
  questions: z3.array(
8351
8345
  z3.object({
@@ -8450,7 +8444,7 @@ async function startMcpServer() {
8450
8444
  registerLinearTools(server);
8451
8445
  if (sideboardMcpProfile() !== "worktree") {
8452
8446
  const { getCaffeinateHold: getCaffeinateHold2, setCaffeinateHold: setCaffeinateHold2 } = await import("./caffeinate-hold-EAZNWJBE.js");
8453
- const { resolveNewThreadOptions: resolveNewThreadOptions2, resolveThreadDefaults: resolveThreadDefaults2 } = await import("./app-settings-6IOQYGBK.js");
8447
+ const { resolveNewThreadOptions: resolveNewThreadOptions2, resolveThreadDefaults: resolveThreadDefaults2 } = await import("./app-settings-MQXL7OUF.js");
8454
8448
  const accountDefaults = resolveThreadDefaults2();
8455
8449
  const accountDefaultsHint = `Account defaults: agent=${accountDefaults.agent}, model=${accountDefaults.model?.trim() || "Auto"}, effort=${accountDefaults.effort}`;
8456
8450
  server.tool(
@@ -8608,7 +8602,7 @@ async function startMcpServer() {
8608
8602
  );
8609
8603
  server.tool(
8610
8604
  "send_to_thread",
8611
- "Queue a prompt on a worktree thread chat (runs under concurrency cap). Use after create_thread to start or continue a conversation. For commit/push/PR/merge, prefer ask_git (canonical desktop-button phrases). Set force_stop=true to interrupt an in-flight/queued turn (kill + clear queue) before queueing this prompt \u2014 use when the thread is mid-turn or has stale queued prompts you need to replace.",
8605
+ 'Queue a prompt on a worktree thread chat (runs under concurrency cap). Use after create_thread to start or continue a conversation. For commit/push/PR, prefer ask_git (canonical desktop-button phrases). Send "Merge PR." / ask_git merge only when the user explicitly asked to merge. Set force_stop=true to interrupt an in-flight/queued turn (kill + clear queue) before queueing this prompt \u2014 use when the thread is mid-turn or has stale queued prompts you need to replace.',
8612
8606
  {
8613
8607
  ref: z3.string(),
8614
8608
  prompt: z3.string(),
@@ -8704,7 +8698,7 @@ async function startMcpServer() {
8704
8698
  );
8705
8699
  server.tool(
8706
8700
  "archive_thread",
8707
- "Archive a thread (stops agent/dev, runs archive script, removes worktree when last chat tab). Coordinators commit, push, open PRs, and merge only by asking the worktree agent (ask_git).",
8701
+ "Archive a thread (stops agent/dev, runs archive script, removes worktree when last chat tab). Coordinators commit, push, and open PRs by asking the worktree agent (ask_git). Merge only when the user explicitly asked.",
8708
8702
  { ref: z3.string() },
8709
8703
  async ({ ref }) => {
8710
8704
  const t = orch.getThread(ref);
@@ -8812,7 +8806,7 @@ async function startMcpServer() {
8812
8806
  );
8813
8807
  server.tool(
8814
8808
  "ask_git",
8815
- "Commit & push, open a draft PR, resolve conflicts, or merge \u2014 same actions as the desktop git buttons. When the worktree is clean, Sideboard pushes / opens the PR itself (HTTPS via `gh` if SSH is missing). When dirty, queues the worktree agent to commit; then wait_for_turn. Pass a worktree thread ref (not the orchestrator). Do not run git or gh from the orchestration cwd.",
8809
+ "Commit & push, open a draft PR, resolve conflicts, or merge \u2014 same actions as the desktop git buttons. When the worktree is clean, Sideboard pushes / opens the PR itself (HTTPS via `gh` if SSH is missing). When dirty, queues the worktree agent to commit; then wait_for_turn. Pass a worktree thread ref (not the orchestrator). action=merge only when the user explicitly asked to merge that PR. Do not run git or gh from the orchestration cwd.",
8816
8810
  {
8817
8811
  ref: z3.string().describe("Worktree thread id/ref"),
8818
8812
  action: z3.enum(AGENT_GIT_ACTIONS).describe(
@@ -9113,7 +9107,7 @@ async function startMcpServer() {
9113
9107
  );
9114
9108
  server.tool(
9115
9109
  "get_pr_stack",
9116
- "Load the GitHub PR stack for a thread worktree (`gh stack view --json`). Returns null JSON when the branch is not stacked. Prefer this before ask_git merge on stacked PRs.",
9110
+ "Load the GitHub PR stack for a thread worktree (`gh stack view --json`). Returns null JSON when the branch is not stacked. Prefer this before ask_git merge on stacked PRs (and only merge when the user explicitly asked).",
9117
9111
  { ref: z3.string() },
9118
9112
  async ({ ref }) => {
9119
9113
  const stack = await orch.getPrStack(ref);
@@ -11197,6 +11191,7 @@ export {
11197
11191
  REVIEW_REQUEST_NAME,
11198
11192
  REVIEW_REQUEST_PATH,
11199
11193
  REVIEW_REQUEST_PREFILL,
11194
+ REVIEW_REQUEST_TEMPLATE,
11200
11195
  SIDEBOARD_FORCE_STOP,
11201
11196
  SIDEBOARD_MCP_ALLOWED_TOOLS,
11202
11197
  SIDEBOARD_MCP_PROFILE_ENV,
@@ -11345,9 +11340,11 @@ export {
11345
11340
  formatGhLandError,
11346
11341
  formatGitAuthModeDirective,
11347
11342
  formatIpcInvokeError,
11343
+ formatMergePrError,
11348
11344
  formatMessagesAsTranscript,
11349
11345
  formatPlanQuestionAnswers,
11350
11346
  formatPlanQuestionsForChat,
11347
+ formatProcessGuideDirective,
11351
11348
  formatRateLimitResetHint,
11352
11349
  formatRenameBranchDirective,
11353
11350
  formatSlackExternalReplyPrompt,
@@ -11355,9 +11352,11 @@ export {
11355
11352
  formatSlackRepliesForTurn,
11356
11353
  formatSlackSignedReply,
11357
11354
  formatTranscriptMarkdown,
11355
+ formatUiReminder,
11358
11356
  formatWorkspaceInventory,
11359
11357
  formatWorktreeDirective,
11360
11358
  formatWorktreeReminder,
11359
+ fromInclusiveInputUsage,
11361
11360
  getAdapter,
11362
11361
  getAgentSetupInfo,
11363
11362
  getBrightsySession,
@@ -11428,6 +11427,7 @@ export {
11428
11427
  isOrchestratorThread,
11429
11428
  isPidAlive,
11430
11429
  isPlaceholderBranch,
11430
+ isPrNotMergeableError,
11431
11431
  isPresentPlanToolName,
11432
11432
  isSessionQuotaLimit,
11433
11433
  isSideboardScratchPath,