@sideboard-ai/core 0.1.192 → 0.1.194

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 (60) hide show
  1. package/dist/{abletime-53T7G667.js → abletime-HR6P4GJH.js} +4 -3
  2. package/dist/{abletime-JFMBCSIQ.js → abletime-JINF5KJV.js} +4 -3
  3. package/dist/agents/cursor-runner.js +3 -3
  4. package/dist/{agents-TXGQIK2E.js → agents-OXDDPH2O.js} +10 -9
  5. package/dist/{agents-T5VBB6X3.js → agents-WQL7SZY6.js} +8 -7
  6. package/dist/{app-settings-663VQWUV.js → app-settings-5KHVKJKO.js} +5 -2
  7. package/dist/{app-settings-74HBAAH7.js → app-settings-J775CYOO.js} +5 -2
  8. package/dist/branch-prefix-7DTIUJT2.js +12 -0
  9. package/dist/branch-prefix-N3KTCRCE.js +10 -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-TWSCTJCR.js → chunk-2X6RGKLI.js} +7 -7
  13. package/dist/{chunk-HVIEYTUK.js → chunk-3OHR73VK.js} +1 -1
  14. package/dist/{chunk-AO35MGOE.js → chunk-4TYXWPAJ.js} +1 -1
  15. package/dist/{chunk-WHD4JNTN.js → chunk-6H2XPPPR.js} +8 -8
  16. package/dist/{chunk-7NSXGL6L.js → chunk-6YTI2HBG.js} +5 -5
  17. package/dist/{chunk-WLPXZFRE.js → chunk-7J72QJOM.js} +1 -1
  18. package/dist/{chunk-OKZFTOM2.js → chunk-AH6WIBLY.js} +19 -1
  19. package/dist/{chunk-GOZ6T3AG.js → chunk-CJFBSQIB.js} +1 -1
  20. package/dist/{chunk-XBLN52RZ.js → chunk-DP4TKAMZ.js} +3 -3
  21. package/dist/{chunk-4M2AK3O5.js → chunk-E37JHCO3.js} +1 -1
  22. package/dist/{chunk-JTJHOYCU.js → chunk-EQNRWDLN.js} +10 -4
  23. package/dist/chunk-FJZWM2ON.js +23 -0
  24. package/dist/{chunk-VV7UT3E2.js → chunk-HZTHWU6A.js} +5 -5
  25. package/dist/{chunk-TCQAFTSV.js → chunk-KJBYIIJU.js} +1 -1
  26. package/dist/{chunk-UBQIELFS.js → chunk-KTHRWHA3.js} +1 -1
  27. package/dist/{chunk-FY64F2ZQ.js → chunk-NLHFAMC2.js} +1 -1
  28. package/dist/{chunk-NF6ENGHS.js → chunk-NY366OEZ.js} +151 -160
  29. package/dist/{chunk-WXKXSZN4.js → chunk-S4QCBBXS.js} +6 -6
  30. package/dist/{chunk-J7LQVLFQ.js → chunk-S5GLSRLP.js} +19 -1
  31. package/dist/{chunk-IEEAVWAP.js → chunk-SALM35KD.js} +5 -5
  32. package/dist/{chunk-FZ3G5TXM.js → chunk-VRPPFKAO.js} +152 -162
  33. package/dist/chunk-WDRMZKVB.js +20 -0
  34. package/dist/{chunk-EFVFB2AH.js → chunk-WFUDY6PC.js} +12 -5
  35. package/dist/{chunk-OCQPTUR7.js → chunk-YWI3IBP2.js} +1 -1
  36. package/dist/{connected-teams-WOYCH7FR.js → connected-teams-PU4AMFNA.js} +2 -2
  37. package/dist/{connected-teams-ON2KIKQX.js → connected-teams-WK47ATT7.js} +2 -2
  38. package/dist/{coordinator-prompt-S4HHFSLI.js → coordinator-prompt-IX66YUJ2.js} +7 -6
  39. package/dist/{coordinator-prompt-PNUDN4DW.js → coordinator-prompt-LYKS3YNG.js} +6 -5
  40. package/dist/{cursor-recover-NDMLLNYX.js → cursor-recover-DTQAUDGO.js} +2 -2
  41. package/dist/{cursor-recover-L5MD6MBO.js → cursor-recover-TXVTLAMA.js} +1 -1
  42. package/dist/{global-workspace-JTBBH2K5.js → global-workspace-4QX6UEOY.js} +7 -6
  43. package/dist/{global-workspace-2BVCJUAL.js → global-workspace-SNJ2Z6SL.js} +6 -5
  44. package/dist/index.cjs +192 -146
  45. package/dist/index.d.cts +46 -8
  46. package/dist/index.d.ts +46 -8
  47. package/dist/index.js +55 -43
  48. package/dist/mcp/run-stdio.cjs +179 -145
  49. package/dist/mcp/run-stdio.js +19 -18
  50. package/dist/{orchestrator-4G76BOHH.js → orchestrator-A5KF2335.js} +10 -9
  51. package/dist/{orchestrator-LWEZ74RK.js → orchestrator-S3M2E7O6.js} +12 -11
  52. package/dist/{paths-RRCLNSJB.js → paths-C2VERLAE.js} +1 -1
  53. package/dist/{paths-53TLA7VQ.js → paths-LOXCISLX.js} +1 -1
  54. package/dist/{thread-store-ZL6GDIDP.js → thread-store-CO77HV2K.js} +2 -2
  55. package/dist/{thread-store-RXXNSRVO.js → thread-store-M4B52FUS.js} +2 -2
  56. package/dist/{workspaces-ZYPME3YD.js → workspaces-URMUVGAQ.js} +7 -6
  57. package/dist/{workspaces-OY7D5RPU.js → workspaces-UTOYGBYB.js} +6 -5
  58. package/dist/{worktree-7LOSSD7G.js → worktree-R43JOR4V.js} +5 -4
  59. package/dist/{worktree-LPWTX2NA.js → worktree-RM6UWNGZ.js} +6 -5
  60. package/package.json +1 -1
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-AN3THU7F.js";
8
8
  import {
9
9
  appDataDir
10
- } from "./chunk-EFVFB2AH.js";
10
+ } from "./chunk-WFUDY6PC.js";
11
11
  import {
12
12
  run
13
13
  } from "./chunk-UFHNSFAS.js";
@@ -18,7 +18,7 @@ import { join } from "path";
18
18
 
19
19
  // src/brightsy/accounts.ts
20
20
  async function loadConnectedTeams() {
21
- const { listConnectedBrightsyTeams: listConnectedBrightsyTeams2 } = await import("./connected-teams-ON2KIKQX.js");
21
+ const { listConnectedBrightsyTeams: listConnectedBrightsyTeams2 } = await import("./connected-teams-WK47ATT7.js");
22
22
  return listConnectedBrightsyTeams2();
23
23
  }
24
24
  async function runBrightsyTeamsJson(args) {
@@ -47,14 +47,14 @@ async function listBrightsyAccounts() {
47
47
  async function getBrightsySession() {
48
48
  try {
49
49
  const { ensureBrightsyLocalConfigFresh: ensureBrightsyLocalConfigFresh2 } = await import("./oauth-6ZQ4Q4XN.js");
50
- const { ensureConnectedBrightsyTeamTokens: ensureConnectedBrightsyTeamTokens2 } = await import("./connected-teams-ON2KIKQX.js");
50
+ const { ensureConnectedBrightsyTeamTokens: ensureConnectedBrightsyTeamTokens2 } = await import("./connected-teams-WK47ATT7.js");
51
51
  await ensureBrightsyLocalConfigFresh2();
52
52
  await ensureConnectedBrightsyTeamTokens2();
53
53
  loadBrightsyConfig();
54
54
  const data = await runBrightsyTeamsJson([]);
55
55
  const accounts = Array.isArray(data.teams) ? data.teams : [];
56
56
  const active = data.active ?? accounts.find((a) => a.active) ?? null;
57
- const { ensureCliTeamTracked: ensureCliTeamTracked2 } = await import("./connected-teams-ON2KIKQX.js");
57
+ const { ensureCliTeamTracked: ensureCliTeamTracked2 } = await import("./connected-teams-WK47ATT7.js");
58
58
  const connectedTeams = ensureCliTeamTracked2(
59
59
  active ? { id: active.id, slug: active.slug, name: active.name } : void 0
60
60
  );
@@ -94,7 +94,7 @@ async function performBrightsyAccountSwitch(accountIdOrSlug) {
94
94
  return { cfg, target: data.active };
95
95
  }
96
96
  async function switchBrightsyAccount(accountIdOrSlug) {
97
- const { connectBrightsyTeam: connectBrightsyTeam2 } = await import("./connected-teams-ON2KIKQX.js");
97
+ const { connectBrightsyTeam: connectBrightsyTeam2 } = await import("./connected-teams-WK47ATT7.js");
98
98
  await connectBrightsyTeam2(accountIdOrSlug);
99
99
  return getBrightsySession();
100
100
  }
@@ -1,5 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ import {
4
+ releaseCaffeinateHoldForThread
5
+ } from "./chunk-YWI3IBP2.js";
3
6
  import {
4
7
  PLAN_MODE_INSTRUCTION,
5
8
  applyAgentEvent,
@@ -33,15 +36,7 @@ import {
33
36
  summarizeTurnStderr,
34
37
  toolDescription,
35
38
  turnFailChatText
36
- } from "./chunk-WHD4JNTN.js";
37
- import {
38
- extractPresentedPlan,
39
- readPlanFile,
40
- writePlanFile
41
- } from "./chunk-JFOPOMK7.js";
42
- import {
43
- releaseCaffeinateHoldForThread
44
- } from "./chunk-OCQPTUR7.js";
39
+ } from "./chunk-6H2XPPPR.js";
45
40
  import {
46
41
  SLACK_REPLY_FORMATTING,
47
42
  addWorkspace,
@@ -64,7 +59,12 @@ import {
64
59
  stageAbsolutePathsAsAttachments,
65
60
  stageBuffersAsAttachments,
66
61
  syncWorkspacesFromThreads
67
- } from "./chunk-7NSXGL6L.js";
62
+ } from "./chunk-6YTI2HBG.js";
63
+ import {
64
+ extractPresentedPlan,
65
+ readPlanFile,
66
+ writePlanFile
67
+ } from "./chunk-JFOPOMK7.js";
68
68
  import {
69
69
  addPrStackLayer,
70
70
  allocateTeamName,
@@ -114,7 +114,7 @@ import {
114
114
  worktreeDisplayLabelForGroup,
115
115
  worktreeNameFromPath,
116
116
  worktreeSlugForTicket
117
- } from "./chunk-XBLN52RZ.js";
117
+ } from "./chunk-DP4TKAMZ.js";
118
118
  import {
119
119
  ATTACHMENTS_DIR,
120
120
  DETACHED_JOBS_DIR,
@@ -132,7 +132,7 @@ import {
132
132
  updateThread,
133
133
  withThreadLock,
134
134
  writeThread
135
- } from "./chunk-GOZ6T3AG.js";
135
+ } from "./chunk-CJFBSQIB.js";
136
136
  import {
137
137
  ensureWorktreeSideboardIgnored
138
138
  } from "./chunk-SYFVUF2C.js";
@@ -168,7 +168,7 @@ import {
168
168
  stripNestedElectronEnv,
169
169
  updateAdvancedSettings,
170
170
  writeSecureJson
171
- } from "./chunk-OKZFTOM2.js";
171
+ } from "./chunk-AH6WIBLY.js";
172
172
  import {
173
173
  writePrivateFile
174
174
  } from "./chunk-NSTQ6QKD.js";
@@ -184,7 +184,11 @@ import {
184
184
  threadsDir,
185
185
  workspaceSettingsSourceLabel,
186
186
  worktreesRoot
187
- } from "./chunk-JTJHOYCU.js";
187
+ } from "./chunk-EQNRWDLN.js";
188
+ import {
189
+ examplePrefixedBranch,
190
+ sanitizeGitBranchPrefix
191
+ } from "./chunk-FJZWM2ON.js";
188
192
 
189
193
  // src/orchestrator/orchestrator.ts
190
194
  import { EventEmitter } from "events";
@@ -402,7 +406,7 @@ async function continueSourceThread(threadId, prompt) {
402
406
  await continueOnReply(threadId, prompt);
403
407
  return;
404
408
  }
405
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-4G76BOHH.js");
409
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-A5KF2335.js");
406
410
  await getOrchestrator2().send(threadId, prompt);
407
411
  } catch {
408
412
  }
@@ -795,9 +799,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
795
799
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
796
800
  );
797
801
  }
798
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-2BVCJUAL.js");
802
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-SNJ2Z6SL.js");
799
803
  if (isGlobalThread2(thread)) {
800
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-PNUDN4DW.js");
804
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-LYKS3YNG.js");
801
805
  ensureGlobalCoordinatorCwd2(
802
806
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
803
807
  );
@@ -912,80 +916,6 @@ async function spawnAgentTurn(thread, input, onEvent) {
912
916
  };
913
917
  }
914
918
 
915
- // src/land/pr-metadata.ts
916
- var GENERIC_TITLE_RE = /^(sideboard:|thread\/|wip\b|tmp\b|update\b|changes?\b|misc\b|stuff\b)/i;
917
- function looksGeneric(title) {
918
- const t = title.trim();
919
- if (!t) return true;
920
- if (t.length < 4) return true;
921
- if (GENERIC_TITLE_RE.test(t)) return true;
922
- if (!/[\s:/\-_]/.test(t) && t.length <= 24) return true;
923
- return false;
924
- }
925
- function truncateTitle(title, max = 72) {
926
- const t = title.trim().replace(/\s+/g, " ");
927
- if (t.length <= max) return t;
928
- return `${t.slice(0, max - 1).trimEnd()}\u2026`;
929
- }
930
- function titleFromPaths(paths) {
931
- if (paths.length === 0) return null;
932
- const top = paths.slice(0, 3).map((p) => p.replace(/\/$/, ""));
933
- if (paths.length === 1) return truncateTitle(`Update ${top[0]}`);
934
- if (paths.length <= 3) return truncateTitle(`Update ${top.join(", ")}`);
935
- return truncateTitle(`Update ${top[0]} and ${paths.length - 1} more files`);
936
- }
937
- async function suggestPrMetadata(worktreePath, opts) {
938
- const [{ stdout: logOut }, { stdout: nameStatus }, { stdout: statOut }] = await Promise.all([
939
- git(["log", "--format=%s", `${opts.base}..HEAD`], worktreePath, {
940
- reject: false
941
- }),
942
- git(["diff", "--name-only", `${opts.base}...HEAD`], worktreePath, {
943
- reject: false
944
- }),
945
- git(["diff", "--stat", `${opts.base}...HEAD`], worktreePath, {
946
- reject: false
947
- })
948
- ]);
949
- const { stdout: dirtyNames } = await git(["diff", "--name-only", "HEAD"], worktreePath, {
950
- reject: false
951
- });
952
- const { stdout: untracked } = await git(
953
- ["ls-files", "--others", "--exclude-standard"],
954
- worktreePath,
955
- { reject: false }
956
- );
957
- const subjects = logOut.split("\n").map((s) => s.trim()).filter(Boolean);
958
- const paths = [
959
- ...new Set(
960
- [...nameStatus.split("\n"), ...dirtyNames.split("\n"), ...untracked.split("\n")].map((p) => p.trim()).filter(Boolean)
961
- )
962
- ].sort((a, b) => a.localeCompare(b));
963
- const meaningfulSubjects = subjects.filter((s) => !looksGeneric(s));
964
- const fallback = opts.fallbackTitle?.trim() || null;
965
- const fallbackOk = fallback && !looksGeneric(fallback) ? fallback : null;
966
- const title = truncateTitle(
967
- meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? "Sideboard changes"
968
- );
969
- const commitMessage = meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? `sideboard: ${title}`;
970
- const summaryLines = meaningfulSubjects.length > 0 ? meaningfulSubjects.slice(0, 12).map((s) => `- ${s}`) : paths.slice(0, 20).map((p) => `- \`${p}\``);
971
- const bodyParts = [
972
- "## Summary",
973
- summaryLines.length > 0 ? summaryLines.join("\n") : "- Changes landed via Sideboard.",
974
- ""
975
- ];
976
- if (statOut.trim()) {
977
- bodyParts.push("## Diff", "```", statOut.trim(), "```", "");
978
- }
979
- if (opts.sourceLabel) {
980
- bodyParts.push(`_Landed via Sideboard from ${opts.sourceLabel}_`);
981
- }
982
- return {
983
- title,
984
- body: bodyParts.join("\n").trim() + "\n",
985
- commitMessage: truncateTitle(commitMessage, 72)
986
- };
987
- }
988
-
989
919
  // src/git/agent-git-actions.ts
990
920
  var AGENT_GIT_ACTIONS = [
991
921
  "commit-push",
@@ -1014,6 +944,19 @@ function agentGitPrompt(action, opts) {
1014
944
  return "Merge PR.";
1015
945
  }
1016
946
  }
947
+ function resolveSidebarGitPrompt(action, opts) {
948
+ if (action === "create-pr" || action === "create-draft" || action === "create-web") {
949
+ const custom = opts?.createPr?.trim();
950
+ if (custom) return custom;
951
+ return agentGitPrompt(action === "create-pr" ? "create-draft" : action);
952
+ }
953
+ if (action === "resolve-conflicts") {
954
+ const custom = opts?.resolveMergeConflicts?.trim();
955
+ if (custom) return custom;
956
+ return agentGitPrompt("resolve-conflicts", opts);
957
+ }
958
+ return agentGitPrompt(action, opts);
959
+ }
1017
960
  var RESOLVE_CONFLICTS_RE = /^Merge the remote branch(?: \(([^)]+)\))? into your branch and resolve conflicts\. Then, commit and push your changes\.$/;
1018
961
  function gitActionExpansion(action, base) {
1019
962
  switch (action) {
@@ -3585,7 +3528,7 @@ async function createThread(input, _onSetupLine) {
3585
3528
  });
3586
3529
  await requireAgent(resolved.agent);
3587
3530
  if (input.cowboy) {
3588
- const { cowboyModeEnabled } = await import("./app-settings-74HBAAH7.js");
3531
+ const { cowboyModeEnabled } = await import("./app-settings-J775CYOO.js");
3589
3532
  if (!cowboyModeEnabled()) {
3590
3533
  throw new Error(
3591
3534
  "Cowboy mode is off. Enable it in Settings \u2192 Advanced."
@@ -3643,7 +3586,7 @@ async function createThread(input, _onSetupLine) {
3643
3586
  let sourceIsFork = false;
3644
3587
  if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
3645
3588
  if (isAbleTimeConnected() && getIssueSource() === "abletime") {
3646
- const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-53T7G667.js");
3589
+ const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-HR6P4GJH.js");
3647
3590
  const task = await ensureAbleTimeTask({
3648
3591
  title: title?.trim() || "Untitled work",
3649
3592
  description: input.prompt?.trim() || void 0
@@ -4155,7 +4098,7 @@ async function adoptThread(input) {
4155
4098
  messages: input.messages ?? []
4156
4099
  });
4157
4100
  writeThread(thread);
4158
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-OY7D5RPU.js");
4101
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-UTOYGBYB.js");
4159
4102
  await ensureWorkspace2(repoPath);
4160
4103
  const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-N5X5I422.js");
4161
4104
  await ensureWorktreeSideboardIgnored2(input.worktreePath);
@@ -5377,6 +5320,80 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
5377
5320
  };
5378
5321
  }
5379
5322
 
5323
+ // src/land/pr-metadata.ts
5324
+ var GENERIC_TITLE_RE = /^(sideboard:|thread\/|wip\b|tmp\b|update\b|changes?\b|misc\b|stuff\b)/i;
5325
+ function looksGeneric(title) {
5326
+ const t = title.trim();
5327
+ if (!t) return true;
5328
+ if (t.length < 4) return true;
5329
+ if (GENERIC_TITLE_RE.test(t)) return true;
5330
+ if (!/[\s:/\-_]/.test(t) && t.length <= 24) return true;
5331
+ return false;
5332
+ }
5333
+ function truncateTitle(title, max = 72) {
5334
+ const t = title.trim().replace(/\s+/g, " ");
5335
+ if (t.length <= max) return t;
5336
+ return `${t.slice(0, max - 1).trimEnd()}\u2026`;
5337
+ }
5338
+ function titleFromPaths(paths) {
5339
+ if (paths.length === 0) return null;
5340
+ const top = paths.slice(0, 3).map((p) => p.replace(/\/$/, ""));
5341
+ if (paths.length === 1) return truncateTitle(`Update ${top[0]}`);
5342
+ if (paths.length <= 3) return truncateTitle(`Update ${top.join(", ")}`);
5343
+ return truncateTitle(`Update ${top[0]} and ${paths.length - 1} more files`);
5344
+ }
5345
+ async function suggestPrMetadata(worktreePath, opts) {
5346
+ const [{ stdout: logOut }, { stdout: nameStatus }, { stdout: statOut }] = await Promise.all([
5347
+ git(["log", "--format=%s", `${opts.base}..HEAD`], worktreePath, {
5348
+ reject: false
5349
+ }),
5350
+ git(["diff", "--name-only", `${opts.base}...HEAD`], worktreePath, {
5351
+ reject: false
5352
+ }),
5353
+ git(["diff", "--stat", `${opts.base}...HEAD`], worktreePath, {
5354
+ reject: false
5355
+ })
5356
+ ]);
5357
+ const { stdout: dirtyNames } = await git(["diff", "--name-only", "HEAD"], worktreePath, {
5358
+ reject: false
5359
+ });
5360
+ const { stdout: untracked } = await git(
5361
+ ["ls-files", "--others", "--exclude-standard"],
5362
+ worktreePath,
5363
+ { reject: false }
5364
+ );
5365
+ const subjects = logOut.split("\n").map((s) => s.trim()).filter(Boolean);
5366
+ const paths = [
5367
+ ...new Set(
5368
+ [...nameStatus.split("\n"), ...dirtyNames.split("\n"), ...untracked.split("\n")].map((p) => p.trim()).filter(Boolean)
5369
+ )
5370
+ ].sort((a, b) => a.localeCompare(b));
5371
+ const meaningfulSubjects = subjects.filter((s) => !looksGeneric(s));
5372
+ const fallback = opts.fallbackTitle?.trim() || null;
5373
+ const fallbackOk = fallback && !looksGeneric(fallback) ? fallback : null;
5374
+ const title = truncateTitle(
5375
+ meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? "Sideboard changes"
5376
+ );
5377
+ const commitMessage = meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? `sideboard: ${title}`;
5378
+ const summaryLines = meaningfulSubjects.length > 0 ? meaningfulSubjects.slice(0, 12).map((s) => `- ${s}`) : paths.slice(0, 20).map((p) => `- \`${p}\``);
5379
+ const bodyParts = [
5380
+ "## Summary",
5381
+ summaryLines.length > 0 ? summaryLines.join("\n") : "- Changes landed via Sideboard.",
5382
+ ""
5383
+ ];
5384
+ if (statOut.trim()) {
5385
+ bodyParts.push("## Diff", "```", statOut.trim(), "```", "");
5386
+ }
5387
+ if (opts.sourceLabel) {
5388
+ bodyParts.push(`_Landed via Sideboard from ${opts.sourceLabel}_`);
5389
+ }
5390
+ return {
5391
+ title,
5392
+ body: bodyParts.join("\n").trim() + "\n",
5393
+ commitMessage: truncateTitle(commitMessage, 72)
5394
+ };
5395
+ }
5396
+
5380
5397
  // src/land/land.ts
5381
5398
  async function previewLand(thread) {
5382
5399
  if (thread.sourceIsFork) {
@@ -5874,13 +5891,14 @@ function formatRenameBranchDirective(thread, opts) {
5874
5891
  if (!isPlaceholderBranch(thread.branchName, thread.worktreePath)) return null;
5875
5892
  const dir = worktreeNameFromPath(thread.worktreePath);
5876
5893
  const ticket = thread.sourceType === "ticket" ? ticketSlugForBranch(thread.sourceRef ?? "") : null;
5877
- const example = ticket ? `\`feat/${ticket}-dark-mode\` or \`fix/${ticket}-panel-width\`` : "`fix/panel-width` or `feat/dark-mode`";
5894
+ const prefix = sanitizeGitBranchPrefix(opts?.branchPrefix);
5895
+ const example = examplePrefixedBranch(prefix, ticket);
5896
+ const shape = prefix ? `\`${prefix}/<ticket-or-task>-<short-kebab-description>\`` : "`<ticket-or-task>-<short-kebab-description>`";
5878
5897
  const lines = [
5879
5898
  "Branch naming (do this early in the turn):",
5880
5899
  `- Current branch \`${thread.branchName}\` is a temporary placeholder. The worktree folder \`${dir}\` is a stable nickname \u2014 do not rename or leave that directory.`,
5881
- `- Rename the git branch to a short kebab-case name that describes this task (what you are changing), e.g. ${example}:`,
5900
+ `- Rename the git branch to ${shape}, e.g. \`${example}\`:`,
5882
5901
  " `git branch -m <new-name>`",
5883
- "- Prefer Conventional Commits style prefixes when they fit (`fix/`, `feat/`, `chore/`, `docs/`).",
5884
5902
  ...ticket ? [
5885
5903
  `- Keep ticket \`${ticket}\` in the new branch name so the issue stays findable.`
5886
5904
  ] : [],
@@ -6458,7 +6476,7 @@ function formatScheduledPrompt(name, prompt) {
6458
6476
  ${prompt}`;
6459
6477
  }
6460
6478
  async function defaultDeps() {
6461
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-4G76BOHH.js");
6479
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-A5KF2335.js");
6462
6480
  const orch = getOrchestrator2();
6463
6481
  return {
6464
6482
  findThread: (id) => findThreadByRef(id),
@@ -6733,7 +6751,7 @@ var Orchestrator = class {
6733
6751
  orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
6734
6752
  });
6735
6753
  }
6736
- const { autoCleanupOrphansEnabled } = await import("./app-settings-74HBAAH7.js");
6754
+ const { autoCleanupOrphansEnabled } = await import("./app-settings-J775CYOO.js");
6737
6755
  if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
6738
6756
  await cleanupOrphanWorktrees({ repoPaths });
6739
6757
  }
@@ -7012,7 +7030,7 @@ var Orchestrator = class {
7012
7030
  }
7013
7031
  await setup;
7014
7032
  if (skipSetup) return;
7015
- const { autoRunAfterSetupEnabled } = await import("./app-settings-74HBAAH7.js");
7033
+ const { autoRunAfterSetupEnabled } = await import("./app-settings-J775CYOO.js");
7016
7034
  if (autoRunAfterSetupEnabled()) {
7017
7035
  try {
7018
7036
  await this.startDev(threadId);
@@ -7335,7 +7353,7 @@ var Orchestrator = class {
7335
7353
  }
7336
7354
  const isBrightsy = fresh.agent === "brightsy";
7337
7355
  const isOrchestration = isOrchestratorThread(fresh);
7338
- const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-74HBAAH7.js");
7356
+ const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-J775CYOO.js");
7339
7357
  const gitAuthMode = getGithubGitAuthMode();
7340
7358
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
7341
7359
  githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
@@ -7371,9 +7389,16 @@ var Orchestrator = class {
7371
7389
  }
7372
7390
  }
7373
7391
  const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
7374
- const renameBranchDirective = !isBrightsy && !isOrchestration && autoRenameBranchEnabled() ? formatRenameBranchDirective(fresh, {
7375
- customPrompt: settings?.prompts?.renameBranch
7376
- }) : null;
7392
+ let renameBranchDirective = null;
7393
+ if (!isBrightsy && !isOrchestration && autoRenameBranchEnabled()) {
7394
+ const { resolveGitBranchPrefix } = await import("./branch-prefix-7DTIUJT2.js");
7395
+ renameBranchDirective = formatRenameBranchDirective(fresh, {
7396
+ customPrompt: settings?.prompts?.renameBranch,
7397
+ branchPrefix: resolveGitBranchPrefix({
7398
+ setting: gitBranchPrefixSetting()
7399
+ })
7400
+ });
7401
+ }
7377
7402
  let seed = null;
7378
7403
  if (!fresh.sessionId) {
7379
7404
  const prior = fresh.messages.slice(0, -1);
@@ -7468,7 +7493,7 @@ var Orchestrator = class {
7468
7493
  if (!this.stoppedTurns.has(threadId) && this.requireThread(threadId).agent === "cursor" && exitCode !== 0 && !assistantText && parts.length === 0) {
7469
7494
  const sessionId = result.sessionId || this.requireThread(threadId).sessionId || "";
7470
7495
  if (sessionId) {
7471
- const { recoverFinishedCursorRun } = await import("./cursor-recover-L5MD6MBO.js");
7496
+ const { recoverFinishedCursorRun } = await import("./cursor-recover-TXVTLAMA.js");
7472
7497
  for (let i = 0; i < 8; i++) {
7473
7498
  const recovered = recoverFinishedCursorRun({
7474
7499
  agentId: sessionId,
@@ -8261,7 +8286,7 @@ var Orchestrator = class {
8261
8286
  updateThread(thread.id, { title: meta.title });
8262
8287
  }
8263
8288
  }
8264
- const { autoArchiveOnMergeEnabled } = await import("./app-settings-74HBAAH7.js");
8289
+ const { autoArchiveOnMergeEnabled } = await import("./app-settings-J775CYOO.js");
8265
8290
  const latest = this.requireThread(thread.id);
8266
8291
  if (!shouldAutoArchiveOnPrMerge({
8267
8292
  previousPrState: prevState || null,
@@ -8403,9 +8428,9 @@ var Orchestrator = class {
8403
8428
  return tab;
8404
8429
  }
8405
8430
  /**
8406
- * Desktop git buttons + MCP `ask_git`.
8407
- * When the worktree is clean, push / open the PR here (HTTPS via `gh` if SSH
8408
- * is missing). When dirty, steer the worktree agent to commit first.
8431
+ * Desktop git buttons + MCP `ask_git`. Always queues the worktree agent
8432
+ * with the action prompt (same path as Resolve). Repository `[prompts]`
8433
+ * overrides apply when set.
8409
8434
  */
8410
8435
  async askGit(threadRef, action) {
8411
8436
  if (!AGENT_GIT_ACTIONS.includes(action)) {
@@ -8423,17 +8448,6 @@ var Orchestrator = class {
8423
8448
  "No pull request linked. Ask the worktree agent to open a draft PR first (ask_git create-draft)."
8424
8449
  );
8425
8450
  }
8426
- if ((action === "commit-push" || action === "create-draft" || action === "create-web") && thread.worktreePath?.trim() && !await isDirty(thread.worktreePath)) {
8427
- try {
8428
- await this.pushAndMaybeOpenPr(thread, action);
8429
- } catch (err) {
8430
- const message = err instanceof Error ? err.message : String(err);
8431
- updateThread(thread.id, { lastError: message });
8432
- this.emit({ type: "error", threadId: thread.id, message });
8433
- throw err;
8434
- }
8435
- return this.requireThread(threadRef);
8436
- }
8437
8451
  let prBase;
8438
8452
  if (action === "resolve-conflicts") {
8439
8453
  try {
@@ -8442,42 +8456,18 @@ var Orchestrator = class {
8442
8456
  } catch {
8443
8457
  }
8444
8458
  }
8445
- return this.send(threadRef, agentGitPrompt(action, { prBase }), {
8446
- followUp: resolveOrchChildFollowUp()
8447
- });
8448
- }
8449
- /** Push origin (gh HTTPS fallback) and create/update the PR when requested. */
8450
- async pushAndMaybeOpenPr(thread, action) {
8451
- const cwd = thread.worktreePath;
8452
- const branch = await currentBranch(cwd);
8453
- await pushBranch(cwd, branch);
8454
- if (action === "commit-push") return;
8455
- const base = await resolveDefaultBranch(thread.repoPath);
8456
- const meta = await suggestPrMetadata(cwd, {
8457
- base,
8458
- fallbackTitle: thread.prTitle ?? thread.title
8459
- });
8460
- const url = await createOrUpdatePr(cwd, {
8461
- title: meta.title,
8462
- body: meta.body,
8463
- base,
8464
- head: branch,
8465
- draft: action === "create-draft",
8466
- web: action === "create-web"
8467
- });
8468
- if (!url) return;
8469
- const patch = {
8470
- prUrl: url,
8471
- prTitle: meta.title,
8472
- prIsDraft: action === "create-draft"
8473
- };
8474
- try {
8475
- const fetched = await getPrMeta(cwd, url);
8476
- if (fetched?.title) patch.prTitle = fetched.title;
8477
- if (fetched) patch.prIsDraft = Boolean(fetched.isDraft);
8478
- } catch {
8479
- }
8480
- updateThread(thread.id, patch);
8459
+ const settings = loadWorkspaceSettings(thread.worktreePath, thread.repoPath);
8460
+ return this.send(
8461
+ threadRef,
8462
+ resolveSidebarGitPrompt(action, {
8463
+ prBase,
8464
+ createPr: settings?.prompts?.createPr,
8465
+ resolveMergeConflicts: settings?.prompts?.resolveMergeConflicts
8466
+ }),
8467
+ {
8468
+ followUp: resolveOrchChildFollowUp()
8469
+ }
8470
+ );
8481
8471
  }
8482
8472
  setThreadOptions(threadRef, patch) {
8483
8473
  const thread = this.requireThread(threadRef);
@@ -8588,7 +8578,7 @@ var Orchestrator = class {
8588
8578
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
8589
8579
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
8590
8580
  try {
8591
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-OY7D5RPU.js");
8581
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-UTOYGBYB.js");
8592
8582
  await ensureWorkspace2(thread.repoPath);
8593
8583
  } catch {
8594
8584
  }
@@ -8615,7 +8605,7 @@ var Orchestrator = class {
8615
8605
  await runArchiveScript(thread.repoPath, thread.worktreePath);
8616
8606
  } catch {
8617
8607
  }
8618
- const { deleteBranchOnPurgeEnabled } = await import("./app-settings-74HBAAH7.js");
8608
+ const { deleteBranchOnPurgeEnabled } = await import("./app-settings-J775CYOO.js");
8619
8609
  const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
8620
8610
  await removeWorktree(thread.repoPath, thread.worktreePath, {
8621
8611
  deleteBranch: deleteBranch ? thread.branchName : void 0
@@ -8630,7 +8620,7 @@ var Orchestrator = class {
8630
8620
  throw new Error("Thread is not archived");
8631
8621
  }
8632
8622
  if (isGlobalThread(thread)) {
8633
- const { globalAgentCwd } = await import("./paths-RRCLNSJB.js");
8623
+ const { globalAgentCwd } = await import("./paths-C2VERLAE.js");
8634
8624
  updateThread(thread.id, { worktreePath: globalAgentCwd() });
8635
8625
  const restored2 = setStatus(thread.id, "idle");
8636
8626
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
@@ -8642,7 +8632,7 @@ var Orchestrator = class {
8642
8632
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
8643
8633
  );
8644
8634
  }
8645
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-7LOSSD7G.js");
8635
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-R43JOR4V.js");
8646
8636
  const slug = thread.worktreePath.split("/").pop();
8647
8637
  const dest = thread.worktreePath;
8648
8638
  await withRepoGitLock(thread.repoPath, async () => {
@@ -8752,7 +8742,7 @@ async function startOrchestration(opts) {
8752
8742
  sourceRef: "default",
8753
8743
  ...createOpts
8754
8744
  }).catch(async () => {
8755
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-7LOSSD7G.js");
8745
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-R43JOR4V.js");
8756
8746
  const repo = await resolveRepoRoot2(repoPath);
8757
8747
  const def = await resolveDefaultBranch2(repo);
8758
8748
  return orch.createThread({
@@ -8762,7 +8752,7 @@ async function startOrchestration(opts) {
8762
8752
  repoPath: repo
8763
8753
  });
8764
8754
  });
8765
- const { updateThread: upd } = await import("./thread-store-ZL6GDIDP.js");
8755
+ const { updateThread: upd } = await import("./thread-store-CO77HV2K.js");
8766
8756
  const updated = upd(thread.id, {
8767
8757
  sourceType: "orchestration",
8768
8758
  sourceRef: goal
@@ -0,0 +1,20 @@
1
+ // src/git/branch-prefix.ts
2
+ function sanitizeGitBranchPrefix(raw) {
3
+ const first = (raw ?? "").trim().replace(/^\/+|\/+$/g, "").split("/")[0] ?? "";
4
+ const slug = first.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 39);
5
+ return slug || null;
6
+ }
7
+ function resolveGitBranchPrefix(opts) {
8
+ return sanitizeGitBranchPrefix(opts.setting);
9
+ }
10
+ function examplePrefixedBranch(prefix, ticket) {
11
+ const head = sanitizeGitBranchPrefix(prefix);
12
+ const slug = ticket?.trim() ? `${ticket.trim()}-eng-fix-thing` : "bb-1234-eng-fix-thing";
13
+ return head ? `${head}/${slug}` : slug;
14
+ }
15
+
16
+ export {
17
+ sanitizeGitBranchPrefix,
18
+ resolveGitBranchPrefix,
19
+ examplePrefixedBranch
20
+ };
@@ -194,9 +194,12 @@ function parseSettingsFile(path, source) {
194
194
  const prompts = {
195
195
  renameBranch: typeof promptsRaw.rename_branch === "string" ? promptsRaw.rename_branch : void 0,
196
196
  createPr: typeof promptsRaw.create_pr === "string" ? promptsRaw.create_pr : void 0,
197
- general: typeof promptsRaw.general === "string" ? promptsRaw.general : void 0
197
+ general: typeof promptsRaw.general === "string" ? promptsRaw.general : void 0,
198
+ resolveMergeConflicts: typeof promptsRaw.resolve_merge_conflicts === "string" ? promptsRaw.resolve_merge_conflicts : void 0
198
199
  };
199
- const hasPrompts = Boolean(prompts.renameBranch || prompts.createPr || prompts.general);
200
+ const hasPrompts = Boolean(
201
+ prompts.renameBranch || prompts.createPr || prompts.general || prompts.resolveMergeConflicts
202
+ );
200
203
  return {
201
204
  source,
202
205
  setup,
@@ -222,9 +225,12 @@ function mergeSettings(base, overlay) {
222
225
  const prompts = {
223
226
  renameBranch: overlay.prompts?.renameBranch ?? base.prompts?.renameBranch,
224
227
  createPr: overlay.prompts?.createPr ?? base.prompts?.createPr,
225
- general: overlay.prompts?.general ?? base.prompts?.general
228
+ general: overlay.prompts?.general ?? base.prompts?.general,
229
+ resolveMergeConflicts: overlay.prompts?.resolveMergeConflicts ?? base.prompts?.resolveMergeConflicts
226
230
  };
227
- const hasPrompts = Boolean(prompts.renameBranch || prompts.createPr || prompts.general);
231
+ const hasPrompts = Boolean(
232
+ prompts.renameBranch || prompts.createPr || prompts.general || prompts.resolveMergeConflicts
233
+ );
228
234
  return {
229
235
  source: overlay.source,
230
236
  setup: overlay.setup ?? base.setup,
@@ -348,7 +354,8 @@ function getRepoSetupInfo(worktreePath, repoPath) {
348
354
  return {
349
355
  hasConfig: hasWorkspaceHook(worktreePath, repoPath) || cursor || Boolean(convention),
350
356
  hasSetupScript,
351
- configLabel
357
+ configLabel,
358
+ ...settings?.prompts ? { prompts: settings.prompts } : {}
352
359
  };
353
360
  }
354
361
 
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-NSTQ6QKD.js";
6
6
  import {
7
7
  appDataDir
8
- } from "./chunk-JTJHOYCU.js";
8
+ } from "./chunk-EQNRWDLN.js";
9
9
 
10
10
  // src/store/caffeinate-hold.ts
11
11
  import { spawn } from "child_process";
@@ -9,11 +9,11 @@ import {
9
9
  ensureConnectedBrightsyTeamTokens,
10
10
  getConnectedBrightsyTeamsRaw,
11
11
  listConnectedBrightsyTeams
12
- } from "./chunk-HVIEYTUK.js";
12
+ } from "./chunk-3OHR73VK.js";
13
13
  import "./chunk-Y4MIXGPA.js";
14
14
  import "./chunk-VKQGAWHY.js";
15
15
  import "./chunk-FNQNJOHY.js";
16
- import "./chunk-JTJHOYCU.js";
16
+ import "./chunk-EQNRWDLN.js";
17
17
  export {
18
18
  applyConnectedTeamToCli,
19
19
  brightsyMcpServerName,
@@ -7,10 +7,10 @@ import {
7
7
  ensureConnectedBrightsyTeamTokens,
8
8
  getConnectedBrightsyTeamsRaw,
9
9
  listConnectedBrightsyTeams
10
- } from "./chunk-IEEAVWAP.js";
10
+ } from "./chunk-SALM35KD.js";
11
11
  import "./chunk-AN3THU7F.js";
12
12
  import "./chunk-N7WZ6NIN.js";
13
- import "./chunk-EFVFB2AH.js";
13
+ import "./chunk-WFUDY6PC.js";
14
14
  import "./chunk-UFHNSFAS.js";
15
15
  export {
16
16
  applyConnectedTeamToCli,