@sideboard-ai/core 0.1.151 → 0.1.152

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 (27) hide show
  1. package/dist/{agents-JAOMXDXN.js → agents-CUKWIM34.js} +3 -3
  2. package/dist/{agents-U2JCFXW4.js → agents-VHXCBBBD.js} +3 -3
  3. package/dist/{chunk-77MP647F.js → chunk-2U6QF3PT.js} +6 -5
  4. package/dist/{chunk-TSCWSAQL.js → chunk-67TIJ7S5.js} +1 -1
  5. package/dist/{chunk-6H4TJ5TA.js → chunk-6X7Z34XE.js} +95 -50
  6. package/dist/{chunk-GCWAAPJ5.js → chunk-7BQNSUR2.js} +86 -65
  7. package/dist/{chunk-OXOU2FRS.js → chunk-7TIUOYBK.js} +6 -5
  8. package/dist/{chunk-LZAOX76N.js → chunk-EY6QXPPO.js} +2 -2
  9. package/dist/{chunk-ADCEGG4A.js → chunk-G4MTYUWS.js} +1 -1
  10. package/dist/{chunk-UIS7BVCX.js → chunk-GFQ57XAX.js} +2 -2
  11. package/dist/{chunk-HWZWBJWL.js → chunk-K2ANSHUO.js} +1 -1
  12. package/dist/{chunk-Y2FNDKHF.js → chunk-SN6CMKF6.js} +1 -1
  13. package/dist/{coordinator-prompt-ZK5MII7W.js → coordinator-prompt-TBX4MOFM.js} +1 -1
  14. package/dist/{coordinator-prompt-LWYUZAXR.js → coordinator-prompt-WGFRYCHE.js} +1 -1
  15. package/dist/{global-workspace-T7RL3XEC.js → global-workspace-BHLUJ46D.js} +2 -2
  16. package/dist/{global-workspace-IB2CCEJF.js → global-workspace-IY5QAV5C.js} +2 -2
  17. package/dist/index.cjs +112 -47
  18. package/dist/index.d.cts +34 -20
  19. package/dist/index.d.ts +34 -20
  20. package/dist/index.js +29 -7
  21. package/dist/mcp/run-stdio.cjs +101 -63
  22. package/dist/mcp/run-stdio.js +23 -7
  23. package/dist/{orchestrator-Y5MWUU7C.js → orchestrator-256DFPSX.js} +5 -5
  24. package/dist/{orchestrator-DPTRBKEH.js → orchestrator-NUA6SEV7.js} +5 -5
  25. package/dist/{workspaces-ZXCUVCZC.js → workspaces-4FSXVIZM.js} +3 -3
  26. package/dist/{workspaces-VICQYI2N.js → workspaces-NECIQTAO.js} +3 -3
  27. package/package.json +1 -1
@@ -33,13 +33,13 @@ import {
33
33
  summarizeTurnStderr,
34
34
  toolDescription,
35
35
  turnFailChatText
36
- } from "./chunk-LZAOX76N.js";
36
+ } from "./chunk-EY6QXPPO.js";
37
37
  import {
38
38
  addWorkspace,
39
39
  ensureWorkspace,
40
40
  removeWorkspace,
41
41
  syncWorkspacesFromThreads
42
- } from "./chunk-TSCWSAQL.js";
42
+ } from "./chunk-67TIJ7S5.js";
43
43
  import {
44
44
  assertOrchestratorCapableAgent,
45
45
  attachmentsFromWorktreePaths,
@@ -56,7 +56,7 @@ import {
56
56
  persistPendingFileAttachments,
57
57
  stageAbsolutePathsAsAttachments,
58
58
  stageBuffersAsAttachments
59
- } from "./chunk-Y2FNDKHF.js";
59
+ } from "./chunk-SN6CMKF6.js";
60
60
  import {
61
61
  extractPresentedPlan,
62
62
  readPlanFile,
@@ -71,7 +71,7 @@ import {
71
71
  coordinatorTurnReminder,
72
72
  enrichWorkspacesWithGithub,
73
73
  ensureGlobalCoordinatorCwd
74
- } from "./chunk-OXOU2FRS.js";
74
+ } from "./chunk-7TIUOYBK.js";
75
75
  import {
76
76
  addPrStackLayer,
77
77
  allocateTeamName,
@@ -395,7 +395,7 @@ async function continueSourceThread(threadId, prompt) {
395
395
  await continueOnReply(threadId, prompt);
396
396
  return;
397
397
  }
398
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-Y5MWUU7C.js");
398
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-256DFPSX.js");
399
399
  await getOrchestrator2().send(threadId, prompt);
400
400
  } catch {
401
401
  }
@@ -736,9 +736,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
736
736
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
737
737
  );
738
738
  }
739
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-T7RL3XEC.js");
739
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-BHLUJ46D.js");
740
740
  if (isGlobalThread2(thread)) {
741
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-ZK5MII7W.js");
741
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-TBX4MOFM.js");
742
742
  ensureGlobalCoordinatorCwd2(
743
743
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
744
744
  );
@@ -1590,32 +1590,15 @@ File: src/client/frontends/desktop/core/UserData.ts
1590
1590
 
1591
1591
  ## Growing the rules
1592
1592
 
1593
- If a blocking issue is a missing or ambiguous repo rule that will recur, add one sentence to \`.claude/skills/review/SKILL.md\` (create the skill if it is missing \u2014 that is allowed and should be committed). Do not only patch this diff when the same miss will happen again. Do not write new skills under \`.sideboard/skills/\`. Do not use \`.sideboard/review.md\` for new notes.
1593
+ If a blocking issue is a missing or ambiguous repo rule that will recur, add one sentence to \`.claude/skills/review/SKILL.md\` when that skill already exists. Otherwise write it to \`.context/review.md\` (do not create a review skill). Do not only patch this diff when the same miss will happen again. Do not write new skills under \`.sideboard/skills/\`.
1594
1594
  `;
1595
1595
  var REVIEW_SKILL_PATH = ".claude/skills/review/SKILL.md";
1596
1596
  var REVIEW_SKILL_NAME = "review";
1597
- var REVIEW_SKILL_FRONTMATTER = `---
1598
- name: review
1599
- description: >-
1600
- Merge-readiness review for this repository. Use when reviewing a PR, worktree
1601
- diff, or Sideboard Review (Approve / Approve with nits / Request changes).
1602
- ---
1603
-
1604
- `;
1605
- function wrapReviewSkillMarkdown(body) {
1606
- const trimmed = body.replace(/^\uFEFF/, "").trim();
1607
- const source = trimmed || REVIEW_REQUEST_TEMPLATE.trim();
1608
- if (/^---\s*\n[\s\S]*?\n---\s*\n/.test(source)) {
1609
- return source.endsWith("\n") ? source : `${source}
1610
- `;
1611
- }
1612
- return `${REVIEW_SKILL_FRONTMATTER}${source}
1613
- `;
1614
- }
1615
1597
 
1616
1598
  // src/review/request-review.ts
1617
1599
  var REPO_REVIEW_PATH = ".sideboard/review.md";
1618
1600
  var REPO_REVIEW_NAME = "review.md";
1601
+ var CONTEXT_REVIEW_PATH = ".context/review.md";
1619
1602
  var REVIEW_REQUEST_PATH = `${ATTACHMENTS_DIR}/Review request.md`;
1620
1603
  var LEGACY_REVIEW_REQUEST_PATH = `${LEGACY_ATTACHMENTS_DIR}/Review request.md`;
1621
1604
  var REVIEW_REQUEST_NAME = "Review request.md";
@@ -1662,37 +1645,57 @@ function skillGuidelines(content, source) {
1662
1645
  source
1663
1646
  };
1664
1647
  }
1665
- function ensureReviewSkillFile(worktreePath) {
1666
- const abs = join4(worktreePath, REVIEW_SKILL_PATH);
1667
- const existing = readTextIfPresent(abs);
1668
- if (existing) {
1669
- return { path: REVIEW_SKILL_PATH, content: existing, wrote: false };
1670
- }
1671
- const fromRepo = readTextIfPresent(join4(worktreePath, REPO_REVIEW_PATH));
1672
- const fromLocal = readLocalGuidelines(worktreePath)?.content ?? null;
1673
- const content = wrapReviewSkillMarkdown(fromRepo ?? fromLocal ?? REVIEW_REQUEST_TEMPLATE);
1674
- mkdirSync(dirname(abs), { recursive: true });
1675
- writeFileSync(abs, content, "utf8");
1676
- return { path: REVIEW_SKILL_PATH, content, wrote: true };
1648
+ function contextGuidelines(content, source) {
1649
+ return {
1650
+ path: CONTEXT_REVIEW_PATH,
1651
+ name: REPO_REVIEW_NAME,
1652
+ content,
1653
+ source
1654
+ };
1677
1655
  }
1678
- function resolveReviewGuidelines(worktreePath) {
1656
+ function writeContextGuidelines(worktreePath, content) {
1657
+ const abs = join4(worktreePath, CONTEXT_REVIEW_PATH);
1658
+ mkdirSync(dirname(abs), { recursive: true });
1659
+ const body = content.endsWith("\n") ? content : `${content}
1660
+ `;
1661
+ writeFileSync(abs, body, "utf8");
1662
+ return body;
1663
+ }
1664
+ function readSideboardReview(worktreePath, repoPath) {
1665
+ const fromWorktree = readTextIfPresent(join4(worktreePath, REPO_REVIEW_PATH));
1666
+ if (fromWorktree) return fromWorktree;
1667
+ const repo = repoPath?.replace(/\/+$/, "");
1668
+ const wt = worktreePath.replace(/\/+$/, "");
1669
+ if (!repo || repo === wt) return null;
1670
+ return readTextIfPresent(join4(repo, REPO_REVIEW_PATH));
1671
+ }
1672
+ function ensureReviewGuidelinesFile(worktreePath, repoPath) {
1679
1673
  const skillContent = readTextIfPresent(join4(worktreePath, REVIEW_SKILL_PATH));
1680
- if (skillContent) return skillGuidelines(skillContent, "skill");
1681
- const local = readLocalGuidelines(worktreePath);
1682
- if (local) {
1683
- return {
1684
- path: local.path,
1685
- name: REVIEW_REQUEST_NAME,
1686
- content: local.content,
1687
- source: "local"
1688
- };
1674
+ if (skillContent) {
1675
+ return { ...skillGuidelines(skillContent, "skill"), wrote: false };
1689
1676
  }
1690
- const seeded = ensureReviewSkillFile(worktreePath);
1691
- return skillGuidelines(seeded.content, seeded.wrote ? "stock" : "skill");
1677
+ const contextContent = readTextIfPresent(join4(worktreePath, CONTEXT_REVIEW_PATH));
1678
+ if (contextContent && !shouldRefreshReviewRequestTemplate(contextContent)) {
1679
+ return { ...contextGuidelines(contextContent, "local"), wrote: false };
1680
+ }
1681
+ const fromSideboard = readSideboardReview(worktreePath, repoPath);
1682
+ if (fromSideboard && !shouldRefreshReviewRequestTemplate(fromSideboard)) {
1683
+ const body2 = writeContextGuidelines(worktreePath, fromSideboard);
1684
+ return { ...contextGuidelines(body2, "repo"), wrote: true };
1685
+ }
1686
+ const local = readLocalGuidelines(worktreePath);
1687
+ const body = writeContextGuidelines(worktreePath, local?.content ?? REVIEW_REQUEST_TEMPLATE);
1688
+ return {
1689
+ ...contextGuidelines(body, local ? "local" : "stock"),
1690
+ wrote: true
1691
+ };
1692
+ }
1693
+ function resolveReviewGuidelines(worktreePath, repoPath) {
1694
+ return ensureReviewGuidelinesFile(worktreePath, repoPath);
1692
1695
  }
1693
1696
  function buildReviewRequestAttachment(content, opts) {
1694
1697
  const path = opts?.path ?? REVIEW_SKILL_PATH;
1695
- const name = opts?.name ?? (path === REVIEW_SKILL_PATH ? REVIEW_SKILL_NAME : path === REPO_REVIEW_PATH ? REPO_REVIEW_NAME : REVIEW_REQUEST_NAME);
1698
+ const name = opts?.name ?? (path === REVIEW_SKILL_PATH ? REVIEW_SKILL_NAME : path === REPO_REVIEW_PATH || path === CONTEXT_REVIEW_PATH ? REPO_REVIEW_NAME : REVIEW_REQUEST_NAME);
1696
1699
  return {
1697
1700
  id: randomUUID2(),
1698
1701
  name,
@@ -1712,7 +1715,7 @@ async function requestReview(threadRef, send) {
1712
1715
  if (from.status === "archived") {
1713
1716
  throw new Error(`Thread is archived: ${from.id}`);
1714
1717
  }
1715
- const guidelines = resolveReviewGuidelines(from.worktreePath);
1718
+ const guidelines = resolveReviewGuidelines(from.worktreePath, from.repoPath);
1716
1719
  const tab = createChatTab({
1717
1720
  fromThreadId: from.id,
1718
1721
  title: "Review",
@@ -1971,11 +1974,9 @@ async function runConventionSetup(repoPath, worktreePath, onLine, opts) {
1971
1974
  }
1972
1975
  async function runWorkspaceSetup(repoPath, worktreePath, onLine, opts) {
1973
1976
  await ensureWorktreeSideboardIgnored(worktreePath);
1974
- const reviewSkill = ensureReviewSkillFile(worktreePath);
1975
- if (reviewSkill.wrote) {
1976
- onLine?.(
1977
- `[setup] wrote ${REVIEW_SKILL_PATH} \u2014 commit it so later worktrees inherit Review guidelines`
1978
- );
1977
+ const review = ensureReviewGuidelinesFile(worktreePath, repoPath);
1978
+ if (review.wrote) {
1979
+ onLine?.(`[setup] wrote ${review.path} \u2014 local Review guidelines`);
1979
1980
  }
1980
1981
  let setup = await runSetupScript(repoPath, worktreePath, onLine, opts);
1981
1982
  if (!setup.ran) {
@@ -3010,7 +3011,7 @@ async function createThread(input, _onSetupLine) {
3010
3011
  return readThread(thread.id) ?? thread;
3011
3012
  }
3012
3013
  async function listLinearIssues(agent, repoPath) {
3013
- const { getAdapter: getAdapter2 } = await import("./agents-JAOMXDXN.js");
3014
+ const { getAdapter: getAdapter2 } = await import("./agents-CUKWIM34.js");
3014
3015
  await requireAgent(agent, { requireLinear: true });
3015
3016
  const adapter = getAdapter2(agent);
3016
3017
  if (!adapter.listLinearIssues) {
@@ -3417,7 +3418,7 @@ async function adoptThread(input) {
3417
3418
  messages: input.messages ?? []
3418
3419
  });
3419
3420
  writeThread(thread);
3420
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-VICQYI2N.js");
3421
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-NECIQTAO.js");
3421
3422
  await ensureWorkspace2(repoPath);
3422
3423
  const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-N5X5I422.js");
3423
3424
  await ensureWorktreeSideboardIgnored2(input.worktreePath);
@@ -4816,6 +4817,16 @@ node <detached-job.js> wait --pid-file FILE --log-file FILE [--ok-pattern TEXT]
4816
4817
  4. On \`ok\`, present once more (\`status=ok\`, last \`delta\`) and finish the task. On \`failed\`, fix from the log.
4817
4818
 
4818
4819
  Never tell the user \u201Csay status when it\u2019s done.\u201D You wait.
4820
+
4821
+ ## PR checks (only if a goal is given)
4822
+
4823
+ Do **not** watch after every push. If the user gave a goal (Greptile 5/5, CI green, until checks pass), wait the same way:
4824
+
4825
+ \`\`\`bash
4826
+ node <detached-job.js> start pr-checks -- gh pr checks --watch
4827
+ \`\`\`
4828
+
4829
+ On miss, fix, commit, push, and watch again until the goal is met or you are blocked. Do not ask the human to poll. Do not merge unless asked.
4819
4830
  `;
4820
4831
 
4821
4832
  // src/skills/discover.ts
@@ -5181,7 +5192,7 @@ function formatWorktreeDirective(thread, opts) {
5181
5192
  "Short git requests from the Sideboard UI are complete instructions \u2014 expand them using the rules above without asking for clarification:"
5182
5193
  );
5183
5194
  lines.push(
5184
- '- "Commit and push." \u2192 commit any uncommitted work with a purpose-stating message, then push to origin (updates an existing PR if one is linked).'
5195
+ '- "Commit and push." \u2192 commit any uncommitted work with a purpose-stating message, then push to origin (updates an existing PR if one is linked). Do not start a checks loop unless they gave a goal.'
5185
5196
  );
5186
5197
  lines.push(
5187
5198
  '- "Commit, push, and open a draft PR." \u2192 commit, push, then create a draft PR with `gh pr create --draft -R \u2026` (title/body from the change purpose).'
@@ -5190,7 +5201,7 @@ function formatWorktreeDirective(thread, opts) {
5190
5201
  '- "Commit, push, and open a PR in the browser." \u2192 commit, push, then `gh pr create --web -R \u2026`.'
5191
5202
  );
5192
5203
  lines.push(
5193
- '- "Fix CI: <name>." \u2192 investigate that failing check, fix it, commit, and push.'
5204
+ '- "Fix CI: <name>." \u2192 investigate that failing check, fix it, commit, and push. Loop only if they gave a goal to keep going until it passes.'
5194
5205
  );
5195
5206
  lines.push(
5196
5207
  '- "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.'
@@ -5202,11 +5213,21 @@ function formatWorktreeDirective(thread, opts) {
5202
5213
  '- "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.'
5203
5214
  );
5204
5215
  lines.push("");
5216
+ lines.push(formatPrGateDirective());
5217
+ lines.push("");
5205
5218
  lines.push(formatProcessGuideDirective());
5206
5219
  return lines.join("\n");
5207
5220
  }
5208
5221
  function formatWorktreeReminder() {
5209
- 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.";
5222
+ 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. If a goal is given (Greptile 5/5, CI green), watch-fix-push until it lands \u2014 do not watch after every push.";
5223
+ }
5224
+ function formatPrGateDirective() {
5225
+ return [
5226
+ "If a goal is given (not after every push):",
5227
+ "- Enter a watch-fix-push loop and stay in it until that goal is met or you are blocked (examples: \u201CGreptile 5/5\u201D, \u201CCI green\u201D, \u201Cuntil checks pass\u201D). Do not stop after one red run or one review cycle.",
5228
+ "- Wait with `/long-running`: `gh pr checks --watch` (add `-R <origin>` when needed). Present the log. Do not ask the human to poll.",
5229
+ "- Greptile 5/5: wait for the greptile check; read the latest `N/5` from the PR body or Greptile\u2019s most recently *updated* issue comment; also fetch unresolved review comments / the \u201CPrompt to fix all with AI\u201D block. Done = **5/5 and zero unresolved Greptile comments**. If Greptile is idle, comment `@greptile review`. Cap about 5 iterations, then report leftovers. Do not merge unless asked."
5230
+ ].join("\n");
5210
5231
  }
5211
5232
  function formatProcessGuideDirective() {
5212
5233
  return [
@@ -5214,7 +5235,7 @@ function formatProcessGuideDirective() {
5214
5235
  "- Long jobs (pack, test, deploy, anything that may run more than ~30s): Sideboard always provides `/long-running`. Detach and wait \u2014 do not ask the human to poll.",
5215
5236
  "- 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.",
5216
5237
  "- 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.",
5217
- "- Merge-readiness notes: create or edit `.claude/skills/review/SKILL.md` and commit it. That file is allowed. Do not use `.sideboard/review.md` for new notes (legacy; setup copies it into the skill).",
5238
+ "- Merge-readiness notes: if `.claude/skills/review/SKILL.md` already exists, edit it. Otherwise write them to `.context/review.md` (copied from `.sideboard/review.md` when that file exists). Do not create a review skill.",
5218
5239
  "- Do not write new skills under `.sideboard/skills/` (that folder only \u2014 other `.sideboard/` files such as settings.toml are fine). Point Codex/OpenCode at the Claude skill from `AGENTS.md`. Optional: symlink `.cursor/skills/<name>` to the Claude skill.",
5219
5240
  "- Skip a guide for a one-off. If a matching skill exists, follow it. Same miss twice \u2192 edit the skill, do not patch around it."
5220
5241
  ].join("\n");
@@ -5618,7 +5639,7 @@ function formatScheduledPrompt(name, prompt) {
5618
5639
  ${prompt}`;
5619
5640
  }
5620
5641
  async function defaultDeps() {
5621
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-Y5MWUU7C.js");
5642
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-256DFPSX.js");
5622
5643
  const orch = getOrchestrator2();
5623
5644
  return {
5624
5645
  findThread: (id) => findThreadByRef(id),
@@ -7605,7 +7626,7 @@ var Orchestrator = class {
7605
7626
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
7606
7627
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
7607
7628
  try {
7608
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-VICQYI2N.js");
7629
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-NECIQTAO.js");
7609
7630
  await ensureWorkspace2(thread.repoPath);
7610
7631
  } catch {
7611
7632
  }
@@ -75,15 +75,16 @@ var COORDINATOR_TOOL_PLAYBOOK = [
75
75
  "- list_run_scripts / run_dev_script / stop_dev_script \u2014 start/stop named run scripts",
76
76
  "Inspect / review / PRs:",
77
77
  "- get_diff \u2014 compact diff summary",
78
- '- request_review \u2014 open a Review chat tab on a worktree thread (attaches .claude/skills/review/SKILL.md when present, else seeds that skill / local guidelines; sends "Review changes in this workspace."); then wait_for_turn (loop while stillRunning) / get_turn_result on the returned id',
79
- "- ask_git \u2014 commit & push, open a draft PR, resolve conflicts, or merge. When the worktree is clean, Sideboard pushes / opens the PR itself. When dirty, it queues the worktree agent \u2014 then wait_for_turn (loop while stillRunning). Prefer this over paraphrasing. If ask_git / get_thread lastError says the GraphQL/PR body is too long, the branch is already pushed \u2014 send_to_thread so the worktree agent runs `gh pr create --body-file` with a short description. Do not invent SSH or auth failures from that error.",
78
+ "- 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.",
79
+ '- request_review \u2014 open a Review chat tab on a worktree thread (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',
80
+ "- ask_git \u2014 commit & push, open a draft PR, resolve conflicts, or merge. When the worktree is clean, Sideboard pushes / opens the PR itself. When dirty, it queues the worktree agent \u2014 then wait_for_turn (loop while stillRunning). Prefer this over paraphrasing. If ask_git / get_thread lastError says the GraphQL/PR body is too long, the branch is already pushed \u2014 send_to_thread so the worktree agent runs `gh pr create --body-file` with a short description. Do not invent SSH or auth failures from that error. If the user gave a goal (Greptile 5/5, CI green), send_to_thread that goal so the worktree agent enters the watch-fix-push loop \u2014 do not tell the human to poll.",
80
81
  '- Merge (`ask_git` action=merge / send_to_thread "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.',
81
82
  '- Or send_to_thread with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Merge the remote branch (main) into your branch and resolve conflicts. Then, commit and push your changes.", "Merge PR." (draft PRs: `gh pr create --draft -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.',
82
83
  "Process guides:",
83
84
  "- 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; do not ask the human to poll.",
84
85
  "- 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.",
85
- "- Recurring shapes: have the worktree agent write `.claude/skills/<kebab-name>/SKILL.md` (commit it) so later threads and native Claude Code / attach see it. Merge-review sentences go in `.claude/skills/review/SKILL.md` (create it \u2014 that is allowed). Do not use `.sideboard/skills/` (that folder only). Codex/OpenCode: one line in AGENTS.md pointing at that file.",
86
- "- One-offs: no guide. Same miss across threads: edit the skill or `.claude/skills/review/SKILL.md`, then rerun the batch \u2014 do not patch three threads.",
86
+ "- Recurring shapes: have the worktree agent write `.claude/skills/<kebab-name>/SKILL.md` (commit it) so later threads and native Claude Code / attach see it. Merge-review sentences go in `.claude/skills/review/SKILL.md` when that skill already exists; otherwise `.context/review.md` (do not create a review skill). Do not use `.sideboard/skills/` (that folder only). Codex/OpenCode: one line in AGENTS.md pointing at that file.",
87
+ "- One-offs: no guide. Same miss across threads: edit the existing skill or `.context/review.md`, then rerun the batch \u2014 do not patch three threads.",
87
88
  "Human-only (do not attempt): ready-for-review land (confirm_land), purge_thread.",
88
89
  "Thread links in replies: when mentioning a chat/thread for the user, include a markdown link `[Title](sideboard://thread/<id>)` using the full id (or the link field from create_thread / list_threads). Sideboard renders these as clickable opens.",
89
90
  "Bash / Read / etc: allowed for (1) inspecting target worktrees / registered repo paths from MCP, and (2) greenfield setup under ~/sideboard/repos (git clone, gh repo create, git init+remote). Never git init/clone *inside* this synthetic home cwd \u2014 emptiness here is expected, not a bug."
@@ -162,7 +163,7 @@ function ensureGlobalCoordinatorCwd(opts) {
162
163
  "Typical flow (Home board): list_board \u2192 create_thread (sourceType=ticket|pr|branch) \u2192 send_to_thread \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft \u2192 wait_for_turn. Merge only if the user explicitly asked (`ask_git` merge).",
163
164
  "Typical flow (branch / explicit source): list_workspaces \u2192 list_branches|list_prs|list_issues \u2192 create_thread \u2192 send_to_thread \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft.",
164
165
  "Typical flow (new app): Bash create/clone under repos dir \u2192 add_workspace \u2192 create_thread \u2192 send_to_thread (implement) \u2192 wait_for_turn (loop while stillRunning) \u2192 ask_git create-draft.",
165
- "Always ask worktree agents to commit, push, and open draft PRs (`ask_git` / `send_to_thread`). Tell them to merge only when the user explicitly asked. The worktree agent runs git/gh; never merge from this orchestration cwd."
166
+ "Always ask worktree agents to commit, push, and open draft PRs (`ask_git` / `send_to_thread`). If the user gave a goal (Greptile 5/5, CI green), pass that goal through so they watch-fix-push until it lands \u2014 do not start that loop on a plain push, and do not tell the human to poll. Tell them to merge only when the user explicitly asked. The worktree agent runs git/gh; never merge from this orchestration cwd."
166
167
  ].join("\n");
167
168
  try {
168
169
  writeFileSync(join(dir, "CLAUDE.md"), `${body}
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-S42XV45P.js";
12
12
  import {
13
13
  isOrchestratorThread
14
- } from "./chunk-Y2FNDKHF.js";
14
+ } from "./chunk-SN6CMKF6.js";
15
15
  import {
16
16
  codexUnattendedGitConfigArgs,
17
17
  mergeAgentGitAuthEnv,
@@ -2098,7 +2098,7 @@ var claudeAdapter = {
2098
2098
  );
2099
2099
  }
2100
2100
  const mode = permissionMode(thread);
2101
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-T7RL3XEC.js");
2101
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-BHLUJ46D.js");
2102
2102
  const isOrchestrator = isOrchestratorThread2(thread);
2103
2103
  const injectedServers = await buildInjectedMcpServers({
2104
2104
  includeSideboard: true,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ensureGlobalCoordinatorCwd
3
- } from "./chunk-77MP647F.js";
3
+ } from "./chunk-2U6QF3PT.js";
4
4
  import {
5
5
  allocateTeamName,
6
6
  takenSlugsFromThread,
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-M267JPEA.js";
10
10
  import {
11
11
  isOrchestratorThread
12
- } from "./chunk-ADCEGG4A.js";
12
+ } from "./chunk-G4MTYUWS.js";
13
13
  import {
14
14
  codexUnattendedGitConfigArgs,
15
15
  mergeAgentGitAuthEnv,
@@ -1777,7 +1777,7 @@ var claudeAdapter = {
1777
1777
  );
1778
1778
  }
1779
1779
  const mode = permissionMode(thread);
1780
- const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-IB2CCEJF.js");
1780
+ const { isOrchestratorThread: isOrchestratorThread2 } = await import("./global-workspace-IY5QAV5C.js");
1781
1781
  const isOrchestrator = isOrchestratorThread2(thread);
1782
1782
  const injectedServers = await buildInjectedMcpServers({
1783
1783
  includeSideboard: true,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isGlobalRepoPath
3
- } from "./chunk-ADCEGG4A.js";
3
+ } from "./chunk-G4MTYUWS.js";
4
4
  import {
5
5
  ensureGhPreferOrigin,
6
6
  resolveRepoRoot
@@ -2,7 +2,7 @@
2
2
 
3
3
  import {
4
4
  ensureGlobalCoordinatorCwd
5
- } from "./chunk-OXOU2FRS.js";
5
+ } from "./chunk-7TIUOYBK.js";
6
6
  import {
7
7
  allocateTeamName,
8
8
  takenSlugsFromThread,
@@ -9,7 +9,7 @@ import {
9
9
  enrichWorkspacesWithGithub,
10
10
  ensureGlobalCoordinatorCwd,
11
11
  formatWorkspaceInventory
12
- } from "./chunk-OXOU2FRS.js";
12
+ } from "./chunk-7TIUOYBK.js";
13
13
  import "./chunk-3JBMACYX.js";
14
14
  import "./chunk-NVXVEGGM.js";
15
15
  import "./chunk-EUXOHTUK.js";
@@ -7,7 +7,7 @@ import {
7
7
  enrichWorkspacesWithGithub,
8
8
  ensureGlobalCoordinatorCwd,
9
9
  formatWorkspaceInventory
10
- } from "./chunk-77MP647F.js";
10
+ } from "./chunk-2U6QF3PT.js";
11
11
  import "./chunk-GE7M3QTE.js";
12
12
  import "./chunk-JRH62XC4.js";
13
13
  import "./chunk-4XNSGDXE.js";
@@ -17,8 +17,8 @@ import {
17
17
  orchestratorSessionPoisonedByBuiltins,
18
18
  slackCoordinatorSourceRef,
19
19
  takenTeamSlugsForOrchestration
20
- } from "./chunk-Y2FNDKHF.js";
21
- import "./chunk-OXOU2FRS.js";
20
+ } from "./chunk-SN6CMKF6.js";
21
+ import "./chunk-7TIUOYBK.js";
22
22
  import "./chunk-3JBMACYX.js";
23
23
  import "./chunk-NVXVEGGM.js";
24
24
  import "./chunk-EUXOHTUK.js";
@@ -15,8 +15,8 @@ import {
15
15
  orchestratorSessionPoisonedByBuiltins,
16
16
  slackCoordinatorSourceRef,
17
17
  takenTeamSlugsForOrchestration
18
- } from "./chunk-ADCEGG4A.js";
19
- import "./chunk-77MP647F.js";
18
+ } from "./chunk-G4MTYUWS.js";
19
+ import "./chunk-2U6QF3PT.js";
20
20
  import "./chunk-GE7M3QTE.js";
21
21
  import "./chunk-JRH62XC4.js";
22
22
  import "./chunk-4XNSGDXE.js";