@sideboard-ai/core 0.1.192 → 0.1.193
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/{abletime-JFMBCSIQ.js → abletime-QHKWGTBY.js} +4 -3
- package/dist/{abletime-53T7G667.js → abletime-UX53JTIH.js} +4 -3
- package/dist/agents/cursor-runner.js +4 -4
- package/dist/{agents-TXGQIK2E.js → agents-MN4GSQTL.js} +19 -17
- package/dist/{agents-T5VBB6X3.js → agents-OK5VD25T.js} +10 -8
- package/dist/{app-settings-663VQWUV.js → app-settings-LO7UFHQ6.js} +5 -2
- package/dist/{app-settings-74HBAAH7.js → app-settings-QYLNKRK4.js} +5 -2
- package/dist/branch-prefix-7F37FIPX.js +10 -0
- package/dist/branch-prefix-EVW2KHGQ.js +12 -0
- package/dist/{caffeinate-hold-SK2QISPE.js → caffeinate-hold-22VFDPSO.js} +2 -2
- package/dist/{caffeinate-hold-DBKMRZZO.js → caffeinate-hold-OK4JJ5PP.js} +2 -2
- package/dist/{chunk-FZ3G5TXM.js → chunk-3DX2T2KR.js} +174 -172
- package/dist/{chunk-HVIEYTUK.js → chunk-3OHR73VK.js} +1 -1
- package/dist/{chunk-VV7UT3E2.js → chunk-4OVCJPVI.js} +11 -9
- package/dist/{chunk-UBQIELFS.js → chunk-4QJRH5DL.js} +1 -1
- package/dist/{chunk-AO35MGOE.js → chunk-4TYXWPAJ.js} +1 -1
- package/dist/chunk-64QSHOKV.js +869 -0
- package/dist/{chunk-FY64F2ZQ.js → chunk-7AJ7OZZF.js} +4 -4
- package/dist/{chunk-WLPXZFRE.js → chunk-7J72QJOM.js} +1 -1
- package/dist/chunk-7SNJMKD6.js +20 -0
- package/dist/{chunk-WXKXSZN4.js → chunk-BIKCWYRP.js} +16 -873
- package/dist/{chunk-J7LQVLFQ.js → chunk-BWRS6GAS.js} +19 -1
- package/dist/{chunk-GOZ6T3AG.js → chunk-CJFBSQIB.js} +1 -1
- package/dist/{chunk-WHD4JNTN.js → chunk-EBPBGQ4P.js} +13 -13
- package/dist/{chunk-JTJHOYCU.js → chunk-EQNRWDLN.js} +10 -4
- package/dist/{chunk-NF6ENGHS.js → chunk-EQXXGOMD.js} +185 -182
- package/dist/{chunk-7NSXGL6L.js → chunk-HIX2VDRE.js} +11 -9
- package/dist/chunk-ILWQT2UN.js +55 -0
- package/dist/chunk-JTWKGOFI.js +23 -0
- package/dist/{chunk-TCQAFTSV.js → chunk-KJBYIIJU.js} +1 -1
- package/dist/{chunk-OKZFTOM2.js → chunk-KORE4WOF.js} +19 -1
- package/dist/{chunk-TWSCTJCR.js → chunk-MQC2VA5U.js} +14 -14
- package/dist/{chunk-4M2AK3O5.js → chunk-O4BMPY5Y.js} +1 -1
- package/dist/chunk-PBEPPXMY.js +57 -0
- package/dist/{chunk-IEEAVWAP.js → chunk-PE337IM2.js} +7 -7
- package/dist/chunk-RCWHL4TK.js +866 -0
- package/dist/{chunk-EFVFB2AH.js → chunk-WFUDY6PC.js} +12 -5
- package/dist/{chunk-XBLN52RZ.js → chunk-XPKKCFRT.js} +9 -866
- package/dist/{chunk-OCQPTUR7.js → chunk-YWI3IBP2.js} +1 -1
- package/dist/{connected-teams-WOYCH7FR.js → connected-teams-PU4AMFNA.js} +2 -2
- package/dist/{connected-teams-ON2KIKQX.js → connected-teams-SYQQGCXD.js} +2 -2
- package/dist/{coordinator-prompt-PNUDN4DW.js → coordinator-prompt-GXJIPWNA.js} +7 -5
- package/dist/{coordinator-prompt-S4HHFSLI.js → coordinator-prompt-WB65HIZ3.js} +9 -7
- package/dist/{cursor-recover-NDMLLNYX.js → cursor-recover-DTQAUDGO.js} +2 -2
- package/dist/{cursor-recover-L5MD6MBO.js → cursor-recover-TXVTLAMA.js} +1 -1
- package/dist/github-DWROJOB7.js +11 -0
- package/dist/github-IIF7AQNO.js +9 -0
- package/dist/{global-workspace-2BVCJUAL.js → global-workspace-BZ6V6TEX.js} +7 -5
- package/dist/{global-workspace-JTBBH2K5.js → global-workspace-MMK5UFUZ.js} +9 -7
- package/dist/index.cjs +274 -194
- package/dist/index.d.cts +47 -8
- package/dist/index.d.ts +47 -8
- package/dist/index.js +98 -127
- package/dist/mcp/run-stdio.cjs +260 -190
- package/dist/mcp/run-stdio.js +36 -76
- package/dist/{orchestrator-LWEZ74RK.js → orchestrator-4KI6VIFG.js} +14 -12
- package/dist/{orchestrator-4G76BOHH.js → orchestrator-SFOT6Q6F.js} +13 -11
- package/dist/{paths-RRCLNSJB.js → paths-C2VERLAE.js} +1 -1
- package/dist/{paths-53TLA7VQ.js → paths-LOXCISLX.js} +1 -1
- package/dist/{thread-store-ZL6GDIDP.js → thread-store-CO77HV2K.js} +2 -2
- package/dist/{thread-store-RXXNSRVO.js → thread-store-M4B52FUS.js} +2 -2
- package/dist/{workspaces-OY7D5RPU.js → workspaces-ACMZMKPD.js} +7 -5
- package/dist/{workspaces-ZYPME3YD.js → workspaces-KPJS7GLY.js} +9 -7
- package/dist/{worktree-7LOSSD7G.js → worktree-6IEVF3GN.js} +15 -12
- package/dist/{worktree-LPWTX2NA.js → worktree-UW6DNBIE.js} +20 -17
- package/dist/worktree-labels-3XDS6O3U.js +22 -0
- package/dist/worktree-labels-PEDOJBMD.js +24 -0
- package/package.json +1 -1
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
import {
|
|
4
|
+
extractPresentedPlan,
|
|
5
|
+
readPlanFile,
|
|
6
|
+
writePlanFile
|
|
7
|
+
} from "./chunk-JFOPOMK7.js";
|
|
8
|
+
import {
|
|
9
|
+
releaseCaffeinateHoldForThread
|
|
10
|
+
} from "./chunk-YWI3IBP2.js";
|
|
3
11
|
import {
|
|
4
12
|
PLAN_MODE_INSTRUCTION,
|
|
5
13
|
applyAgentEvent,
|
|
@@ -33,15 +41,7 @@ import {
|
|
|
33
41
|
summarizeTurnStderr,
|
|
34
42
|
toolDescription,
|
|
35
43
|
turnFailChatText
|
|
36
|
-
} from "./chunk-
|
|
37
|
-
import {
|
|
38
|
-
extractPresentedPlan,
|
|
39
|
-
readPlanFile,
|
|
40
|
-
writePlanFile
|
|
41
|
-
} from "./chunk-JFOPOMK7.js";
|
|
42
|
-
import {
|
|
43
|
-
releaseCaffeinateHoldForThread
|
|
44
|
-
} from "./chunk-OCQPTUR7.js";
|
|
44
|
+
} from "./chunk-EBPBGQ4P.js";
|
|
45
45
|
import {
|
|
46
46
|
SLACK_REPLY_FORMATTING,
|
|
47
47
|
addWorkspace,
|
|
@@ -64,10 +64,9 @@ import {
|
|
|
64
64
|
stageAbsolutePathsAsAttachments,
|
|
65
65
|
stageBuffersAsAttachments,
|
|
66
66
|
syncWorkspacesFromThreads
|
|
67
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-HIX2VDRE.js";
|
|
68
68
|
import {
|
|
69
69
|
addPrStackLayer,
|
|
70
|
-
allocateTeamName,
|
|
71
70
|
allocateTeamSlug,
|
|
72
71
|
canonicalizeRepoPath,
|
|
73
72
|
commitAll,
|
|
@@ -90,13 +89,11 @@ import {
|
|
|
90
89
|
getPrStack,
|
|
91
90
|
initPrStack,
|
|
92
91
|
isDirty,
|
|
93
|
-
isPlaceholderBranch,
|
|
94
92
|
isSideboardScratchPath,
|
|
95
93
|
listWorktrees,
|
|
96
94
|
markPrReady,
|
|
97
95
|
mergeAgentGitAuthEnv,
|
|
98
96
|
mergePr,
|
|
99
|
-
normalizeWorktreePath,
|
|
100
97
|
originGhRepoEnv,
|
|
101
98
|
pushBranch,
|
|
102
99
|
removeWorktree,
|
|
@@ -107,14 +104,8 @@ import {
|
|
|
107
104
|
resolvePrSelector,
|
|
108
105
|
resolvePrSelectors,
|
|
109
106
|
resolveRepoRoot,
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
ticketSlugForBranch,
|
|
113
|
-
withRepoGitLock,
|
|
114
|
-
worktreeDisplayLabelForGroup,
|
|
115
|
-
worktreeNameFromPath,
|
|
116
|
-
worktreeSlugForTicket
|
|
117
|
-
} from "./chunk-XBLN52RZ.js";
|
|
107
|
+
withRepoGitLock
|
|
108
|
+
} from "./chunk-XPKKCFRT.js";
|
|
118
109
|
import {
|
|
119
110
|
ATTACHMENTS_DIR,
|
|
120
111
|
DETACHED_JOBS_DIR,
|
|
@@ -132,7 +123,18 @@ import {
|
|
|
132
123
|
updateThread,
|
|
133
124
|
withThreadLock,
|
|
134
125
|
writeThread
|
|
135
|
-
} from "./chunk-
|
|
126
|
+
} from "./chunk-CJFBSQIB.js";
|
|
127
|
+
import {
|
|
128
|
+
allocateTeamName,
|
|
129
|
+
isPlaceholderBranch,
|
|
130
|
+
normalizeWorktreePath,
|
|
131
|
+
takenSlugsFromThread,
|
|
132
|
+
threadDisplayLabel,
|
|
133
|
+
ticketSlugForBranch,
|
|
134
|
+
worktreeDisplayLabelForGroup,
|
|
135
|
+
worktreeNameFromPath,
|
|
136
|
+
worktreeSlugForTicket
|
|
137
|
+
} from "./chunk-64QSHOKV.js";
|
|
136
138
|
import {
|
|
137
139
|
ensureWorktreeSideboardIgnored
|
|
138
140
|
} from "./chunk-SYFVUF2C.js";
|
|
@@ -168,7 +170,7 @@ import {
|
|
|
168
170
|
stripNestedElectronEnv,
|
|
169
171
|
updateAdvancedSettings,
|
|
170
172
|
writeSecureJson
|
|
171
|
-
} from "./chunk-
|
|
173
|
+
} from "./chunk-KORE4WOF.js";
|
|
172
174
|
import {
|
|
173
175
|
writePrivateFile
|
|
174
176
|
} from "./chunk-NSTQ6QKD.js";
|
|
@@ -184,7 +186,11 @@ import {
|
|
|
184
186
|
threadsDir,
|
|
185
187
|
workspaceSettingsSourceLabel,
|
|
186
188
|
worktreesRoot
|
|
187
|
-
} from "./chunk-
|
|
189
|
+
} from "./chunk-EQNRWDLN.js";
|
|
190
|
+
import {
|
|
191
|
+
examplePrefixedBranch,
|
|
192
|
+
sanitizeGitBranchPrefix
|
|
193
|
+
} from "./chunk-JTWKGOFI.js";
|
|
188
194
|
|
|
189
195
|
// src/orchestrator/orchestrator.ts
|
|
190
196
|
import { EventEmitter } from "events";
|
|
@@ -402,7 +408,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
402
408
|
await continueOnReply(threadId, prompt);
|
|
403
409
|
return;
|
|
404
410
|
}
|
|
405
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
411
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-SFOT6Q6F.js");
|
|
406
412
|
await getOrchestrator2().send(threadId, prompt);
|
|
407
413
|
} catch {
|
|
408
414
|
}
|
|
@@ -795,9 +801,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
795
801
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
796
802
|
);
|
|
797
803
|
}
|
|
798
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
804
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-BZ6V6TEX.js");
|
|
799
805
|
if (isGlobalThread2(thread)) {
|
|
800
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
806
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-GXJIPWNA.js");
|
|
801
807
|
ensureGlobalCoordinatorCwd2(
|
|
802
808
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
803
809
|
);
|
|
@@ -912,80 +918,6 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
912
918
|
};
|
|
913
919
|
}
|
|
914
920
|
|
|
915
|
-
// src/land/pr-metadata.ts
|
|
916
|
-
var GENERIC_TITLE_RE = /^(sideboard:|thread\/|wip\b|tmp\b|update\b|changes?\b|misc\b|stuff\b)/i;
|
|
917
|
-
function looksGeneric(title) {
|
|
918
|
-
const t = title.trim();
|
|
919
|
-
if (!t) return true;
|
|
920
|
-
if (t.length < 4) return true;
|
|
921
|
-
if (GENERIC_TITLE_RE.test(t)) return true;
|
|
922
|
-
if (!/[\s:/\-_]/.test(t) && t.length <= 24) return true;
|
|
923
|
-
return false;
|
|
924
|
-
}
|
|
925
|
-
function truncateTitle(title, max = 72) {
|
|
926
|
-
const t = title.trim().replace(/\s+/g, " ");
|
|
927
|
-
if (t.length <= max) return t;
|
|
928
|
-
return `${t.slice(0, max - 1).trimEnd()}\u2026`;
|
|
929
|
-
}
|
|
930
|
-
function titleFromPaths(paths) {
|
|
931
|
-
if (paths.length === 0) return null;
|
|
932
|
-
const top = paths.slice(0, 3).map((p) => p.replace(/\/$/, ""));
|
|
933
|
-
if (paths.length === 1) return truncateTitle(`Update ${top[0]}`);
|
|
934
|
-
if (paths.length <= 3) return truncateTitle(`Update ${top.join(", ")}`);
|
|
935
|
-
return truncateTitle(`Update ${top[0]} and ${paths.length - 1} more files`);
|
|
936
|
-
}
|
|
937
|
-
async function suggestPrMetadata(worktreePath, opts) {
|
|
938
|
-
const [{ stdout: logOut }, { stdout: nameStatus }, { stdout: statOut }] = await Promise.all([
|
|
939
|
-
git(["log", "--format=%s", `${opts.base}..HEAD`], worktreePath, {
|
|
940
|
-
reject: false
|
|
941
|
-
}),
|
|
942
|
-
git(["diff", "--name-only", `${opts.base}...HEAD`], worktreePath, {
|
|
943
|
-
reject: false
|
|
944
|
-
}),
|
|
945
|
-
git(["diff", "--stat", `${opts.base}...HEAD`], worktreePath, {
|
|
946
|
-
reject: false
|
|
947
|
-
})
|
|
948
|
-
]);
|
|
949
|
-
const { stdout: dirtyNames } = await git(["diff", "--name-only", "HEAD"], worktreePath, {
|
|
950
|
-
reject: false
|
|
951
|
-
});
|
|
952
|
-
const { stdout: untracked } = await git(
|
|
953
|
-
["ls-files", "--others", "--exclude-standard"],
|
|
954
|
-
worktreePath,
|
|
955
|
-
{ reject: false }
|
|
956
|
-
);
|
|
957
|
-
const subjects = logOut.split("\n").map((s) => s.trim()).filter(Boolean);
|
|
958
|
-
const paths = [
|
|
959
|
-
...new Set(
|
|
960
|
-
[...nameStatus.split("\n"), ...dirtyNames.split("\n"), ...untracked.split("\n")].map((p) => p.trim()).filter(Boolean)
|
|
961
|
-
)
|
|
962
|
-
].sort((a, b) => a.localeCompare(b));
|
|
963
|
-
const meaningfulSubjects = subjects.filter((s) => !looksGeneric(s));
|
|
964
|
-
const fallback = opts.fallbackTitle?.trim() || null;
|
|
965
|
-
const fallbackOk = fallback && !looksGeneric(fallback) ? fallback : null;
|
|
966
|
-
const title = truncateTitle(
|
|
967
|
-
meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? "Sideboard changes"
|
|
968
|
-
);
|
|
969
|
-
const commitMessage = meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? `sideboard: ${title}`;
|
|
970
|
-
const summaryLines = meaningfulSubjects.length > 0 ? meaningfulSubjects.slice(0, 12).map((s) => `- ${s}`) : paths.slice(0, 20).map((p) => `- \`${p}\``);
|
|
971
|
-
const bodyParts = [
|
|
972
|
-
"## Summary",
|
|
973
|
-
summaryLines.length > 0 ? summaryLines.join("\n") : "- Changes landed via Sideboard.",
|
|
974
|
-
""
|
|
975
|
-
];
|
|
976
|
-
if (statOut.trim()) {
|
|
977
|
-
bodyParts.push("## Diff", "```", statOut.trim(), "```", "");
|
|
978
|
-
}
|
|
979
|
-
if (opts.sourceLabel) {
|
|
980
|
-
bodyParts.push(`_Landed via Sideboard from ${opts.sourceLabel}_`);
|
|
981
|
-
}
|
|
982
|
-
return {
|
|
983
|
-
title,
|
|
984
|
-
body: bodyParts.join("\n").trim() + "\n",
|
|
985
|
-
commitMessage: truncateTitle(commitMessage, 72)
|
|
986
|
-
};
|
|
987
|
-
}
|
|
988
|
-
|
|
989
921
|
// src/git/agent-git-actions.ts
|
|
990
922
|
var AGENT_GIT_ACTIONS = [
|
|
991
923
|
"commit-push",
|
|
@@ -1014,6 +946,19 @@ function agentGitPrompt(action, opts) {
|
|
|
1014
946
|
return "Merge PR.";
|
|
1015
947
|
}
|
|
1016
948
|
}
|
|
949
|
+
function resolveSidebarGitPrompt(action, opts) {
|
|
950
|
+
if (action === "create-pr" || action === "create-draft" || action === "create-web") {
|
|
951
|
+
const custom = opts?.createPr?.trim();
|
|
952
|
+
if (custom) return custom;
|
|
953
|
+
return agentGitPrompt(action === "create-pr" ? "create-draft" : action);
|
|
954
|
+
}
|
|
955
|
+
if (action === "resolve-conflicts") {
|
|
956
|
+
const custom = opts?.resolveMergeConflicts?.trim();
|
|
957
|
+
if (custom) return custom;
|
|
958
|
+
return agentGitPrompt("resolve-conflicts", opts);
|
|
959
|
+
}
|
|
960
|
+
return agentGitPrompt(action, opts);
|
|
961
|
+
}
|
|
1017
962
|
var RESOLVE_CONFLICTS_RE = /^Merge the remote branch(?: \(([^)]+)\))? into your branch and resolve conflicts\. Then, commit and push your changes\.$/;
|
|
1018
963
|
function gitActionExpansion(action, base) {
|
|
1019
964
|
switch (action) {
|
|
@@ -3585,7 +3530,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
3585
3530
|
});
|
|
3586
3531
|
await requireAgent(resolved.agent);
|
|
3587
3532
|
if (input.cowboy) {
|
|
3588
|
-
const { cowboyModeEnabled } = await import("./app-settings-
|
|
3533
|
+
const { cowboyModeEnabled } = await import("./app-settings-QYLNKRK4.js");
|
|
3589
3534
|
if (!cowboyModeEnabled()) {
|
|
3590
3535
|
throw new Error(
|
|
3591
3536
|
"Cowboy mode is off. Enable it in Settings \u2192 Advanced."
|
|
@@ -3643,7 +3588,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
3643
3588
|
let sourceIsFork = false;
|
|
3644
3589
|
if (!input.cowboy && sourceType === "branch" && (!sourceRef || sourceRef === "HEAD" || sourceRef === "default")) {
|
|
3645
3590
|
if (isAbleTimeConnected() && getIssueSource() === "abletime") {
|
|
3646
|
-
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-
|
|
3591
|
+
const { ensureAbleTimeTask, issueAttachmentForAbleTimeTask } = await import("./abletime-UX53JTIH.js");
|
|
3647
3592
|
const task = await ensureAbleTimeTask({
|
|
3648
3593
|
title: title?.trim() || "Untitled work",
|
|
3649
3594
|
description: input.prompt?.trim() || void 0
|
|
@@ -4155,7 +4100,7 @@ async function adoptThread(input) {
|
|
|
4155
4100
|
messages: input.messages ?? []
|
|
4156
4101
|
});
|
|
4157
4102
|
writeThread(thread);
|
|
4158
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
4103
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ACMZMKPD.js");
|
|
4159
4104
|
await ensureWorkspace2(repoPath);
|
|
4160
4105
|
const { ensureWorktreeSideboardIgnored: ensureWorktreeSideboardIgnored2 } = await import("./worktree-exclude-N5X5I422.js");
|
|
4161
4106
|
await ensureWorktreeSideboardIgnored2(input.worktreePath);
|
|
@@ -5377,6 +5322,80 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
|
5377
5322
|
};
|
|
5378
5323
|
}
|
|
5379
5324
|
|
|
5325
|
+
// src/land/pr-metadata.ts
|
|
5326
|
+
var GENERIC_TITLE_RE = /^(sideboard:|thread\/|wip\b|tmp\b|update\b|changes?\b|misc\b|stuff\b)/i;
|
|
5327
|
+
function looksGeneric(title) {
|
|
5328
|
+
const t = title.trim();
|
|
5329
|
+
if (!t) return true;
|
|
5330
|
+
if (t.length < 4) return true;
|
|
5331
|
+
if (GENERIC_TITLE_RE.test(t)) return true;
|
|
5332
|
+
if (!/[\s:/\-_]/.test(t) && t.length <= 24) return true;
|
|
5333
|
+
return false;
|
|
5334
|
+
}
|
|
5335
|
+
function truncateTitle(title, max = 72) {
|
|
5336
|
+
const t = title.trim().replace(/\s+/g, " ");
|
|
5337
|
+
if (t.length <= max) return t;
|
|
5338
|
+
return `${t.slice(0, max - 1).trimEnd()}\u2026`;
|
|
5339
|
+
}
|
|
5340
|
+
function titleFromPaths(paths) {
|
|
5341
|
+
if (paths.length === 0) return null;
|
|
5342
|
+
const top = paths.slice(0, 3).map((p) => p.replace(/\/$/, ""));
|
|
5343
|
+
if (paths.length === 1) return truncateTitle(`Update ${top[0]}`);
|
|
5344
|
+
if (paths.length <= 3) return truncateTitle(`Update ${top.join(", ")}`);
|
|
5345
|
+
return truncateTitle(`Update ${top[0]} and ${paths.length - 1} more files`);
|
|
5346
|
+
}
|
|
5347
|
+
async function suggestPrMetadata(worktreePath, opts) {
|
|
5348
|
+
const [{ stdout: logOut }, { stdout: nameStatus }, { stdout: statOut }] = await Promise.all([
|
|
5349
|
+
git(["log", "--format=%s", `${opts.base}..HEAD`], worktreePath, {
|
|
5350
|
+
reject: false
|
|
5351
|
+
}),
|
|
5352
|
+
git(["diff", "--name-only", `${opts.base}...HEAD`], worktreePath, {
|
|
5353
|
+
reject: false
|
|
5354
|
+
}),
|
|
5355
|
+
git(["diff", "--stat", `${opts.base}...HEAD`], worktreePath, {
|
|
5356
|
+
reject: false
|
|
5357
|
+
})
|
|
5358
|
+
]);
|
|
5359
|
+
const { stdout: dirtyNames } = await git(["diff", "--name-only", "HEAD"], worktreePath, {
|
|
5360
|
+
reject: false
|
|
5361
|
+
});
|
|
5362
|
+
const { stdout: untracked } = await git(
|
|
5363
|
+
["ls-files", "--others", "--exclude-standard"],
|
|
5364
|
+
worktreePath,
|
|
5365
|
+
{ reject: false }
|
|
5366
|
+
);
|
|
5367
|
+
const subjects = logOut.split("\n").map((s) => s.trim()).filter(Boolean);
|
|
5368
|
+
const paths = [
|
|
5369
|
+
...new Set(
|
|
5370
|
+
[...nameStatus.split("\n"), ...dirtyNames.split("\n"), ...untracked.split("\n")].map((p) => p.trim()).filter(Boolean)
|
|
5371
|
+
)
|
|
5372
|
+
].sort((a, b) => a.localeCompare(b));
|
|
5373
|
+
const meaningfulSubjects = subjects.filter((s) => !looksGeneric(s));
|
|
5374
|
+
const fallback = opts.fallbackTitle?.trim() || null;
|
|
5375
|
+
const fallbackOk = fallback && !looksGeneric(fallback) ? fallback : null;
|
|
5376
|
+
const title = truncateTitle(
|
|
5377
|
+
meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? "Sideboard changes"
|
|
5378
|
+
);
|
|
5379
|
+
const commitMessage = meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? `sideboard: ${title}`;
|
|
5380
|
+
const summaryLines = meaningfulSubjects.length > 0 ? meaningfulSubjects.slice(0, 12).map((s) => `- ${s}`) : paths.slice(0, 20).map((p) => `- \`${p}\``);
|
|
5381
|
+
const bodyParts = [
|
|
5382
|
+
"## Summary",
|
|
5383
|
+
summaryLines.length > 0 ? summaryLines.join("\n") : "- Changes landed via Sideboard.",
|
|
5384
|
+
""
|
|
5385
|
+
];
|
|
5386
|
+
if (statOut.trim()) {
|
|
5387
|
+
bodyParts.push("## Diff", "```", statOut.trim(), "```", "");
|
|
5388
|
+
}
|
|
5389
|
+
if (opts.sourceLabel) {
|
|
5390
|
+
bodyParts.push(`_Landed via Sideboard from ${opts.sourceLabel}_`);
|
|
5391
|
+
}
|
|
5392
|
+
return {
|
|
5393
|
+
title,
|
|
5394
|
+
body: bodyParts.join("\n").trim() + "\n",
|
|
5395
|
+
commitMessage: truncateTitle(commitMessage, 72)
|
|
5396
|
+
};
|
|
5397
|
+
}
|
|
5398
|
+
|
|
5380
5399
|
// src/land/land.ts
|
|
5381
5400
|
async function previewLand(thread) {
|
|
5382
5401
|
if (thread.sourceIsFork) {
|
|
@@ -5874,13 +5893,14 @@ function formatRenameBranchDirective(thread, opts) {
|
|
|
5874
5893
|
if (!isPlaceholderBranch(thread.branchName, thread.worktreePath)) return null;
|
|
5875
5894
|
const dir = worktreeNameFromPath(thread.worktreePath);
|
|
5876
5895
|
const ticket = thread.sourceType === "ticket" ? ticketSlugForBranch(thread.sourceRef ?? "") : null;
|
|
5877
|
-
const
|
|
5896
|
+
const prefix = sanitizeGitBranchPrefix(opts?.branchPrefix);
|
|
5897
|
+
const example = examplePrefixedBranch(prefix, ticket);
|
|
5898
|
+
const shape = prefix ? `\`${prefix}/<ticket-or-task>-<short-kebab-description>\`` : "`<ticket-or-task>-<short-kebab-description>`";
|
|
5878
5899
|
const lines = [
|
|
5879
5900
|
"Branch naming (do this early in the turn):",
|
|
5880
5901
|
`- Current branch \`${thread.branchName}\` is a temporary placeholder. The worktree folder \`${dir}\` is a stable nickname \u2014 do not rename or leave that directory.`,
|
|
5881
|
-
`- Rename the git branch to
|
|
5902
|
+
`- Rename the git branch to ${shape}, e.g. \`${example}\`:`,
|
|
5882
5903
|
" `git branch -m <new-name>`",
|
|
5883
|
-
"- Prefer Conventional Commits style prefixes when they fit (`fix/`, `feat/`, `chore/`, `docs/`).",
|
|
5884
5904
|
...ticket ? [
|
|
5885
5905
|
`- Keep ticket \`${ticket}\` in the new branch name so the issue stays findable.`
|
|
5886
5906
|
] : [],
|
|
@@ -6458,7 +6478,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
6458
6478
|
${prompt}`;
|
|
6459
6479
|
}
|
|
6460
6480
|
async function defaultDeps() {
|
|
6461
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
6481
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-SFOT6Q6F.js");
|
|
6462
6482
|
const orch = getOrchestrator2();
|
|
6463
6483
|
return {
|
|
6464
6484
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -6733,7 +6753,7 @@ var Orchestrator = class {
|
|
|
6733
6753
|
orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
|
|
6734
6754
|
});
|
|
6735
6755
|
}
|
|
6736
|
-
const { autoCleanupOrphansEnabled } = await import("./app-settings-
|
|
6756
|
+
const { autoCleanupOrphansEnabled } = await import("./app-settings-QYLNKRK4.js");
|
|
6737
6757
|
if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
|
|
6738
6758
|
await cleanupOrphanWorktrees({ repoPaths });
|
|
6739
6759
|
}
|
|
@@ -7012,7 +7032,7 @@ var Orchestrator = class {
|
|
|
7012
7032
|
}
|
|
7013
7033
|
await setup;
|
|
7014
7034
|
if (skipSetup) return;
|
|
7015
|
-
const { autoRunAfterSetupEnabled } = await import("./app-settings-
|
|
7035
|
+
const { autoRunAfterSetupEnabled } = await import("./app-settings-QYLNKRK4.js");
|
|
7016
7036
|
if (autoRunAfterSetupEnabled()) {
|
|
7017
7037
|
try {
|
|
7018
7038
|
await this.startDev(threadId);
|
|
@@ -7335,7 +7355,7 @@ var Orchestrator = class {
|
|
|
7335
7355
|
}
|
|
7336
7356
|
const isBrightsy = fresh.agent === "brightsy";
|
|
7337
7357
|
const isOrchestration = isOrchestratorThread(fresh);
|
|
7338
|
-
const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("./app-settings-
|
|
7358
|
+
const { autoRenameBranchEnabled, getGithubGitAuthMode, gitBranchPrefixSetting } = await import("./app-settings-QYLNKRK4.js");
|
|
7339
7359
|
const gitAuthMode = getGithubGitAuthMode();
|
|
7340
7360
|
const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
|
|
7341
7361
|
githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
|
|
@@ -7371,9 +7391,26 @@ var Orchestrator = class {
|
|
|
7371
7391
|
}
|
|
7372
7392
|
}
|
|
7373
7393
|
const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
|
|
7374
|
-
|
|
7375
|
-
|
|
7376
|
-
|
|
7394
|
+
let renameBranchDirective = null;
|
|
7395
|
+
if (!isBrightsy && !isOrchestration && autoRenameBranchEnabled()) {
|
|
7396
|
+
const { isPlaceholderBranch: isPlaceholderBranch2 } = await import("./worktree-labels-PEDOJBMD.js");
|
|
7397
|
+
let githubLogin = null;
|
|
7398
|
+
if (isPlaceholderBranch2(fresh.branchName, fresh.worktreePath) && !gitBranchPrefixSetting()) {
|
|
7399
|
+
try {
|
|
7400
|
+
const { getGitHubStatus } = await import("./github-DWROJOB7.js");
|
|
7401
|
+
githubLogin = (await getGitHubStatus()).login;
|
|
7402
|
+
} catch {
|
|
7403
|
+
}
|
|
7404
|
+
}
|
|
7405
|
+
const { resolveGitBranchPrefix } = await import("./branch-prefix-EVW2KHGQ.js");
|
|
7406
|
+
renameBranchDirective = formatRenameBranchDirective(fresh, {
|
|
7407
|
+
customPrompt: settings?.prompts?.renameBranch,
|
|
7408
|
+
branchPrefix: resolveGitBranchPrefix({
|
|
7409
|
+
setting: gitBranchPrefixSetting(),
|
|
7410
|
+
githubLogin
|
|
7411
|
+
})
|
|
7412
|
+
});
|
|
7413
|
+
}
|
|
7377
7414
|
let seed = null;
|
|
7378
7415
|
if (!fresh.sessionId) {
|
|
7379
7416
|
const prior = fresh.messages.slice(0, -1);
|
|
@@ -7468,7 +7505,7 @@ var Orchestrator = class {
|
|
|
7468
7505
|
if (!this.stoppedTurns.has(threadId) && this.requireThread(threadId).agent === "cursor" && exitCode !== 0 && !assistantText && parts.length === 0) {
|
|
7469
7506
|
const sessionId = result.sessionId || this.requireThread(threadId).sessionId || "";
|
|
7470
7507
|
if (sessionId) {
|
|
7471
|
-
const { recoverFinishedCursorRun } = await import("./cursor-recover-
|
|
7508
|
+
const { recoverFinishedCursorRun } = await import("./cursor-recover-TXVTLAMA.js");
|
|
7472
7509
|
for (let i = 0; i < 8; i++) {
|
|
7473
7510
|
const recovered = recoverFinishedCursorRun({
|
|
7474
7511
|
agentId: sessionId,
|
|
@@ -8261,7 +8298,7 @@ var Orchestrator = class {
|
|
|
8261
8298
|
updateThread(thread.id, { title: meta.title });
|
|
8262
8299
|
}
|
|
8263
8300
|
}
|
|
8264
|
-
const { autoArchiveOnMergeEnabled } = await import("./app-settings-
|
|
8301
|
+
const { autoArchiveOnMergeEnabled } = await import("./app-settings-QYLNKRK4.js");
|
|
8265
8302
|
const latest = this.requireThread(thread.id);
|
|
8266
8303
|
if (!shouldAutoArchiveOnPrMerge({
|
|
8267
8304
|
previousPrState: prevState || null,
|
|
@@ -8403,9 +8440,9 @@ var Orchestrator = class {
|
|
|
8403
8440
|
return tab;
|
|
8404
8441
|
}
|
|
8405
8442
|
/**
|
|
8406
|
-
* Desktop git buttons + MCP `ask_git`.
|
|
8407
|
-
*
|
|
8408
|
-
*
|
|
8443
|
+
* Desktop git buttons + MCP `ask_git`. Always queues the worktree agent
|
|
8444
|
+
* with the action prompt (same path as Resolve). Repository `[prompts]`
|
|
8445
|
+
* overrides apply when set.
|
|
8409
8446
|
*/
|
|
8410
8447
|
async askGit(threadRef, action) {
|
|
8411
8448
|
if (!AGENT_GIT_ACTIONS.includes(action)) {
|
|
@@ -8423,17 +8460,6 @@ var Orchestrator = class {
|
|
|
8423
8460
|
"No pull request linked. Ask the worktree agent to open a draft PR first (ask_git create-draft)."
|
|
8424
8461
|
);
|
|
8425
8462
|
}
|
|
8426
|
-
if ((action === "commit-push" || action === "create-draft" || action === "create-web") && thread.worktreePath?.trim() && !await isDirty(thread.worktreePath)) {
|
|
8427
|
-
try {
|
|
8428
|
-
await this.pushAndMaybeOpenPr(thread, action);
|
|
8429
|
-
} catch (err) {
|
|
8430
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
8431
|
-
updateThread(thread.id, { lastError: message });
|
|
8432
|
-
this.emit({ type: "error", threadId: thread.id, message });
|
|
8433
|
-
throw err;
|
|
8434
|
-
}
|
|
8435
|
-
return this.requireThread(threadRef);
|
|
8436
|
-
}
|
|
8437
8463
|
let prBase;
|
|
8438
8464
|
if (action === "resolve-conflicts") {
|
|
8439
8465
|
try {
|
|
@@ -8442,42 +8468,18 @@ var Orchestrator = class {
|
|
|
8442
8468
|
} catch {
|
|
8443
8469
|
}
|
|
8444
8470
|
}
|
|
8445
|
-
|
|
8446
|
-
|
|
8447
|
-
|
|
8448
|
-
|
|
8449
|
-
|
|
8450
|
-
|
|
8451
|
-
|
|
8452
|
-
|
|
8453
|
-
|
|
8454
|
-
|
|
8455
|
-
|
|
8456
|
-
|
|
8457
|
-
base,
|
|
8458
|
-
fallbackTitle: thread.prTitle ?? thread.title
|
|
8459
|
-
});
|
|
8460
|
-
const url = await createOrUpdatePr(cwd, {
|
|
8461
|
-
title: meta.title,
|
|
8462
|
-
body: meta.body,
|
|
8463
|
-
base,
|
|
8464
|
-
head: branch,
|
|
8465
|
-
draft: action === "create-draft",
|
|
8466
|
-
web: action === "create-web"
|
|
8467
|
-
});
|
|
8468
|
-
if (!url) return;
|
|
8469
|
-
const patch = {
|
|
8470
|
-
prUrl: url,
|
|
8471
|
-
prTitle: meta.title,
|
|
8472
|
-
prIsDraft: action === "create-draft"
|
|
8473
|
-
};
|
|
8474
|
-
try {
|
|
8475
|
-
const fetched = await getPrMeta(cwd, url);
|
|
8476
|
-
if (fetched?.title) patch.prTitle = fetched.title;
|
|
8477
|
-
if (fetched) patch.prIsDraft = Boolean(fetched.isDraft);
|
|
8478
|
-
} catch {
|
|
8479
|
-
}
|
|
8480
|
-
updateThread(thread.id, patch);
|
|
8471
|
+
const settings = loadWorkspaceSettings(thread.worktreePath, thread.repoPath);
|
|
8472
|
+
return this.send(
|
|
8473
|
+
threadRef,
|
|
8474
|
+
resolveSidebarGitPrompt(action, {
|
|
8475
|
+
prBase,
|
|
8476
|
+
createPr: settings?.prompts?.createPr,
|
|
8477
|
+
resolveMergeConflicts: settings?.prompts?.resolveMergeConflicts
|
|
8478
|
+
}),
|
|
8479
|
+
{
|
|
8480
|
+
followUp: resolveOrchChildFollowUp()
|
|
8481
|
+
}
|
|
8482
|
+
);
|
|
8481
8483
|
}
|
|
8482
8484
|
setThreadOptions(threadRef, patch) {
|
|
8483
8485
|
const thread = this.requireThread(threadRef);
|
|
@@ -8588,7 +8590,7 @@ var Orchestrator = class {
|
|
|
8588
8590
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
8589
8591
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
8590
8592
|
try {
|
|
8591
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
8593
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-ACMZMKPD.js");
|
|
8592
8594
|
await ensureWorkspace2(thread.repoPath);
|
|
8593
8595
|
} catch {
|
|
8594
8596
|
}
|
|
@@ -8615,7 +8617,7 @@ var Orchestrator = class {
|
|
|
8615
8617
|
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
8616
8618
|
} catch {
|
|
8617
8619
|
}
|
|
8618
|
-
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-
|
|
8620
|
+
const { deleteBranchOnPurgeEnabled } = await import("./app-settings-QYLNKRK4.js");
|
|
8619
8621
|
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
|
|
8620
8622
|
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
8621
8623
|
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
@@ -8630,7 +8632,7 @@ var Orchestrator = class {
|
|
|
8630
8632
|
throw new Error("Thread is not archived");
|
|
8631
8633
|
}
|
|
8632
8634
|
if (isGlobalThread(thread)) {
|
|
8633
|
-
const { globalAgentCwd } = await import("./paths-
|
|
8635
|
+
const { globalAgentCwd } = await import("./paths-C2VERLAE.js");
|
|
8634
8636
|
updateThread(thread.id, { worktreePath: globalAgentCwd() });
|
|
8635
8637
|
const restored2 = setStatus(thread.id, "idle");
|
|
8636
8638
|
this.emit({ type: "status_changed", threadId: restored2.id, status: restored2.status });
|
|
@@ -8642,7 +8644,7 @@ var Orchestrator = class {
|
|
|
8642
8644
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
8643
8645
|
);
|
|
8644
8646
|
}
|
|
8645
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
8647
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-6IEVF3GN.js");
|
|
8646
8648
|
const slug = thread.worktreePath.split("/").pop();
|
|
8647
8649
|
const dest = thread.worktreePath;
|
|
8648
8650
|
await withRepoGitLock(thread.repoPath, async () => {
|
|
@@ -8752,7 +8754,7 @@ async function startOrchestration(opts) {
|
|
|
8752
8754
|
sourceRef: "default",
|
|
8753
8755
|
...createOpts
|
|
8754
8756
|
}).catch(async () => {
|
|
8755
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
8757
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-6IEVF3GN.js");
|
|
8756
8758
|
const repo = await resolveRepoRoot2(repoPath);
|
|
8757
8759
|
const def = await resolveDefaultBranch2(repo);
|
|
8758
8760
|
return orch.createThread({
|
|
@@ -8762,7 +8764,7 @@ async function startOrchestration(opts) {
|
|
|
8762
8764
|
repoPath: repo
|
|
8763
8765
|
});
|
|
8764
8766
|
});
|
|
8765
|
-
const { updateThread: upd } = await import("./thread-store-
|
|
8767
|
+
const { updateThread: upd } = await import("./thread-store-CO77HV2K.js");
|
|
8766
8768
|
const updated = upd(thread.id, {
|
|
8767
8769
|
sourceType: "orchestration",
|
|
8768
8770
|
sourceRef: goal
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
allocateTeamName,
|
|
3
2
|
ensureGhPreferOrigin,
|
|
4
3
|
resolveGithubRepoSlug,
|
|
5
|
-
resolveRepoRoot
|
|
6
|
-
|
|
7
|
-
teamSlugFromName
|
|
8
|
-
} from "./chunk-WXKXSZN4.js";
|
|
4
|
+
resolveRepoRoot
|
|
5
|
+
} from "./chunk-BIKCWYRP.js";
|
|
9
6
|
import {
|
|
10
7
|
ATTACHMENTS_DIR,
|
|
11
8
|
attachmentsGitignoreBody
|
|
@@ -22,18 +19,23 @@ import {
|
|
|
22
19
|
resolveThreadDefaults,
|
|
23
20
|
resolveViewerProfile,
|
|
24
21
|
resolveViewerProfileForRepo
|
|
25
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-BWRS6GAS.js";
|
|
26
23
|
import {
|
|
27
24
|
createEmptyThread,
|
|
28
25
|
listThreads,
|
|
29
26
|
updateThread,
|
|
30
27
|
writeThread
|
|
31
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-KJBYIIJU.js";
|
|
32
29
|
import {
|
|
33
30
|
appDataDir,
|
|
34
31
|
globalAgentCwd,
|
|
35
32
|
sideboardReposDir
|
|
36
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-WFUDY6PC.js";
|
|
34
|
+
import {
|
|
35
|
+
allocateTeamName,
|
|
36
|
+
takenSlugsFromThread,
|
|
37
|
+
teamSlugFromName
|
|
38
|
+
} from "./chunk-RCWHL4TK.js";
|
|
37
39
|
|
|
38
40
|
// src/store/workspaces.ts
|
|
39
41
|
import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
@@ -406,7 +408,7 @@ var COORDINATOR_TOOL_PLAYBOOK = [
|
|
|
406
408
|
"- get_diff \u2014 compact diff summary",
|
|
407
409
|
"- get_pr_checks \u2014 snapshot of a worktree thread's PR checks (null = no PR). Use this to inspect status. If the user gave a goal, the worktree agent watches with `gh pr checks --watch` \u2014 do not poll for the human.",
|
|
408
410
|
'- request_review \u2014 open a Review chat tab on a worktree thread (attaches .claude/skills/review/SKILL.md when present, else .context/review.md copied from .sideboard/review.md / stock; sends "Review changes in this workspace."); then wait_for_turn (loop while stillRunning) / get_turn_result on the returned id. The review stays in that chat so they can read it and type next steps \u2014 do not tell the child to comment or update the PR or ticket.',
|
|
409
|
-
"- ask_git \u2014 commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge
|
|
411
|
+
"- ask_git \u2014 commit & push, open a draft PR, mark ready for review, resolve conflicts, or merge \u2014 same prompts as the desktop git buttons (Resolve, Create PR, \u2026). Always steers the worktree agent; then wait_for_turn (loop while stillRunning). Prefer this over paraphrasing. If the user gave a goal (Greptile 5/5, CI green), send_to_thread that goal so the worktree agent enters the watch-fix-push loop \u2014 do not tell the human to poll.",
|
|
410
412
|
'- Merge (`ask_git` action=merge / send_to_thread "Merge PR.") only when the user explicitly asked to merge that PR. Do not merge because the work looks done, CI is green, or a typical flow includes it.',
|
|
411
413
|
'- Or send_to_thread with those exact phrases: "Commit and push.", "Commit, push, and open a draft PR.", "Ready for review.", "Merge the remote branch (main) into your branch and resolve conflicts. Then, commit and push your changes.", "Merge PR." (draft PRs: `gh pr create --draft -R <origin-owner/name>` using the workspace `github:` slug \u2014 never upstream). Never run git/gh from this orchestration cwd, and never merge the PR yourself.',
|
|
412
414
|
"Process guides:",
|