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