@sideboard-ai/core 0.1.168 → 0.1.170

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 (35) hide show
  1. package/dist/{abletime-BMS53RIZ.js → abletime-ESVTHTFH.js} +2 -2
  2. package/dist/{abletime-AGF54TNA.js → abletime-IC2V7CNB.js} +2 -2
  3. package/dist/{agents-TSO4MB3X.js → agents-GOBVOXFG.js} +9 -9
  4. package/dist/{agents-KWJXZAHB.js → agents-ZCIMZHXZ.js} +9 -9
  5. package/dist/{app-settings-BRLZQA7N.js → app-settings-LF3TS7XS.js} +5 -1
  6. package/dist/{app-settings-JJQDWPEK.js → app-settings-VMOTQORT.js} +5 -1
  7. package/dist/{chunk-74TWOSQP.js → chunk-3C4B52TS.js} +78 -42
  8. package/dist/{chunk-CVZ4KXVP.js → chunk-7IUO67CW.js} +122 -2
  9. package/dist/{chunk-HSGSQA42.js → chunk-DHPZW2EA.js} +8 -34
  10. package/dist/{chunk-KJFFQAMA.js → chunk-DKLGWRWC.js} +1 -1
  11. package/dist/{chunk-NYMFNUT5.js → chunk-GQHVICNT.js} +194 -147
  12. package/dist/{chunk-ILXKJ4ZD.js → chunk-NB7TEKCF.js} +1 -1
  13. package/dist/{chunk-RS756MKF.js → chunk-P2VCMIZU.js} +8 -34
  14. package/dist/{chunk-UIR4VDYA.js → chunk-SAZIRJR4.js} +30 -10
  15. package/dist/{chunk-UVLPL2FJ.js → chunk-TEI72FYD.js} +198 -216
  16. package/dist/{chunk-3A54S244.js → chunk-UDEWGTP6.js} +29 -10
  17. package/dist/{chunk-TW5A2HFY.js → chunk-Y7DJA3UW.js} +78 -42
  18. package/dist/{chunk-LTXS26K5.js → chunk-YMF5WCIA.js} +122 -2
  19. package/dist/{coordinator-prompt-75N74HAO.js → coordinator-prompt-JTDCEU74.js} +3 -3
  20. package/dist/{coordinator-prompt-Y372QRFE.js → coordinator-prompt-RRUU2OYO.js} +3 -3
  21. package/dist/{global-workspace-JNNFVSP7.js → global-workspace-4SI3CRRT.js} +3 -3
  22. package/dist/{global-workspace-TPE4LKVM.js → global-workspace-ZF6EJAM3.js} +3 -3
  23. package/dist/index.cjs +421 -278
  24. package/dist/index.d.cts +135 -37
  25. package/dist/index.d.ts +135 -37
  26. package/dist/index.js +33 -19
  27. package/dist/mcp/run-stdio.cjs +401 -207
  28. package/dist/mcp/run-stdio.js +8 -8
  29. package/dist/{orchestrator-XG3QCMOS.js → orchestrator-LE6L6MJC.js} +5 -5
  30. package/dist/{orchestrator-IIME6KXQ.js → orchestrator-UZSFTDKA.js} +5 -5
  31. package/dist/{workspaces-2IGQNFPL.js → workspaces-A7C3WA54.js} +3 -3
  32. package/dist/{workspaces-BWZSDSGG.js → workspaces-NOC2MWQV.js} +3 -3
  33. package/dist/{worktree-7X7XNSYL.js → worktree-GXO2VDQF.js} +12 -4
  34. package/dist/{worktree-5BFEK6PF.js → worktree-PODE23PD.js} +12 -4
  35. package/package.json +1 -1
@@ -33,7 +33,7 @@ import {
33
33
  summarizeTurnStderr,
34
34
  toolDescription,
35
35
  turnFailChatText
36
- } from "./chunk-3A54S244.js";
36
+ } from "./chunk-UDEWGTP6.js";
37
37
  import {
38
38
  extractPresentedPlan,
39
39
  readPlanFile,
@@ -45,9 +45,7 @@ import {
45
45
  import {
46
46
  SLACK_REPLY_FORMATTING,
47
47
  addWorkspace,
48
- assertOrchestratorCapableAgent,
49
48
  attachmentsFromWorktreePaths,
50
- coerceOrchestratorAgent,
51
49
  coordinatorSystemPrompt,
52
50
  coordinatorTurnReminder,
53
51
  createGlobalChat,
@@ -58,7 +56,6 @@ import {
58
56
  isCloudCoordinatorThread,
59
57
  isGlobalRepoPath,
60
58
  isGlobalThread,
61
- isOrchestratorCapableAgent,
62
59
  isOrchestratorThread,
63
60
  isSlackCoordinatorThread,
64
61
  orchestratorSessionPoisonedByBuiltins,
@@ -67,7 +64,7 @@ import {
67
64
  stageAbsolutePathsAsAttachments,
68
65
  stageBuffersAsAttachments,
69
66
  syncWorkspacesFromThreads
70
- } from "./chunk-RS756MKF.js";
67
+ } from "./chunk-P2VCMIZU.js";
71
68
  import {
72
69
  addPrStackLayer,
73
70
  allocateTeamName,
@@ -112,10 +109,12 @@ import {
112
109
  resolveRepoRoot,
113
110
  takenSlugsFromThread,
114
111
  threadDisplayLabel,
112
+ ticketSlugForBranch,
115
113
  withRepoGitLock,
116
114
  worktreeDisplayLabelForGroup,
117
- worktreeNameFromPath
118
- } from "./chunk-TW5A2HFY.js";
115
+ worktreeNameFromPath,
116
+ worktreeSlugForTicket
117
+ } from "./chunk-Y7DJA3UW.js";
119
118
  import {
120
119
  ATTACHMENTS_DIR,
121
120
  DETACHED_JOBS_DIR,
@@ -146,12 +145,15 @@ import {
146
145
  run
147
146
  } from "./chunk-FNQNJOHY.js";
148
147
  import {
148
+ assertOrchestratorCapableAgent,
149
149
  childEnvWithAppSettings,
150
+ coerceOrchestratorAgent,
150
151
  formatViewerContextDirective,
151
152
  formatViewerContextReminder,
152
153
  getIssueSource,
153
154
  isAbleTimeConnected,
154
155
  isLinearConnected,
156
+ isOrchestratorCapableAgent,
155
157
  isSecureFileEncrypted,
156
158
  loadAppSettings,
157
159
  orchestrationQuotaFallbackAgent,
@@ -159,13 +161,13 @@ import {
159
161
  readSecureJson,
160
162
  resolveEffectiveIssueSource,
161
163
  resolveNewThreadOptions,
162
- resolveThreadDefaults,
164
+ resolveOrchestratorDefaults,
163
165
  resolveVaultKey,
164
166
  resolveViewerProfileForRepo,
165
167
  stripNestedElectronEnv,
166
168
  updateAdvancedSettings,
167
169
  writeSecureJson
168
- } from "./chunk-LTXS26K5.js";
170
+ } from "./chunk-YMF5WCIA.js";
169
171
  import {
170
172
  writePrivateFile
171
173
  } from "./chunk-NSTQ6QKD.js";
@@ -399,7 +401,7 @@ async function continueSourceThread(threadId, prompt) {
399
401
  await continueOnReply(threadId, prompt);
400
402
  return;
401
403
  }
402
- const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-XG3QCMOS.js");
404
+ const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-LE6L6MJC.js");
403
405
  await getOrchestrator2().send(threadId, prompt);
404
406
  } catch {
405
407
  }
@@ -742,9 +744,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
742
744
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
743
745
  );
744
746
  }
745
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-JNNFVSP7.js");
747
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-4SI3CRRT.js");
746
748
  if (isGlobalThread2(thread)) {
747
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-Y372QRFE.js");
749
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-RRUU2OYO.js");
748
750
  ensureGlobalCoordinatorCwd2(
749
751
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
750
752
  );
@@ -955,6 +957,51 @@ function agentGitPrompt(action, opts) {
955
957
  return "Merge PR.";
956
958
  }
957
959
  }
960
+ var RESOLVE_CONFLICTS_RE = /^Merge the remote branch(?: \(([^)]+)\))? into your branch and resolve conflicts\. Then, commit and push your changes\.$/;
961
+ function gitActionExpansion(action, base) {
962
+ switch (action) {
963
+ case "commit-push":
964
+ return "Commit any uncommitted work with a purpose-stating message, then push to origin (`git push -u origin HEAD`; this updates an existing PR when one is linked). Do not start a checks loop unless a goal was given.";
965
+ case "create-draft":
966
+ return "Commit, push, then create a draft PR with `gh pr create --draft -R <origin-owner/name>` (title/body from the change purpose). Update the existing PR instead if one is linked.";
967
+ case "create-web":
968
+ return "Commit, push, then `gh pr create --web -R <origin-owner/name>`.";
969
+ case "resolve-conflicts":
970
+ return `Fetch the PR base${base ? ` (\`${base}\`)` : ""}, merge it into this branch, resolve conflicts carefully, then commit and push until the PR is mergeable.`;
971
+ case "merge":
972
+ return "This phrase is the explicit ask to merge this thread's open pull request on GitHub. If `gh stack view` shows a stack, use `gh stack merge`; otherwise `gh pr merge` (respect repo defaults / squash vs merge). Do not force-push main/master or merge locally into the main checkout.";
973
+ }
974
+ }
975
+ function expandCanonicalGitRequest(prompt) {
976
+ const trimmed = prompt.trim();
977
+ let action = null;
978
+ let base = null;
979
+ for (const candidate of AGENT_GIT_ACTIONS) {
980
+ if (candidate === "resolve-conflicts") continue;
981
+ if (agentGitPrompt(candidate) === trimmed) {
982
+ action = candidate;
983
+ break;
984
+ }
985
+ }
986
+ if (!action) {
987
+ const m = RESOLVE_CONFLICTS_RE.exec(trimmed);
988
+ if (m) {
989
+ action = "resolve-conflicts";
990
+ base = m[1] ?? null;
991
+ }
992
+ }
993
+ let expansion = action ? gitActionExpansion(action, base) : null;
994
+ if (!expansion && trimmed === "Address review comments.") {
995
+ expansion = "Read the PR review feedback (`gh pr view --comments`, `gh api` review comments), make the requested changes, commit, and push.";
996
+ } else if (!expansion && FIX_CI_RE.test(trimmed)) {
997
+ expansion = "Investigate that failing check (`gh pr checks`, `gh run view --log-failed`), fix it, commit, and push. Loop only if a goal to keep going until it passes was given.";
998
+ }
999
+ if (!expansion) return prompt;
1000
+ return `${trimmed}
1001
+
1002
+ (Sideboard git request \u2014 do not ask for clarification: ${expansion})`;
1003
+ }
1004
+ var FIX_CI_RE = /^Fix CI: .+\.$/;
958
1005
 
959
1006
  // src/git/pr-merge-archive.ts
960
1007
  function normalizePrState(state) {
@@ -1196,47 +1243,84 @@ function formatToolPart(t, detail) {
1196
1243
  }
1197
1244
  function formatMessagesAsTranscript(messages, opts) {
1198
1245
  const tools = opts?.tools ?? "full";
1199
- const blocks = [];
1200
- for (const m of messages) {
1201
- if (m.role === "summary") {
1202
- blocks.push(`## Prior summary
1203
- ${m.text}`);
1204
- continue;
1205
- }
1206
- if (m.role === "user") {
1207
- blocks.push(`### User
1246
+ const thinking = opts?.thinking ?? true;
1247
+ return messages.map((m) => formatMessageBlock(m, { tools, thinking })).join("\n\n");
1248
+ }
1249
+ function formatMessageBlock(m, opts) {
1250
+ if (m.role === "summary") return `## Prior summary
1251
+ ${m.text}`;
1252
+ if (m.role === "user") return `### User
1253
+ ${m.text}`;
1254
+ const bits = [];
1255
+ if (m.text?.trim()) {
1256
+ bits.push(`### Agent
1208
1257
  ${m.text}`);
1209
- continue;
1210
- }
1211
- const bits = [];
1212
- if (m.text?.trim()) {
1213
- bits.push(`### Agent
1214
- ${m.text}`);
1215
- } else {
1216
- bits.push("### Agent");
1217
- }
1218
- const thinking = (m.parts ?? []).filter((p) => p.type === "thinking");
1219
- for (const th of thinking) {
1258
+ } else {
1259
+ bits.push("### Agent");
1260
+ }
1261
+ if (opts.thinking) {
1262
+ for (const th of m.parts ?? []) {
1220
1263
  if (th.type !== "thinking" || !th.text.trim()) continue;
1221
1264
  bits.push("Thinking:");
1222
1265
  bits.push(th.text);
1223
1266
  }
1224
- const toolParts = (m.parts ?? []).filter(
1225
- (p) => p.type === "tool"
1226
- );
1227
- if (tools !== "none" && toolParts.length > 0) {
1228
- if (tools === "summary") bits.push("Tools:");
1229
- for (const t of toolParts) {
1230
- bits.push(formatToolPart(t, tools));
1231
- }
1267
+ }
1268
+ const toolParts = (m.parts ?? []).filter(
1269
+ (p) => p.type === "tool"
1270
+ );
1271
+ if (opts.tools !== "none" && toolParts.length > 0) {
1272
+ if (opts.tools === "summary") bits.push("Tools:");
1273
+ for (const t of toolParts) {
1274
+ bits.push(formatToolPart(t, opts.tools));
1232
1275
  }
1233
- blocks.push(bits.join("\n"));
1234
1276
  }
1235
- return blocks.join("\n\n");
1277
+ return bits.join("\n");
1236
1278
  }
1279
+ var SEED_MAX_CHARS = 6e4;
1280
+ var SEED_FULL_TOOL_MESSAGES = 6;
1237
1281
  function buildSessionSeed(messages, opts) {
1238
1282
  if (messages.length === 0) return null;
1239
- const body = formatMessagesAsTranscript(messages, { tools: opts?.tools ?? "full" });
1283
+ const tools = opts?.tools ?? "full";
1284
+ const fullCount = opts?.fullToolMessages ?? SEED_FULL_TOOL_MESSAGES;
1285
+ const maxChars = opts?.maxChars ?? SEED_MAX_CHARS;
1286
+ const olderTools = tools === "none" ? "none" : "summary";
1287
+ const fullFrom = Math.max(0, messages.length - fullCount);
1288
+ const blocks = messages.map(
1289
+ (m, i) => formatMessageBlock(m, {
1290
+ tools: i >= fullFrom ? tools : olderTools,
1291
+ thinking: false
1292
+ })
1293
+ );
1294
+ const keep = new Array(blocks.length).fill(false);
1295
+ let used = 0;
1296
+ for (let i = 0; i < blocks.length; i++) {
1297
+ if (messages[i].role === "summary") {
1298
+ keep[i] = true;
1299
+ used += blocks[i].length + 2;
1300
+ }
1301
+ }
1302
+ for (let i = blocks.length - 1; i >= 0; i--) {
1303
+ if (keep[i]) continue;
1304
+ const next = used + blocks[i].length + 2;
1305
+ if (next > maxChars && used > 0) break;
1306
+ keep[i] = true;
1307
+ used = next;
1308
+ }
1309
+ const dropped = keep.filter((k) => !k).length;
1310
+ const kept = [];
1311
+ let markerPlaced = false;
1312
+ for (let i = 0; i < blocks.length; i++) {
1313
+ if (!keep[i]) continue;
1314
+ if (dropped > 0 && !markerPlaced && messages[i].role !== "summary") {
1315
+ kept.push(`_(${dropped} older message${dropped === 1 ? "" : "s"} omitted for length)_`);
1316
+ markerPlaced = true;
1317
+ }
1318
+ kept.push(blocks[i]);
1319
+ }
1320
+ if (dropped > 0 && !markerPlaced) {
1321
+ kept.push(`_(${dropped} older message${dropped === 1 ? "" : "s"} omitted for length)_`);
1322
+ }
1323
+ const body = kept.join("\n\n");
1240
1324
  if (!body.trim()) return null;
1241
1325
  return [
1242
1326
  "Sideboard conversation context (restored after compaction or a new session):",
@@ -1290,7 +1374,7 @@ function findLastBrightsyContextSummary(messages) {
1290
1374
  function buildBrightsySessionSeed(messages) {
1291
1375
  const match = findLastBrightsyContextSummary(messages);
1292
1376
  const tail = match ? messages.slice(match.index + 1) : messages;
1293
- const body = formatMessagesAsTranscript(tail, { tools: "none" });
1377
+ const body = formatMessagesAsTranscript(tail, { tools: "none", thinking: false });
1294
1378
  if (!match && !body.trim()) return null;
1295
1379
  const blocks = [
1296
1380
  "Sideboard conversation context (restored after compaction or a new session):",
@@ -3359,7 +3443,7 @@ async function createThread(input, _onSetupLine) {
3359
3443
  });
3360
3444
  await requireAgent(resolved.agent);
3361
3445
  if (input.cowboy) {
3362
- const { cowboyModeEnabled } = await import("./app-settings-BRLZQA7N.js");
3446
+ const { cowboyModeEnabled } = await import("./app-settings-LF3TS7XS.js");
3363
3447
  if (!cowboyModeEnabled()) {
3364
3448
  throw new Error(
3365
3449
  "Cowboy mode is off. Enable it in Settings \u2192 Advanced."
@@ -3417,7 +3501,7 @@ async function createThread(input, _onSetupLine) {
3417
3501
  let sourceIsFork = false;
3418
3502
  if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
3419
3503
  if (isAbleTimeConnected() && getIssueSource() === "abletime") {
3420
- const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-BMS53RIZ.js");
3504
+ const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-ESVTHTFH.js");
3421
3505
  const task = await ensureAbleTimeTask({
3422
3506
  title: title?.trim() || "Untitled work",
3423
3507
  description: input.prompt?.trim() || void 0
@@ -3481,10 +3565,11 @@ async function createThread(input, _onSetupLine) {
3481
3565
  throw new Error("Use adoptThread() for adopt sources");
3482
3566
  }
3483
3567
  const team = allocateTeamSlug(repoPath);
3568
+ const slug = sourceType === "ticket" ? worktreeSlugForTicket(persistedSourceRef, team.slug) : team.slug;
3484
3569
  const { branchName, worktreePath } = await createThreadWorktree({
3485
3570
  repoPath,
3486
3571
  sourceRef,
3487
- slug: team.slug
3572
+ slug
3488
3573
  });
3489
3574
  copyConfiguredFiles(repoPath, worktreePath);
3490
3575
  const explicitTitle = title?.trim();
@@ -3924,7 +4009,7 @@ async function adoptThread(input) {
3924
4009
  messages: input.messages ?? []
3925
4010
  });
3926
4011
  writeThread(thread);
3927
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-BWZSDSGG.js");
4012
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-NOC2MWQV.js");
3928
4013
  await ensureWorkspace2(repoPath);
3929
4014
  const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-N5X5I422.js");
3930
4015
  await ensureWorktreeSideboardIgnored2(input.worktreePath);
@@ -5596,7 +5681,7 @@ function expandComposerPrompt(worktreePath, prompt, opts) {
5596
5681
  }
5597
5682
 
5598
5683
  // src/agents/instructions.ts
5599
- import { existsSync as existsSync16, readFileSync as readFileSync12, statSync as statSync4 } from "fs";
5684
+ import { existsSync as existsSync16 } from "fs";
5600
5685
  import { join as join15 } from "path";
5601
5686
 
5602
5687
  // src/skills/detached-job-path.ts
@@ -5642,12 +5727,17 @@ function normPath(p) {
5642
5727
  function formatRenameBranchDirective(thread, opts) {
5643
5728
  if (!isPlaceholderBranch(thread.branchName, thread.worktreePath)) return null;
5644
5729
  const dir = worktreeNameFromPath(thread.worktreePath);
5730
+ const ticket = thread.sourceType === "ticket" ? ticketSlugForBranch(thread.sourceRef ?? "") : null;
5731
+ const example = ticket ? `\`feat/${ticket}-dark-mode\` or \`fix/${ticket}-panel-width\`` : "`fix/panel-width` or `feat/dark-mode`";
5645
5732
  const lines = [
5646
5733
  "Branch naming (do this early in the turn):",
5647
- `- Current branch \`${thread.branchName}\` is a temporary placeholder. The worktree folder \`${dir}\` is a stable soccer-team nickname \u2014 do not rename or leave that directory.`,
5648
- "- Rename the git branch to a short kebab-case name that describes this task (what you are changing), e.g. `fix/panel-width` or `feat/dark-mode`:",
5734
+ `- Current branch \`${thread.branchName}\` is a temporary placeholder. The worktree folder \`${dir}\` is a stable nickname \u2014 do not rename or leave that directory.`,
5735
+ `- Rename the git branch to a short kebab-case name that describes this task (what you are changing), e.g. ${example}:`,
5649
5736
  " `git branch -m <new-name>`",
5650
5737
  "- Prefer Conventional Commits style prefixes when they fit (`fix/`, `feat/`, `chore/`, `docs/`).",
5738
+ ...ticket ? [
5739
+ `- Keep ticket \`${ticket}\` in the new branch name so the issue stays findable.`
5740
+ ] : [],
5651
5741
  "- Never push this placeholder to main/master."
5652
5742
  ];
5653
5743
  const custom = opts?.customPrompt?.trim();
@@ -5681,67 +5771,38 @@ function formatWorktreeDirective(thread, opts) {
5681
5771
  lines.push(
5682
5772
  "- Always use this worktree's `origin` remote (`git remote get-url origin` from this cwd). Never push to or open PRs against `upstream` (template remotes)."
5683
5773
  );
5684
- lines.push(
5685
- "- Push with `git push -u origin HEAD` (or the current branch name). Do not `git push upstream`."
5686
- );
5687
- lines.push("");
5688
5774
  lines.push(formatGitAuthModeDirective(opts?.gitAuthMode ?? "auto"));
5689
5775
  lines.push(
5690
- "- Derive the PR title and body from what the changes actually do and why \u2014 inspect the diff/commits and the user request. Do not use the soccer-team worktree nickname or placeholder branch as the PR title."
5776
+ "- PR title/body and commit messages state what the change does and why (inspect the diff/commits and the user request) \u2014 never the worktree nickname or placeholder branch. Concise imperative title (Conventional Commits when it fits: feat:/fix:/chore:/docs:); body = intent, key changes, test notes."
5691
5777
  );
5692
5778
  lines.push(
5693
- "- Prefer a concise imperative title (Conventional Commits style when it fits: feat:/fix:/chore:/docs:). Body should summarize intent, key changes, and test notes."
5694
- );
5695
- lines.push(
5696
- "- Commit with messages that state the purpose of the change (same standard as the PR). Stay on this thread branch. Never push directly to main/master or merge locally into the main checkout. Do not merge the PR unless this turn is a Merge PR request or the user explicitly asked. When merging, use GitHub from this worktree (`gh pr merge` / `gh stack merge`)."
5779
+ "- Stay on this thread branch. Never push to main/master or merge locally into the main checkout. Merge the PR only when this turn is a Merge PR request or the user explicitly asked \u2014 via GitHub from this worktree (`gh pr merge` / `gh stack merge`)."
5697
5780
  );
5698
5781
  if (thread.prUrl) {
5699
5782
  lines.push(
5700
5783
  `- A PR already exists (${thread.prUrl}). Update it (push + edit title/body if the purpose drifted) instead of opening a duplicate.`
5701
5784
  );
5702
- } else if (opts?.githubSlug) {
5703
- lines.push(
5704
- `- Prefer a draft PR first: \`gh pr create --draft -R ${opts.githubSlug}\` (or update via \`gh pr edit -R ${opts.githubSlug}\`) once the change set is coherent. Always pass \`-R ${opts.githubSlug}\` (this worktree's origin). Bare \`gh pr create\` may target upstream instead of origin on dual-remote checkouts. Mark ready for review only when asked. Title/body must reflect the change purpose, not the worktree name. If GitHub rejects the GraphQL body as too long, retry with a short \`--body-file\` (limit 65,536 characters) \u2014 do not paste a changelog or diff into \`--body\`.`
5705
- );
5706
5785
  } else {
5786
+ const slug = opts?.githubSlug ?? "<origin-owner/name>";
5787
+ const resolve = opts?.githubSlug ? "" : " Resolve `<origin-owner/name>` with `git remote get-url origin` in this worktree.";
5707
5788
  lines.push(
5708
- "- Prefer a draft PR first: `gh pr create --draft -R <origin-owner/name>` (or update via `gh pr edit -R \u2026`) once the change set is coherent. Resolve `<origin-owner/name>` with `git remote get-url origin` in this worktree \u2014 never from `upstream`. Mark ready for review only when asked. Title/body must reflect the change purpose, not the worktree name. If GitHub rejects the GraphQL body as too long, retry with a short `--body-file` (limit 65,536 characters) \u2014 do not paste a changelog or diff into `--body`."
5789
+ `- Prefer a draft PR first: \`gh pr create --draft -R ${slug}\` (update via \`gh pr edit -R ${slug}\`). Always pass \`-R\` \u2014 bare \`gh pr create\` may target upstream on dual-remote checkouts.${resolve} Mark ready for review only when asked. If GitHub rejects the body as too long, retry with a short \`--body-file\` \u2014 do not paste a changelog or diff into \`--body\`.`
5709
5790
  );
5710
5791
  }
5711
- lines.push("");
5712
5792
  lines.push(
5713
- "Short git requests from the Sideboard UI are complete instructions \u2014 expand them using the rules above without asking for clarification:"
5714
- );
5715
- lines.push(
5716
- '- "Commit and push." \u2192 commit any uncommitted work with a purpose-stating message, then push to origin (updates an existing PR if one is linked). Do not start a checks loop unless they gave a goal.'
5717
- );
5718
- lines.push(
5719
- '- "Commit, push, and open a draft PR." \u2192 commit, push, then create a draft PR with `gh pr create --draft -R \u2026` (title/body from the change purpose).'
5720
- );
5721
- lines.push(
5722
- '- "Commit, push, and open a PR in the browser." \u2192 commit, push, then `gh pr create --web -R \u2026`.'
5723
- );
5724
- lines.push(
5725
- '- "Fix CI: <name>." \u2192 investigate that failing check, fix it, commit, and push. Loop only if they gave a goal to keep going until it passes.'
5726
- );
5727
- lines.push(
5728
- '- "Merge the remote branch (<base>) into your branch and resolve conflicts. Then, commit and push your changes." \u2192 fetch the PR base, merge it into this branch, resolve conflicts carefully, commit, and push until the PR is mergeable.'
5729
- );
5730
- lines.push(
5731
- '- "Address review comments." \u2192 read PR review feedback, make the requested changes, commit, and push.'
5732
- );
5733
- lines.push(
5734
- '- "Merge PR." \u2192 merge this thread\'s open pull request on GitHub (this phrase is the explicit ask). If `gh stack view` shows a stack, use `gh stack merge`; otherwise `gh pr merge` (respect repo defaults / squash vs merge). Do not force-push main/master or merge locally into the main checkout.'
5793
+ '- Sideboard git buttons send short phrases ("Commit and push.", "Merge PR.", \u2026) with their meaning attached \u2014 act on them without asking for clarification. If the user gives a goal (Greptile 5/5, CI green, until checks pass), you get the watch-fix-push playbook with that request.'
5735
5794
  );
5736
5795
  lines.push("");
5737
- lines.push(formatPrGateDirective());
5738
- lines.push("");
5739
- lines.push(formatProcessGuideDirective());
5796
+ lines.push(formatProcessGuideDirective({ worktreePath: thread.worktreePath }));
5740
5797
  return lines.join("\n");
5741
5798
  }
5742
5799
  function formatWorktreeReminder() {
5743
5800
  return "Sideboard worktree: stay in this cwd for all file and git work. Push and open PRs against origin, never upstream. Do not edit the main repo checkout. If a goal is given (Greptile 5/5, CI green), watch-fix-push until it lands \u2014 do not watch after every push.";
5744
5801
  }
5802
+ var PR_GOAL_RE = /greptile|\bci\b.*\b(green|pass)|checks?\s+(pass|green)|until\s+.*\b(pass|green|merge|clean)|\bfix ci\b|watch[- ]fix[- ]push/i;
5803
+ function mentionsPrGoal(prompt) {
5804
+ return PR_GOAL_RE.test(prompt);
5805
+ }
5745
5806
  var GITHUB_TICKET_REF = /^(?:#?\d+|gh-\d+)$/i;
5746
5807
  var KEYED_TICKET_REF = /^(?:[A-Z][A-Z0-9]{0,9}-\d+|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i;
5747
5808
  function issueTicketFromThread(thread, preferredSource = "github") {
@@ -5810,29 +5871,27 @@ function formatPrGateDirective() {
5810
5871
  "- Greptile 5/5: wait for the greptile check; read the latest `N/5` from the PR body or Greptile\u2019s most recently *updated* issue comment; also fetch unresolved review comments / the \u201CPrompt to fix all with AI\u201D block. Done = **5/5 and zero unresolved Greptile comments**. If Greptile is idle, comment `@greptile review`. Cap about 5 iterations, then report leftovers. Do not merge unless asked."
5811
5872
  ].join("\n");
5812
5873
  }
5813
- function formatProcessGuideDirective() {
5874
+ function formatProcessGuideDirective(opts) {
5875
+ const worktree = opts?.worktreePath?.trim();
5876
+ const hasGraphSkill = !!worktree && existsSync16(join15(worktree, ".claude/skills/graph-engineering/SKILL.md"));
5877
+ const hasReviewSkill = !!worktree && existsSync16(join15(worktree, ".claude/skills/review/SKILL.md"));
5814
5878
  return [
5815
5879
  "Process guides (recurring work only):",
5816
- "- Long jobs (pack, test, deploy, anything that may run more than ~30s): Sideboard always provides `/long-running`. Detach and wait; `stop_job` if hanging or wrong. Do not ask the human to poll.",
5817
- "- If `.claude/skills/graph-engineering/SKILL.md` exists, follow it (`/graph-engineering`) for migrations, ports, batch fixes, and other fan-out. Judge first; state on disk; grow the rulebook; do not patch around it.",
5818
- "- If this same shape of work will happen again, write `.claude/skills/<kebab-name>/SKILL.md` in this worktree (Claude Code project skill). Sideboard `/name`, Claude Code, and `attach` all load that path. Do not leave the method only in chat.",
5819
- "- Merge-readiness notes: if `.claude/skills/review/SKILL.md` already exists, edit it. Otherwise write them to `.context/review.md` (copied from `.sideboard/review.md` when that file exists). Do not create a review skill.",
5820
- "- Do not write new skills under `.sideboard/skills/` (that folder only \u2014 other `.sideboard/` files such as settings.toml are fine). Point Codex/OpenCode at the Claude skill from `AGENTS.md`. Optional: symlink `.cursor/skills/<name>` to the Claude skill.",
5880
+ hasGraphSkill ? "- Migrations, ports, batch fixes, and other fan-out: follow `.claude/skills/graph-engineering/SKILL.md` (`/graph-engineering`). Judge first; state on disk; grow the rulebook; do not patch around it." : null,
5881
+ "- If this same shape of work will happen again, write `.claude/skills/<kebab-name>/SKILL.md` in this worktree (Claude Code project skill; Sideboard `/name`, Claude Code, and `attach` all load it). Not under `.sideboard/skills/`. Point Codex/OpenCode at it from `AGENTS.md`.",
5882
+ hasReviewSkill ? "- Merge-readiness notes go in `.claude/skills/review/SKILL.md` (edit it; do not create another review skill)." : "- Merge-readiness notes go in `.context/review.md` (copied from `.sideboard/review.md` when that file exists). Do not create a review skill.",
5821
5883
  "- Skip a guide for a one-off. If a matching skill exists, follow it. Same miss twice \u2192 edit the skill, do not patch around it."
5822
- ].join("\n");
5884
+ ].filter(Boolean).join("\n");
5823
5885
  }
5824
5886
  function formatLongRunningDirective(opts) {
5825
5887
  const invoke = formatDetachedJobInvoke(opts?.scriptPath);
5826
5888
  return [
5827
- "Long-running jobs (mandatory when a command may run more than ~30s):",
5828
- "A Sideboard worktree turn SIGTERMs the agent shell (and its process group) when the user sends another message or the turn is interrupted. `block_until_ms: 0` is not enough. Do not ask the human to poll.",
5829
- `Helper (same tool as \`scripts/detached-job.cjs\` when that file exists in the worktree): \`${invoke}\``,
5830
- `- Start once: \`${invoke} start <id> -- <command> [args...]\` (cwd = this worktree). If JSON says already-running, do not start again.`,
5831
- "- Immediately `present_artifact` `type=log` with `artifact_id=<id>` and `status=running` \u2014 the side column is the live view.",
5832
- `- Loop Sideboard MCP \`wait_for_job\` with the same id (returns in ~45s). stillRunning \u2192 present the same id with \`content=delta\` only \u2192 wait_for_job again. Shell fallback: \`${invoke} wait <id>\`. Do not resend the full log or HTML.`,
5833
- `- If it is hanging, producing no useful output, or doing the wrong thing: MCP \`stop_job\` (same id, optional reason) or \`${invoke} stop <id>\`. Do not loop forever. Do not stop a pack/test/deploy that is clearly making progress.`,
5834
- "- Do not end the turn with \u201CI\u2019ll let you know when it\u2019s done.\u201D Stay in the loop until stillRunning is false (or you stopped it).",
5835
- "- ok \u2192 finish the task. failed / stopped \u2192 read the log, fix or narrow the command, start once.",
5889
+ "Long-running jobs (mandatory when a command may run more than ~30s \u2014 pack, test, deploy, `gh pr checks --watch`):",
5890
+ "A Sideboard worktree turn SIGTERMs the agent shell (and its process group) when the user sends another message or the turn is interrupted; `block_until_ms: 0` is not enough. Detach instead, and never ask the human to poll.",
5891
+ `- Start once: \`${invoke} start <id> -- <command> [args...]\` (cwd = this worktree; same tool as \`scripts/detached-job.cjs\` when the worktree has it). If JSON says already-running, do not start again.`,
5892
+ "- Immediately `present_artifact` `type=log` with `artifact_id=<id>` and `status=running`, then loop Sideboard MCP `wait_for_job` (returns in ~45s). stillRunning \u2192 present the same id with `content=delta` only \u2192 wait again. Shell fallback: the same helper with `wait <id>`.",
5893
+ "- Hanging, no useful output, or the wrong thing \u2192 `stop_job` (or the helper with `stop <id>`). Do not stop a pack/test/deploy that is clearly making progress.",
5894
+ "- Stay in the loop until stillRunning is false (or you stopped it). ok \u2192 finish the task. failed / stopped \u2192 read the log, fix or narrow the command, start once.",
5836
5895
  "State: `.context/.sideboard/detached-jobs/<id>/` (local scratch). Full guide: `/long-running` (always available)."
5837
5896
  ].join("\n");
5838
5897
  }
@@ -5842,27 +5901,11 @@ function formatLongRunningReminder(opts) {
5842
5901
  }
5843
5902
  function formatArtifactDirective() {
5844
5903
  return [
5845
- "Sideboard side column (desktop UI):",
5846
- "claude.ai\u2019s \u201CArtifact\u201D tool does NOT exist in Claude Code. That is expected.",
5847
- "Do not unprompted-duplicate a payload. Chat markdown (including tables) already renders in the transcript \u2014 do not also call present_schema with those same rows just to display them. If the user asks for an editable / interactive table, call present_schema even if markdown already showed the data. Do not also call present_artifact for a document you already fenced in chat.",
5848
- "Documents (HTML/SVG/markdown):",
5849
- "1) Emit a fenced code block tagged `html` (preferred), `svg`, or `markdown` with the FULL document \u2014 Sideboard opens a side column. Example:",
5850
- "```html",
5851
- "<!DOCTYPE html><html><head><title>Demo</title></head><body><h1>Hi</h1></body></html>",
5852
- "```",
5853
- "2) Or call Sideboard MCP `present_artifact` with title, type (html|svg|markdown|react|log), and content \u2014 not both a fence and this tool for the same body.",
5854
- " type=log is append-only: same `artifact_id`, `content` = new lines only (plus optional status/phase). Do not resend the full log or wrap it in HTML.",
5855
- "CMS / JSON Schema forms & tables (Brightsy or any schema+schemaUi source):",
5856
- "3) Call Sideboard MCP `present_schema` when the user needs to filter, edit, publish, or persist rows \u2014 including after you already showed a markdown table, if they then ask for an editable table. If they only need to read the data, a markdown table is enough. When you do call it, pass title, mode (table|form), and either:",
5857
- " - datasource=brightsy + resource_id (record type UUID) after fetching types via Brightsy MCP, or",
5858
- " - datasource=inline + resource: { id, title, schema, schemaUi } and optional records/record.",
5859
- "Files / media browser (CMS file manager column):",
5860
- "4) Call Sideboard MCP `present_files` with optional title, path, and datasource (brightsy|memory).",
5861
- " Opens the Files column for browse/upload/pick. Do NOT say a file manager UI is missing.",
5862
- "Multiple-choice questions:",
5863
- "5) Call Sideboard MCP `ask_user` only when work is blocked on choosing among a few concrete options (approach forks, which API, auth vs cookies). First write a short chat message that explains the decision and what each option means (tradeoffs, when to pick it). Include a description on every option. After calling, stop and wait for their next message with answers. If you are asking a real multiple-choice, use ask_user rather than chat bullets so Sideboard shows the composer picker.",
5864
- "Do not call ask_user for greetings, check-ins, \u201Chello\u201D, open-ended how-can-I-help, or to invent a menu of possible next tasks \u2014 reply in chat. If one option is the obvious default, proceed without asking.",
5865
- "Never say artifacts, CMS UI, or the Files column are unavailable. present_schema is for interactive list/edit/publish (use it when they ask to edit, even if chat already had a markdown table); present_files for storage UI; html fences for standalone pages; ask_user only for those blocked predefined-option questions."
5904
+ "Sideboard side column (desktop UI) \u2014 Sideboard MCP tools present_artifact, present_schema, present_files, ask_user (see their descriptions). claude.ai\u2019s \u201CArtifact\u201D tool does not exist here; never say artifacts, the CMS UI, or the Files column are unavailable.",
5905
+ "- Standalone documents: a fenced block tagged `html` (preferred), `svg`, or `markdown` containing the FULL document opens the side column by itself. Use that or present_artifact \u2014 never both for the same body.",
5906
+ "- present_artifact type=log appends: same artifact_id, content = new lines only (plus status/phase). Do not resend the full log or wrap it in HTML.",
5907
+ "- Data: a markdown table is enough to read. Call present_schema only when the user needs to filter/edit/publish/persist rows \u2014 including when they ask for an editable table after you already showed markdown. Never re-present rows you already wrote just to display them.",
5908
+ "- ask_user only when work is blocked on a few concrete options (approach fork, which API, auth vs cookies): first a short chat message explaining the decision and each option, then the call (description on every option), then stop and wait. Not for greetings, check-ins, or an invented menu of next tasks \u2014 reply in chat. If one option is the obvious default, proceed."
5866
5909
  ].join("\n");
5867
5910
  }
5868
5911
  function formatUiReminder() {
@@ -6004,7 +6047,7 @@ async function syncThreadBranchFromGit(threadId) {
6004
6047
 
6005
6048
  // src/store/schedules.ts
6006
6049
  import { randomUUID as randomUUID4 } from "crypto";
6007
- import { existsSync as existsSync17, readFileSync as readFileSync13 } from "fs";
6050
+ import { existsSync as existsSync17, readFileSync as readFileSync12 } from "fs";
6008
6051
  import { join as join16 } from "path";
6009
6052
  import { Cron } from "croner";
6010
6053
  var DURATION_RE = /^(\d+)(s|m|h|d)$/i;
@@ -6117,7 +6160,7 @@ function readAll() {
6117
6160
  const path = schedulesPath();
6118
6161
  if (!existsSync17(path)) return [];
6119
6162
  try {
6120
- const parsed = JSON.parse(readFileSync13(path, "utf8"));
6163
+ const parsed = JSON.parse(readFileSync12(path, "utf8"));
6121
6164
  if (!Array.isArray(parsed)) return [];
6122
6165
  return parsed.map((row) => {
6123
6166
  try {
@@ -6240,7 +6283,7 @@ function formatScheduledPrompt(name, prompt) {
6240
6283
  ${prompt}`;
6241
6284
  }
6242
6285
  async function defaultDeps() {
6243
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-XG3QCMOS.js");
6286
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-LE6L6MJC.js");
6244
6287
  const orch = getOrchestrator2();
6245
6288
  return {
6246
6289
  findThread: (id) => findThreadByRef(id),
@@ -6250,7 +6293,7 @@ async function defaultDeps() {
6250
6293
  }
6251
6294
  function pickAgent(schedule) {
6252
6295
  if (schedule.agent) return schedule.agent;
6253
- return coerceOrchestratorAgent(resolveThreadDefaults().agent);
6296
+ return coerceOrchestratorAgent(resolveOrchestratorDefaults().agent);
6254
6297
  }
6255
6298
  async function fireSchedule(id) {
6256
6299
  const schedule = getSchedule(id);
@@ -6502,7 +6545,7 @@ var Orchestrator = class {
6502
6545
  orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
6503
6546
  });
6504
6547
  }
6505
- const { autoCleanupOrphansEnabled } = await import("./app-settings-BRLZQA7N.js");
6548
+ const { autoCleanupOrphansEnabled } = await import("./app-settings-LF3TS7XS.js");
6506
6549
  if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
6507
6550
  await cleanupOrphanWorktrees({ repoPaths });
6508
6551
  }
@@ -6781,7 +6824,7 @@ var Orchestrator = class {
6781
6824
  }
6782
6825
  await setup;
6783
6826
  if (skipSetup) return;
6784
- const { autoRunAfterSetupEnabled } = await import("./app-settings-BRLZQA7N.js");
6827
+ const { autoRunAfterSetupEnabled } = await import("./app-settings-LF3TS7XS.js");
6785
6828
  if (autoRunAfterSetupEnabled()) {
6786
6829
  try {
6787
6830
  await this.startDev(threadId);
@@ -7064,17 +7107,21 @@ var Orchestrator = class {
7064
7107
  const slackReplyContext = formatSlackRepliesForTurn(
7065
7108
  pendingSlackExternalReplies(thread.messages)
7066
7109
  );
7067
- const agentPrompt = [
7068
- thread.planMode ? PLAN_MODE_INSTRUCTION : null,
7069
- orchestrationReminder,
7110
+ const turnReminders = [
7070
7111
  worktreeReminder,
7071
7112
  optionalServicesReminder,
7072
7113
  issueToolsReminder,
7073
7114
  viewerContextReminder,
7074
7115
  artifactReminder,
7075
- longRunningReminder,
7116
+ longRunningReminder
7117
+ ].filter(Boolean).join("\n\n") || void 0;
7118
+ const prGateDirective = thread.agent !== "brightsy" && !isOrchestratorThread(thread) && mentionsPrGoal(expandedPrompt) ? formatPrGateDirective() : null;
7119
+ const agentPrompt = [
7120
+ thread.planMode ? PLAN_MODE_INSTRUCTION : null,
7121
+ orchestrationReminder,
7122
+ prGateDirective,
7076
7123
  slackReplyContext,
7077
- expandedPrompt
7124
+ expandCanonicalGitRequest(expandedPrompt)
7078
7125
  ].filter(Boolean).join("\n\n");
7079
7126
  if (thread.attachments.length > 0) {
7080
7127
  updateThread(threadId, { attachments: [] });
@@ -7092,7 +7139,7 @@ var Orchestrator = class {
7092
7139
  }
7093
7140
  const isBrightsy = fresh.agent === "brightsy";
7094
7141
  const isOrchestration = isOrchestratorThread(fresh);
7095
- const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-BRLZQA7N.js");
7142
+ const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-LF3TS7XS.js");
7096
7143
  const gitAuthMode = getGithubGitAuthMode();
7097
7144
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
7098
7145
  githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
@@ -7164,7 +7211,7 @@ var Orchestrator = class {
7164
7211
  const stderrTail = [];
7165
7212
  const handle = await spawnAgentTurn(
7166
7213
  fresh,
7167
- { cachedPrefix, prompt: agentPrompt },
7214
+ { cachedPrefix, prompt: agentPrompt, systemPrompt: turnReminders },
7168
7215
  (event) => {
7169
7216
  this.emit({ type: "turn_output", threadId, event });
7170
7217
  noteTurnLiveEvent(threadId, event);
@@ -7273,7 +7320,7 @@ var Orchestrator = class {
7273
7320
  ].filter(Boolean).join("\n\n---\n\n");
7274
7321
  const retryHandle = await spawnAgentTurn(
7275
7322
  retryThread,
7276
- { cachedPrefix: retryPrefix, prompt: agentPrompt },
7323
+ { cachedPrefix: retryPrefix, prompt: agentPrompt, systemPrompt: turnReminders },
7277
7324
  (event) => {
7278
7325
  this.emit({ type: "turn_output", threadId, event });
7279
7326
  if (event.type === "session_id") {
@@ -8004,7 +8051,7 @@ var Orchestrator = class {
8004
8051
  updateThread(thread.id, { title: meta.title });
8005
8052
  }
8006
8053
  }
8007
- const { autoArchiveOnMergeEnabled } = await import("./app-settings-BRLZQA7N.js");
8054
+ const { autoArchiveOnMergeEnabled } = await import("./app-settings-LF3TS7XS.js");
8008
8055
  const latest = this.requireThread(thread.id);
8009
8056
  if (!shouldAutoArchiveOnPrMerge({
8010
8057
  previousPrState: prevState || null,
@@ -8321,7 +8368,7 @@ var Orchestrator = class {
8321
8368
  this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
8322
8369
  if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
8323
8370
  try {
8324
- const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-BWZSDSGG.js");
8371
+ const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-NOC2MWQV.js");
8325
8372
  await ensureWorkspace2(thread.repoPath);
8326
8373
  } catch {
8327
8374
  }
@@ -8348,7 +8395,7 @@ var Orchestrator = class {
8348
8395
  await runArchiveScript(thread.repoPath, thread.worktreePath);
8349
8396
  } catch {
8350
8397
  }
8351
- const { deleteBranchOnPurgeEnabled } = await import("./app-settings-BRLZQA7N.js");
8398
+ const { deleteBranchOnPurgeEnabled } = await import("./app-settings-LF3TS7XS.js");
8352
8399
  const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
8353
8400
  await removeWorktree(thread.repoPath, thread.worktreePath, {
8354
8401
  deleteBranch: deleteBranch ? thread.branchName : void 0
@@ -8375,7 +8422,7 @@ var Orchestrator = class {
8375
8422
  `Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
8376
8423
  );
8377
8424
  }
8378
- const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-7X7XNSYL.js");
8425
+ const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-GXO2VDQF.js");
8379
8426
  const slug = thread.worktreePath.split("/").pop();
8380
8427
  const dest = thread.worktreePath;
8381
8428
  await withRepoGitLock(thread.repoPath, async () => {
@@ -8485,7 +8532,7 @@ async function startOrchestration(opts) {
8485
8532
  sourceRef: "default",
8486
8533
  ...createOpts
8487
8534
  }).catch(async () => {
8488
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-7X7XNSYL.js");
8535
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-GXO2VDQF.js");
8489
8536
  const repo = await resolveRepoRoot2(repoPath);
8490
8537
  const def = await resolveDefaultBranch2(repo);
8491
8538
  return orch.createThread({