@sideboard-ai/core 0.1.192 → 0.1.193

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 (68) hide show
  1. package/dist/{abletime-JFMBCSIQ.js → abletime-QHKWGTBY.js} +4 -3
  2. package/dist/{abletime-53T7G667.js → abletime-UX53JTIH.js} +4 -3
  3. package/dist/agents/cursor-runner.js +4 -4
  4. package/dist/{agents-TXGQIK2E.js → agents-MN4GSQTL.js} +19 -17
  5. package/dist/{agents-T5VBB6X3.js → agents-OK5VD25T.js} +10 -8
  6. package/dist/{app-settings-663VQWUV.js → app-settings-LO7UFHQ6.js} +5 -2
  7. package/dist/{app-settings-74HBAAH7.js → app-settings-QYLNKRK4.js} +5 -2
  8. package/dist/branch-prefix-7F37FIPX.js +10 -0
  9. package/dist/branch-prefix-EVW2KHGQ.js +12 -0
  10. package/dist/{caffeinate-hold-SK2QISPE.js → caffeinate-hold-22VFDPSO.js} +2 -2
  11. package/dist/{caffeinate-hold-DBKMRZZO.js → caffeinate-hold-OK4JJ5PP.js} +2 -2
  12. package/dist/{chunk-FZ3G5TXM.js → chunk-3DX2T2KR.js} +174 -172
  13. package/dist/{chunk-HVIEYTUK.js → chunk-3OHR73VK.js} +1 -1
  14. package/dist/{chunk-VV7UT3E2.js → chunk-4OVCJPVI.js} +11 -9
  15. package/dist/{chunk-UBQIELFS.js → chunk-4QJRH5DL.js} +1 -1
  16. package/dist/{chunk-AO35MGOE.js → chunk-4TYXWPAJ.js} +1 -1
  17. package/dist/chunk-64QSHOKV.js +869 -0
  18. package/dist/{chunk-FY64F2ZQ.js → chunk-7AJ7OZZF.js} +4 -4
  19. package/dist/{chunk-WLPXZFRE.js → chunk-7J72QJOM.js} +1 -1
  20. package/dist/chunk-7SNJMKD6.js +20 -0
  21. package/dist/{chunk-WXKXSZN4.js → chunk-BIKCWYRP.js} +16 -873
  22. package/dist/{chunk-J7LQVLFQ.js → chunk-BWRS6GAS.js} +19 -1
  23. package/dist/{chunk-GOZ6T3AG.js → chunk-CJFBSQIB.js} +1 -1
  24. package/dist/{chunk-WHD4JNTN.js → chunk-EBPBGQ4P.js} +13 -13
  25. package/dist/{chunk-JTJHOYCU.js → chunk-EQNRWDLN.js} +10 -4
  26. package/dist/{chunk-NF6ENGHS.js → chunk-EQXXGOMD.js} +185 -182
  27. package/dist/{chunk-7NSXGL6L.js → chunk-HIX2VDRE.js} +11 -9
  28. package/dist/chunk-ILWQT2UN.js +55 -0
  29. package/dist/chunk-JTWKGOFI.js +23 -0
  30. package/dist/{chunk-TCQAFTSV.js → chunk-KJBYIIJU.js} +1 -1
  31. package/dist/{chunk-OKZFTOM2.js → chunk-KORE4WOF.js} +19 -1
  32. package/dist/{chunk-TWSCTJCR.js → chunk-MQC2VA5U.js} +14 -14
  33. package/dist/{chunk-4M2AK3O5.js → chunk-O4BMPY5Y.js} +1 -1
  34. package/dist/chunk-PBEPPXMY.js +57 -0
  35. package/dist/{chunk-IEEAVWAP.js → chunk-PE337IM2.js} +7 -7
  36. package/dist/chunk-RCWHL4TK.js +866 -0
  37. package/dist/{chunk-EFVFB2AH.js → chunk-WFUDY6PC.js} +12 -5
  38. package/dist/{chunk-XBLN52RZ.js → chunk-XPKKCFRT.js} +9 -866
  39. package/dist/{chunk-OCQPTUR7.js → chunk-YWI3IBP2.js} +1 -1
  40. package/dist/{connected-teams-WOYCH7FR.js → connected-teams-PU4AMFNA.js} +2 -2
  41. package/dist/{connected-teams-ON2KIKQX.js → connected-teams-SYQQGCXD.js} +2 -2
  42. package/dist/{coordinator-prompt-PNUDN4DW.js → coordinator-prompt-GXJIPWNA.js} +7 -5
  43. package/dist/{coordinator-prompt-S4HHFSLI.js → coordinator-prompt-WB65HIZ3.js} +9 -7
  44. package/dist/{cursor-recover-NDMLLNYX.js → cursor-recover-DTQAUDGO.js} +2 -2
  45. package/dist/{cursor-recover-L5MD6MBO.js → cursor-recover-TXVTLAMA.js} +1 -1
  46. package/dist/github-DWROJOB7.js +11 -0
  47. package/dist/github-IIF7AQNO.js +9 -0
  48. package/dist/{global-workspace-2BVCJUAL.js → global-workspace-BZ6V6TEX.js} +7 -5
  49. package/dist/{global-workspace-JTBBH2K5.js → global-workspace-MMK5UFUZ.js} +9 -7
  50. package/dist/index.cjs +274 -194
  51. package/dist/index.d.cts +47 -8
  52. package/dist/index.d.ts +47 -8
  53. package/dist/index.js +98 -127
  54. package/dist/mcp/run-stdio.cjs +260 -190
  55. package/dist/mcp/run-stdio.js +36 -76
  56. package/dist/{orchestrator-LWEZ74RK.js → orchestrator-4KI6VIFG.js} +14 -12
  57. package/dist/{orchestrator-4G76BOHH.js → orchestrator-SFOT6Q6F.js} +13 -11
  58. package/dist/{paths-RRCLNSJB.js → paths-C2VERLAE.js} +1 -1
  59. package/dist/{paths-53TLA7VQ.js → paths-LOXCISLX.js} +1 -1
  60. package/dist/{thread-store-ZL6GDIDP.js → thread-store-CO77HV2K.js} +2 -2
  61. package/dist/{thread-store-RXXNSRVO.js → thread-store-M4B52FUS.js} +2 -2
  62. package/dist/{workspaces-OY7D5RPU.js → workspaces-ACMZMKPD.js} +7 -5
  63. package/dist/{workspaces-ZYPME3YD.js → workspaces-KPJS7GLY.js} +9 -7
  64. package/dist/{worktree-7LOSSD7G.js → worktree-6IEVF3GN.js} +15 -12
  65. package/dist/{worktree-LPWTX2NA.js → worktree-UW6DNBIE.js} +20 -17
  66. package/dist/worktree-labels-3XDS6O3U.js +22 -0
  67. package/dist/worktree-labels-PEDOJBMD.js +24 -0
  68. package/package.json +1 -1
@@ -1,8 +1,3 @@
1
- import {
2
- extractPresentedPlan,
3
- readPlanFile,
4
- writePlanFile
5
- } from "./chunk-DJU54RYW.js";
6
1
  import {
7
2
  PLAN_MODE_INSTRUCTION,
8
3
  allAdapters,
@@ -24,7 +19,12 @@ import {
24
19
  stripBrightsyNdjsonNoise,
25
20
  sumUsageList,
26
21
  toolDescription
27
- } from "./chunk-TWSCTJCR.js";
22
+ } from "./chunk-MQC2VA5U.js";
23
+ import {
24
+ extractPresentedPlan,
25
+ readPlanFile,
26
+ writePlanFile
27
+ } from "./chunk-DJU54RYW.js";
28
28
  import {
29
29
  SLACK_REPLY_FORMATTING,
30
30
  addWorkspace,
@@ -47,10 +47,9 @@ import {
47
47
  stageAbsolutePathsAsAttachments,
48
48
  stageBuffersAsAttachments,
49
49
  syncWorkspacesFromThreads
50
- } from "./chunk-VV7UT3E2.js";
50
+ } from "./chunk-4OVCJPVI.js";
51
51
  import {
52
52
  addPrStackLayer,
53
- allocateTeamName,
54
53
  allocateTeamSlug,
55
54
  canonicalizeRepoPath,
56
55
  commitAll,
@@ -73,13 +72,11 @@ import {
73
72
  getPrStack,
74
73
  initPrStack,
75
74
  isDirty,
76
- isPlaceholderBranch,
77
75
  isSideboardScratchPath,
78
76
  listWorktrees,
79
77
  markPrReady,
80
78
  mergeAgentGitAuthEnv,
81
79
  mergePr,
82
- normalizeWorktreePath,
83
80
  originGhRepoEnv,
84
81
  pushBranch,
85
82
  removeWorktree,
@@ -90,20 +87,17 @@ import {
90
87
  resolvePrSelector,
91
88
  resolvePrSelectors,
92
89
  resolveRepoRoot,
93
- takenSlugsFromThread,
94
- threadDisplayLabel,
95
- ticketSlugForBranch,
96
- withRepoGitLock,
97
- worktreeDisplayLabelForGroup,
98
- worktreeNameFromPath,
99
- worktreeSlugForTicket
100
- } from "./chunk-WXKXSZN4.js";
90
+ withRepoGitLock
91
+ } from "./chunk-BIKCWYRP.js";
101
92
  import {
102
93
  ATTACHMENTS_DIR,
103
94
  DETACHED_JOBS_DIR,
104
95
  LEGACY_ATTACHMENTS_DIR,
105
96
  LEGACY_DETACHED_JOBS_DIR
106
97
  } from "./chunk-6K64FJDD.js";
98
+ import {
99
+ ensureWorktreeSideboardIgnored
100
+ } from "./chunk-QQKDGPUI.js";
107
101
  import {
108
102
  httpFetch
109
103
  } from "./chunk-N7WZ6NIN.js";
@@ -124,7 +118,15 @@ import {
124
118
  shouldRetryFailedAgentTurn,
125
119
  summarizeTurnStderr,
126
120
  turnFailChatText
127
- } from "./chunk-FY64F2ZQ.js";
121
+ } from "./chunk-7AJ7OZZF.js";
122
+ import {
123
+ clearStaleIndexLocks,
124
+ enrichPathWithNpmGlobalBin,
125
+ ensureAgentPath,
126
+ git,
127
+ resolveGitDirsForLockRecovery,
128
+ run
129
+ } from "./chunk-UFHNSFAS.js";
128
130
  import {
129
131
  assertOrchestratorCapableAgent,
130
132
  childEnvWithAppSettings,
@@ -149,13 +151,17 @@ import {
149
151
  saveAppSettings,
150
152
  updateAdvancedSettings,
151
153
  writeSecureJson
152
- } from "./chunk-J7LQVLFQ.js";
154
+ } from "./chunk-BWRS6GAS.js";
153
155
  import {
154
156
  stripNestedElectronEnv
155
157
  } from "./chunk-4TR3HZFT.js";
158
+ import {
159
+ examplePrefixedBranch,
160
+ sanitizeGitBranchPrefix
161
+ } from "./chunk-7SNJMKD6.js";
156
162
  import {
157
163
  releaseCaffeinateHoldForThread
158
- } from "./chunk-AO35MGOE.js";
164
+ } from "./chunk-4TYXWPAJ.js";
159
165
  import {
160
166
  writePrivateFile
161
167
  } from "./chunk-JT7R45JB.js";
@@ -170,7 +176,7 @@ import {
170
176
  updateThread,
171
177
  withThreadLock,
172
178
  writeThread
173
- } from "./chunk-TCQAFTSV.js";
179
+ } from "./chunk-KJBYIIJU.js";
174
180
  import {
175
181
  appDataDir,
176
182
  findConventionSetup,
@@ -183,18 +189,18 @@ import {
183
189
  threadsDir,
184
190
  workspaceSettingsSourceLabel,
185
191
  worktreesRoot
186
- } from "./chunk-EFVFB2AH.js";
187
- import {
188
- ensureWorktreeSideboardIgnored
189
- } from "./chunk-QQKDGPUI.js";
192
+ } from "./chunk-WFUDY6PC.js";
190
193
  import {
191
- clearStaleIndexLocks,
192
- enrichPathWithNpmGlobalBin,
193
- ensureAgentPath,
194
- git,
195
- resolveGitDirsForLockRecovery,
196
- run
197
- } from "./chunk-UFHNSFAS.js";
194
+ allocateTeamName,
195
+ isPlaceholderBranch,
196
+ normalizeWorktreePath,
197
+ takenSlugsFromThread,
198
+ threadDisplayLabel,
199
+ ticketSlugForBranch,
200
+ worktreeDisplayLabelForGroup,
201
+ worktreeNameFromPath,
202
+ worktreeSlugForTicket
203
+ } from "./chunk-RCWHL4TK.js";
198
204
 
199
205
  // src/orchestrator/orchestrator.ts
200
206
  import { EventEmitter } from "events";
@@ -467,7 +473,7 @@ async function continueSourceThread(threadId, prompt) {
467
473
  await continueOnReply(threadId, prompt);
468
474
  return;
469
475
  }
470
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-LWEZ74RK.js");
476
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-4KI6VIFG.js");
471
477
  await getOrchestrator2().send(threadId, prompt);
472
478
  } catch {
473
479
  }
@@ -801,9 +807,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
801
807
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
802
808
  );
803
809
  }
804
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-JTBBH2K5.js");
810
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-MMK5UFUZ.js");
805
811
  if (isGlobalThread2(thread)) {
806
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-S4HHFSLI.js");
812
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-WB65HIZ3.js");
807
813
  ensureGlobalCoordinatorCwd2(
808
814
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
809
815
  );
@@ -918,80 +924,6 @@ async function spawnAgentTurn(thread, input, onEvent) {
918
924
  };
919
925
  }
920
926
 
921
- // src/land/pr-metadata.ts
922
- var GENERIC_TITLE_RE = /^(sideboard:|thread\/|wip\b|tmp\b|update\b|changes?\b|misc\b|stuff\b)/i;
923
- function looksGeneric(title) {
924
- const t = title.trim();
925
- if (!t) return true;
926
- if (t.length < 4) return true;
927
- if (GENERIC_TITLE_RE.test(t)) return true;
928
- if (!/[\s:/\-_]/.test(t) && t.length <= 24) return true;
929
- return false;
930
- }
931
- function truncateTitle(title, max = 72) {
932
- const t = title.trim().replace(/\s+/g, " ");
933
- if (t.length <= max) return t;
934
- return `${t.slice(0, max - 1).trimEnd()}\u2026`;
935
- }
936
- function titleFromPaths(paths) {
937
- if (paths.length === 0) return null;
938
- const top = paths.slice(0, 3).map((p) => p.replace(/\/$/, ""));
939
- if (paths.length === 1) return truncateTitle(`Update ${top[0]}`);
940
- if (paths.length <= 3) return truncateTitle(`Update ${top.join(", ")}`);
941
- return truncateTitle(`Update ${top[0]} and ${paths.length - 1} more files`);
942
- }
943
- async function suggestPrMetadata(worktreePath, opts) {
944
- const [{ stdout: logOut }, { stdout: nameStatus }, { stdout: statOut }] = await Promise.all([
945
- git(["log", "--format=%s", `${opts.base}..HEAD`], worktreePath, {
946
- reject: false
947
- }),
948
- git(["diff", "--name-only", `${opts.base}...HEAD`], worktreePath, {
949
- reject: false
950
- }),
951
- git(["diff", "--stat", `${opts.base}...HEAD`], worktreePath, {
952
- reject: false
953
- })
954
- ]);
955
- const { stdout: dirtyNames } = await git(["diff", "--name-only", "HEAD"], worktreePath, {
956
- reject: false
957
- });
958
- const { stdout: untracked } = await git(
959
- ["ls-files", "--others", "--exclude-standard"],
960
- worktreePath,
961
- { reject: false }
962
- );
963
- const subjects = logOut.split("\n").map((s) => s.trim()).filter(Boolean);
964
- const paths = [
965
- ...new Set(
966
- [...nameStatus.split("\n"), ...dirtyNames.split("\n"), ...untracked.split("\n")].map((p) => p.trim()).filter(Boolean)
967
- )
968
- ].sort((a, b) => a.localeCompare(b));
969
- const meaningfulSubjects = subjects.filter((s) => !looksGeneric(s));
970
- const fallback = opts.fallbackTitle?.trim() || null;
971
- const fallbackOk = fallback && !looksGeneric(fallback) ? fallback : null;
972
- const title = truncateTitle(
973
- meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? "Sideboard changes"
974
- );
975
- const commitMessage = meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? `sideboard: ${title}`;
976
- const summaryLines = meaningfulSubjects.length > 0 ? meaningfulSubjects.slice(0, 12).map((s) => `- ${s}`) : paths.slice(0, 20).map((p) => `- \`${p}\``);
977
- const bodyParts = [
978
- "## Summary",
979
- summaryLines.length > 0 ? summaryLines.join("\n") : "- Changes landed via Sideboard.",
980
- ""
981
- ];
982
- if (statOut.trim()) {
983
- bodyParts.push("## Diff", "```", statOut.trim(), "```", "");
984
- }
985
- if (opts.sourceLabel) {
986
- bodyParts.push(`_Landed via Sideboard from ${opts.sourceLabel}_`);
987
- }
988
- return {
989
- title,
990
- body: bodyParts.join("\n").trim() + "\n",
991
- commitMessage: truncateTitle(commitMessage, 72)
992
- };
993
- }
994
-
995
927
  // src/git/agent-git-actions.ts
996
928
  var AGENT_GIT_ACTIONS = [
997
929
  "commit-push",
@@ -1020,6 +952,19 @@ function agentGitPrompt(action, opts) {
1020
952
  return "Merge PR.";
1021
953
  }
1022
954
  }
955
+ function resolveSidebarGitPrompt(action, opts) {
956
+ if (action === "create-pr" || action === "create-draft" || action === "create-web") {
957
+ const custom = opts?.createPr?.trim();
958
+ if (custom) return custom;
959
+ return agentGitPrompt(action === "create-pr" ? "create-draft" : action);
960
+ }
961
+ if (action === "resolve-conflicts") {
962
+ const custom = opts?.resolveMergeConflicts?.trim();
963
+ if (custom) return custom;
964
+ return agentGitPrompt("resolve-conflicts", opts);
965
+ }
966
+ return agentGitPrompt(action, opts);
967
+ }
1023
968
  var RESOLVE_CONFLICTS_RE = /^Merge the remote branch(?: \(([^)]+)\))? into your branch and resolve conflicts\. Then, commit and push your changes\.$/;
1024
969
  function gitActionExpansion(action, base) {
1025
970
  switch (action) {
@@ -3714,7 +3659,7 @@ async function createThread(input, _onSetupLine) {
3714
3659
  });
3715
3660
  await requireAgent(resolved.agent);
3716
3661
  if (input.cowboy) {
3717
- const { cowboyModeEnabled } = await import("./app-settings-663VQWUV.js");
3662
+ const { cowboyModeEnabled } = await import("./app-settings-LO7UFHQ6.js");
3718
3663
  if (!cowboyModeEnabled()) {
3719
3664
  throw new Error(
3720
3665
  "Cowboy mode is off. Enable it in Settings \u2192 Advanced."
@@ -3772,7 +3717,7 @@ async function createThread(input, _onSetupLine) {
3772
3717
  let sourceIsFork = false;
3773
3718
  if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
3774
3719
  if (isAbleTimeConnected() && getIssueSource() === "abletime") {
3775
- const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-JFMBCSIQ.js");
3720
+ const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-QHKWGTBY.js");
3776
3721
  const task = await ensureAbleTimeTask({
3777
3722
  title: title?.trim() || "Untitled work",
3778
3723
  description: input.prompt?.trim() || void 0
@@ -3874,7 +3819,7 @@ async function createThread(input, _onSetupLine) {
3874
3819
  return readThread(thread.id) ?? thread;
3875
3820
  }
3876
3821
  async function listLinearIssues(agent, repoPath) {
3877
- const { getAdapter: getAdapter2 } = await import("./agents-TXGQIK2E.js");
3822
+ const { getAdapter: getAdapter2 } = await import("./agents-MN4GSQTL.js");
3878
3823
  await requireAgent(agent, { requireLinear: true });
3879
3824
  const adapter = getAdapter2(agent);
3880
3825
  if (!adapter.listLinearIssues) {
@@ -4296,7 +4241,7 @@ async function adoptThread(input) {
4296
4241
  messages: input.messages ?? []
4297
4242
  });
4298
4243
  writeThread(thread);
4299
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ZYPME3YD.js");
4244
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-KPJS7GLY.js");
4300
4245
  await ensureWorkspace2(repoPath);
4301
4246
  const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-X54WSOXM.js");
4302
4247
  await ensureWorktreeSideboardIgnored2(input.worktreePath);
@@ -5531,6 +5476,80 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
5531
5476
  };
5532
5477
  }
5533
5478
 
5479
+ // src/land/pr-metadata.ts
5480
+ var GENERIC_TITLE_RE = /^(sideboard:|thread\/|wip\b|tmp\b|update\b|changes?\b|misc\b|stuff\b)/i;
5481
+ function looksGeneric(title) {
5482
+ const t = title.trim();
5483
+ if (!t) return true;
5484
+ if (t.length < 4) return true;
5485
+ if (GENERIC_TITLE_RE.test(t)) return true;
5486
+ if (!/[\s:/\-_]/.test(t) && t.length <= 24) return true;
5487
+ return false;
5488
+ }
5489
+ function truncateTitle(title, max = 72) {
5490
+ const t = title.trim().replace(/\s+/g, " ");
5491
+ if (t.length <= max) return t;
5492
+ return `${t.slice(0, max - 1).trimEnd()}\u2026`;
5493
+ }
5494
+ function titleFromPaths(paths) {
5495
+ if (paths.length === 0) return null;
5496
+ const top = paths.slice(0, 3).map((p) => p.replace(/\/$/, ""));
5497
+ if (paths.length === 1) return truncateTitle(`Update ${top[0]}`);
5498
+ if (paths.length <= 3) return truncateTitle(`Update ${top.join(", ")}`);
5499
+ return truncateTitle(`Update ${top[0]} and ${paths.length - 1} more files`);
5500
+ }
5501
+ async function suggestPrMetadata(worktreePath, opts) {
5502
+ const [{ stdout: logOut }, { stdout: nameStatus }, { stdout: statOut }] = await Promise.all([
5503
+ git(["log", "--format=%s", `${opts.base}..HEAD`], worktreePath, {
5504
+ reject: false
5505
+ }),
5506
+ git(["diff", "--name-only", `${opts.base}...HEAD`], worktreePath, {
5507
+ reject: false
5508
+ }),
5509
+ git(["diff", "--stat", `${opts.base}...HEAD`], worktreePath, {
5510
+ reject: false
5511
+ })
5512
+ ]);
5513
+ const { stdout: dirtyNames } = await git(["diff", "--name-only", "HEAD"], worktreePath, {
5514
+ reject: false
5515
+ });
5516
+ const { stdout: untracked } = await git(
5517
+ ["ls-files", "--others", "--exclude-standard"],
5518
+ worktreePath,
5519
+ { reject: false }
5520
+ );
5521
+ const subjects = logOut.split("\n").map((s) => s.trim()).filter(Boolean);
5522
+ const paths = [
5523
+ ...new Set(
5524
+ [...nameStatus.split("\n"), ...dirtyNames.split("\n"), ...untracked.split("\n")].map((p) => p.trim()).filter(Boolean)
5525
+ )
5526
+ ].sort((a, b) => a.localeCompare(b));
5527
+ const meaningfulSubjects = subjects.filter((s) => !looksGeneric(s));
5528
+ const fallback = opts.fallbackTitle?.trim() || null;
5529
+ const fallbackOk = fallback && !looksGeneric(fallback) ? fallback : null;
5530
+ const title = truncateTitle(
5531
+ meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? "Sideboard changes"
5532
+ );
5533
+ const commitMessage = meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? `sideboard: ${title}`;
5534
+ const summaryLines = meaningfulSubjects.length > 0 ? meaningfulSubjects.slice(0, 12).map((s) => `- ${s}`) : paths.slice(0, 20).map((p) => `- \`${p}\``);
5535
+ const bodyParts = [
5536
+ "## Summary",
5537
+ summaryLines.length > 0 ? summaryLines.join("\n") : "- Changes landed via Sideboard.",
5538
+ ""
5539
+ ];
5540
+ if (statOut.trim()) {
5541
+ bodyParts.push("## Diff", "```", statOut.trim(), "```", "");
5542
+ }
5543
+ if (opts.sourceLabel) {
5544
+ bodyParts.push(`_Landed via Sideboard from ${opts.sourceLabel}_`);
5545
+ }
5546
+ return {
5547
+ title,
5548
+ body: bodyParts.join("\n").trim() + "\n",
5549
+ commitMessage: truncateTitle(commitMessage, 72)
5550
+ };
5551
+ }
5552
+
5534
5553
  // src/land/land.ts
5535
5554
  async function previewLand(thread) {
5536
5555
  if (thread.sourceIsFork) {
@@ -6028,13 +6047,14 @@ function formatRenameBranchDirective(thread, opts) {
6028
6047
  if (!isPlaceholderBranch(thread.branchName, thread.worktreePath)) return null;
6029
6048
  const dir = worktreeNameFromPath(thread.worktreePath);
6030
6049
  const ticket = thread.sourceType === "ticket" ? ticketSlugForBranch(thread.sourceRef ?? "") : null;
6031
- const example = ticket ? `\`feat/${ticket}-dark-mode\` or \`fix/${ticket}-panel-width\`` : "`fix/panel-width` or `feat/dark-mode`";
6050
+ const prefix = sanitizeGitBranchPrefix(opts?.branchPrefix);
6051
+ const example = examplePrefixedBranch(prefix, ticket);
6052
+ const shape = prefix ? `\`${prefix}/<ticket-or-task>-<short-kebab-description>\`` : "`<ticket-or-task>-<short-kebab-description>`";
6032
6053
  const lines = [
6033
6054
  "Branch naming (do this early in the turn):",
6034
6055
  `- Current branch \`${thread.branchName}\` is a temporary placeholder. The worktree folder \`${dir}\` is a stable nickname \u2014 do not rename or leave that directory.`,
6035
- `- Rename the git branch to a short kebab-case name that describes this task (what you are changing), e.g. ${example}:`,
6056
+ `- Rename the git branch to ${shape}, e.g. \`${example}\`:`,
6036
6057
  " `git branch -m <new-name>`",
6037
- "- Prefer Conventional Commits style prefixes when they fit (`fix/`, `feat/`, `chore/`, `docs/`).",
6038
6058
  ...ticket ? [
6039
6059
  `- Keep ticket \`${ticket}\` in the new branch name so the issue stays findable.`
6040
6060
  ] : [],
@@ -6805,7 +6825,7 @@ function formatScheduledPrompt(name, prompt) {
6805
6825
  ${prompt}`;
6806
6826
  }
6807
6827
  async function defaultDeps() {
6808
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-LWEZ74RK.js");
6828
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-4KI6VIFG.js");
6809
6829
  const orch = getOrchestrator2();
6810
6830
  return {
6811
6831
  findThread: (id) => findThreadByRef(id),
@@ -7080,7 +7100,7 @@ var Orchestrator = class {
7080
7100
  orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
7081
7101
  });
7082
7102
  }
7083
- const { autoCleanupOrphansEnabled } = await import("./app-settings-663VQWUV.js");
7103
+ const { autoCleanupOrphansEnabled } = await import("./app-settings-LO7UFHQ6.js");
7084
7104
  if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
7085
7105
  await cleanupOrphanWorktrees({ repoPaths });
7086
7106
  }
@@ -7359,7 +7379,7 @@ var Orchestrator = class {
7359
7379
  }
7360
7380
  await setup;
7361
7381
  if (skipSetup) return;
7362
- const { autoRunAfterSetupEnabled } = await import("./app-settings-663VQWUV.js");
7382
+ const { autoRunAfterSetupEnabled } = await import("./app-settings-LO7UFHQ6.js");
7363
7383
  if (autoRunAfterSetupEnabled()) {
7364
7384
  try {
7365
7385
  await this.startDev(threadId);
@@ -7682,7 +7702,7 @@ var Orchestrator = class {
7682
7702
  }
7683
7703
  const isBrightsy = fresh.agent === "brightsy";
7684
7704
  const isOrchestration = isOrchestratorThread(fresh);
7685
- const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-663VQWUV.js");
7705
+ const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-LO7UFHQ6.js");
7686
7706
  const gitAuthMode = getGithubGitAuthMode();
7687
7707
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
7688
7708
  githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
@@ -7718,9 +7738,26 @@ var Orchestrator = class {
7718
7738
  }
7719
7739
  }
7720
7740
  const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
7721
- const renameBranchDirective = !isBrightsy && !isOrchestration && autoRenameBranchEnabled() ? formatRenameBranchDirective(fresh, {
7722
- customPrompt: settings?.prompts?.renameBranch
7723
- }) : null;
7741
+ let renameBranchDirective = null;
7742
+ if (!isBrightsy && !isOrchestration && autoRenameBranchEnabled()) {
7743
+ const { isPlaceholderBranch: isPlaceholderBranch2 } = await import("./worktree-labels-3XDS6O3U.js");
7744
+ let githubLogin = null;
7745
+ if (isPlaceholderBranch2(fresh.branchName, fresh.worktreePath) && !gitBranchPrefixSetting()) {
7746
+ try {
7747
+ const { getGitHubStatus } = await import("./github-IIF7AQNO.js");
7748
+ githubLogin = (await getGitHubStatus()).login;
7749
+ } catch {
7750
+ }
7751
+ }
7752
+ const { resolveGitBranchPrefix } = await import("./branch-prefix-7F37FIPX.js");
7753
+ renameBranchDirective = formatRenameBranchDirective(fresh, {
7754
+ customPrompt: settings?.prompts?.renameBranch,
7755
+ branchPrefix: resolveGitBranchPrefix({
7756
+ setting: gitBranchPrefixSetting(),
7757
+ githubLogin
7758
+ })
7759
+ });
7760
+ }
7724
7761
  let seed = null;
7725
7762
  if (!fresh.sessionId) {
7726
7763
  const prior = fresh.messages.slice(0, -1);
@@ -7815,7 +7852,7 @@ var Orchestrator = class {
7815
7852
  if (!this.stoppedTurns.has(threadId) && this.requireThread(threadId).agent === "cursor" && exitCode !== 0 && !assistantText && parts.length === 0) {
7816
7853
  const sessionId = result.sessionId || this.requireThread(threadId).sessionId || "";
7817
7854
  if (sessionId) {
7818
- const { recoverFinishedCursorRun } = await import("./cursor-recover-NDMLLNYX.js");
7855
+ const { recoverFinishedCursorRun } = await import("./cursor-recover-DTQAUDGO.js");
7819
7856
  for (let i = 0; i < 8; i++) {
7820
7857
  const recovered = recoverFinishedCursorRun({
7821
7858
  agentId: sessionId,
@@ -8608,7 +8645,7 @@ var Orchestrator = class {
8608
8645
  updateThread(thread.id, { title: meta.title });
8609
8646
  }
8610
8647
  }
8611
- const { autoArchiveOnMergeEnabled } = await import("./app-settings-663VQWUV.js");
8648
+ const { autoArchiveOnMergeEnabled } = await import("./app-settings-LO7UFHQ6.js");
8612
8649
  const latest = this.requireThread(thread.id);
8613
8650
  if (!shouldAutoArchiveOnPrMerge({
8614
8651
  previousPrState: prevState || null,
@@ -8750,9 +8787,9 @@ var Orchestrator = class {
8750
8787
  return tab;
8751
8788
  }
8752
8789
  /**
8753
- * Desktop git buttons + MCP `ask_git`.
8754
- * When the worktree is clean, push / open the PR here (HTTPS via `gh` if SSH
8755
- * is missing). When dirty, steer the worktree agent to commit first.
8790
+ * Desktop git buttons + MCP `ask_git`. Always queues the worktree agent
8791
+ * with the action prompt (same path as Resolve). Repository `[prompts]`
8792
+ * overrides apply when set.
8756
8793
  */
8757
8794
  async askGit(threadRef, action) {
8758
8795
  if (!AGENT_GIT_ACTIONS.includes(action)) {
@@ -8770,17 +8807,6 @@ var Orchestrator = class {
8770
8807
  "No pull request linked. Ask the worktree agent to open a draft PR first (ask_git create-draft)."
8771
8808
  );
8772
8809
  }
8773
- if ((action === "commit-push" || action === "create-draft" || action === "create-web") && thread.worktreePath?.trim() && !await isDirty(thread.worktreePath)) {
8774
- try {
8775
- await this.pushAndMaybeOpenPr(thread, action);
8776
- } catch (err) {
8777
- const message = err instanceof Error ? err.message : String(err);
8778
- updateThread(thread.id, { lastError: message });
8779
- this.emit({ type: "error", threadId: thread.id, message });
8780
- throw err;
8781
- }
8782
- return this.requireThread(threadRef);
8783
- }
8784
8810
  let prBase;
8785
8811
  if (action === "resolve-conflicts") {
8786
8812
  try {
@@ -8789,42 +8815,18 @@ var Orchestrator = class {
8789
8815
  } catch {
8790
8816
  }
8791
8817
  }
8792
- return this.send(threadRef, agentGitPrompt(action, { prBase }), {
8793
- followUp: resolveOrchChildFollowUp()
8794
- });
8795
- }
8796
- /** Push origin (gh HTTPS fallback) and create/update the PR when requested. */
8797
- async pushAndMaybeOpenPr(thread, action) {
8798
- const cwd = thread.worktreePath;
8799
- const branch = await currentBranch(cwd);
8800
- await pushBranch(cwd, branch);
8801
- if (action === "commit-push") return;
8802
- const base = await resolveDefaultBranch(thread.repoPath);
8803
- const meta = await suggestPrMetadata(cwd, {
8804
- base,
8805
- fallbackTitle: thread.prTitle ?? thread.title
8806
- });
8807
- const url = await createOrUpdatePr(cwd, {
8808
- title: meta.title,
8809
- body: meta.body,
8810
- base,
8811
- head: branch,
8812
- draft: action === "create-draft",
8813
- web: action === "create-web"
8814
- });
8815
- if (!url) return;
8816
- const patch = {
8817
- prUrl: url,
8818
- prTitle: meta.title,
8819
- prIsDraft: action === "create-draft"
8820
- };
8821
- try {
8822
- const fetched = await getPrMeta(cwd, url);
8823
- if (fetched?.title) patch.prTitle = fetched.title;
8824
- if (fetched) patch.prIsDraft = Boolean(fetched.isDraft);
8825
- } catch {
8826
- }
8827
- updateThread(thread.id, patch);
8818
+ const settings = loadWorkspaceSettings(thread.worktreePath, thread.repoPath);
8819
+ return this.send(
8820
+ threadRef,
8821
+ resolveSidebarGitPrompt(action, {
8822
+ prBase,
8823
+ createPr: settings?.prompts?.createPr,
8824
+ resolveMergeConflicts: settings?.prompts?.resolveMergeConflicts
8825
+ }),
8826
+ {
8827
+ followUp: resolveOrchChildFollowUp()
8828
+ }
8829
+ );
8828
8830
  }
8829
8831
  setThreadOptions(threadRef, patch) {
8830
8832
  const thread = this.requireThread(threadRef);
@@ -8935,7 +8937,7 @@ var Orchestrator = class {
8935
8937
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
8936
8938
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
8937
8939
  try {
8938
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ZYPME3YD.js");
8940
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-KPJS7GLY.js");
8939
8941
  await ensureWorkspace2(thread.repoPath);
8940
8942
  } catch {
8941
8943
  }
@@ -8962,7 +8964,7 @@ var Orchestrator = class {
8962
8964
  await runArchiveScript(thread.repoPath, thread.worktreePath);
8963
8965
  } catch {
8964
8966
  }
8965
- const { deleteBranchOnPurgeEnabled } = await import("./app-settings-663VQWUV.js");
8967
+ const { deleteBranchOnPurgeEnabled } = await import("./app-settings-LO7UFHQ6.js");
8966
8968
  const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
8967
8969
  await removeWorktree(thread.repoPath, thread.worktreePath, {
8968
8970
  deleteBranch: deleteBranch ? thread.branchName : void 0
@@ -8977,7 +8979,7 @@ var Orchestrator = class {
8977
8979
  throw new Error("Thread is not archived");
8978
8980
  }
8979
8981
  if (isGlobalThread(thread)) {
8980
- const { globalAgentCwd } = await import("./paths-53TLA7VQ.js");
8982
+ const { globalAgentCwd } = await import("./paths-LOXCISLX.js");
8981
8983
  updateThread(thread.id, { worktreePath: globalAgentCwd() });
8982
8984
  const restored2 = setStatus(thread.id, "idle");
8983
8985
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
@@ -8989,7 +8991,7 @@ var Orchestrator = class {
8989
8991
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
8990
8992
  );
8991
8993
  }
8992
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-LPWTX2NA.js");
8994
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-UW6DNBIE.js");
8993
8995
  const slug = thread.worktreePath.split("/").pop();
8994
8996
  const dest = thread.worktreePath;
8995
8997
  await withRepoGitLock(thread.repoPath, async () => {
@@ -9099,7 +9101,7 @@ async function startOrchestration(opts) {
9099
9101
  sourceRef: "default",
9100
9102
  ...createOpts
9101
9103
  }).catch(async () => {
9102
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-LPWTX2NA.js");
9104
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-UW6DNBIE.js");
9103
9105
  const repo = await resolveRepoRoot2(repoPath);
9104
9106
  const def = await resolveDefaultBranch2(repo);
9105
9107
  return orch.createThread({
@@ -9109,7 +9111,7 @@ async function startOrchestration(opts) {
9109
9111
  repoPath: repo
9110
9112
  });
9111
9113
  });
9112
- const { updateThread: upd } = await import("./thread-store-RXXNSRVO.js");
9114
+ const { updateThread: upd } = await import("./thread-store-M4B52FUS.js");
9113
9115
  const updated = upd(thread.id, {
9114
9116
  sourceType: "orchestration",
9115
9117
  sourceRef: goal
@@ -9168,6 +9170,7 @@ export {
9168
9170
  spawnAgentTurn,
9169
9171
  AGENT_GIT_ACTIONS,
9170
9172
  agentGitPrompt,
9173
+ resolveSidebarGitPrompt,
9171
9174
  CHARS_PER_CONTEXT_TOKEN,
9172
9175
  estimateMessageChars,
9173
9176
  estimateThreadChars,
@@ -1,13 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import {
4
- allocateTeamName,
5
4
  ensureGhPreferOrigin,
6
5
  resolveGithubRepoSlug,
7
- resolveRepoRoot,
8
- takenSlugsFromThread,
9
- teamSlugFromName
10
- } from "./chunk-XBLN52RZ.js";
6
+ resolveRepoRoot
7
+ } from "./chunk-XPKKCFRT.js";
11
8
  import {
12
9
  ATTACHMENTS_DIR,
13
10
  attachmentsGitignoreBody
@@ -17,7 +14,12 @@ import {
17
14
  listThreads,
18
15
  updateThread,
19
16
  writeThread
20
- } from "./chunk-GOZ6T3AG.js";
17
+ } from "./chunk-CJFBSQIB.js";
18
+ import {
19
+ allocateTeamName,
20
+ takenSlugsFromThread,
21
+ teamSlugFromName
22
+ } from "./chunk-64QSHOKV.js";
21
23
  import {
22
24
  assertOrchestratorCapableAgent,
23
25
  formatAccountProfilePlaybookLine,
@@ -30,12 +32,12 @@ import {
30
32
  resolveThreadDefaults,
31
33
  resolveViewerProfile,
32
34
  resolveViewerProfileForRepo
33
- } from "./chunk-OKZFTOM2.js";
35
+ } from "./chunk-KORE4WOF.js";
34
36
  import {
35
37
  appDataDir,
36
38
  globalAgentCwd,
37
39
  sideboardReposDir
38
- } from "./chunk-JTJHOYCU.js";
40
+ } from "./chunk-EQNRWDLN.js";
39
41
 
40
42
  // src/store/workspaces.ts
41
43
  import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
@@ -361,7 +363,7 @@ var COORDINATOR_TOOL_PLAYBOOK = [
361
363
  "- get_diff \u2014 compact diff summary",
362
364
  "- 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.",
363
365
  '- 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. 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.',
364
- "- ask_git \u2014 commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge. When the worktree is clean, Sideboard pushes / opens the PR itself. When dirty, it steers 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.",
366
+ "- 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_thread that goal so the worktree agent enters the watch-fix-push loop \u2014 do not tell the human to poll.",
365
367
  '- 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.',
366
368
  '- Or send_to_thread with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Ready for review.", "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.',
367
369
  "Process guides:",