@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
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  formatOptionalServicesDirectiveForTurn,
8
8
  formatOptionalServicesReminderForTurn
9
- } from "./chunk-OAFBHCSM.js";
9
+ } from "./chunk-UX6EDDGR.js";
10
10
  import {
11
11
  extractPresentedPlan,
12
12
  isPresentPlanToolName,
@@ -27,7 +27,7 @@ import {
27
27
  parseSessionQuotaResetAt,
28
28
  planModeTurnInstruction,
29
29
  resolveQuotaFallbackAgent
30
- } from "./chunk-ZYZBCLJR.js";
30
+ } from "./chunk-XDQSHSL6.js";
31
31
  import {
32
32
  applyWorktreePkgCacheEnv,
33
33
  askBlockStillWaiting,
@@ -65,7 +65,7 @@ import {
65
65
  worktreeDevProcessKey,
66
66
  worktreeRunProcessKey,
67
67
  worktreeSetupProcessKey
68
- } from "./chunk-P74GXA5V.js";
68
+ } from "./chunk-RGUZPMTF.js";
69
69
  import {
70
70
  applyAgentEvent,
71
71
  clipAgentEventForPaint,
@@ -117,20 +117,23 @@ import {
117
117
  stageAbsolutePathsAsAttachments,
118
118
  stageBuffersAsAttachments,
119
119
  syncWorkspacesFromThreads
120
- } from "./chunk-5S3YP5KH.js";
120
+ } from "./chunk-SPMIZSKH.js";
121
121
  import {
122
122
  addPrStackLayer,
123
123
  allocateTeamSlug,
124
124
  canonicalizeRepoPath,
125
125
  ciChecksFailed,
126
+ clampGithubPrBody,
126
127
  commitAll,
127
128
  connectedPrSelectors,
128
129
  createExistingBranchWorktree,
129
- createOrUpdatePr,
130
+ createOrUpdateCursorPr,
130
131
  createThreadWorktree,
131
132
  currentBranch,
132
133
  detectGhStack,
133
134
  enqueueByKey,
135
+ ensureGhPreferOrigin,
136
+ entireUsesTrails,
134
137
  fastForwardMainCheckoutIfSafe,
135
138
  fetchOriginForWorktree,
136
139
  fetchPrHead,
@@ -142,8 +145,11 @@ import {
142
145
  getPrForHeadBranch,
143
146
  getPrMeta,
144
147
  getPrStack,
148
+ ghHeadRef,
149
+ ghRepoSelectArgs,
145
150
  initPrStack,
146
151
  isDirty,
152
+ isGhRateLimitError,
147
153
  isSideboardScratchPath,
148
154
  listWorktrees,
149
155
  markPrReady,
@@ -155,18 +161,20 @@ import {
155
161
  resolveDefaultBranch,
156
162
  resolveDiffBaseRef,
157
163
  resolveGithubRepoSlug,
164
+ resolveOriginRemote,
158
165
  resolvePrSelector,
159
166
  resolveRepoRoot,
160
167
  switchWorktreeBranch,
161
168
  withRepoGitLock
162
- } from "./chunk-PNLGWAYE.js";
169
+ } from "./chunk-YWBLQBSN.js";
163
170
  import {
164
171
  clearStaleIndexLocks,
165
172
  enrichPathWithNpmGlobalBin,
166
173
  ensureAgentPath,
174
+ gh,
167
175
  git,
168
176
  resolveGitDirsForLockRecovery
169
- } from "./chunk-2UG25RMK.js";
177
+ } from "./chunk-YBTSZ2SW.js";
170
178
  import {
171
179
  HISTORY_CLEANUP_INTERVAL_HOURS_DEFAULT,
172
180
  applyTurnUsage,
@@ -242,7 +250,7 @@ import {
242
250
  worktreeNameFromPath,
243
251
  worktreeSlugForTicket,
244
252
  writeThread
245
- } from "./chunk-XMHMVEIY.js";
253
+ } from "./chunk-B4CDSSRN.js";
246
254
  import {
247
255
  normalizeThinkingEffort
248
256
  } from "./chunk-KGZBYWZ3.js";
@@ -510,9 +518,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
510
518
  `Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
511
519
  );
512
520
  }
513
- const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-5A4H34AF.js");
521
+ const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-743TPQNF.js");
514
522
  if (isGlobalThread2(thread)) {
515
- const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-M75TAN43.js");
523
+ const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-TU24TQ4I.js");
516
524
  ensureGlobalCoordinatorCwd2(
517
525
  isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
518
526
  );
@@ -728,7 +736,9 @@ function resolveSidebarGitPrompt(action, opts) {
728
736
  }
729
737
  var RESOLVE_CONFLICTS_RE = /^Merge the remote branch(?: \(([^)]+)\))? into your branch and resolve conflicts\. Then, commit and push your changes\.$/;
730
738
  var MERGE_INTO_RE = /^Merge PR into (.+)\.$/;
731
- function gitActionExpansion(action, base) {
739
+ function gitActionExpansion(action, base, forge) {
740
+ if (forge === "cursor") return cursorGitActionExpansion(action, base);
741
+ if (forge === "entire") return entireGitActionExpansion(action, base);
732
742
  switch (action) {
733
743
  case "commit-push":
734
744
  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.";
@@ -753,7 +763,57 @@ function gitActionExpansion(action, base) {
753
763
  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.";
754
764
  }
755
765
  }
756
- function expandCanonicalGitRequest(prompt) {
766
+ function cursorGitActionExpansion(action, base) {
767
+ switch (action) {
768
+ case "commit-push":
769
+ 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.";
770
+ case "create-draft":
771
+ 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`.";
772
+ case "create-web":
773
+ 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`.";
774
+ case "resolve-conflicts":
775
+ if (base && !isMainishPrBase(base)) {
776
+ 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.`;
777
+ }
778
+ if (base) {
779
+ return `Fetch the PR base (\`${base}\`), merge it into this branch, resolve conflicts carefully, then commit and push until the PR is mergeable.`;
780
+ }
781
+ 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`.";
782
+ case "ready-for-review":
783
+ 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`.";
784
+ case "merge":
785
+ if (base && !isMainishPrBase(base)) {
786
+ 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\`.`;
787
+ }
788
+ 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`.";
789
+ }
790
+ }
791
+ function entireGitActionExpansion(action, base) {
792
+ switch (action) {
793
+ case "commit-push":
794
+ 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.";
795
+ case "create-draft":
796
+ 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`.';
797
+ case "create-web":
798
+ 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`.';
799
+ case "resolve-conflicts":
800
+ if (base && !isMainishPrBase(base)) {
801
+ 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.`;
802
+ }
803
+ if (base) {
804
+ return `Fetch the Trail base (\`${base}\`), merge it into this branch, resolve conflicts carefully, then commit and push.`;
805
+ }
806
+ 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`.";
807
+ case "ready-for-review":
808
+ 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`.";
809
+ case "merge":
810
+ if (base && !isMainishPrBase(base)) {
811
+ 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\`.`;
812
+ }
813
+ 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`.";
814
+ }
815
+ }
816
+ function expandCanonicalGitRequest(prompt, opts) {
757
817
  const trimmed = prompt.trim();
758
818
  let action = null;
759
819
  let base = null;
@@ -778,11 +838,12 @@ function expandCanonicalGitRequest(prompt) {
778
838
  base = m[1]?.trim() || null;
779
839
  }
780
840
  }
781
- let expansion = action ? gitActionExpansion(action, base) : null;
841
+ const forge = opts?.forge ?? null;
842
+ let expansion = action ? gitActionExpansion(action, base, forge) : null;
782
843
  if (!expansion && trimmed === "Address review comments.") {
783
- expansion = "Read the PR review feedback (`gh pr view --comments`, `gh api` review comments), make the requested changes, commit, and push.";
844
+ 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.";
784
845
  } else if (!expansion && FIX_CI_RE.test(trimmed)) {
785
- 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.";
846
+ 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.";
786
847
  }
787
848
  if (!expansion) return prompt;
788
849
  return `${trimmed}
@@ -3626,7 +3687,7 @@ async function adoptThread(input) {
3626
3687
  throw new Error(`Worktree not found: ${input.worktreePath}`);
3627
3688
  }
3628
3689
  const repoPath = await resolveRepoRoot(input.worktreePath);
3629
- const { stdout: branch } = await import("./run-TB7RBII2.js").then(
3690
+ const { stdout: branch } = await import("./run-UPNCCRCN.js").then(
3630
3691
  ({ git: git2 }) => git2(["rev-parse", "--abbrev-ref", "HEAD"], input.worktreePath)
3631
3692
  );
3632
3693
  const thread = createEmptyThread({
@@ -3641,9 +3702,9 @@ async function adoptThread(input) {
3641
3702
  messages: input.messages ?? []
3642
3703
  });
3643
3704
  writeThread(thread);
3644
- const { addWorkspace: addWorkspace2 } = await import("./workspaces-5QA3YM4L.js");
3705
+ const { addWorkspace: addWorkspace2 } = await import("./workspaces-75FD4QUR.js");
3645
3706
  await addWorkspace2(repoPath);
3646
- const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-5N2KTYIT.js");
3707
+ const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-P5NJODWP.js");
3647
3708
  await ensureWorktreeSideboardIgnored(input.worktreePath);
3648
3709
  return thread;
3649
3710
  }
@@ -4122,9 +4183,177 @@ async function createPrStack(input, onSetupLine) {
4122
4183
  return { stack, threads, createdThreadIds };
4123
4184
  }
4124
4185
 
4186
+ // src/git/pr-write.ts
4187
+ import { randomBytes } from "crypto";
4188
+ import { unlinkSync as unlinkSync3, writeFileSync as writeFileSync5 } from "fs";
4189
+ import { tmpdir as tmpdir2 } from "os";
4190
+ import { join as join8 } from "path";
4191
+ async function lookupGithubGraphqlReset(cwd) {
4192
+ const result = await gh(["api", "rate_limit"], cwd, { reject: false });
4193
+ if (result.exitCode !== 0 || !result.stdout.trim()) return void 0;
4194
+ try {
4195
+ const data = JSON.parse(result.stdout);
4196
+ const reset = data.resources?.graphql?.reset;
4197
+ return typeof reset === "number" ? reset : void 0;
4198
+ } catch {
4199
+ return void 0;
4200
+ }
4201
+ }
4202
+ async function formatPrCreateFailure(raw, cwd, ctx) {
4203
+ if (!isGhRateLimitError(raw)) {
4204
+ return formatGhLandError(raw, {
4205
+ targetedRepo: ctx?.slug,
4206
+ headRef: ctx?.head
4207
+ });
4208
+ }
4209
+ const resetAt = await lookupGithubGraphqlReset(cwd);
4210
+ return formatGhLandError(raw, {
4211
+ resetAt,
4212
+ targetedRepo: ctx?.slug,
4213
+ headRef: ctx?.head
4214
+ });
4215
+ }
4216
+ async function createCursorPullRequest(worktreePath, slug, opts) {
4217
+ const bodyText = (opts.body ?? opts.title).trim() || opts.title;
4218
+ const bodyFile = join8(
4219
+ tmpdir2(),
4220
+ `sideboard-pr-body-${process.pid}-${randomBytes(6).toString("hex")}.md`
4221
+ );
4222
+ writeFileSync5(bodyFile, bodyText.endsWith("\n") ? bodyText : `${bodyText}
4223
+ `, "utf8");
4224
+ try {
4225
+ return await createOrUpdateCursorPr(worktreePath, slug, {
4226
+ title: opts.title,
4227
+ bodyFile,
4228
+ base: opts.base,
4229
+ head: opts.head,
4230
+ draft: opts.draft
4231
+ });
4232
+ } finally {
4233
+ try {
4234
+ unlinkSync3(bodyFile);
4235
+ } catch {
4236
+ }
4237
+ }
4238
+ }
4239
+ function ghPrCreateAssigneeArgs(assignee) {
4240
+ const raw = assignee?.trim();
4241
+ if (raw && /^(none|unassigned)$/i.test(raw)) return [];
4242
+ return ["--assignee", raw || "@me"];
4243
+ }
4244
+ async function createOrUpdatePr(worktreePath, opts) {
4245
+ const origin = await resolveOriginRemote(worktreePath);
4246
+ if (origin?.forge === "entire") throw entireUsesTrails();
4247
+ const cursorSlug = origin?.forge === "cursor" ? origin.slug : null;
4248
+ if (cursorSlug) return createCursorPullRequest(worktreePath, cursorSlug, opts);
4249
+ await ensureGhPreferOrigin(worktreePath);
4250
+ const slug = await resolveGithubRepoSlug(worktreePath);
4251
+ if (!slug) {
4252
+ throw new Error(
4253
+ "Could not resolve the origin GitHub repo (owner/name) for this worktree. Check that `git remote get-url origin` points at github.com."
4254
+ );
4255
+ }
4256
+ const repoArgs = ghRepoSelectArgs(slug);
4257
+ const headRef = ghHeadRef(slug, opts.head);
4258
+ const branchOnly = opts.head.trim().replace(/^refs\/heads\//, "");
4259
+ const bodyText = clampGithubPrBody(opts.body ?? opts.title);
4260
+ const bodyFile = join8(
4261
+ tmpdir2(),
4262
+ `sideboard-pr-body-${process.pid}-${randomBytes(6).toString("hex")}.md`
4263
+ );
4264
+ writeFileSync5(bodyFile, bodyText.endsWith("\n") ? bodyText : `${bodyText}
4265
+ `, "utf8");
4266
+ const bodyArgs = ["--body-file", bodyFile];
4267
+ try {
4268
+ return await createOrUpdatePrWithBodyFile(worktreePath, {
4269
+ ...opts,
4270
+ slug,
4271
+ repoArgs,
4272
+ headRef,
4273
+ branchOnly,
4274
+ bodyArgs
4275
+ });
4276
+ } finally {
4277
+ try {
4278
+ unlinkSync3(bodyFile);
4279
+ } catch {
4280
+ }
4281
+ }
4282
+ }
4283
+ async function createOrUpdatePrWithBodyFile(worktreePath, opts) {
4284
+ const { slug, repoArgs, headRef, branchOnly, bodyArgs } = opts;
4285
+ const existing = await gh(
4286
+ [...repoArgs, "pr", "view", branchOnly, "--json", "url", "--jq", ".url"],
4287
+ worktreePath,
4288
+ { reject: false }
4289
+ );
4290
+ if (existing.exitCode === 0 && existing.stdout.trim() && !opts.web) {
4291
+ const url2 = existing.stdout.trim();
4292
+ await gh(
4293
+ [
4294
+ ...repoArgs,
4295
+ "pr",
4296
+ "edit",
4297
+ branchOnly,
4298
+ "--title",
4299
+ opts.title,
4300
+ ...bodyArgs
4301
+ ],
4302
+ worktreePath,
4303
+ { reject: false }
4304
+ );
4305
+ return url2;
4306
+ }
4307
+ if (opts.web) {
4308
+ const args2 = [
4309
+ ...repoArgs,
4310
+ "pr",
4311
+ "create",
4312
+ "--web",
4313
+ "--title",
4314
+ opts.title,
4315
+ ...bodyArgs,
4316
+ "--base",
4317
+ opts.base,
4318
+ "--head",
4319
+ headRef
4320
+ ];
4321
+ if (opts.draft) args2.push("--draft");
4322
+ args2.push(...ghPrCreateAssigneeArgs(opts.assignee));
4323
+ await gh(args2, worktreePath, { reject: false });
4324
+ const again = await gh(
4325
+ [...repoArgs, "pr", "view", branchOnly, "--json", "url", "--jq", ".url"],
4326
+ worktreePath,
4327
+ { reject: false }
4328
+ );
4329
+ return again.stdout.trim() || "";
4330
+ }
4331
+ const args = [
4332
+ ...repoArgs,
4333
+ "pr",
4334
+ "create",
4335
+ "--title",
4336
+ opts.title,
4337
+ ...bodyArgs,
4338
+ "--base",
4339
+ opts.base,
4340
+ "--head",
4341
+ headRef
4342
+ ];
4343
+ if (opts.draft) args.push("--draft");
4344
+ args.push(...ghPrCreateAssigneeArgs(opts.assignee));
4345
+ const created = await gh(args, worktreePath, { reject: false });
4346
+ if (created.exitCode !== 0) {
4347
+ const raw = created.stderr.trim() || created.stdout.trim() || "gh pr create failed";
4348
+ throw new Error(await formatPrCreateFailure(raw, worktreePath, { slug, head: headRef }));
4349
+ }
4350
+ const url = created.stdout.trim().split("\n").find((l) => l.startsWith("http")) ?? created.stdout.trim();
4351
+ return url;
4352
+ }
4353
+
4125
4354
  // src/diff/diff.ts
4126
- import { existsSync as existsSync9, mkdirSync, readFileSync as readFileSync6, statSync as statSync2, writeFileSync as writeFileSync5 } from "fs";
4127
- import { dirname as dirname2, join as join8 } from "path";
4355
+ import { existsSync as existsSync9, mkdirSync, readFileSync as readFileSync6, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
4356
+ import { dirname as dirname2, join as join9 } from "path";
4128
4357
  async function inspectGitWorktree(worktreePath) {
4129
4358
  if (!worktreePath || !existsSync9(worktreePath)) return "missing_worktree";
4130
4359
  const check = await git(["rev-parse", "--is-inside-work-tree"], worktreePath, {
@@ -4270,7 +4499,7 @@ new file mode 100644
4270
4499
  };
4271
4500
  }
4272
4501
  async function untrackedPatch(worktreePath, path, maxHunk) {
4273
- const abs = join8(worktreePath, path);
4502
+ const abs = join9(worktreePath, path);
4274
4503
  try {
4275
4504
  const st = statSync2(abs);
4276
4505
  if (st.isFile() && st.size > maxHunk) {
@@ -4742,7 +4971,7 @@ async function getDiff(worktreePath, repoPath, opts) {
4742
4971
  }
4743
4972
  function statWorktreePath(worktreePath, relativePath) {
4744
4973
  assertSafeRelativePath(relativePath);
4745
- const abs = join8(worktreePath, relativePath);
4974
+ const abs = join9(worktreePath, relativePath);
4746
4975
  if (!existsSync9(abs)) return "missing";
4747
4976
  const st = statSync2(abs);
4748
4977
  if (st.isDirectory()) return "dir";
@@ -4784,7 +5013,7 @@ var DEFAULT_UPLOAD_MAX_BYTES = 5e7;
4784
5013
  function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
4785
5014
  assertSafeRelativePath(relativePath);
4786
5015
  const maxBytes = opts?.maxBytes ?? DEFAULT_UPLOAD_MAX_BYTES;
4787
- const abs = join8(worktreePath, relativePath);
5016
+ const abs = join9(worktreePath, relativePath);
4788
5017
  const st = statSync2(abs);
4789
5018
  if (!st.isFile()) {
4790
5019
  throw new Error(`Not a file: ${relativePath}`);
@@ -4804,7 +5033,7 @@ function readWorktreeFileForUpload(worktreePath, relativePath, opts) {
4804
5033
  function readWorktreeFile(worktreePath, relativePath, opts) {
4805
5034
  assertSafeRelativePath(relativePath);
4806
5035
  const maxBytes = opts?.maxBytes ?? 2e5;
4807
- const abs = join8(worktreePath, relativePath);
5036
+ const abs = join9(worktreePath, relativePath);
4808
5037
  const st = statSync2(abs);
4809
5038
  if (!st.isFile()) {
4810
5039
  throw new Error(`Not a file: ${relativePath}`);
@@ -4852,9 +5081,9 @@ function assertSafeRelativePath(relativePath) {
4852
5081
  }
4853
5082
  function writeWorktreeFile(worktreePath, relativePath, content) {
4854
5083
  assertSafeRelativePath(relativePath);
4855
- const abs = join8(worktreePath, relativePath);
5084
+ const abs = join9(worktreePath, relativePath);
4856
5085
  mkdirSync(dirname2(abs), { recursive: true });
4857
- writeFileSync5(abs, content, "utf8");
5086
+ writeFileSync6(abs, content, "utf8");
4858
5087
  return { path: relativePath };
4859
5088
  }
4860
5089
  async function getWorktreeDirtyStat(worktreePath) {
@@ -5046,7 +5275,7 @@ async function confirmLand(thread, opts) {
5046
5275
  if (preview.dirty) {
5047
5276
  committed = await commitAll(thread.worktreePath, meta.commitMessage);
5048
5277
  }
5049
- const { git: git2 } = await import("./run-TB7RBII2.js");
5278
+ const { git: git2 } = await import("./run-UPNCCRCN.js");
5050
5279
  const { stdout: headOut } = await git2(
5051
5280
  ["rev-parse", "--abbrev-ref", "HEAD"],
5052
5281
  thread.worktreePath,
@@ -5077,13 +5306,13 @@ async function confirmLand(thread, opts) {
5077
5306
 
5078
5307
  // src/diff/read-worktree-tail.ts
5079
5308
  import { closeSync, fstatSync, openSync, readSync } from "fs";
5080
- import { join as join9 } from "path";
5309
+ import { join as join10 } from "path";
5081
5310
  var WORKTREE_TAIL_BYTES = 2e5;
5082
5311
  function readWorktreeFileTail(worktreePath, relativePath, maxBytes = WORKTREE_TAIL_BYTES) {
5083
5312
  if (!relativePath || relativePath.includes("..") || relativePath.startsWith("/")) {
5084
5313
  throw new Error("Invalid path");
5085
5314
  }
5086
- const abs = join9(worktreePath, relativePath);
5315
+ const abs = join10(worktreePath, relativePath);
5087
5316
  const fd = openSync(abs, "r");
5088
5317
  try {
5089
5318
  const st = fstatSync(fd);
@@ -5117,7 +5346,7 @@ function readWorktreeFileTail(worktreePath, relativePath, maxBytes = WORKTREE_TA
5117
5346
  // src/skills/discover.ts
5118
5347
  import { existsSync as existsSync10, readdirSync as readdirSync3, readFileSync as readFileSync7, statSync as statSync3 } from "fs";
5119
5348
  import { homedir } from "os";
5120
- import { join as join10 } from "path";
5349
+ import { join as join11 } from "path";
5121
5350
 
5122
5351
  // src/skills/bundled/long-running.ts
5123
5352
  var LONG_RUNNING_SKILL_COMMAND = "long-running";
@@ -5286,7 +5515,7 @@ function scanSkillsDir(dir, source, out) {
5286
5515
  }
5287
5516
  for (const entry of entries) {
5288
5517
  if (entry.startsWith(".")) continue;
5289
- const skillMd = join10(dir, entry, "SKILL.md");
5518
+ const skillMd = join11(dir, entry, "SKILL.md");
5290
5519
  if (!existsSync10(skillMd)) continue;
5291
5520
  try {
5292
5521
  if (!statSync3(skillMd).isFile()) continue;
@@ -5308,12 +5537,12 @@ function scanClaudePluginSkills(pluginsRoot, out) {
5308
5537
  return;
5309
5538
  }
5310
5539
  if (lookingForSkillsDir && entries.includes("SKILL.md")) {
5311
- const skill = readSkill(join10(dir, "SKILL.md"), "cli");
5540
+ const skill = readSkill(join11(dir, "SKILL.md"), "cli");
5312
5541
  if (skill) out.push(skill);
5313
5542
  }
5314
5543
  for (const entry of entries) {
5315
5544
  if (entry === "node_modules" || entry === ".git") continue;
5316
- const full = join10(dir, entry);
5545
+ const full = join11(dir, entry);
5317
5546
  try {
5318
5547
  if (!statSync3(full).isDirectory()) continue;
5319
5548
  } catch {
@@ -5333,17 +5562,17 @@ function discoverSkills(worktreePath) {
5333
5562
  const home = homedir();
5334
5563
  const collected = [];
5335
5564
  for (const rel of [".claude/skills", ".cursor/skills", ".sideboard/skills", ".brightsy/skills", "skills"]) {
5336
- scanSkillsDir(join10(worktreePath, rel), "workspace", collected);
5565
+ scanSkillsDir(join11(worktreePath, rel), "workspace", collected);
5337
5566
  }
5338
5567
  for (const abs of [
5339
- join10(home, ".claude/skills"),
5340
- join10(home, ".cursor/skills"),
5341
- join10(home, ".sideboard/skills"),
5342
- join10(home, ".brightsy/skills")
5568
+ join11(home, ".claude/skills"),
5569
+ join11(home, ".cursor/skills"),
5570
+ join11(home, ".sideboard/skills"),
5571
+ join11(home, ".brightsy/skills")
5343
5572
  ]) {
5344
5573
  scanSkillsDir(abs, "user", collected);
5345
5574
  }
5346
- scanClaudePluginSkills(join10(home, ".claude/plugins"), collected);
5575
+ scanClaudePluginSkills(join11(home, ".claude/plugins"), collected);
5347
5576
  collected.push(...bundledSkills());
5348
5577
  const rank = {
5349
5578
  workspace: 0,
@@ -5571,7 +5800,7 @@ function promptForJoinedSteer(input) {
5571
5800
  rewriteTrailingUserPrompt(input.threadId, input.promptText, input.latestPrompt);
5572
5801
  const { agentPrompt: expandedLatest } = expandComposerPrompt(
5573
5802
  input.worktreePath,
5574
- expandCanonicalGitRequest(input.latestPrompt),
5803
+ expandCanonicalGitRequest(input.latestPrompt, { forge: input.gitForge }),
5575
5804
  { attachments: input.attachments }
5576
5805
  );
5577
5806
  return input.expandedPrompt && input.agentPrompt.endsWith(input.expandedPrompt) ? input.agentPrompt.slice(0, -input.expandedPrompt.length) + expandedLatest : `${input.agentPrompt}
@@ -5667,11 +5896,33 @@ async function enqueueThreadSend(host, threadRef, prompt, opts) {
5667
5896
 
5668
5897
  // src/agents/instructions.ts
5669
5898
  import { existsSync as existsSync12 } from "fs";
5670
- import { join as join12 } from "path";
5899
+ import { join as join13 } from "path";
5900
+
5901
+ // src/agents/forge-git-directives.ts
5902
+ function formatCursorGitDirective(slug) {
5903
+ const repo = slug?.trim() || "<origin-owner/name>";
5904
+ return [
5905
+ `Git host (Settings \u2192 Git \u2192 Cursor): this checkout is on Cursor (\`origin.cursor.com\`, \`${repo}\`).`,
5906
+ "- Use the `origin` CLI, not `gh`. Where commands overlap, flags follow `gh` (`origin <command> --help`).",
5907
+ "- `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.",
5908
+ "- 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.",
5909
+ "- Origin has no issue tracker. Tickets for this repo come from Linear or AbleTime via `list_issues`. Do not use `gh issue`."
5910
+ ].join("\n");
5911
+ }
5912
+ function formatEntireGitDirective(slug) {
5913
+ const repo = slug?.trim() || "<origin-owner/name>";
5914
+ return [
5915
+ `Git host (Settings \u2192 Git \u2192 Entire): this checkout is on Entire (\`${repo}\`).`,
5916
+ "- Use the `entire` CLI, not `gh` or `origin`. Trails replace pull requests and GitHub issues.",
5917
+ "- `entire` uses the login from Settings \u2192 Git \u2192 Entire. Do not read tokens, set `ENTIRE_TOKEN`, or run `entire login` from this turn.",
5918
+ "- 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.",
5919
+ "- Tickets for this repo are Trails (`entire trail list` / `entire trail show`). Do not use `gh issue`."
5920
+ ].join("\n");
5921
+ }
5671
5922
 
5672
5923
  // src/skills/detached-job-path.ts
5673
5924
  import { existsSync as existsSync11 } from "fs";
5674
- import { dirname as dirname3, join as join11 } from "path";
5925
+ import { dirname as dirname3, join as join12 } from "path";
5675
5926
  import { fileURLToPath } from "url";
5676
5927
  var DETACHED_JOB_FILENAMES = ["detached-job.cjs", "detached-job.js"];
5677
5928
  function compiledModuleDir() {
@@ -5688,7 +5939,7 @@ function compiledModuleDir() {
5688
5939
  }
5689
5940
  function detachedJobScriptIn(dir) {
5690
5941
  for (const name of DETACHED_JOB_FILENAMES) {
5691
- const script = join11(dir, "scripts", name);
5942
+ const script = join12(dir, "scripts", name);
5692
5943
  if (existsSync11(script)) return script;
5693
5944
  }
5694
5945
  return null;
@@ -5798,17 +6049,35 @@ function formatWorktreeDirective(thread, opts) {
5798
6049
  lines.push(
5799
6050
  "- 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)."
5800
6051
  );
5801
- lines.push(formatGitAuthModeDirective(opts?.gitAuthMode ?? "auto"));
6052
+ const cursorRepo = opts?.originForge === "cursor";
6053
+ const entireRepo = opts?.originForge === "entire";
6054
+ if (cursorRepo) {
6055
+ lines.push(formatCursorGitDirective(opts?.originSlug));
6056
+ } else if (entireRepo) {
6057
+ lines.push(formatEntireGitDirective(opts?.originSlug));
6058
+ } else {
6059
+ lines.push(formatGitAuthModeDirective(opts?.gitAuthMode ?? "auto"));
6060
+ }
5802
6061
  lines.push(
5803
6062
  "- 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."
5804
6063
  );
5805
6064
  lines.push(
5806
- "- 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`)."
6065
+ 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`)."
5807
6066
  );
5808
6067
  if (thread.prUrl) {
5809
6068
  lines.push(
5810
6069
  `- A PR already exists (${thread.prUrl}). Update it (push + edit title/body if the purpose drifted) instead of opening a duplicate.`
5811
6070
  );
6071
+ } else if (entireRepo) {
6072
+ lines.push(
6073
+ '- 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`.'
6074
+ );
6075
+ } else if (cursorRepo) {
6076
+ const slug = opts?.originSlug?.trim() || "<origin-owner/name>";
6077
+ const resolve = opts?.originSlug?.trim() ? "" : " Resolve `<origin-owner/name>` with `git remote get-url origin` in this worktree.";
6078
+ lines.push(
6079
+ `- 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\`.`
6080
+ );
5812
6081
  } else {
5813
6082
  const slug = opts?.githubSlug ?? "<origin-owner/name>";
5814
6083
  const resolve = opts?.githubSlug ? "" : " Resolve `<origin-owner/name>` with `git remote get-url origin` in this worktree.";
@@ -5929,9 +6198,9 @@ function formatPrGateDirective() {
5929
6198
  }
5930
6199
  function formatProcessGuideDirective(opts) {
5931
6200
  const worktree = opts?.worktreePath?.trim();
5932
- const hasGraphSkill = !!worktree && existsSync12(join12(worktree, ".claude/skills/graph-engineering/SKILL.md"));
5933
- const hasReviewSkill = !!worktree && existsSync12(join12(worktree, ".claude/skills/review/SKILL.md"));
5934
- const hasInstallSkill = !!worktree && existsSync12(join12(worktree, ".claude/skills/worktree-install/SKILL.md"));
6201
+ const hasGraphSkill = !!worktree && existsSync12(join13(worktree, ".claude/skills/graph-engineering/SKILL.md"));
6202
+ const hasReviewSkill = !!worktree && existsSync12(join13(worktree, ".claude/skills/review/SKILL.md"));
6203
+ const hasInstallSkill = !!worktree && existsSync12(join13(worktree, ".claude/skills/worktree-install/SKILL.md"));
5935
6204
  return [
5936
6205
  "Process guides (recurring work only):",
5937
6206
  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,
@@ -6085,6 +6354,7 @@ function compactIssueRow(issue, opts) {
6085
6354
  function formatMcpIssueList(input) {
6086
6355
  const truncated = input.truncated || Boolean(input.commentsTruncated);
6087
6356
  const comments = input.comments ?? [];
6357
+ 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;
6088
6358
  return {
6089
6359
  ...input.source ? { source: input.source } : {},
6090
6360
  ...input.viewer ? { viewer: input.viewer } : {},
@@ -6092,9 +6362,8 @@ function formatMcpIssueList(input) {
6092
6362
  returned: input.issues.length,
6093
6363
  truncated,
6094
6364
  ...input.since ? { since: input.since } : {},
6095
- ...truncated ? {
6096
- 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."
6097
- } : {},
6365
+ ...input.unavailableReason ? { unavailableReason: input.unavailableReason } : {},
6366
+ ...pageHint ? { hint: pageHint } : {},
6098
6367
  issues: input.issues.map((issue) => compactIssueRow(issue, { since: input.since })),
6099
6368
  ...input.since || comments.length > 0 ? { comments } : {}
6100
6369
  };
@@ -6111,7 +6380,8 @@ function formatListedIssuesForMcp(result, page) {
6111
6380
  truncated: windowed.truncated,
6112
6381
  since: result.since,
6113
6382
  comments: commentWindow.items,
6114
- commentsTruncated: commentWindow.truncated
6383
+ commentsTruncated: commentWindow.truncated,
6384
+ unavailableReason: result.unavailableReason
6115
6385
  });
6116
6386
  }
6117
6387
  function mcpJson(payload, isError = false) {
@@ -6439,7 +6709,7 @@ async function syncThreadBranchFromGit(threadId) {
6439
6709
  // src/store/schedules.ts
6440
6710
  import { randomUUID as randomUUID4 } from "crypto";
6441
6711
  import { existsSync as existsSync13, readFileSync as readFileSync8 } from "fs";
6442
- import { join as join13 } from "path";
6712
+ import { join as join14 } from "path";
6443
6713
  import { Cron } from "croner";
6444
6714
  var DURATION_RE = /^(\d+)(s|m|h|d)$/i;
6445
6715
  var UNIT_MS = {
@@ -6449,7 +6719,7 @@ var UNIT_MS = {
6449
6719
  d: 864e5
6450
6720
  };
6451
6721
  function schedulesPath() {
6452
- return join13(appDataDir(), "schedules.json");
6722
+ return join14(appDataDir(), "schedules.json");
6453
6723
  }
6454
6724
  function parseDurationMs(every) {
6455
6725
  const m = every.trim().match(DURATION_RE);
@@ -6741,7 +7011,7 @@ function formatScheduledPrompt(name, prompt) {
6741
7011
  ${prompt}`;
6742
7012
  }
6743
7013
  async function defaultDeps() {
6744
- const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-7BDZ5GWD.js");
7014
+ const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-VQ4HRYVB.js");
6745
7015
  const orch = getOrchestrator2();
6746
7016
  return {
6747
7017
  findThread: (id) => findThreadByRef(id),
@@ -7794,7 +8064,8 @@ var Orchestrator = class {
7794
8064
  return;
7795
8065
  }
7796
8066
  thread = this.requireThread(threadId);
7797
- const gitPrompt = expandCanonicalGitRequest(promptText);
8067
+ const turnOrigin = thread.worktreePath?.trim() ? await resolveOriginRemote(thread.worktreePath).catch(() => null) : null;
8068
+ const gitPrompt = expandCanonicalGitRequest(promptText, { forge: turnOrigin?.forge });
7798
8069
  const { agentPrompt: expandedPrompt } = expandComposerPrompt(
7799
8070
  thread.worktreePath,
7800
8071
  gitPrompt,
@@ -7881,11 +8152,9 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
7881
8152
  const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-KMPVI2B7.js");
7882
8153
  const gitAuthMode = getGithubGitAuthMode();
7883
8154
  const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
7884
- githubSlug: await withTimeout(
7885
- resolveGithubRepoSlug(fresh.worktreePath),
7886
- 8e3,
7887
- "resolveGithubRepoSlug"
7888
- ).catch(() => null),
8155
+ githubSlug: turnOrigin?.forge === "github" ? turnOrigin.slug : await withTimeout(resolveGithubRepoSlug(fresh.worktreePath), 8e3, "resolveGithubRepoSlug").catch(() => null),
8156
+ originForge: turnOrigin?.forge ?? null,
8157
+ originSlug: turnOrigin?.slug ?? null,
7889
8158
  gitAuthMode,
7890
8159
  activeRuns: annotateDevAccessRuns(
7891
8160
  mergeWorktreeActiveRuns(
@@ -7978,7 +8247,8 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
7978
8247
  agentPrompt,
7979
8248
  expandedPrompt,
7980
8249
  worktreePath: fresh.worktreePath,
7981
- attachments: autoContinue ? [] : sentAttachments ?? []
8250
+ attachments: autoContinue ? [] : sentAttachments ?? [],
8251
+ gitForge: turnOrigin?.forge
7982
8252
  });
7983
8253
  const handle = await spawnAgentTurn(
7984
8254
  fresh,
@@ -9562,7 +9832,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
9562
9832
  await withRepoGitLock(thread.repoPath, async () => {
9563
9833
  await git(["worktree", "add", dest, thread.branchName], thread.repoPath);
9564
9834
  });
9565
- const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-5N2KTYIT.js");
9835
+ const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-P5NJODWP.js");
9566
9836
  await ensureWorktreeSideboardIgnored(dest);
9567
9837
  }
9568
9838
  const restorePatch = {};
@@ -9668,7 +9938,7 @@ async function startOrchestration(opts) {
9668
9938
  sourceRef: "default",
9669
9939
  ...createOpts
9670
9940
  }).catch(async () => {
9671
- const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-O6BANO2I.js");
9941
+ const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-G3E6WP66.js");
9672
9942
  const repo = await resolveRepoRoot2(repoPath);
9673
9943
  const def = await resolveDefaultBranch2(repo);
9674
9944
  return orch.createThread({
@@ -9678,7 +9948,7 @@ async function startOrchestration(opts) {
9678
9948
  repoPath: repo
9679
9949
  });
9680
9950
  });
9681
- const { updateThread: upd } = await import("./thread-store-JWHVXLDX.js");
9951
+ const { updateThread: upd } = await import("./thread-store-3F7GR64A.js");
9682
9952
  const updated = upd(thread.id, {
9683
9953
  sourceType: "orchestration",
9684
9954
  sourceRef: goal