@sideboard-ai/core 0.1.320 → 0.1.321
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.
- package/dist/agents/cursor-runner.js +2 -2
- package/dist/{agents-CJZYJOWP.js → agents-PFVYC36J.js} +8 -8
- package/dist/{agents-F2E2HACB.js → agents-ROFDNE7Z.js} +9 -9
- package/dist/{chunk-QVN2WOKJ.js → chunk-2TUE6JKQ.js} +12 -0
- package/dist/{chunk-B7UL36WH.js → chunk-45UB2J47.js} +335 -65
- package/dist/{chunk-DD67JWTN.js → chunk-4YXZOXMT.js} +1 -1
- package/dist/{chunk-V5BTGQ6M.js → chunk-6U6QRUHY.js} +1 -1
- package/dist/{chunk-QGY3UNNL.js → chunk-7JV5QP5K.js} +1 -1
- package/dist/{chunk-DJZRDTZY.js → chunk-BANN5HUX.js} +6 -6
- package/dist/{chunk-CB5Z5C3J.js → chunk-BPDVHB4U.js} +1 -1
- package/dist/{chunk-RHJPP26T.js → chunk-H6GXYV5Q.js} +14 -11
- package/dist/{chunk-4GZC6DDH.js → chunk-IFWGG2M2.js} +7 -0
- package/dist/{chunk-LLIEU2ZB.js → chunk-JNEFEA2A.js} +6 -6
- package/dist/{chunk-IDPFLXRY.js → chunk-LD2DXHBP.js} +341 -67
- package/dist/{chunk-2P4XKWV2.js → chunk-QKHEVSB5.js} +1 -1
- package/dist/{chunk-P74GXA5V.js → chunk-RGUZPMTF.js} +6 -6
- package/dist/{chunk-UK2KESBN.js → chunk-RHJKZOPQ.js} +3 -3
- package/dist/{chunk-HH3VVTEC.js → chunk-S5CJUIPY.js} +5 -5
- package/dist/{chunk-5S3YP5KH.js → chunk-SPMIZSKH.js} +14 -11
- package/dist/{chunk-EQ5JY3MJ.js → chunk-TEFFR6PB.js} +1 -1
- package/dist/{chunk-EDXTP2VR.js → chunk-UWJUARFA.js} +545 -186
- package/dist/{chunk-OAFBHCSM.js → chunk-UX6EDDGR.js} +1 -1
- package/dist/{chunk-ZYZBCLJR.js → chunk-XDQSHSL6.js} +6 -6
- package/dist/{chunk-2UG25RMK.js → chunk-YBTSZ2SW.js} +12 -0
- package/dist/{chunk-PNLGWAYE.js → chunk-YWBLQBSN.js} +548 -187
- package/dist/{chunk-Y3Y7SZBZ.js → chunk-ZHGMRBSC.js} +1 -1
- package/dist/{conductor-FPFY6Z5S.js → conductor-CNT3VL3S.js} +6 -6
- package/dist/{conductor-JA5W3L7C.js → conductor-XLXJU24U.js} +6 -6
- package/dist/{connected-teams-IHK2WXUI.js → connected-teams-H4LZOJDC.js} +2 -2
- package/dist/{connected-teams-IFW3NQ6G.js → connected-teams-XYRZMQO4.js} +2 -2
- package/dist/{coordinator-prompt-NUC2ZXMJ.js → coordinator-prompt-D5EE2YTV.js} +5 -5
- package/dist/{coordinator-prompt-M75TAN43.js → coordinator-prompt-TU24TQ4I.js} +5 -5
- package/dist/{global-workspace-5A4H34AF.js → global-workspace-743TPQNF.js} +5 -5
- package/dist/{global-workspace-SCLQUNUI.js → global-workspace-UPMXDQM7.js} +5 -5
- package/dist/index.cjs +1577 -471
- package/dist/index.d.cts +182 -70
- package/dist/index.d.ts +182 -70
- package/dist/index.js +480 -62
- package/dist/mcp/run-stdio.cjs +1159 -447
- package/dist/mcp/run-stdio.js +65 -17
- package/dist/{optional-cli-MRNQKVIR.js → optional-cli-2YDQQCCD.js} +4 -4
- package/dist/{optional-cli-2V3SLME5.js → optional-cli-USD6PROE.js} +3 -3
- package/dist/{orchestrator-NPFWU3XU.js → orchestrator-B4STIW4B.js} +12 -12
- package/dist/{orchestrator-7BDZ5GWD.js → orchestrator-VQ4HRYVB.js} +11 -11
- package/dist/{run-PCX5QWR4.js → run-7QMRYP3F.js} +3 -1
- package/dist/{run-TB7RBII2.js → run-UPNCCRCN.js} +3 -1
- package/dist/{thread-store-JWHVXLDX.js → thread-store-3F7GR64A.js} +1 -1
- package/dist/{thread-store-QHYN2ZMQ.js → thread-store-JRSL4HQY.js} +1 -1
- package/dist/{workspaces-KWMBOTQD.js → workspaces-47WQL5IG.js} +5 -5
- package/dist/{workspaces-5QA3YM4L.js → workspaces-75FD4QUR.js} +5 -5
- package/dist/{worktree-O6BANO2I.js → worktree-G3E6WP66.js} +10 -8
- package/dist/{worktree-7EATHVYQ.js → worktree-PDNPL5CQ.js} +10 -8
- package/dist/{worktree-exclude-RXZPTCNH.js → worktree-exclude-INRDQFWV.js} +2 -2
- package/dist/{worktree-exclude-5N2KTYIT.js → worktree-exclude-P5NJODWP.js} +2 -2
- package/package.json +1 -1
- /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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
521
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-743TPQNF.js");
|
|
514
522
|
if (isGlobalThread2(thread)) {
|
|
515
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
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
|
|
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
|
-
|
|
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-
|
|
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-
|
|
3705
|
+
const { addWorkspace: addWorkspace2 } = await import("./workspaces-75FD4QUR.js");
|
|
3645
3706
|
await addWorkspace2(repoPath);
|
|
3646
|
-
const { ensureWorktreeSideboardIgnored } = await import("./worktree-exclude-
|
|
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
|
|
4127
|
-
import { dirname as dirname2, join as
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
5084
|
+
const abs = join9(worktreePath, relativePath);
|
|
4856
5085
|
mkdirSync(dirname2(abs), { recursive: true });
|
|
4857
|
-
|
|
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-
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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(
|
|
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 =
|
|
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(
|
|
5565
|
+
scanSkillsDir(join11(worktreePath, rel), "workspace", collected);
|
|
5337
5566
|
}
|
|
5338
5567
|
for (const abs of [
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
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(
|
|
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
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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(
|
|
5933
|
-
const hasReviewSkill = !!worktree && existsSync12(
|
|
5934
|
-
const hasInstallSkill = !!worktree && existsSync12(
|
|
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
|
-
...
|
|
6096
|
-
|
|
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
|
|
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
|
|
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-
|
|
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
|
|
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
|
-
|
|
7886
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|