@sideboard-ai/core 0.1.320 → 0.1.322

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 (56) hide show
  1. package/dist/agents/cursor-runner.js +2 -2
  2. package/dist/{agents-CJZYJOWP.js → agents-PFVYC36J.js} +8 -8
  3. package/dist/{agents-F2E2HACB.js → agents-ROFDNE7Z.js} +9 -9
  4. package/dist/{chunk-QVN2WOKJ.js → chunk-2TUE6JKQ.js} +12 -0
  5. package/dist/{chunk-B7UL36WH.js → chunk-45UB2J47.js} +335 -65
  6. package/dist/{chunk-DD67JWTN.js → chunk-4YXZOXMT.js} +1 -1
  7. package/dist/{chunk-V5BTGQ6M.js → chunk-6U6QRUHY.js} +1 -1
  8. package/dist/{chunk-QGY3UNNL.js → chunk-7JV5QP5K.js} +1 -1
  9. package/dist/{chunk-DJZRDTZY.js → chunk-BANN5HUX.js} +6 -6
  10. package/dist/{chunk-CB5Z5C3J.js → chunk-BPDVHB4U.js} +1 -1
  11. package/dist/{chunk-RHJPP26T.js → chunk-H6GXYV5Q.js} +14 -11
  12. package/dist/{chunk-4GZC6DDH.js → chunk-IFWGG2M2.js} +7 -0
  13. package/dist/{chunk-LLIEU2ZB.js → chunk-JNEFEA2A.js} +6 -6
  14. package/dist/{chunk-IDPFLXRY.js → chunk-LD2DXHBP.js} +341 -67
  15. package/dist/{chunk-2P4XKWV2.js → chunk-QKHEVSB5.js} +1 -1
  16. package/dist/{chunk-P74GXA5V.js → chunk-RGUZPMTF.js} +6 -6
  17. package/dist/{chunk-UK2KESBN.js → chunk-RHJKZOPQ.js} +3 -3
  18. package/dist/{chunk-HH3VVTEC.js → chunk-S5CJUIPY.js} +5 -5
  19. package/dist/{chunk-5S3YP5KH.js → chunk-SPMIZSKH.js} +14 -11
  20. package/dist/{chunk-EQ5JY3MJ.js → chunk-TEFFR6PB.js} +1 -1
  21. package/dist/{chunk-EDXTP2VR.js → chunk-UWJUARFA.js} +545 -186
  22. package/dist/{chunk-OAFBHCSM.js → chunk-UX6EDDGR.js} +1 -1
  23. package/dist/{chunk-ZYZBCLJR.js → chunk-XDQSHSL6.js} +6 -6
  24. package/dist/{chunk-2UG25RMK.js → chunk-YBTSZ2SW.js} +12 -0
  25. package/dist/{chunk-PNLGWAYE.js → chunk-YWBLQBSN.js} +548 -187
  26. package/dist/{chunk-Y3Y7SZBZ.js → chunk-ZHGMRBSC.js} +1 -1
  27. package/dist/{conductor-FPFY6Z5S.js → conductor-CNT3VL3S.js} +6 -6
  28. package/dist/{conductor-JA5W3L7C.js → conductor-XLXJU24U.js} +6 -6
  29. package/dist/{connected-teams-IHK2WXUI.js → connected-teams-H4LZOJDC.js} +2 -2
  30. package/dist/{connected-teams-IFW3NQ6G.js → connected-teams-XYRZMQO4.js} +2 -2
  31. package/dist/{coordinator-prompt-NUC2ZXMJ.js → coordinator-prompt-D5EE2YTV.js} +5 -5
  32. package/dist/{coordinator-prompt-M75TAN43.js → coordinator-prompt-TU24TQ4I.js} +5 -5
  33. package/dist/{global-workspace-5A4H34AF.js → global-workspace-743TPQNF.js} +5 -5
  34. package/dist/{global-workspace-SCLQUNUI.js → global-workspace-UPMXDQM7.js} +5 -5
  35. package/dist/index.cjs +1577 -471
  36. package/dist/index.d.cts +182 -70
  37. package/dist/index.d.ts +182 -70
  38. package/dist/index.js +480 -62
  39. package/dist/mcp/run-stdio.cjs +1159 -447
  40. package/dist/mcp/run-stdio.js +65 -17
  41. package/dist/{optional-cli-MRNQKVIR.js → optional-cli-2YDQQCCD.js} +4 -4
  42. package/dist/{optional-cli-2V3SLME5.js → optional-cli-USD6PROE.js} +3 -3
  43. package/dist/{orchestrator-NPFWU3XU.js → orchestrator-B4STIW4B.js} +12 -12
  44. package/dist/{orchestrator-7BDZ5GWD.js → orchestrator-VQ4HRYVB.js} +11 -11
  45. package/dist/{run-PCX5QWR4.js → run-7QMRYP3F.js} +3 -1
  46. package/dist/{run-TB7RBII2.js → run-UPNCCRCN.js} +3 -1
  47. package/dist/{thread-store-JWHVXLDX.js → thread-store-3F7GR64A.js} +1 -1
  48. package/dist/{thread-store-QHYN2ZMQ.js → thread-store-JRSL4HQY.js} +1 -1
  49. package/dist/{workspaces-KWMBOTQD.js → workspaces-47WQL5IG.js} +5 -5
  50. package/dist/{workspaces-5QA3YM4L.js → workspaces-75FD4QUR.js} +5 -5
  51. package/dist/{worktree-O6BANO2I.js → worktree-G3E6WP66.js} +10 -8
  52. package/dist/{worktree-7EATHVYQ.js → worktree-PDNPL5CQ.js} +10 -8
  53. package/dist/{worktree-exclude-RXZPTCNH.js → worktree-exclude-INRDQFWV.js} +2 -2
  54. package/dist/{worktree-exclude-5N2KTYIT.js → worktree-exclude-P5NJODWP.js} +2 -2
  55. package/package.json +1 -1
  56. /package/dist/{chunk-XMHMVEIY.js → chunk-B4CDSSRN.js} +0 -0
@@ -14,7 +14,7 @@ import {
14
14
  parseSessionQuotaResetAt,
15
15
  planModeTurnInstruction,
16
16
  resolveQuotaFallbackAgent
17
- } from "./chunk-LLIEU2ZB.js";
17
+ } from "./chunk-JNEFEA2A.js";
18
18
  import {
19
19
  applyWorktreePkgCacheEnv,
20
20
  askBlockStillWaiting,
@@ -52,7 +52,7 @@ import {
52
52
  worktreeDevProcessKey,
53
53
  worktreeRunProcessKey,
54
54
  worktreeSetupProcessKey
55
- } from "./chunk-DJZRDTZY.js";
55
+ } from "./chunk-BANN5HUX.js";
56
56
  import {
57
57
  applyAgentEvent,
58
58
  clipAgentEventForPaint,
@@ -74,7 +74,7 @@ import {
74
74
  import {
75
75
  formatOptionalServicesDirectiveForTurn,
76
76
  formatOptionalServicesReminderForTurn
77
- } from "./chunk-EQ5JY3MJ.js";
77
+ } from "./chunk-TEFFR6PB.js";
78
78
  import {
79
79
  SLACK_REPLY_FORMATTING,
80
80
  addWorkspace,
@@ -99,21 +99,24 @@ import {
99
99
  stageAbsolutePathsAsAttachments,
100
100
  stageBuffersAsAttachments,
101
101
  syncWorkspacesFromThreads
102
- } from "./chunk-RHJPP26T.js";
102
+ } from "./chunk-H6GXYV5Q.js";
103
103
  import {
104
104
  addPrStackLayer,
105
105
  allocateTeamSlug,
106
106
  canonicalizeRepoPath,
107
107
  ciChecksFailed,
108
+ clampGithubPrBody,
108
109
  classifyPrMergeIssue,
109
110
  commitAll,
110
111
  connectedPrSelectors,
111
112
  createExistingBranchWorktree,
112
- createOrUpdatePr,
113
+ createOrUpdateCursorPr,
113
114
  createThreadWorktree,
114
115
  currentBranch,
115
116
  detectGhStack,
116
117
  enqueueByKey,
118
+ ensureGhPreferOrigin,
119
+ entireUsesTrails,
117
120
  fastForwardMainCheckoutIfSafe,
118
121
  fetchOriginForWorktree,
119
122
  fetchPrHead,
@@ -125,8 +128,11 @@ import {
125
128
  getPrForHeadBranch,
126
129
  getPrMeta,
127
130
  getPrStack,
131
+ ghHeadRef,
132
+ ghRepoSelectArgs,
128
133
  initPrStack,
129
134
  isDirty,
135
+ isGhRateLimitError,
130
136
  isSideboardScratchPath,
131
137
  listWorktrees,
132
138
  markPrReady,
@@ -139,11 +145,12 @@ import {
139
145
  resolveDefaultBranch,
140
146
  resolveDiffBaseRef,
141
147
  resolveGithubRepoSlug,
148
+ resolveOriginRemote,
142
149
  resolvePrSelector,
143
150
  resolveRepoRoot,
144
151
  switchWorktreeBranch,
145
152
  withRepoGitLock
146
- } from "./chunk-EDXTP2VR.js";
153
+ } from "./chunk-UWJUARFA.js";
147
154
  import {
148
155
  REVIEW_TAB_TITLE,
149
156
  agentNicknameFromWorktreePath,
@@ -171,7 +178,7 @@ import {
171
178
  worktreeNameFromPath,
172
179
  worktreeSlugForTicket,
173
180
  writeThread
174
- } from "./chunk-4GZC6DDH.js";
181
+ } from "./chunk-IFWGG2M2.js";
175
182
  import {
176
183
  mcpServerIdForPermission,
177
184
  mcpServerPermissionUpdate
@@ -182,7 +189,7 @@ import {
182
189
  import {
183
190
  applyAgentRunnerHeapEnv,
184
191
  packagedMcpDir
185
- } from "./chunk-Y3Y7SZBZ.js";
192
+ } from "./chunk-ZHGMRBSC.js";
186
193
  import {
187
194
  fallbackTurnFailDetail,
188
195
  formatAgentErrorContinuePrompt,
@@ -202,9 +209,10 @@ import {
202
209
  clearStaleIndexLocks,
203
210
  enrichPathWithNpmGlobalBin,
204
211
  ensureAgentPath,
212
+ gh,
205
213
  git,
206
214
  resolveGitDirsForLockRecovery
207
- } from "./chunk-QVN2WOKJ.js";
215
+ } from "./chunk-2TUE6JKQ.js";
208
216
  import {
209
217
  HISTORY_CLEANUP_INTERVAL_HOURS_DEFAULT,
210
218
  applyTurnUsage,
@@ -464,9 +472,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
464
472
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
465
473
  );
466
474
  }
467
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-SCLQUNUI.js");
475
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-UPMXDQM7.js");
468
476
  if (isGlobalThread2(thread)) {
469
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-NUC2ZXMJ.js");
477
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-D5EE2YTV.js");
470
478
  ensureGlobalCoordinatorCwd2(
471
479
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
472
480
  );
@@ -682,7 +690,9 @@ function resolveSidebarGitPrompt(action, opts) {
682
690
  }
683
691
  var RESOLVE_CONFLICTS_RE = /^Merge the remote branch(?: \(([^)]+)\))? into your branch and resolve conflicts\. Then, commit and push your changes\.$/;
684
692
  var MERGE_INTO_RE = /^Merge PR into (.+)\.$/;
685
- function gitActionExpansion(action, base) {
693
+ function gitActionExpansion(action, base, forge) {
694
+ if (forge === "cursor") return cursorGitActionExpansion(action, base);
695
+ if (forge === "entire") return entireGitActionExpansion(action, base);
686
696
  switch (action) {
687
697
  case "commit-push":
688
698
  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.";
@@ -707,7 +717,57 @@ function gitActionExpansion(action, base) {
707
717
  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.";
708
718
  }
709
719
  }
710
- function expandCanonicalGitRequest(prompt) {
720
+ function cursorGitActionExpansion(action, base) {
721
+ switch (action) {
722
+ case "commit-push":
723
+ 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). Use `origin`, not `gh`. Do not start a checks loop unless a goal was given.";
724
+ case "create-draft":
725
+ return "Commit, push, then create a draft PR with `origin pr create --draft --push -R <origin-owner/name> --body-file <short.md>` (title/body from the change purpose). Take the URL from `--json url`. Update the existing PR with `origin pr edit` if one is linked. Do not use `gh`.";
726
+ case "create-web":
727
+ return "Commit, push, then `origin pr create --push -R <origin-owner/name>` and open the URL from `--json url`. Origin has no `--web` form. Add `--draft` when they asked for a draft. Do not use `gh`.";
728
+ case "resolve-conflicts":
729
+ if (base && !isMainishPrBase(base)) {
730
+ return `Fetch \`origin/${base}\` (this PR's base \u2014 not main/master), merge it into this branch, resolve conflicts carefully, then commit and push until the PR is mergeable. Do not merge origin/main.`;
731
+ }
732
+ if (base) {
733
+ return `Fetch the PR base (\`${base}\`), merge it into this branch, resolve conflicts carefully, then commit and push until the PR is mergeable.`;
734
+ }
735
+ return "Look up this PR's base with `origin pr view --json baseRefName` and merge that remote branch into this branch (do not assume main). Resolve conflicts carefully, then commit and push until the PR is mergeable. Do not use `gh`.";
736
+ case "ready-for-review":
737
+ return "This phrase is the explicit ask to mark this thread's draft pull request ready for review on Cursor (`origin pr ready -R <origin-owner/name>`). Update title/body if the purpose drifted. Do not merge. Do not use `gh`.";
738
+ case "merge":
739
+ if (base && !isMainishPrBase(base)) {
740
+ return `This phrase is the explicit ask to merge this thread's open pull request into \`${base}\` on Cursor with \`origin pr merge\`. This PR targets \`${base}\`, not main \u2014 do not use \`origin stack merge\` and do not retarget or merge into main/master. Do not force-push main/master or merge locally into the main checkout. Do not use \`gh\`.`;
741
+ }
742
+ return "This phrase is the explicit ask to merge this thread's open pull request on Cursor. If `origin stack view` shows a stack, use `origin stack merge`; otherwise `origin pr merge`. Do not force-push main/master or merge locally into the main checkout. Do not use `gh`.";
743
+ }
744
+ }
745
+ function entireGitActionExpansion(action, base) {
746
+ switch (action) {
747
+ case "commit-push":
748
+ return "Commit any uncommitted work with a purpose-stating message, then push to origin (`git push -u origin HEAD`). Use `entire`, not `gh` or `origin`. Do not start a checks loop unless a goal was given.";
749
+ case "create-draft":
750
+ return 'Commit, push, then open a Trail with `entire trail create --title "<title>" --body "<short>"` (title/body from the change purpose). Take the URL from `--json`. If this branch already has a trail, `entire trail update` instead of creating another. Trails have no draft flag. Do not use `gh` or `origin`.';
751
+ case "create-web":
752
+ return 'Commit, push, then `entire trail create --title "<title>" --body "<short>"` and open the URL from `--json`. Entire has no `--web` form. Do not use `gh` or `origin`.';
753
+ case "resolve-conflicts":
754
+ if (base && !isMainishPrBase(base)) {
755
+ return `Fetch \`origin/${base}\` (this Trail's base \u2014 not main/master), merge it into this branch, resolve conflicts carefully, then commit and push. Do not merge origin/main.`;
756
+ }
757
+ if (base) {
758
+ return `Fetch the Trail base (\`${base}\`), merge it into this branch, resolve conflicts carefully, then commit and push.`;
759
+ }
760
+ return "Look up this Trail's base with `entire trail show --json` and merge that remote branch into this branch (do not assume main). Resolve conflicts carefully, then commit and push. Do not use `gh`.";
761
+ case "ready-for-review":
762
+ return "This phrase means the Trail should be ready for a person to review. Trails have no draft flag and start open. Update title or body with `entire trail update` if the purpose drifted. Do not approve the trail and do not merge. Do not use `gh`.";
763
+ case "merge":
764
+ if (base && !isMainishPrBase(base)) {
765
+ return `This phrase is the explicit ask to merge this thread's Trail change into \`${base}\` with \`entire trail merge\`. This change targets \`${base}\`, not main \u2014 do not retarget or merge into main/master. Do not force-push main/master or merge locally into the main checkout. Do not use \`gh\`.`;
766
+ }
767
+ return "This phrase is the explicit ask to merge this thread's Trail change with `entire trail merge`. Do not force-push main/master or merge locally into the main checkout. Do not use `gh`.";
768
+ }
769
+ }
770
+ function expandCanonicalGitRequest(prompt, opts) {
711
771
  const trimmed = prompt.trim();
712
772
  let action = null;
713
773
  let base = null;
@@ -732,11 +792,12 @@ function expandCanonicalGitRequest(prompt) {
732
792
  base = m[1]?.trim() || null;
733
793
  }
734
794
  }
735
- let expansion = action ? gitActionExpansion(action, base) : null;
795
+ const forge = opts?.forge ?? null;
796
+ let expansion = action ? gitActionExpansion(action, base, forge) : null;
736
797
  if (!expansion && trimmed === "Address review comments.") {
737
- expansion = "Read the PR review feedback (`gh pr view --comments`, `gh api` review comments), make the requested changes, commit, and push.";
798
+ expansion = forge === "cursor" ? "Read the PR review feedback (`origin pr view --comments`, `origin pr thread list`), make the requested changes, commit, and push. Do not use `gh`." : forge === "entire" ? "Read open findings (`entire trail finding list`), make the requested changes, commit, and push. Do not use `gh` or `entire trail comment` (agent sessions cannot post trail comments)." : "Read the PR review feedback (`gh pr view --comments`, `gh api` review comments), make the requested changes, commit, and push.";
738
799
  } else if (!expansion && FIX_CI_RE.test(trimmed)) {
739
- 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.";
800
+ expansion = forge === "cursor" ? "Investigate that failing check (`origin pr checks`, `origin pr watch`), fix it, commit, and push. Loop only if a goal to keep going until it passes was given. Do not use `gh run`." : forge === "entire" ? "Investigate the blocking gate (`entire trail merge --dry-run`, `entire trail finding list`, `entire trail watch`), fix it, commit, and push. Loop only if a goal to keep going until it passes was given. Do not use `gh run`." : "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.";
740
801
  }
741
802
  if (!expansion) return prompt;
742
803
  return `${trimmed}
@@ -3168,7 +3229,7 @@ async function createThread(input, _onSetupLine) {
3168
3229
  return readThread(thread.id) ?? thread;
3169
3230
  }
3170
3231
  async function listLinearIssues(agent, repoPath) {
3171
- const { getAdapter: getAdapter2 } = await import("./agents-F2E2HACB.js");
3232
+ const { getAdapter: getAdapter2 } = await import("./agents-ROFDNE7Z.js");
3172
3233
  await requireAgent(agent, { requireLinear: true });
3173
3234
  const adapter = getAdapter2(agent);
3174
3235
  if (!adapter.listLinearIssues) {
@@ -3936,7 +3997,7 @@ async function adoptThread(input) {
3936
3997
  throw new Error(`Worktree not found: ${input.worktreePath}`);
3937
3998
  }
3938
3999
  const repoPath = await resolveRepoRoot(input.worktreePath);
3939
- const { stdout: branch } = await import("./run-PCX5QWR4.js").then(
4000
+ const { stdout: branch } = await import("./run-7QMRYP3F.js").then(
3940
4001
  ({ git: git2 }) => git2(["rev-parse", "--abbrev-ref", "HEAD"], input.worktreePath)
3941
4002
  );
3942
4003
  const thread = createEmptyThread({
@@ -3951,9 +4012,9 @@ async function adoptThread(input) {
3951
4012
  messages: input.messages ?? []
3952
4013
  });
3953
4014
  writeThread(thread);
3954
- const { addWorkspace: addWorkspace2 } = await import("./workspaces-KWMBOTQD.js");
4015
+ const { addWorkspace: addWorkspace2 } = await import("./workspaces-47WQL5IG.js");
3955
4016
  await addWorkspace2(repoPath);
3956
- const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-RXZPTCNH.js");
4017
+ const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-INRDQFWV.js");
3957
4018
  await ensureWorktreeSideboardIgnored(input.worktreePath);
3958
4019
  return thread;
3959
4020
  }
@@ -4445,9 +4506,177 @@ function stackAgentDefaultsFrom(input) {
4445
4506
  };
4446
4507
  }
4447
4508
 
4509
+ // src/git/pr-write.ts
4510
+ import { randomBytes } from "crypto";
4511
+ import { unlinkSync as unlinkSync3, writeFileSync as writeFileSync5 } from "fs";
4512
+ import { tmpdir as tmpdir2 } from "os";
4513
+ import { join as join8 } from "path";
4514
+ async function lookupGithubGraphqlReset(cwd) {
4515
+ const result = await gh(["api", "rate_limit"], cwd, { reject: false });
4516
+ if (result.exitCode !== 0 || !result.stdout.trim()) return void 0;
4517
+ try {
4518
+ const data = JSON.parse(result.stdout);
4519
+ const reset = data.resources?.graphql?.reset;
4520
+ return typeof reset === "number" ? reset : void 0;
4521
+ } catch {
4522
+ return void 0;
4523
+ }
4524
+ }
4525
+ async function formatPrCreateFailure(raw, cwd, ctx) {
4526
+ if (!isGhRateLimitError(raw)) {
4527
+ return formatGhLandError(raw, {
4528
+ targetedRepo: ctx?.slug,
4529
+ headRef: ctx?.head
4530
+ });
4531
+ }
4532
+ const resetAt = await lookupGithubGraphqlReset(cwd);
4533
+ return formatGhLandError(raw, {
4534
+ resetAt,
4535
+ targetedRepo: ctx?.slug,
4536
+ headRef: ctx?.head
4537
+ });
4538
+ }
4539
+ async function createCursorPullRequest(worktreePath, slug, opts) {
4540
+ const bodyText = (opts.body ?? opts.title).trim() || opts.title;
4541
+ const bodyFile = join8(
4542
+ tmpdir2(),
4543
+ `sideboard-pr-body-${process.pid}-${randomBytes(6).toString("hex")}.md`
4544
+ );
4545
+ writeFileSync5(bodyFile, bodyText.endsWith("\n") ? bodyText : `${bodyText}
4546
+ `, "utf8");
4547
+ try {
4548
+ return await createOrUpdateCursorPr(worktreePath, slug, {
4549
+ title: opts.title,
4550
+ bodyFile,
4551
+ base: opts.base,
4552
+ head: opts.head,
4553
+ draft: opts.draft
4554
+ });
4555
+ } finally {
4556
+ try {
4557
+ unlinkSync3(bodyFile);
4558
+ } catch {
4559
+ }
4560
+ }
4561
+ }
4562
+ function ghPrCreateAssigneeArgs(assignee) {
4563
+ const raw = assignee?.trim();
4564
+ if (raw && /^(none|unassigned)$/i.test(raw)) return [];
4565
+ return ["--assignee", raw || "@me"];
4566
+ }
4567
+ async function createOrUpdatePr(worktreePath, opts) {
4568
+ const origin = await resolveOriginRemote(worktreePath);
4569
+ if (origin?.forge === "entire") throw entireUsesTrails();
4570
+ const cursorSlug = origin?.forge === "cursor" ? origin.slug : null;
4571
+ if (cursorSlug) return createCursorPullRequest(worktreePath, cursorSlug, opts);
4572
+ await ensureGhPreferOrigin(worktreePath);
4573
+ const slug = await resolveGithubRepoSlug(worktreePath);
4574
+ if (!slug) {
4575
+ throw new Error(
4576
+ "Could not resolve the origin GitHub repo (owner/name) for this worktree. Check that `git remote get-url origin` points at github.com."
4577
+ );
4578
+ }
4579
+ const repoArgs = ghRepoSelectArgs(slug);
4580
+ const headRef = ghHeadRef(slug, opts.head);
4581
+ const branchOnly = opts.head.trim().replace(/^refs\/heads\//, "");
4582
+ const bodyText = clampGithubPrBody(opts.body ?? opts.title);
4583
+ const bodyFile = join8(
4584
+ tmpdir2(),
4585
+ `sideboard-pr-body-${process.pid}-${randomBytes(6).toString("hex")}.md`
4586
+ );
4587
+ writeFileSync5(bodyFile, bodyText.endsWith("\n") ? bodyText : `${bodyText}
4588
+ `, "utf8");
4589
+ const bodyArgs = ["--body-file", bodyFile];
4590
+ try {
4591
+ return await createOrUpdatePrWithBodyFile(worktreePath, {
4592
+ ...opts,
4593
+ slug,
4594
+ repoArgs,
4595
+ headRef,
4596
+ branchOnly,
4597
+ bodyArgs
4598
+ });
4599
+ } finally {
4600
+ try {
4601
+ unlinkSync3(bodyFile);
4602
+ } catch {
4603
+ }
4604
+ }
4605
+ }
4606
+ async function createOrUpdatePrWithBodyFile(worktreePath, opts) {
4607
+ const { slug, repoArgs, headRef, branchOnly, bodyArgs } = opts;
4608
+ const existing = await gh(
4609
+ [...repoArgs, "pr", "view", branchOnly, "--json", "url", "--jq", ".url"],
4610
+ worktreePath,
4611
+ { reject: false }
4612
+ );
4613
+ if (existing.exitCode === 0 && existing.stdout.trim() && !opts.web) {
4614
+ const url2 = existing.stdout.trim();
4615
+ await gh(
4616
+ [
4617
+ ...repoArgs,
4618
+ "pr",
4619
+ "edit",
4620
+ branchOnly,
4621
+ "--title",
4622
+ opts.title,
4623
+ ...bodyArgs
4624
+ ],
4625
+ worktreePath,
4626
+ { reject: false }
4627
+ );
4628
+ return url2;
4629
+ }
4630
+ if (opts.web) {
4631
+ const args2 = [
4632
+ ...repoArgs,
4633
+ "pr",
4634
+ "create",
4635
+ "--web",
4636
+ "--title",
4637
+ opts.title,
4638
+ ...bodyArgs,
4639
+ "--base",
4640
+ opts.base,
4641
+ "--head",
4642
+ headRef
4643
+ ];
4644
+ if (opts.draft) args2.push("--draft");
4645
+ args2.push(...ghPrCreateAssigneeArgs(opts.assignee));
4646
+ await gh(args2, worktreePath, { reject: false });
4647
+ const again = await gh(
4648
+ [...repoArgs, "pr", "view", branchOnly, "--json", "url", "--jq", ".url"],
4649
+ worktreePath,
4650
+ { reject: false }
4651
+ );
4652
+ return again.stdout.trim() || "";
4653
+ }
4654
+ const args = [
4655
+ ...repoArgs,
4656
+ "pr",
4657
+ "create",
4658
+ "--title",
4659
+ opts.title,
4660
+ ...bodyArgs,
4661
+ "--base",
4662
+ opts.base,
4663
+ "--head",
4664
+ headRef
4665
+ ];
4666
+ if (opts.draft) args.push("--draft");
4667
+ args.push(...ghPrCreateAssigneeArgs(opts.assignee));
4668
+ const created = await gh(args, worktreePath, { reject: false });
4669
+ if (created.exitCode !== 0) {
4670
+ const raw = created.stderr.trim() || created.stdout.trim() || "gh pr create failed";
4671
+ throw new Error(await formatPrCreateFailure(raw, worktreePath, { slug, head: headRef }));
4672
+ }
4673
+ const url = created.stdout.trim().split("\n").find((l) => l.startsWith("http")) ?? created.stdout.trim();
4674
+ return url;
4675
+ }
4676
+
4448
4677
  // src/diff/diff.ts
4449
- import { existsSync as existsSync9, mkdirSync, readFileSync as readFileSync6, statSync as statSync2, writeFileSync as writeFileSync5 } from "fs";
4450
- import { dirname as dirname2, join as join8 } from "path";
4678
+ import { existsSync as existsSync9, mkdirSync, readFileSync as readFileSync6, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
4679
+ import { dirname as dirname2, join as join9 } from "path";
4451
4680
  async function inspectGitWorktree(worktreePath) {
4452
4681
  if (!worktreePath || !existsSync9(worktreePath)) return "missing_worktree";
4453
4682
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
@@ -4593,7 +4822,7 @@ new file mode 100644
4593
4822
  };
4594
4823
  }
4595
4824
  async function untrackedPatch(worktreePath, path, maxHunk) {
4596
- const abs = join8(worktreePath, path);
4825
+ const abs = join9(worktreePath, path);
4597
4826
  try {
4598
4827
  const st = statSync2(abs);
4599
4828
  if (st.isFile() && st.size > maxHunk) {
@@ -5065,7 +5294,7 @@ async function getDiff(worktreePath, repoPath, opts) {
5065
5294
  }
5066
5295
  function statWorktreePath(worktreePath, relativePath) {
5067
5296
  assertSafeRelativePath(relativePath);
5068
- const abs = join8(worktreePath, relativePath);
5297
+ const abs = join9(worktreePath, relativePath);
5069
5298
  if (!existsSync9(abs)) return "missing";
5070
5299
  const st = statSync2(abs);
5071
5300
  if (st.isDirectory()) return "dir";
@@ -5107,7 +5336,7 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
5107
5336
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
5108
5337
  assertSafeRelativePath(relativePath);
5109
5338
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
5110
- const abs = join8(worktreePath, relativePath);
5339
+ const abs = join9(worktreePath, relativePath);
5111
5340
  const st = statSync2(abs);
5112
5341
  if (!st.isFile()) {
5113
5342
  throw new Error(`Not a file: ${relativePath}`);
@@ -5127,7 +5356,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
5127
5356
  function readWorktreeFile(worktreePath, relativePath, opts) {
5128
5357
  assertSafeRelativePath(relativePath);
5129
5358
  const maxBytes = opts?.maxBytes ?? 2e5;
5130
- const abs = join8(worktreePath, relativePath);
5359
+ const abs = join9(worktreePath, relativePath);
5131
5360
  const st = statSync2(abs);
5132
5361
  if (!st.isFile()) {
5133
5362
  throw new Error(`Not a file: ${relativePath}`);
@@ -5175,9 +5404,9 @@ function assertSafeRelativePath(relativePath) {
5175
5404
  }
5176
5405
  function writeWorktreeFile(worktreePath, relativePath, content) {
5177
5406
  assertSafeRelativePath(relativePath);
5178
- const abs = join8(worktreePath, relativePath);
5407
+ const abs = join9(worktreePath, relativePath);
5179
5408
  mkdirSync(dirname2(abs), { recursive: true });
5180
- writeFileSync5(abs, content, "utf8");
5409
+ writeFileSync6(abs, content, "utf8");
5181
5410
  return { path: relativePath };
5182
5411
  }
5183
5412
  async function getWorktreeDirtyStat(worktreePath) {
@@ -5369,7 +5598,7 @@ async function confirmLand(thread, opts) {
5369
5598
  if (preview.dirty) {
5370
5599
  committed = await commitAll(thread.worktreePath, meta.commitMessage);
5371
5600
  }
5372
- const { git: git2 } = await import("./run-PCX5QWR4.js");
5601
+ const { git: git2 } = await import("./run-7QMRYP3F.js");
5373
5602
  const { stdout: headOut } = await git2(
5374
5603
  ["rev-parse", "--abbrev-ref", "HEAD"],
5375
5604
  thread.worktreePath,
@@ -5400,13 +5629,13 @@ async function confirmLand(thread, opts) {
5400
5629
 
5401
5630
  // src/diff/read-worktree-tail.ts
5402
5631
  import { closeSync, fstatSync, openSync, readSync } from "fs";
5403
- import { join as join9 } from "path";
5632
+ import { join as join10 } from "path";
5404
5633
  var WORKTREE_TAIL_BYTES = 2e5;
5405
5634
  function readWorktreeFileTail(worktreePath, relativePath, maxBytes = WORKTREE_TAIL_BYTES) {
5406
5635
  if (!relativePath || relativePath.includes("..") || relativePath.startsWith("/")) {
5407
5636
  throw new Error("Invalid path");
5408
5637
  }
5409
- const abs = join9(worktreePath, relativePath);
5638
+ const abs = join10(worktreePath, relativePath);
5410
5639
  const fd = openSync(abs, "r");
5411
5640
  try {
5412
5641
  const st = fstatSync(fd);
@@ -5440,7 +5669,7 @@ function readWorktreeFileTail(worktreePath, relativePath, maxBytes = WORKTREE_TA
5440
5669
  // src/skills/discover.ts
5441
5670
  import { existsSync as existsSync10, readdirSync as readdirSync3, readFileSync as readFileSync7, statSync as statSync3 } from "fs";
5442
5671
  import { homedir } from "os";
5443
- import { join as join10 } from "path";
5672
+ import { join as join11 } from "path";
5444
5673
 
5445
5674
  // src/skills/bundled/long-running.ts
5446
5675
  var LONG_RUNNING_SKILL_COMMAND = "long-running";
@@ -5609,7 +5838,7 @@ function scanSkillsDir(dir, source, out) {
5609
5838
  }
5610
5839
  for (const entry of entries) {
5611
5840
  if (entry.startsWith(".")) continue;
5612
- const skillMd = join10(dir, entry, "SKILL.md");
5841
+ const skillMd = join11(dir, entry, "SKILL.md");
5613
5842
  if (!existsSync10(skillMd)) continue;
5614
5843
  try {
5615
5844
  if (!statSync3(skillMd).isFile()) continue;
@@ -5631,12 +5860,12 @@ function scanClaudePluginSkills(pluginsRoot, out) {
5631
5860
  return;
5632
5861
  }
5633
5862
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
5634
- const skill = readSkill(join10(dir, "SKILL.md"), "cli");
5863
+ const skill = readSkill(join11(dir, "SKILL.md"), "cli");
5635
5864
  if (skill) out.push(skill);
5636
5865
  }
5637
5866
  for (const entry of entries) {
5638
5867
  if (entry === "node_modules" || entry === ".git") continue;
5639
- const full = join10(dir, entry);
5868
+ const full = join11(dir, entry);
5640
5869
  try {
5641
5870
  if (!statSync3(full).isDirectory()) continue;
5642
5871
  } catch {
@@ -5656,17 +5885,17 @@ function discoverSkills(worktreePath) {
5656
5885
  const home = homedir();
5657
5886
  const collected = [];
5658
5887
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
5659
- scanSkillsDir(join10(worktreePath, rel), "workspace", collected);
5888
+ scanSkillsDir(join11(worktreePath, rel), "workspace", collected);
5660
5889
  }
5661
5890
  for (const abs of [
5662
- join10(home, ".claude/skills"),
5663
- join10(home, ".cursor/skills"),
5664
- join10(home, ".sideboard/skills"),
5665
- join10(home, ".brightsy/skills")
5891
+ join11(home, ".claude/skills"),
5892
+ join11(home, ".cursor/skills"),
5893
+ join11(home, ".sideboard/skills"),
5894
+ join11(home, ".brightsy/skills")
5666
5895
  ]) {
5667
5896
  scanSkillsDir(abs, "user", collected);
5668
5897
  }
5669
- scanClaudePluginSkills(join10(home, ".claude/plugins"), collected);
5898
+ scanClaudePluginSkills(join11(home, ".claude/plugins"), collected);
5670
5899
  collected.push(...bundledSkills());
5671
5900
  const rank = {
5672
5901
  workspace: 0,
@@ -5894,7 +6123,7 @@ function promptForJoinedSteer(input) {
5894
6123
  rewriteTrailingUserPrompt(input.threadId, input.promptText, input.latestPrompt);
5895
6124
  const { agentPrompt: expandedLatest } = expandComposerPrompt(
5896
6125
  input.worktreePath,
5897
- expandCanonicalGitRequest(input.latestPrompt),
6126
+ expandCanonicalGitRequest(input.latestPrompt, { forge: input.gitForge }),
5898
6127
  { attachments: input.attachments }
5899
6128
  );
5900
6129
  return input.expandedPrompt && input.agentPrompt.endsWith(input.expandedPrompt) ? input.agentPrompt.slice(0, -input.expandedPrompt.length) + expandedLatest : `${input.agentPrompt}
@@ -5990,11 +6219,33 @@ async function enqueueThreadSend(host, threadRef, prompt, opts) {
5990
6219
 
5991
6220
  // src/agents/instructions.ts
5992
6221
  import { existsSync as existsSync12 } from "fs";
5993
- import { join as join12 } from "path";
6222
+ import { join as join13 } from "path";
6223
+
6224
+ // src/agents/forge-git-directives.ts
6225
+ function formatCursorGitDirective(slug) {
6226
+ const repo = slug?.trim() || "<origin-owner/name>";
6227
+ return [
6228
+ `Git host (Settings \u2192 Git \u2192 Cursor): this checkout is on Cursor (\`origin.cursor.com\`, \`${repo}\`).`,
6229
+ "- Use the `origin` CLI, not `gh`. Where commands overlap, flags follow `gh` (`origin <command> --help`).",
6230
+ "- `origin` already authenticates from `CURSOR_AUTH_TOKEN`, then `CURSOR_API_KEY`, then the login stored in Settings \u2192 Git \u2192 Cursor. Do not read those values, set them, or run `origin auth login` from this turn.",
6231
+ "- Push with `git push -u origin HEAD`. If git asks for credentials, tell the user to open Settings \u2192 Git \u2192 Cursor and choose Configure git (`origin auth setup-git`). Do not wait for a Keychain dialog.",
6232
+ "- Origin has no issue tracker. Tickets for this repo come from Linear or AbleTime via `list_issues`. Do not use `gh issue`."
6233
+ ].join("\n");
6234
+ }
6235
+ function formatEntireGitDirective(slug) {
6236
+ const repo = slug?.trim() || "<origin-owner/name>";
6237
+ return [
6238
+ `Git host (Settings \u2192 Git \u2192 Entire): this checkout is on Entire (\`${repo}\`).`,
6239
+ "- Use the `entire` CLI, not `gh` or `origin`. Trails replace pull requests and GitHub issues.",
6240
+ "- `entire` uses the login from Settings \u2192 Git \u2192 Entire. Do not read tokens, set `ENTIRE_TOKEN`, or run `entire login` from this turn.",
6241
+ "- Push with `git push -u origin HEAD`. If git asks for credentials, tell the user to open Settings \u2192 Git \u2192 Entire and log in. Do not wait for a Keychain dialog.",
6242
+ "- Tickets for this repo are Trails (`entire trail list` / `entire trail show`). Do not use `gh issue`."
6243
+ ].join("\n");
6244
+ }
5994
6245
 
5995
6246
  // src/skills/detached-job-path.ts
5996
6247
  import { existsSync as existsSync11 } from "fs";
5997
- import { dirname as dirname3, join as join11 } from "path";
6248
+ import { dirname as dirname3, join as join12 } from "path";
5998
6249
  import { fileURLToPath } from "url";
5999
6250
  var DETACHED_JOB_FILENAMES = ["detached-job.cjs", "detached-job.js"];
6000
6251
  function compiledModuleDir() {
@@ -6011,7 +6262,7 @@ function compiledModuleDir() {
6011
6262
  }
6012
6263
  function detachedJobScriptIn(dir) {
6013
6264
  for (const name of DETACHED_JOB_FILENAMES) {
6014
- const script = join11(dir, "scripts", name);
6265
+ const script = join12(dir, "scripts", name);
6015
6266
  if (existsSync11(script)) return script;
6016
6267
  }
6017
6268
  return null;
@@ -6121,17 +6372,35 @@ function formatWorktreeDirective(thread, opts) {
6121
6372
  lines.push(
6122
6373
  "- 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)."
6123
6374
  );
6124
- lines.push(formatGitAuthModeDirective(opts?.gitAuthMode ?? "auto"));
6375
+ const cursorRepo = opts?.originForge === "cursor";
6376
+ const entireRepo = opts?.originForge === "entire";
6377
+ if (cursorRepo) {
6378
+ lines.push(formatCursorGitDirective(opts?.originSlug));
6379
+ } else if (entireRepo) {
6380
+ lines.push(formatEntireGitDirective(opts?.originSlug));
6381
+ } else {
6382
+ lines.push(formatGitAuthModeDirective(opts?.gitAuthMode ?? "auto"));
6383
+ }
6125
6384
  lines.push(
6126
6385
  "- 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."
6127
6386
  );
6128
6387
  lines.push(
6129
- "- Stay on this workspace 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`)."
6388
+ cursorRepo ? "- Stay on this workspace 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 Origin from this worktree (`origin pr merge` / `origin stack merge`)." : entireRepo ? "- Stay on this workspace branch. Never push to main/master or merge locally into the main checkout. Merge only when this turn is a Merge PR request or the user explicitly asked \u2014 via Entire from this worktree (`entire trail merge`)." : "- Stay on this workspace 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`)."
6130
6389
  );
6131
6390
  if (thread.prUrl) {
6132
6391
  lines.push(
6133
6392
  `- A PR already exists (${thread.prUrl}). Update it (push + edit title/body if the purpose drifted) instead of opening a duplicate.`
6134
6393
  );
6394
+ } else if (entireRepo) {
6395
+ lines.push(
6396
+ '- Prefer a Trail: `entire trail create --title "<title>" --body "<short>"`. Take the URL from `--json`. If this branch already has a trail, `entire trail update` instead of creating another. Trails have no draft state. Do not use `gh` or `origin`.'
6397
+ );
6398
+ } else if (cursorRepo) {
6399
+ const slug = opts?.originSlug?.trim() || "<origin-owner/name>";
6400
+ const resolve = opts?.originSlug?.trim() ? "" : " Resolve `<origin-owner/name>` with `git remote get-url origin` in this worktree.";
6401
+ lines.push(
6402
+ `- Prefer a draft PR first: \`origin pr create --draft --push -R ${slug}\` (update via \`origin pr edit -R ${slug}\`). Take the URL from \`--json url\` \u2014 do not build it. Do not use \`gh\`.${resolve} Mark ready only when asked (\`origin pr ready\`). If the body is too long, retry with a short \`--body-file\`.`
6403
+ );
6135
6404
  } else {
6136
6405
  const slug = opts?.githubSlug ?? "<origin-owner/name>";
6137
6406
  const resolve = opts?.githubSlug ? "" : " Resolve `<origin-owner/name>` with `git remote get-url origin` in this worktree.";
@@ -6274,9 +6543,9 @@ function formatPrGateDirective() {
6274
6543
  }
6275
6544
  function formatProcessGuideDirective(opts) {
6276
6545
  const worktree = opts?.worktreePath?.trim();
6277
- const hasGraphSkill = !!worktree && existsSync12(join12(worktree, ".claude/skills/graph-engineering/SKILL.md"));
6278
- const hasReviewSkill = !!worktree && existsSync12(join12(worktree, ".claude/skills/review/SKILL.md"));
6279
- const hasInstallSkill = !!worktree && existsSync12(join12(worktree, ".claude/skills/worktree-install/SKILL.md"));
6546
+ const hasGraphSkill = !!worktree && existsSync12(join13(worktree, ".claude/skills/graph-engineering/SKILL.md"));
6547
+ const hasReviewSkill = !!worktree && existsSync12(join13(worktree, ".claude/skills/review/SKILL.md"));
6548
+ const hasInstallSkill = !!worktree && existsSync12(join13(worktree, ".claude/skills/worktree-install/SKILL.md"));
6280
6549
  return [
6281
6550
  "Process guides (recurring work only):",
6282
6551
  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,
@@ -6430,6 +6699,7 @@ function compactIssueRow(issue, opts) {
6430
6699
  function formatMcpIssueList(input) {
6431
6700
  const truncated = input.truncated || Boolean(input.commentsTruncated);
6432
6701
  const comments = input.comments ?? [];
6702
+ const pageHint = input.unavailableReason ? input.unavailableReason : truncated ? input.since ? "More issues or comments match. Pass a higher limit (max 250) or a tighter query." : "More issues match. Pass a higher limit (max 250) or a tighter query." : void 0;
6433
6703
  return {
6434
6704
  ...input.source ? { source: input.source } : {},
6435
6705
  ...input.viewer ? { viewer: input.viewer } : {},
@@ -6437,9 +6707,8 @@ function formatMcpIssueList(input) {
6437
6707
  returned: input.issues.length,
6438
6708
  truncated,
6439
6709
  ...input.since ? { since: input.since } : {},
6440
- ...truncated ? {
6441
- hint: input.since ? "More issues or comments match. Pass a higher limit (max 250) or a tighter query." : "More issues match. Pass a higher limit (max 250) or a tighter query."
6442
- } : {},
6710
+ ...input.unavailableReason ? { unavailableReason: input.unavailableReason } : {},
6711
+ ...pageHint ? { hint: pageHint } : {},
6443
6712
  issues: input.issues.map((issue) => compactIssueRow(issue, { since: input.since })),
6444
6713
  ...input.since || comments.length > 0 ? { comments } : {}
6445
6714
  };
@@ -6456,7 +6725,8 @@ function formatListedIssuesForMcp(result, page) {
6456
6725
  truncated: windowed.truncated,
6457
6726
  since: result.since,
6458
6727
  comments: commentWindow.items,
6459
- commentsTruncated: commentWindow.truncated
6728
+ commentsTruncated: commentWindow.truncated,
6729
+ unavailableReason: result.unavailableReason
6460
6730
  });
6461
6731
  }
6462
6732
  function mcpJson(payload, isError = false) {
@@ -6784,7 +7054,7 @@ async function syncThreadBranchFromGit(threadId) {
6784
7054
  // src/store/schedules.ts
6785
7055
  import { randomUUID as randomUUID4 } from "crypto";
6786
7056
  import { existsSync as existsSync13, readFileSync as readFileSync8 } from "fs";
6787
- import { join as join13 } from "path";
7057
+ import { join as join14 } from "path";
6788
7058
  import { Cron } from "croner";
6789
7059
  var DURATION_RE = /^(\d+)(s|m|h|d)$/i;
6790
7060
  var UNIT_MS = {
@@ -6794,7 +7064,7 @@ var UNIT_MS = {
6794
7064
  d: 864e5
6795
7065
  };
6796
7066
  function schedulesPath() {
6797
- return join13(appDataDir(), "schedules.json");
7067
+ return join14(appDataDir(), "schedules.json");
6798
7068
  }
6799
7069
  function parseDurationMs(every) {
6800
7070
  const m = every.trim().match(DURATION_RE);
@@ -7095,7 +7365,7 @@ function formatScheduledPrompt(name, prompt) {
7095
7365
  ${prompt}`;
7096
7366
  }
7097
7367
  async function defaultDeps() {
7098
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-NPFWU3XU.js");
7368
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-B4STIW4B.js");
7099
7369
  const orch = getOrchestrator2();
7100
7370
  return {
7101
7371
  findThread: (id) => findThreadByRef(id),
@@ -8148,7 +8418,8 @@ var Orchestrator = class {
8148
8418
  return;
8149
8419
  }
8150
8420
  thread = this.requireThread(threadId);
8151
- const gitPrompt = expandCanonicalGitRequest(promptText);
8421
+ const turnOrigin = thread.worktreePath?.trim() ? await resolveOriginRemote(thread.worktreePath).catch(() => null) : null;
8422
+ const gitPrompt = expandCanonicalGitRequest(promptText, { forge: turnOrigin?.forge });
8152
8423
  const { agentPrompt: expandedPrompt } = expandComposerPrompt(
8153
8424
  thread.worktreePath,
8154
8425
  gitPrompt,
@@ -8235,11 +8506,9 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
8235
8506
  const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-P3H4SEIK.js");
8236
8507
  const gitAuthMode = getGithubGitAuthMode();
8237
8508
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
8238
- githubSlug: await withTimeout(
8239
- resolveGithubRepoSlug(fresh.worktreePath),
8240
- 8e3,
8241
- "resolveGithubRepoSlug"
8242
- ).catch(() => null),
8509
+ githubSlug: turnOrigin?.forge === "github" ? turnOrigin.slug : await withTimeout(resolveGithubRepoSlug(fresh.worktreePath), 8e3, "resolveGithubRepoSlug").catch(() => null),
8510
+ originForge: turnOrigin?.forge ?? null,
8511
+ originSlug: turnOrigin?.slug ?? null,
8243
8512
  gitAuthMode,
8244
8513
  activeRuns: annotateDevAccessRuns(
8245
8514
  mergeWorktreeActiveRuns(
@@ -8332,7 +8601,8 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
8332
8601
  agentPrompt,
8333
8602
  expandedPrompt,
8334
8603
  worktreePath: fresh.worktreePath,
8335
- attachments: autoContinue ? [] : sentAttachments ?? []
8604
+ attachments: autoContinue ? [] : sentAttachments ?? [],
8605
+ gitForge: turnOrigin?.forge
8336
8606
  });
8337
8607
  const handle = await spawnAgentTurn(
8338
8608
  fresh,
@@ -9916,7 +10186,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
9916
10186
  await withRepoGitLock(thread.repoPath, async () => {
9917
10187
  await git(["worktree", "add", dest, thread.branchName], thread.repoPath);
9918
10188
  });
9919
- const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-RXZPTCNH.js");
10189
+ const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-INRDQFWV.js");
9920
10190
  await ensureWorktreeSideboardIgnored(dest);
9921
10191
  }
9922
10192
  const restorePatch = {};
@@ -10022,7 +10292,7 @@ async function startOrchestration(opts) {
10022
10292
  sourceRef: "default",
10023
10293
  ...createOpts
10024
10294
  }).catch(async () => {
10025
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-7EATHVYQ.js");
10295
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-PDNPL5CQ.js");
10026
10296
  const repo = await resolveRepoRoot2(repoPath);
10027
10297
  const def = await resolveDefaultBranch2(repo);
10028
10298
  return orch.createThread({
@@ -10032,7 +10302,7 @@ async function startOrchestration(opts) {
10032
10302
  repoPath: repo
10033
10303
  });
10034
10304
  });
10035
- const { updateThread: upd } = await import("./thread-store-QHYN2ZMQ.js");
10305
+ const { updateThread: upd } = await import("./thread-store-JRSL4HQY.js");
10036
10306
  const updated = upd(thread.id, {
10037
10307
  sourceType: "orchestration",
10038
10308
  sourceRef: goal
@@ -10173,6 +10443,8 @@ export {
10173
10443
  initStackFromThread,
10174
10444
  createPrStack,
10175
10445
  stackAgentDefaultsFrom,
10446
+ ghPrCreateAssigneeArgs,
10447
+ createOrUpdatePr,
10176
10448
  inspectGitWorktree,
10177
10449
  initializeGitRepository,
10178
10450
  captureTurnBaseline,
@@ -10205,6 +10477,8 @@ export {
10205
10477
  moveQueuedItemToFront,
10206
10478
  shiftQueuedItem,
10207
10479
  resolveSendFollowUp,
10480
+ formatCursorGitDirective,
10481
+ formatEntireGitDirective,
10208
10482
  packagedDetachedJobPath,
10209
10483
  resolveDetachedJobScript,
10210
10484
  formatDetachedJobInvoke,