@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
@@ -24,7 +24,7 @@ import {
24
24
  stripBrightsyNdjsonNoise,
25
25
  sumUsageList,
26
26
  toolDescription
27
- } from "./chunk-TWSCTJCR.js";
27
+ } from "./chunk-2X6RGKLI.js";
28
28
  import {
29
29
  SLACK_REPLY_FORMATTING,
30
30
  addWorkspace,
@@ -47,7 +47,7 @@ import {
47
47
  stageAbsolutePathsAsAttachments,
48
48
  stageBuffersAsAttachments,
49
49
  syncWorkspacesFromThreads
50
- } from "./chunk-VV7UT3E2.js";
50
+ } from "./chunk-HZTHWU6A.js";
51
51
  import {
52
52
  addPrStackLayer,
53
53
  allocateTeamName,
@@ -97,13 +97,16 @@ import {
97
97
  worktreeDisplayLabelForGroup,
98
98
  worktreeNameFromPath,
99
99
  worktreeSlugForTicket
100
- } from "./chunk-WXKXSZN4.js";
100
+ } from "./chunk-S4QCBBXS.js";
101
101
  import {
102
102
  ATTACHMENTS_DIR,
103
103
  DETACHED_JOBS_DIR,
104
104
  LEGACY_ATTACHMENTS_DIR,
105
105
  LEGACY_DETACHED_JOBS_DIR
106
106
  } from "./chunk-6K64FJDD.js";
107
+ import {
108
+ ensureWorktreeSideboardIgnored
109
+ } from "./chunk-QQKDGPUI.js";
107
110
  import {
108
111
  httpFetch
109
112
  } from "./chunk-N7WZ6NIN.js";
@@ -124,7 +127,7 @@ import {
124
127
  shouldRetryFailedAgentTurn,
125
128
  summarizeTurnStderr,
126
129
  turnFailChatText
127
- } from "./chunk-FY64F2ZQ.js";
130
+ } from "./chunk-NLHFAMC2.js";
128
131
  import {
129
132
  assertOrchestratorCapableAgent,
130
133
  childEnvWithAppSettings,
@@ -149,13 +152,17 @@ import {
149
152
  saveAppSettings,
150
153
  updateAdvancedSettings,
151
154
  writeSecureJson
152
- } from "./chunk-J7LQVLFQ.js";
155
+ } from "./chunk-S5GLSRLP.js";
153
156
  import {
154
157
  stripNestedElectronEnv
155
158
  } from "./chunk-4TR3HZFT.js";
159
+ import {
160
+ examplePrefixedBranch,
161
+ sanitizeGitBranchPrefix
162
+ } from "./chunk-WDRMZKVB.js";
156
163
  import {
157
164
  releaseCaffeinateHoldForThread
158
- } from "./chunk-AO35MGOE.js";
165
+ } from "./chunk-4TYXWPAJ.js";
159
166
  import {
160
167
  writePrivateFile
161
168
  } from "./chunk-JT7R45JB.js";
@@ -170,7 +177,7 @@ import {
170
177
  updateThread,
171
178
  withThreadLock,
172
179
  writeThread
173
- } from "./chunk-TCQAFTSV.js";
180
+ } from "./chunk-KJBYIIJU.js";
174
181
  import {
175
182
  appDataDir,
176
183
  findConventionSetup,
@@ -183,10 +190,7 @@ import {
183
190
  threadsDir,
184
191
  workspaceSettingsSourceLabel,
185
192
  worktreesRoot
186
- } from "./chunk-EFVFB2AH.js";
187
- import {
188
- ensureWorktreeSideboardIgnored
189
- } from "./chunk-QQKDGPUI.js";
193
+ } from "./chunk-WFUDY6PC.js";
190
194
  import {
191
195
  clearStaleIndexLocks,
192
196
  enrichPathWithNpmGlobalBin,
@@ -467,7 +471,7 @@ async function continueSourceThread(threadId, prompt) {
467
471
  await continueOnReply(threadId, prompt);
468
472
  return;
469
473
  }
470
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-LWEZ74RK.js");
474
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-S3M2E7O6.js");
471
475
  await getOrchestrator2().send(threadId, prompt);
472
476
  } catch {
473
477
  }
@@ -801,9 +805,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
801
805
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
802
806
  );
803
807
  }
804
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-JTBBH2K5.js");
808
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-4QX6UEOY.js");
805
809
  if (isGlobalThread2(thread)) {
806
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-S4HHFSLI.js");
810
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-IX66YUJ2.js");
807
811
  ensureGlobalCoordinatorCwd2(
808
812
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
809
813
  );
@@ -918,80 +922,6 @@ async function spawnAgentTurn(thread, input, onEvent) {
918
922
  };
919
923
  }
920
924
 
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
925
  // src/git/agent-git-actions.ts
996
926
  var AGENT_GIT_ACTIONS = [
997
927
  "commit-push",
@@ -1020,6 +950,19 @@ function agentGitPrompt(action, opts) {
1020
950
  return "Merge PR.";
1021
951
  }
1022
952
  }
953
+ function resolveSidebarGitPrompt(action, opts) {
954
+ if (action === "create-pr" || action === "create-draft" || action === "create-web") {
955
+ const custom = opts?.createPr?.trim();
956
+ if (custom) return custom;
957
+ return agentGitPrompt(action === "create-pr" ? "create-draft" : action);
958
+ }
959
+ if (action === "resolve-conflicts") {
960
+ const custom = opts?.resolveMergeConflicts?.trim();
961
+ if (custom) return custom;
962
+ return agentGitPrompt("resolve-conflicts", opts);
963
+ }
964
+ return agentGitPrompt(action, opts);
965
+ }
1023
966
  var RESOLVE_CONFLICTS_RE = /^Merge the remote branch(?: \(([^)]+)\))? into your branch and resolve conflicts\. Then, commit and push your changes\.$/;
1024
967
  function gitActionExpansion(action, base) {
1025
968
  switch (action) {
@@ -3714,7 +3657,7 @@ async function createThread(input, _onSetupLine) {
3714
3657
  });
3715
3658
  await requireAgent(resolved.agent);
3716
3659
  if (input.cowboy) {
3717
- const { cowboyModeEnabled } = await import("./app-settings-663VQWUV.js");
3660
+ const { cowboyModeEnabled } = await import("./app-settings-5KHVKJKO.js");
3718
3661
  if (!cowboyModeEnabled()) {
3719
3662
  throw new Error(
3720
3663
  "Cowboy mode is off. Enable it in Settings \u2192 Advanced."
@@ -3772,7 +3715,7 @@ async function createThread(input, _onSetupLine) {
3772
3715
  let sourceIsFork = false;
3773
3716
  if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
3774
3717
  if (isAbleTimeConnected() && getIssueSource() === "abletime") {
3775
- const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-JFMBCSIQ.js");
3718
+ const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-JINF5KJV.js");
3776
3719
  const task = await ensureAbleTimeTask({
3777
3720
  title: title?.trim() || "Untitled work",
3778
3721
  description: input.prompt?.trim() || void 0
@@ -3874,7 +3817,7 @@ async function createThread(input, _onSetupLine) {
3874
3817
  return readThread(thread.id) ?? thread;
3875
3818
  }
3876
3819
  async function listLinearIssues(agent, repoPath) {
3877
- const { getAdapter: getAdapter2 } = await import("./agents-TXGQIK2E.js");
3820
+ const { getAdapter: getAdapter2 } = await import("./agents-OXDDPH2O.js");
3878
3821
  await requireAgent(agent, { requireLinear: true });
3879
3822
  const adapter = getAdapter2(agent);
3880
3823
  if (!adapter.listLinearIssues) {
@@ -4296,7 +4239,7 @@ async function adoptThread(input) {
4296
4239
  messages: input.messages ?? []
4297
4240
  });
4298
4241
  writeThread(thread);
4299
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ZYPME3YD.js");
4242
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-URMUVGAQ.js");
4300
4243
  await ensureWorkspace2(repoPath);
4301
4244
  const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-X54WSOXM.js");
4302
4245
  await ensureWorktreeSideboardIgnored2(input.worktreePath);
@@ -5531,6 +5474,80 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
5531
5474
  };
5532
5475
  }
5533
5476
 
5477
+ // src/land/pr-metadata.ts
5478
+ var GENERIC_TITLE_RE = /^(sideboard:|thread\/|wip\b|tmp\b|update\b|changes?\b|misc\b|stuff\b)/i;
5479
+ function looksGeneric(title) {
5480
+ const t = title.trim();
5481
+ if (!t) return true;
5482
+ if (t.length < 4) return true;
5483
+ if (GENERIC_TITLE_RE.test(t)) return true;
5484
+ if (!/[\s:/\-_]/.test(t) && t.length <= 24) return true;
5485
+ return false;
5486
+ }
5487
+ function truncateTitle(title, max = 72) {
5488
+ const t = title.trim().replace(/\s+/g, " ");
5489
+ if (t.length <= max) return t;
5490
+ return `${t.slice(0, max - 1).trimEnd()}\u2026`;
5491
+ }
5492
+ function titleFromPaths(paths) {
5493
+ if (paths.length === 0) return null;
5494
+ const top = paths.slice(0, 3).map((p) => p.replace(/\/$/, ""));
5495
+ if (paths.length === 1) return truncateTitle(`Update ${top[0]}`);
5496
+ if (paths.length <= 3) return truncateTitle(`Update ${top.join(", ")}`);
5497
+ return truncateTitle(`Update ${top[0]} and ${paths.length - 1} more files`);
5498
+ }
5499
+ async function suggestPrMetadata(worktreePath, opts) {
5500
+ const [{ stdout: logOut }, { stdout: nameStatus }, { stdout: statOut }] = await Promise.all([
5501
+ git(["log", "--format=%s", `${opts.base}..HEAD`], worktreePath, {
5502
+ reject: false
5503
+ }),
5504
+ git(["diff", "--name-only", `${opts.base}...HEAD`], worktreePath, {
5505
+ reject: false
5506
+ }),
5507
+ git(["diff", "--stat", `${opts.base}...HEAD`], worktreePath, {
5508
+ reject: false
5509
+ })
5510
+ ]);
5511
+ const { stdout: dirtyNames } = await git(["diff", "--name-only", "HEAD"], worktreePath, {
5512
+ reject: false
5513
+ });
5514
+ const { stdout: untracked } = await git(
5515
+ ["ls-files", "--others", "--exclude-standard"],
5516
+ worktreePath,
5517
+ { reject: false }
5518
+ );
5519
+ const subjects = logOut.split("\n").map((s) => s.trim()).filter(Boolean);
5520
+ const paths = [
5521
+ ...new Set(
5522
+ [...nameStatus.split("\n"), ...dirtyNames.split("\n"), ...untracked.split("\n")].map((p) => p.trim()).filter(Boolean)
5523
+ )
5524
+ ].sort((a, b) => a.localeCompare(b));
5525
+ const meaningfulSubjects = subjects.filter((s) => !looksGeneric(s));
5526
+ const fallback = opts.fallbackTitle?.trim() || null;
5527
+ const fallbackOk = fallback && !looksGeneric(fallback) ? fallback : null;
5528
+ const title = truncateTitle(
5529
+ meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? "Sideboard changes"
5530
+ );
5531
+ const commitMessage = meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? `sideboard: ${title}`;
5532
+ const summaryLines = meaningfulSubjects.length > 0 ? meaningfulSubjects.slice(0, 12).map((s) => `- ${s}`) : paths.slice(0, 20).map((p) => `- \`${p}\``);
5533
+ const bodyParts = [
5534
+ "## Summary",
5535
+ summaryLines.length > 0 ? summaryLines.join("\n") : "- Changes landed via Sideboard.",
5536
+ ""
5537
+ ];
5538
+ if (statOut.trim()) {
5539
+ bodyParts.push("## Diff", "```", statOut.trim(), "```", "");
5540
+ }
5541
+ if (opts.sourceLabel) {
5542
+ bodyParts.push(`_Landed via Sideboard from ${opts.sourceLabel}_`);
5543
+ }
5544
+ return {
5545
+ title,
5546
+ body: bodyParts.join("\n").trim() + "\n",
5547
+ commitMessage: truncateTitle(commitMessage, 72)
5548
+ };
5549
+ }
5550
+
5534
5551
  // src/land/land.ts
5535
5552
  async function previewLand(thread) {
5536
5553
  if (thread.sourceIsFork) {
@@ -6028,13 +6045,14 @@ function formatRenameBranchDirective(thread, opts) {
6028
6045
  if (!isPlaceholderBranch(thread.branchName, thread.worktreePath)) return null;
6029
6046
  const dir = worktreeNameFromPath(thread.worktreePath);
6030
6047
  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`";
6048
+ const prefix = sanitizeGitBranchPrefix(opts?.branchPrefix);
6049
+ const example = examplePrefixedBranch(prefix, ticket);
6050
+ const shape = prefix ? `\`${prefix}/<ticket-or-task>-<short-kebab-description>\`` : "`<ticket-or-task>-<short-kebab-description>`";
6032
6051
  const lines = [
6033
6052
  "Branch naming (do this early in the turn):",
6034
6053
  `- 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}:`,
6054
+ `- Rename the git branch to ${shape}, e.g. \`${example}\`:`,
6036
6055
  " `git branch -m <new-name>`",
6037
- "- Prefer Conventional Commits style prefixes when they fit (`fix/`, `feat/`, `chore/`, `docs/`).",
6038
6056
  ...ticket ? [
6039
6057
  `- Keep ticket \`${ticket}\` in the new branch name so the issue stays findable.`
6040
6058
  ] : [],
@@ -6805,7 +6823,7 @@ function formatScheduledPrompt(name, prompt) {
6805
6823
  ${prompt}`;
6806
6824
  }
6807
6825
  async function defaultDeps() {
6808
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-LWEZ74RK.js");
6826
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-S3M2E7O6.js");
6809
6827
  const orch = getOrchestrator2();
6810
6828
  return {
6811
6829
  findThread: (id) => findThreadByRef(id),
@@ -7080,7 +7098,7 @@ var Orchestrator = class {
7080
7098
  orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
7081
7099
  });
7082
7100
  }
7083
- const { autoCleanupOrphansEnabled } = await import("./app-settings-663VQWUV.js");
7101
+ const { autoCleanupOrphansEnabled } = await import("./app-settings-5KHVKJKO.js");
7084
7102
  if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
7085
7103
  await cleanupOrphanWorktrees({ repoPaths });
7086
7104
  }
@@ -7359,7 +7377,7 @@ var Orchestrator = class {
7359
7377
  }
7360
7378
  await setup;
7361
7379
  if (skipSetup) return;
7362
- const { autoRunAfterSetupEnabled } = await import("./app-settings-663VQWUV.js");
7380
+ const { autoRunAfterSetupEnabled } = await import("./app-settings-5KHVKJKO.js");
7363
7381
  if (autoRunAfterSetupEnabled()) {
7364
7382
  try {
7365
7383
  await this.startDev(threadId);
@@ -7682,7 +7700,7 @@ var Orchestrator = class {
7682
7700
  }
7683
7701
  const isBrightsy = fresh.agent === "brightsy";
7684
7702
  const isOrchestration = isOrchestratorThread(fresh);
7685
- const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-663VQWUV.js");
7703
+ const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-5KHVKJKO.js");
7686
7704
  const gitAuthMode = getGithubGitAuthMode();
7687
7705
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
7688
7706
  githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
@@ -7718,9 +7736,16 @@ var Orchestrator = class {
7718
7736
  }
7719
7737
  }
7720
7738
  const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
7721
- const renameBranchDirective = !isBrightsy && !isOrchestration && autoRenameBranchEnabled() ? formatRenameBranchDirective(fresh, {
7722
- customPrompt: settings?.prompts?.renameBranch
7723
- }) : null;
7739
+ let renameBranchDirective = null;
7740
+ if (!isBrightsy && !isOrchestration && autoRenameBranchEnabled()) {
7741
+ const { resolveGitBranchPrefix } = await import("./branch-prefix-N3KTCRCE.js");
7742
+ renameBranchDirective = formatRenameBranchDirective(fresh, {
7743
+ customPrompt: settings?.prompts?.renameBranch,
7744
+ branchPrefix: resolveGitBranchPrefix({
7745
+ setting: gitBranchPrefixSetting()
7746
+ })
7747
+ });
7748
+ }
7724
7749
  let seed = null;
7725
7750
  if (!fresh.sessionId) {
7726
7751
  const prior = fresh.messages.slice(0, -1);
@@ -7815,7 +7840,7 @@ var Orchestrator = class {
7815
7840
  if (!this.stoppedTurns.has(threadId) && this.requireThread(threadId).agent === "cursor" && exitCode !== 0 && !assistantText && parts.length === 0) {
7816
7841
  const sessionId = result.sessionId || this.requireThread(threadId).sessionId || "";
7817
7842
  if (sessionId) {
7818
- const { recoverFinishedCursorRun } = await import("./cursor-recover-NDMLLNYX.js");
7843
+ const { recoverFinishedCursorRun } = await import("./cursor-recover-DTQAUDGO.js");
7819
7844
  for (let i = 0; i < 8; i++) {
7820
7845
  const recovered = recoverFinishedCursorRun({
7821
7846
  agentId: sessionId,
@@ -8608,7 +8633,7 @@ var Orchestrator = class {
8608
8633
  updateThread(thread.id, { title: meta.title });
8609
8634
  }
8610
8635
  }
8611
- const { autoArchiveOnMergeEnabled } = await import("./app-settings-663VQWUV.js");
8636
+ const { autoArchiveOnMergeEnabled } = await import("./app-settings-5KHVKJKO.js");
8612
8637
  const latest = this.requireThread(thread.id);
8613
8638
  if (!shouldAutoArchiveOnPrMerge({
8614
8639
  previousPrState: prevState || null,
@@ -8750,9 +8775,9 @@ var Orchestrator = class {
8750
8775
  return tab;
8751
8776
  }
8752
8777
  /**
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.
8778
+ * Desktop git buttons + MCP `ask_git`. Always queues the worktree agent
8779
+ * with the action prompt (same path as Resolve). Repository `[prompts]`
8780
+ * overrides apply when set.
8756
8781
  */
8757
8782
  async askGit(threadRef, action) {
8758
8783
  if (!AGENT_GIT_ACTIONS.includes(action)) {
@@ -8770,17 +8795,6 @@ var Orchestrator = class {
8770
8795
  "No pull request linked. Ask the worktree agent to open a draft PR first (ask_git create-draft)."
8771
8796
  );
8772
8797
  }
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
8798
  let prBase;
8785
8799
  if (action === "resolve-conflicts") {
8786
8800
  try {
@@ -8789,42 +8803,18 @@ var Orchestrator = class {
8789
8803
  } catch {
8790
8804
  }
8791
8805
  }
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);
8806
+ const settings = loadWorkspaceSettings(thread.worktreePath, thread.repoPath);
8807
+ return this.send(
8808
+ threadRef,
8809
+ resolveSidebarGitPrompt(action, {
8810
+ prBase,
8811
+ createPr: settings?.prompts?.createPr,
8812
+ resolveMergeConflicts: settings?.prompts?.resolveMergeConflicts
8813
+ }),
8814
+ {
8815
+ followUp: resolveOrchChildFollowUp()
8816
+ }
8817
+ );
8828
8818
  }
8829
8819
  setThreadOptions(threadRef, patch) {
8830
8820
  const thread = this.requireThread(threadRef);
@@ -8935,7 +8925,7 @@ var Orchestrator = class {
8935
8925
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
8936
8926
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
8937
8927
  try {
8938
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ZYPME3YD.js");
8928
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-URMUVGAQ.js");
8939
8929
  await ensureWorkspace2(thread.repoPath);
8940
8930
  } catch {
8941
8931
  }
@@ -8962,7 +8952,7 @@ var Orchestrator = class {
8962
8952
  await runArchiveScript(thread.repoPath, thread.worktreePath);
8963
8953
  } catch {
8964
8954
  }
8965
- const { deleteBranchOnPurgeEnabled } = await import("./app-settings-663VQWUV.js");
8955
+ const { deleteBranchOnPurgeEnabled } = await import("./app-settings-5KHVKJKO.js");
8966
8956
  const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
8967
8957
  await removeWorktree(thread.repoPath, thread.worktreePath, {
8968
8958
  deleteBranch: deleteBranch ? thread.branchName : void 0
@@ -8977,7 +8967,7 @@ var Orchestrator = class {
8977
8967
  throw new Error("Thread is not archived");
8978
8968
  }
8979
8969
  if (isGlobalThread(thread)) {
8980
- const { globalAgentCwd } = await import("./paths-53TLA7VQ.js");
8970
+ const { globalAgentCwd } = await import("./paths-LOXCISLX.js");
8981
8971
  updateThread(thread.id, { worktreePath: globalAgentCwd() });
8982
8972
  const restored2 = setStatus(thread.id, "idle");
8983
8973
  this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
@@ -8989,7 +8979,7 @@ var Orchestrator = class {
8989
8979
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
8990
8980
  );
8991
8981
  }
8992
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-LPWTX2NA.js");
8982
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-RM6UWNGZ.js");
8993
8983
  const slug = thread.worktreePath.split("/").pop();
8994
8984
  const dest = thread.worktreePath;
8995
8985
  await withRepoGitLock(thread.repoPath, async () => {
@@ -9099,7 +9089,7 @@ async function startOrchestration(opts) {
9099
9089
  sourceRef: "default",
9100
9090
  ...createOpts
9101
9091
  }).catch(async () => {
9102
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-LPWTX2NA.js");
9092
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-RM6UWNGZ.js");
9103
9093
  const repo = await resolveRepoRoot2(repoPath);
9104
9094
  const def = await resolveDefaultBranch2(repo);
9105
9095
  return orch.createThread({
@@ -9109,7 +9099,7 @@ async function startOrchestration(opts) {
9109
9099
  repoPath: repo
9110
9100
  });
9111
9101
  });
9112
- const { updateThread: upd } = await import("./thread-store-RXXNSRVO.js");
9102
+ const { updateThread: upd } = await import("./thread-store-M4B52FUS.js");
9113
9103
  const updated = upd(thread.id, {
9114
9104
  sourceType: "orchestration",
9115
9105
  sourceRef: goal
@@ -9168,6 +9158,7 @@ export {
9168
9158
  spawnAgentTurn,
9169
9159
  AGENT_GIT_ACTIONS,
9170
9160
  agentGitPrompt,
9161
+ resolveSidebarGitPrompt,
9171
9162
  CHARS_PER_CONTEXT_TOKEN,
9172
9163
  estimateMessageChars,
9173
9164
  estimateThreadChars,
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  isWorkspaceScratchPath
3
3
  } from "./chunk-6K64FJDD.js";
4
+ import {
5
+ ensureWorktreeSideboardIgnored
6
+ } from "./chunk-QQKDGPUI.js";
4
7
  import {
5
8
  getGithubGitAuthMode,
6
9
  getGithubPat
7
- } from "./chunk-J7LQVLFQ.js";
10
+ } from "./chunk-S5GLSRLP.js";
8
11
  import {
9
12
  listThreads
10
- } from "./chunk-TCQAFTSV.js";
13
+ } from "./chunk-KJBYIIJU.js";
11
14
  import {
12
15
  worktreesRoot
13
- } from "./chunk-EFVFB2AH.js";
14
- import {
15
- ensureWorktreeSideboardIgnored
16
- } from "./chunk-QQKDGPUI.js";
16
+ } from "./chunk-WFUDY6PC.js";
17
17
  import {
18
18
  gh,
19
19
  git,
@@ -1,6 +1,9 @@
1
1
  import {
2
2
  stripNestedElectronEnv
3
3
  } from "./chunk-4TR3HZFT.js";
4
+ import {
5
+ sanitizeGitBranchPrefix
6
+ } from "./chunk-WDRMZKVB.js";
4
7
  import {
5
8
  chmodOwnerOnly,
6
9
  writePrivateFile
@@ -10,7 +13,7 @@ import {
10
13
  } from "./chunk-77WWLBCI.js";
11
14
  import {
12
15
  appDataDir
13
- } from "./chunk-EFVFB2AH.js";
16
+ } from "./chunk-WFUDY6PC.js";
14
17
 
15
18
  // src/store/app-settings.ts
16
19
  import { randomUUID } from "crypto";
@@ -723,6 +726,10 @@ function normalizeAdvanced(raw) {
723
726
  if (typeof source.autoRenameBranch === "boolean") {
724
727
  out.autoRenameBranch = source.autoRenameBranch;
725
728
  }
729
+ if (typeof source.branchPrefix === "string") {
730
+ const prefix = sanitizeGitBranchPrefix(source.branchPrefix);
731
+ if (prefix) out.branchPrefix = prefix;
732
+ }
726
733
  if (typeof source.autoRunAfterSetup === "boolean") {
727
734
  out.autoRunAfterSetup = source.autoRunAfterSetup;
728
735
  }
@@ -1589,6 +1596,13 @@ function updateAdvancedSettings(patch) {
1589
1596
  if (typeof patch.autoRenameBranch === "boolean") {
1590
1597
  advanced.autoRenameBranch = patch.autoRenameBranch;
1591
1598
  }
1599
+ if (patch.branchPrefix === null || patch.branchPrefix === "") {
1600
+ delete advanced.branchPrefix;
1601
+ } else if (typeof patch.branchPrefix === "string") {
1602
+ const prefix = sanitizeGitBranchPrefix(patch.branchPrefix);
1603
+ if (prefix) advanced.branchPrefix = prefix;
1604
+ else delete advanced.branchPrefix;
1605
+ }
1592
1606
  if (typeof patch.autoRunAfterSetup === "boolean") {
1593
1607
  advanced.autoRunAfterSetup = patch.autoRunAfterSetup;
1594
1608
  }
@@ -1649,6 +1663,9 @@ function updateAdvancedSettings(patch) {
1649
1663
  function autoRenameBranchEnabled(settings = loadAppSettings()) {
1650
1664
  return settings.advanced.autoRenameBranch !== false;
1651
1665
  }
1666
+ function gitBranchPrefixSetting(settings = loadAppSettings()) {
1667
+ return sanitizeGitBranchPrefix(settings.advanced.branchPrefix);
1668
+ }
1652
1669
  function autoRunAfterSetupEnabled(settings = loadAppSettings()) {
1653
1670
  return Boolean(settings.advanced.autoRunAfterSetup);
1654
1671
  }
@@ -1862,6 +1879,7 @@ export {
1862
1879
  brightsyCloudConnectAgent,
1863
1880
  updateAdvancedSettings,
1864
1881
  autoRenameBranchEnabled,
1882
+ gitBranchPrefixSetting,
1865
1883
  autoRunAfterSetupEnabled,
1866
1884
  caffeinateWhileRunningEnabled,
1867
1885
  caffeinateWhileSlackListenEnabled,