@sideboard-ai/core 0.1.77 → 0.1.81
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-LKUHPPEQ.js → agents-EBKJ55PN.js} +5 -5
- package/dist/{agents-XJV6J3K2.js → agents-UQ7D6U6L.js} +6 -6
- package/dist/{app-settings-3TLA2EJ7.js → app-settings-6IOQYGBK.js} +7 -1
- package/dist/{app-settings-P42Z3VOB.js → app-settings-NILNWNNQ.js} +7 -1
- package/dist/{chunk-2FJI5JXX.js → chunk-4AVU4QXO.js} +54 -20
- package/dist/{chunk-XJNCWYFR.js → chunk-4HJK57XU.js} +8 -14
- package/dist/{chunk-VERLUKN2.js → chunk-6F2TQFJE.js} +6 -6
- package/dist/{chunk-EEKSZTMU.js → chunk-CQBQWX73.js} +10 -16
- package/dist/{chunk-OE7YBB5X.js → chunk-FUUVPN4A.js} +108 -3
- package/dist/{chunk-W7YOTDVO.js → chunk-IFPN6TER.js} +47 -2
- package/dist/{chunk-75U65MBE.js → chunk-K553XK7M.js} +2 -2
- package/dist/{chunk-GWTLKXXP.js → chunk-P5VDPGAN.js} +3 -3
- package/dist/{chunk-2ZIPJRJE.js → chunk-TDJ43HUD.js} +2 -2
- package/dist/{chunk-PTJJIQK7.js → chunk-XKNBSYA7.js} +47 -2
- package/dist/{chunk-QD37IILI.js → chunk-XNECBC6T.js} +66 -20
- package/dist/{chunk-MF2YMEGD.js → chunk-YVVXWWCC.js} +110 -3
- package/dist/{coordinator-prompt-LLFJUO2R.js → coordinator-prompt-JQF72JKX.js} +4 -4
- package/dist/{coordinator-prompt-MRCMMRSF.js → coordinator-prompt-NYNEFKIV.js} +3 -3
- package/dist/{global-workspace-YNMNO4CL.js → global-workspace-DZM4ZFGU.js} +5 -5
- package/dist/{global-workspace-TWHMYLTZ.js → global-workspace-NUMUJRWG.js} +4 -4
- package/dist/index.cjs +585 -251
- package/dist/index.d.cts +97 -8
- package/dist/index.d.ts +97 -8
- package/dist/index.js +363 -222
- package/dist/mcp/run-stdio.cjs +2502 -2286
- package/dist/mcp/run-stdio.js +162 -133
- package/dist/{workspaces-O3U5BENH.js → workspaces-QLRCOXAY.js} +6 -6
- package/dist/{workspaces-GQ4XKBD3.js → workspaces-SUU2GO3A.js} +5 -5
- package/dist/{worktree-VOCH3WS3.js → worktree-5VLLFI5W.js} +5 -1
- package/dist/{worktree-KWXHMKRN.js → worktree-UNSOCYZU.js} +5 -1
- package/package.json +1 -1
package/dist/mcp/run-stdio.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
PLAN_MODE_INSTRUCTION,
|
|
5
|
+
applyTurnUsage,
|
|
5
6
|
fallbackTurnFailDetail,
|
|
6
7
|
formatTurnExitError,
|
|
7
8
|
getAdapter,
|
|
@@ -16,14 +17,14 @@ import {
|
|
|
16
17
|
resolveQuotaFallbackAgent,
|
|
17
18
|
sideboardMcpProfile,
|
|
18
19
|
summarizeTurnStderr
|
|
19
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-4AVU4QXO.js";
|
|
20
21
|
import "../chunk-VROPG6QF.js";
|
|
21
22
|
import {
|
|
22
23
|
addWorkspace,
|
|
23
24
|
ensureWorkspace,
|
|
24
25
|
removeWorkspace,
|
|
25
26
|
syncWorkspacesFromThreads
|
|
26
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-TDJ43HUD.js";
|
|
27
28
|
import {
|
|
28
29
|
extractPresentedPlan,
|
|
29
30
|
readPlanFile,
|
|
@@ -41,14 +42,14 @@ import {
|
|
|
41
42
|
isGlobalThread,
|
|
42
43
|
isOrchestratorThread,
|
|
43
44
|
orchestratorSessionPoisonedByBuiltins
|
|
44
|
-
} from "../chunk-
|
|
45
|
+
} from "../chunk-P5VDPGAN.js";
|
|
45
46
|
import {
|
|
46
47
|
SLACK_REPLY_FORMATTING,
|
|
47
48
|
coordinatorSystemPrompt,
|
|
48
49
|
coordinatorTurnReminder,
|
|
49
50
|
enrichWorkspacesWithGithub,
|
|
50
51
|
ensureGlobalCoordinatorCwd
|
|
51
|
-
} from "../chunk-
|
|
52
|
+
} from "../chunk-4HJK57XU.js";
|
|
52
53
|
import {
|
|
53
54
|
addPrStackLayer,
|
|
54
55
|
allocateTeamName,
|
|
@@ -57,9 +58,11 @@ import {
|
|
|
57
58
|
createExistingBranchWorktree,
|
|
58
59
|
createOrUpdatePr,
|
|
59
60
|
createThreadWorktree,
|
|
61
|
+
currentBranch,
|
|
60
62
|
detectGhStack,
|
|
61
63
|
fetchPrHead,
|
|
62
64
|
formatGhLandError,
|
|
65
|
+
formatGitAuthModeDirective,
|
|
63
66
|
getPr,
|
|
64
67
|
getPrChecks,
|
|
65
68
|
getPrDetails,
|
|
@@ -85,7 +88,7 @@ import {
|
|
|
85
88
|
takenSlugsFromThread,
|
|
86
89
|
threadDisplayLabel,
|
|
87
90
|
worktreeNameFromPath
|
|
88
|
-
} from "../chunk-
|
|
91
|
+
} from "../chunk-FUUVPN4A.js";
|
|
89
92
|
import {
|
|
90
93
|
ATTACHMENTS_DIR,
|
|
91
94
|
LEGACY_ATTACHMENTS_DIR,
|
|
@@ -125,7 +128,7 @@ import {
|
|
|
125
128
|
saveLinearOAuth,
|
|
126
129
|
updateAdvancedSettings,
|
|
127
130
|
writeSecureJson
|
|
128
|
-
} from "../chunk-
|
|
131
|
+
} from "../chunk-XKNBSYA7.js";
|
|
129
132
|
import {
|
|
130
133
|
writePrivateFile
|
|
131
134
|
} from "../chunk-NSTQ6QKD.js";
|
|
@@ -880,34 +883,6 @@ function normalizeParseResult(parsed) {
|
|
|
880
883
|
return Array.isArray(parsed) ? parsed : [parsed];
|
|
881
884
|
}
|
|
882
885
|
|
|
883
|
-
// src/agents/usage.ts
|
|
884
|
-
function sumOptional(a, b) {
|
|
885
|
-
if (a == null && b == null) return void 0;
|
|
886
|
-
return (a ?? 0) + (b ?? 0);
|
|
887
|
-
}
|
|
888
|
-
function requestOccupancy(u) {
|
|
889
|
-
return u.inputTokens + (u.cacheReadTokens ?? 0) + (u.cacheWriteTokens ?? 0);
|
|
890
|
-
}
|
|
891
|
-
function mergeUsage(a, b) {
|
|
892
|
-
return {
|
|
893
|
-
inputTokens: (a?.inputTokens ?? 0) + b.inputTokens,
|
|
894
|
-
outputTokens: (a?.outputTokens ?? 0) + b.outputTokens,
|
|
895
|
-
cacheReadTokens: sumOptional(a?.cacheReadTokens, b.cacheReadTokens),
|
|
896
|
-
cacheWriteTokens: sumOptional(a?.cacheWriteTokens, b.cacheWriteTokens),
|
|
897
|
-
lastRequestTokens: b.lastRequestTokens ?? a?.lastRequestTokens
|
|
898
|
-
};
|
|
899
|
-
}
|
|
900
|
-
function applyTurnUsage(current, incoming, scope = "request") {
|
|
901
|
-
if (scope === "turn") {
|
|
902
|
-
return {
|
|
903
|
-
...incoming,
|
|
904
|
-
lastRequestTokens: current?.lastRequestTokens ?? requestOccupancy(incoming)
|
|
905
|
-
};
|
|
906
|
-
}
|
|
907
|
-
const merged = mergeUsage(current, incoming);
|
|
908
|
-
return { ...merged, lastRequestTokens: requestOccupancy(incoming) };
|
|
909
|
-
}
|
|
910
|
-
|
|
911
886
|
// src/agents/spawn.ts
|
|
912
887
|
async function spawnAgentTurn(thread, input, onEvent) {
|
|
913
888
|
ensureAgentPath();
|
|
@@ -916,9 +891,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
916
891
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
917
892
|
);
|
|
918
893
|
}
|
|
919
|
-
const { isGlobalThread: isGlobalThread2 } = await import("../global-workspace-
|
|
894
|
+
const { isGlobalThread: isGlobalThread2 } = await import("../global-workspace-NUMUJRWG.js");
|
|
920
895
|
if (isGlobalThread2(thread)) {
|
|
921
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("../coordinator-prompt-
|
|
896
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("../coordinator-prompt-NYNEFKIV.js");
|
|
922
897
|
ensureGlobalCoordinatorCwd2(
|
|
923
898
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
924
899
|
);
|
|
@@ -935,8 +910,13 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
935
910
|
}
|
|
936
911
|
const env = childEnvWithAppSettings(cmd.env);
|
|
937
912
|
if (!isOrchestratorThread(thread)) {
|
|
938
|
-
|
|
939
|
-
|
|
913
|
+
try {
|
|
914
|
+
const originEnv = await originGhRepoEnv(thread.worktreePath, { env });
|
|
915
|
+
Object.assign(env, originEnv);
|
|
916
|
+
} catch (err) {
|
|
917
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
918
|
+
console.warn(`[sideboard] originGhRepoEnv failed (${thread.worktreePath}): ${detail}`);
|
|
919
|
+
}
|
|
940
920
|
}
|
|
941
921
|
const child = execa(cmd.file, cmd.args, {
|
|
942
922
|
cwd: cmd.cwd,
|
|
@@ -1020,6 +1000,80 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
1020
1000
|
};
|
|
1021
1001
|
}
|
|
1022
1002
|
|
|
1003
|
+
// src/land/pr-metadata.ts
|
|
1004
|
+
var GENERIC_TITLE_RE = /^(sideboard:|thread\/|wip\b|tmp\b|update\b|changes?\b|misc\b|stuff\b)/i;
|
|
1005
|
+
function looksGeneric(title) {
|
|
1006
|
+
const t = title.trim();
|
|
1007
|
+
if (!t) return true;
|
|
1008
|
+
if (t.length < 4) return true;
|
|
1009
|
+
if (GENERIC_TITLE_RE.test(t)) return true;
|
|
1010
|
+
if (!/[\s:/\-_]/.test(t) && t.length <= 24) return true;
|
|
1011
|
+
return false;
|
|
1012
|
+
}
|
|
1013
|
+
function truncateTitle(title, max = 72) {
|
|
1014
|
+
const t = title.trim().replace(/\s+/g, " ");
|
|
1015
|
+
if (t.length <= max) return t;
|
|
1016
|
+
return `${t.slice(0, max - 1).trimEnd()}\u2026`;
|
|
1017
|
+
}
|
|
1018
|
+
function titleFromPaths(paths) {
|
|
1019
|
+
if (paths.length === 0) return null;
|
|
1020
|
+
const top = paths.slice(0, 3).map((p) => p.replace(/\/$/, ""));
|
|
1021
|
+
if (paths.length === 1) return truncateTitle(`Update ${top[0]}`);
|
|
1022
|
+
if (paths.length <= 3) return truncateTitle(`Update ${top.join(", ")}`);
|
|
1023
|
+
return truncateTitle(`Update ${top[0]} and ${paths.length - 1} more files`);
|
|
1024
|
+
}
|
|
1025
|
+
async function suggestPrMetadata(worktreePath, opts) {
|
|
1026
|
+
const [{ stdout: logOut }, { stdout: nameStatus }, { stdout: statOut }] = await Promise.all([
|
|
1027
|
+
git(["log", "--format=%s", `${opts.base}..HEAD`], worktreePath, {
|
|
1028
|
+
reject: false
|
|
1029
|
+
}),
|
|
1030
|
+
git(["diff", "--name-only", `${opts.base}...HEAD`], worktreePath, {
|
|
1031
|
+
reject: false
|
|
1032
|
+
}),
|
|
1033
|
+
git(["diff", "--stat", `${opts.base}...HEAD`], worktreePath, {
|
|
1034
|
+
reject: false
|
|
1035
|
+
})
|
|
1036
|
+
]);
|
|
1037
|
+
const { stdout: dirtyNames } = await git(["diff", "--name-only", "HEAD"], worktreePath, {
|
|
1038
|
+
reject: false
|
|
1039
|
+
});
|
|
1040
|
+
const { stdout: untracked } = await git(
|
|
1041
|
+
["ls-files", "--others", "--exclude-standard"],
|
|
1042
|
+
worktreePath,
|
|
1043
|
+
{ reject: false }
|
|
1044
|
+
);
|
|
1045
|
+
const subjects = logOut.split("\n").map((s) => s.trim()).filter(Boolean);
|
|
1046
|
+
const paths = [
|
|
1047
|
+
...new Set(
|
|
1048
|
+
[...nameStatus.split("\n"), ...dirtyNames.split("\n"), ...untracked.split("\n")].map((p) => p.trim()).filter(Boolean)
|
|
1049
|
+
)
|
|
1050
|
+
].sort((a, b) => a.localeCompare(b));
|
|
1051
|
+
const meaningfulSubjects = subjects.filter((s) => !looksGeneric(s));
|
|
1052
|
+
const fallback = opts.fallbackTitle?.trim() || null;
|
|
1053
|
+
const fallbackOk = fallback && !looksGeneric(fallback) ? fallback : null;
|
|
1054
|
+
const title = truncateTitle(
|
|
1055
|
+
meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? "Sideboard changes"
|
|
1056
|
+
);
|
|
1057
|
+
const commitMessage = meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? `sideboard: ${title}`;
|
|
1058
|
+
const summaryLines = meaningfulSubjects.length > 0 ? meaningfulSubjects.slice(0, 12).map((s) => `- ${s}`) : paths.slice(0, 20).map((p) => `- \`${p}\``);
|
|
1059
|
+
const bodyParts = [
|
|
1060
|
+
"## Summary",
|
|
1061
|
+
summaryLines.length > 0 ? summaryLines.join("\n") : "- Changes landed via Sideboard.",
|
|
1062
|
+
""
|
|
1063
|
+
];
|
|
1064
|
+
if (statOut.trim()) {
|
|
1065
|
+
bodyParts.push("## Diff", "```", statOut.trim(), "```", "");
|
|
1066
|
+
}
|
|
1067
|
+
if (opts.sourceLabel) {
|
|
1068
|
+
bodyParts.push(`_Landed via Sideboard from ${opts.sourceLabel}_`);
|
|
1069
|
+
}
|
|
1070
|
+
return {
|
|
1071
|
+
title,
|
|
1072
|
+
body: bodyParts.join("\n").trim() + "\n",
|
|
1073
|
+
commitMessage: truncateTitle(commitMessage, 72)
|
|
1074
|
+
};
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1023
1077
|
// src/git/agent-git-actions.ts
|
|
1024
1078
|
var AGENT_GIT_ACTIONS = [
|
|
1025
1079
|
"commit-push",
|
|
@@ -1154,8 +1208,20 @@ async function captureLoginEnv() {
|
|
|
1154
1208
|
cachedLoginEnv = { ...process.env };
|
|
1155
1209
|
return { ...cachedLoginEnv };
|
|
1156
1210
|
}
|
|
1211
|
+
var NESTED_ELECTRON_ENV_PREFIXES = ["ELECTRON_", "CHROME_"];
|
|
1212
|
+
function stripNestedElectronEnv(env) {
|
|
1213
|
+
const out = { ...env };
|
|
1214
|
+
for (const key of Object.keys(out)) {
|
|
1215
|
+
if (NESTED_ELECTRON_ENV_PREFIXES.some((prefix) => key.startsWith(prefix))) {
|
|
1216
|
+
delete out[key];
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
return out;
|
|
1220
|
+
}
|
|
1157
1221
|
function buildWorkspaceScriptEnv(opts, baseEnv) {
|
|
1158
|
-
const env = {
|
|
1222
|
+
const env = stripNestedElectronEnv({
|
|
1223
|
+
...baseEnv ?? process.env
|
|
1224
|
+
});
|
|
1159
1225
|
const name = opts.workspaceName ?? basename(opts.worktreePath);
|
|
1160
1226
|
const ports = opts.ports ?? [];
|
|
1161
1227
|
const primary = ports[0];
|
|
@@ -1759,7 +1825,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
1759
1825
|
return readThread(thread.id) ?? thread;
|
|
1760
1826
|
}
|
|
1761
1827
|
async function listLinearIssues(agent, repoPath) {
|
|
1762
|
-
const { getAdapter: getAdapter2 } = await import("../agents-
|
|
1828
|
+
const { getAdapter: getAdapter2 } = await import("../agents-EBKJ55PN.js");
|
|
1763
1829
|
await requireAgent(agent, { requireLinear: true });
|
|
1764
1830
|
const adapter = getAdapter2(agent);
|
|
1765
1831
|
if (!adapter.listLinearIssues) {
|
|
@@ -2623,7 +2689,7 @@ async function adoptThread(input) {
|
|
|
2623
2689
|
messages: input.messages ?? []
|
|
2624
2690
|
});
|
|
2625
2691
|
writeThread(thread);
|
|
2626
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("../workspaces-
|
|
2692
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("../workspaces-SUU2GO3A.js");
|
|
2627
2693
|
await ensureWorkspace2(repoPath);
|
|
2628
2694
|
return thread;
|
|
2629
2695
|
}
|
|
@@ -3842,80 +3908,6 @@ async function getDiffSummary(worktreePath, repoPath, opts) {
|
|
|
3842
3908
|
};
|
|
3843
3909
|
}
|
|
3844
3910
|
|
|
3845
|
-
// src/land/pr-metadata.ts
|
|
3846
|
-
var GENERIC_TITLE_RE = /^(sideboard:|thread\/|wip\b|tmp\b|update\b|changes?\b|misc\b|stuff\b)/i;
|
|
3847
|
-
function looksGeneric(title) {
|
|
3848
|
-
const t = title.trim();
|
|
3849
|
-
if (!t) return true;
|
|
3850
|
-
if (t.length < 4) return true;
|
|
3851
|
-
if (GENERIC_TITLE_RE.test(t)) return true;
|
|
3852
|
-
if (!/[\s:/\-_]/.test(t) && t.length <= 24) return true;
|
|
3853
|
-
return false;
|
|
3854
|
-
}
|
|
3855
|
-
function truncateTitle(title, max = 72) {
|
|
3856
|
-
const t = title.trim().replace(/\s+/g, " ");
|
|
3857
|
-
if (t.length <= max) return t;
|
|
3858
|
-
return `${t.slice(0, max - 1).trimEnd()}\u2026`;
|
|
3859
|
-
}
|
|
3860
|
-
function titleFromPaths(paths) {
|
|
3861
|
-
if (paths.length === 0) return null;
|
|
3862
|
-
const top = paths.slice(0, 3).map((p) => p.replace(/\/$/, ""));
|
|
3863
|
-
if (paths.length === 1) return truncateTitle(`Update ${top[0]}`);
|
|
3864
|
-
if (paths.length <= 3) return truncateTitle(`Update ${top.join(", ")}`);
|
|
3865
|
-
return truncateTitle(`Update ${top[0]} and ${paths.length - 1} more files`);
|
|
3866
|
-
}
|
|
3867
|
-
async function suggestPrMetadata(worktreePath, opts) {
|
|
3868
|
-
const [{ stdout: logOut }, { stdout: nameStatus }, { stdout: statOut }] = await Promise.all([
|
|
3869
|
-
git(["log", "--format=%s", `${opts.base}..HEAD`], worktreePath, {
|
|
3870
|
-
reject: false
|
|
3871
|
-
}),
|
|
3872
|
-
git(["diff", "--name-only", `${opts.base}...HEAD`], worktreePath, {
|
|
3873
|
-
reject: false
|
|
3874
|
-
}),
|
|
3875
|
-
git(["diff", "--stat", `${opts.base}...HEAD`], worktreePath, {
|
|
3876
|
-
reject: false
|
|
3877
|
-
})
|
|
3878
|
-
]);
|
|
3879
|
-
const { stdout: dirtyNames } = await git(["diff", "--name-only", "HEAD"], worktreePath, {
|
|
3880
|
-
reject: false
|
|
3881
|
-
});
|
|
3882
|
-
const { stdout: untracked } = await git(
|
|
3883
|
-
["ls-files", "--others", "--exclude-standard"],
|
|
3884
|
-
worktreePath,
|
|
3885
|
-
{ reject: false }
|
|
3886
|
-
);
|
|
3887
|
-
const subjects = logOut.split("\n").map((s) => s.trim()).filter(Boolean);
|
|
3888
|
-
const paths = [
|
|
3889
|
-
...new Set(
|
|
3890
|
-
[...nameStatus.split("\n"), ...dirtyNames.split("\n"), ...untracked.split("\n")].map((p) => p.trim()).filter(Boolean)
|
|
3891
|
-
)
|
|
3892
|
-
].sort((a, b) => a.localeCompare(b));
|
|
3893
|
-
const meaningfulSubjects = subjects.filter((s) => !looksGeneric(s));
|
|
3894
|
-
const fallback = opts.fallbackTitle?.trim() || null;
|
|
3895
|
-
const fallbackOk = fallback && !looksGeneric(fallback) ? fallback : null;
|
|
3896
|
-
const title = truncateTitle(
|
|
3897
|
-
meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? "Sideboard changes"
|
|
3898
|
-
);
|
|
3899
|
-
const commitMessage = meaningfulSubjects[0] ?? fallbackOk ?? titleFromPaths(paths) ?? `sideboard: ${title}`;
|
|
3900
|
-
const summaryLines = meaningfulSubjects.length > 0 ? meaningfulSubjects.slice(0, 12).map((s) => `- ${s}`) : paths.slice(0, 20).map((p) => `- \`${p}\``);
|
|
3901
|
-
const bodyParts = [
|
|
3902
|
-
"## Summary",
|
|
3903
|
-
summaryLines.length > 0 ? summaryLines.join("\n") : "- Changes landed via Sideboard.",
|
|
3904
|
-
""
|
|
3905
|
-
];
|
|
3906
|
-
if (statOut.trim()) {
|
|
3907
|
-
bodyParts.push("## Diff", "```", statOut.trim(), "```", "");
|
|
3908
|
-
}
|
|
3909
|
-
if (opts.sourceLabel) {
|
|
3910
|
-
bodyParts.push(`_Landed via Sideboard from ${opts.sourceLabel}_`);
|
|
3911
|
-
}
|
|
3912
|
-
return {
|
|
3913
|
-
title,
|
|
3914
|
-
body: bodyParts.join("\n").trim() + "\n",
|
|
3915
|
-
commitMessage: truncateTitle(commitMessage, 72)
|
|
3916
|
-
};
|
|
3917
|
-
}
|
|
3918
|
-
|
|
3919
3911
|
// src/land/land.ts
|
|
3920
3912
|
async function previewLand(thread) {
|
|
3921
3913
|
if (thread.sourceIsFork) {
|
|
@@ -4459,6 +4451,8 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
4459
4451
|
lines.push(
|
|
4460
4452
|
"- Push with `git push -u origin HEAD` (or the current branch name). Do not `git push upstream`."
|
|
4461
4453
|
);
|
|
4454
|
+
lines.push("");
|
|
4455
|
+
lines.push(formatGitAuthModeDirective(opts?.gitAuthMode ?? "auto"));
|
|
4462
4456
|
lines.push(
|
|
4463
4457
|
"- Derive the PR title and body from what the changes actually do and why \u2014 inspect the diff/commits and the user request. Do not use the soccer-team worktree nickname or placeholder branch as the PR title."
|
|
4464
4458
|
);
|
|
@@ -4466,7 +4460,7 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
4466
4460
|
"- Prefer a concise imperative title (Conventional Commits style when it fits: feat:/fix:/chore:/docs:). Body should summarize intent, key changes, and test notes."
|
|
4467
4461
|
);
|
|
4468
4462
|
lines.push(
|
|
4469
|
-
"- Commit with messages that state the purpose of the change (same standard as the PR). Stay on this thread branch. Never push directly to main/master or merge locally into the main checkout.
|
|
4463
|
+
"- Commit with messages that state the purpose of the change (same standard as the PR). Stay on this thread branch. Never push directly to main/master or merge locally into the main checkout. Do not merge the PR unless this turn is a Merge PR request or the user explicitly asked. When merging, use GitHub from this worktree (`gh pr merge` / `gh stack merge`)."
|
|
4470
4464
|
);
|
|
4471
4465
|
if (thread.prUrl) {
|
|
4472
4466
|
lines.push(
|
|
@@ -4504,7 +4498,7 @@ function formatWorktreeDirective(thread, opts) {
|
|
|
4504
4498
|
'- "Address review comments." \u2192 read PR review feedback, make the requested changes, commit, and push.'
|
|
4505
4499
|
);
|
|
4506
4500
|
lines.push(
|
|
4507
|
-
'- "Merge PR." \u2192 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.'
|
|
4501
|
+
'- "Merge PR." \u2192 merge this thread\'s open pull request on GitHub (this phrase is the explicit ask). 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.'
|
|
4508
4502
|
);
|
|
4509
4503
|
return lines.join("\n");
|
|
4510
4504
|
}
|
|
@@ -4663,7 +4657,7 @@ var Orchestrator = class {
|
|
|
4663
4657
|
orphans: orphans.map((o) => ({ path: o.path, repoPath: o.repoPath }))
|
|
4664
4658
|
});
|
|
4665
4659
|
}
|
|
4666
|
-
const { autoCleanupOrphansEnabled } = await import("../app-settings-
|
|
4660
|
+
const { autoCleanupOrphansEnabled } = await import("../app-settings-NILNWNNQ.js");
|
|
4667
4661
|
if (autoCleanupOrphansEnabled() && shouldRunWorktreeCleanup() && orphans.length > 0) {
|
|
4668
4662
|
await cleanupOrphanWorktrees({ repoPaths });
|
|
4669
4663
|
}
|
|
@@ -4820,7 +4814,7 @@ var Orchestrator = class {
|
|
|
4820
4814
|
}
|
|
4821
4815
|
async finishCreateThread(threadId, prompt) {
|
|
4822
4816
|
await this.runSetupAfterCreate(threadId);
|
|
4823
|
-
const { autoRunAfterSetupEnabled } = await import("../app-settings-
|
|
4817
|
+
const { autoRunAfterSetupEnabled } = await import("../app-settings-NILNWNNQ.js");
|
|
4824
4818
|
if (autoRunAfterSetupEnabled()) {
|
|
4825
4819
|
try {
|
|
4826
4820
|
await this.startDev(threadId);
|
|
@@ -5098,14 +5092,16 @@ var Orchestrator = class {
|
|
|
5098
5092
|
}
|
|
5099
5093
|
const isBrightsy = fresh.agent === "brightsy";
|
|
5100
5094
|
const isOrchestration = isOrchestratorThread(fresh);
|
|
5095
|
+
const { autoRenameBranchEnabled, getGithubGitAuthMode } = await import("../app-settings-NILNWNNQ.js");
|
|
5096
|
+
const gitAuthMode = getGithubGitAuthMode();
|
|
5101
5097
|
const worktreeDirective = isBrightsy || isOrchestration ? null : formatWorktreeDirective(fresh, {
|
|
5102
5098
|
githubSlug: await resolveGithubRepoSlug(fresh.worktreePath).catch(
|
|
5103
5099
|
() => null
|
|
5104
|
-
)
|
|
5100
|
+
),
|
|
5101
|
+
gitAuthMode
|
|
5105
5102
|
});
|
|
5106
5103
|
const artifactDirective = isBrightsy ? null : formatArtifactDirective();
|
|
5107
5104
|
const settings = loadWorkspaceSettings(fresh.worktreePath, fresh.repoPath);
|
|
5108
|
-
const { autoRenameBranchEnabled } = await import("../app-settings-P42Z3VOB.js");
|
|
5109
5105
|
const renameBranchDirective = !isBrightsy && !isOrchestration && autoRenameBranchEnabled() ? formatRenameBranchDirective(fresh, {
|
|
5110
5106
|
customPrompt: settings?.prompts?.renameBranch
|
|
5111
5107
|
}) : null;
|
|
@@ -5811,7 +5807,7 @@ var Orchestrator = class {
|
|
|
5811
5807
|
updateThread(thread.id, { title: meta.title });
|
|
5812
5808
|
}
|
|
5813
5809
|
}
|
|
5814
|
-
const { autoArchiveOnMergeEnabled } = await import("../app-settings-
|
|
5810
|
+
const { autoArchiveOnMergeEnabled } = await import("../app-settings-NILNWNNQ.js");
|
|
5815
5811
|
const latest = this.requireThread(thread.id);
|
|
5816
5812
|
if (!shouldAutoArchiveOnPrMerge({
|
|
5817
5813
|
previousPrState: prevState || null,
|
|
@@ -5942,8 +5938,9 @@ var Orchestrator = class {
|
|
|
5942
5938
|
return tab;
|
|
5943
5939
|
}
|
|
5944
5940
|
/**
|
|
5945
|
-
*
|
|
5946
|
-
*
|
|
5941
|
+
* Desktop git buttons + MCP `ask_git`.
|
|
5942
|
+
* When the worktree is clean, push / open the PR here (HTTPS via `gh` if SSH
|
|
5943
|
+
* is missing). When dirty, queue the worktree agent to commit first.
|
|
5947
5944
|
*/
|
|
5948
5945
|
async askGit(threadRef, action) {
|
|
5949
5946
|
if (!AGENT_GIT_ACTIONS.includes(action)) {
|
|
@@ -5961,6 +5958,10 @@ var Orchestrator = class {
|
|
|
5961
5958
|
"No pull request linked. Ask the worktree agent to open a draft PR first (ask_git create-draft)."
|
|
5962
5959
|
);
|
|
5963
5960
|
}
|
|
5961
|
+
if ((action === "commit-push" || action === "create-draft" || action === "create-web") && thread.worktreePath?.trim() && !await isDirty(thread.worktreePath)) {
|
|
5962
|
+
await this.pushAndMaybeOpenPr(thread, action);
|
|
5963
|
+
return this.requireThread(threadRef);
|
|
5964
|
+
}
|
|
5964
5965
|
let prBase;
|
|
5965
5966
|
if (action === "resolve-conflicts") {
|
|
5966
5967
|
try {
|
|
@@ -5971,6 +5972,34 @@ var Orchestrator = class {
|
|
|
5971
5972
|
}
|
|
5972
5973
|
return this.send(threadRef, agentGitPrompt(action, { prBase }));
|
|
5973
5974
|
}
|
|
5975
|
+
/** Push origin (gh HTTPS fallback) and create/update the PR when requested. */
|
|
5976
|
+
async pushAndMaybeOpenPr(thread, action) {
|
|
5977
|
+
const cwd = thread.worktreePath;
|
|
5978
|
+
const branch = await currentBranch(cwd);
|
|
5979
|
+
await pushBranch(cwd, branch);
|
|
5980
|
+
if (action === "commit-push") return;
|
|
5981
|
+
const base = await resolveDefaultBranch(thread.repoPath);
|
|
5982
|
+
const meta = await suggestPrMetadata(cwd, {
|
|
5983
|
+
base,
|
|
5984
|
+
fallbackTitle: thread.prTitle ?? thread.title
|
|
5985
|
+
});
|
|
5986
|
+
const url = await createOrUpdatePr(cwd, {
|
|
5987
|
+
title: meta.title,
|
|
5988
|
+
body: meta.body,
|
|
5989
|
+
base,
|
|
5990
|
+
head: branch,
|
|
5991
|
+
draft: action === "create-draft",
|
|
5992
|
+
web: action === "create-web"
|
|
5993
|
+
});
|
|
5994
|
+
if (!url) return;
|
|
5995
|
+
const patch = { prUrl: url, prTitle: meta.title };
|
|
5996
|
+
try {
|
|
5997
|
+
const fetched = await getPrMeta(cwd, url);
|
|
5998
|
+
if (fetched?.title) patch.prTitle = fetched.title;
|
|
5999
|
+
} catch {
|
|
6000
|
+
}
|
|
6001
|
+
updateThread(thread.id, patch);
|
|
6002
|
+
}
|
|
5974
6003
|
setThreadOptions(threadRef, patch) {
|
|
5975
6004
|
const thread = this.requireThread(threadRef);
|
|
5976
6005
|
const next = {};
|
|
@@ -6066,7 +6095,7 @@ var Orchestrator = class {
|
|
|
6066
6095
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
6067
6096
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
6068
6097
|
try {
|
|
6069
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("../workspaces-
|
|
6098
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("../workspaces-SUU2GO3A.js");
|
|
6070
6099
|
await ensureWorkspace2(thread.repoPath);
|
|
6071
6100
|
} catch {
|
|
6072
6101
|
}
|
|
@@ -6088,7 +6117,7 @@ var Orchestrator = class {
|
|
|
6088
6117
|
await runArchiveScript(thread.repoPath, thread.worktreePath);
|
|
6089
6118
|
} catch {
|
|
6090
6119
|
}
|
|
6091
|
-
const { deleteBranchOnPurgeEnabled } = await import("../app-settings-
|
|
6120
|
+
const { deleteBranchOnPurgeEnabled } = await import("../app-settings-NILNWNNQ.js");
|
|
6092
6121
|
const deleteBranch = opts?.deleteBranch ?? deleteBranchOnPurgeEnabled();
|
|
6093
6122
|
await removeWorktree(thread.repoPath, thread.worktreePath, {
|
|
6094
6123
|
deleteBranch: deleteBranch ? thread.branchName : void 0
|
|
@@ -6109,7 +6138,7 @@ var Orchestrator = class {
|
|
|
6109
6138
|
return restored2;
|
|
6110
6139
|
}
|
|
6111
6140
|
if (!existsSync15(thread.worktreePath)) {
|
|
6112
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("../worktree-
|
|
6141
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("../worktree-UNSOCYZU.js");
|
|
6113
6142
|
const { execa: execa6 } = await import("execa");
|
|
6114
6143
|
const slug = thread.worktreePath.split("/").pop();
|
|
6115
6144
|
const dest = thread.worktreePath;
|
|
@@ -7280,7 +7309,7 @@ function withTimeout(promise, ms, label) {
|
|
|
7280
7309
|
async function startMcpServer() {
|
|
7281
7310
|
const orch = getOrchestrator();
|
|
7282
7311
|
try {
|
|
7283
|
-
const { maxConcurrentAgents } = await import("../app-settings-
|
|
7312
|
+
const { maxConcurrentAgents } = await import("../app-settings-NILNWNNQ.js");
|
|
7284
7313
|
orch.setMaxConcurrent(maxConcurrentAgents());
|
|
7285
7314
|
} catch {
|
|
7286
7315
|
}
|
|
@@ -7490,7 +7519,7 @@ async function startMcpServer() {
|
|
|
7490
7519
|
registerLinearTools(server);
|
|
7491
7520
|
if (sideboardMcpProfile() !== "worktree") {
|
|
7492
7521
|
const { getCaffeinateHold, setCaffeinateHold } = await import("../caffeinate-hold-OHAUWOA6.js");
|
|
7493
|
-
const { resolveNewThreadOptions: resolveNewThreadOptions2, resolveThreadDefaults } = await import("../app-settings-
|
|
7522
|
+
const { resolveNewThreadOptions: resolveNewThreadOptions2, resolveThreadDefaults } = await import("../app-settings-NILNWNNQ.js");
|
|
7494
7523
|
const accountDefaults = resolveThreadDefaults();
|
|
7495
7524
|
const accountDefaultsHint = `Account defaults: agent=${accountDefaults.agent}, model=${accountDefaults.model?.trim() || "Auto"}, effort=${accountDefaults.effort}`;
|
|
7496
7525
|
server.tool(
|
|
@@ -7648,7 +7677,7 @@ async function startMcpServer() {
|
|
|
7648
7677
|
);
|
|
7649
7678
|
server.tool(
|
|
7650
7679
|
"send_to_thread",
|
|
7651
|
-
|
|
7680
|
+
'Queue a prompt on a worktree thread chat (runs under concurrency cap). Use after create_thread to start or continue a conversation. For commit/push/PR, prefer ask_git (canonical desktop-button phrases). Send "Merge PR." / ask_git merge only when the user explicitly asked to merge. Set force_stop=true to interrupt an in-flight/queued turn (kill + clear queue) before queueing this prompt \u2014 use when the thread is mid-turn or has stale queued prompts you need to replace.',
|
|
7652
7681
|
{
|
|
7653
7682
|
ref: z3.string(),
|
|
7654
7683
|
prompt: z3.string(),
|
|
@@ -7744,7 +7773,7 @@ async function startMcpServer() {
|
|
|
7744
7773
|
);
|
|
7745
7774
|
server.tool(
|
|
7746
7775
|
"archive_thread",
|
|
7747
|
-
"Archive a thread (stops agent/dev, runs archive script, removes worktree when last chat tab). Coordinators commit, push, open PRs
|
|
7776
|
+
"Archive a thread (stops agent/dev, runs archive script, removes worktree when last chat tab). Coordinators commit, push, and open PRs by asking the worktree agent (ask_git). Merge only when the user explicitly asked.",
|
|
7748
7777
|
{ ref: z3.string() },
|
|
7749
7778
|
async ({ ref }) => {
|
|
7750
7779
|
const t = orch.getThread(ref);
|
|
@@ -7852,7 +7881,7 @@ async function startMcpServer() {
|
|
|
7852
7881
|
);
|
|
7853
7882
|
server.tool(
|
|
7854
7883
|
"ask_git",
|
|
7855
|
-
"
|
|
7884
|
+
"Commit & push, open a draft PR, resolve conflicts, or merge \u2014 same actions as the desktop git buttons. When the worktree is clean, Sideboard pushes / opens the PR itself (HTTPS via `gh` if SSH is missing). When dirty, queues the worktree agent to commit; then wait_for_turn. Pass a worktree thread ref (not the orchestrator). action=merge only when the user explicitly asked to merge that PR. Do not run git or gh from the orchestration cwd.",
|
|
7856
7885
|
{
|
|
7857
7886
|
ref: z3.string().describe("Worktree thread id/ref"),
|
|
7858
7887
|
action: z3.enum(AGENT_GIT_ACTIONS).describe(
|
|
@@ -8153,7 +8182,7 @@ async function startMcpServer() {
|
|
|
8153
8182
|
);
|
|
8154
8183
|
server.tool(
|
|
8155
8184
|
"get_pr_stack",
|
|
8156
|
-
"Load the GitHub PR stack for a thread worktree (`gh stack view --json`). Returns null JSON when the branch is not stacked. Prefer this before ask_git merge on stacked PRs.",
|
|
8185
|
+
"Load the GitHub PR stack for a thread worktree (`gh stack view --json`). Returns null JSON when the branch is not stacked. Prefer this before ask_git merge on stacked PRs (and only merge when the user explicitly asked).",
|
|
8157
8186
|
{ ref: z3.string() },
|
|
8158
8187
|
async ({ ref }) => {
|
|
8159
8188
|
const stack = await orch.getPrStack(ref);
|
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
listWorkspaces,
|
|
5
5
|
removeWorkspace,
|
|
6
6
|
syncWorkspacesFromThreads
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-JT7R45JB.js";
|
|
12
|
-
import "./chunk-MF2YMEGD.js";
|
|
7
|
+
} from "./chunk-K553XK7M.js";
|
|
8
|
+
import "./chunk-6F2TQFJE.js";
|
|
9
|
+
import "./chunk-CQBQWX73.js";
|
|
10
|
+
import "./chunk-YVVXWWCC.js";
|
|
13
11
|
import "./chunk-FKOIHGKV.js";
|
|
12
|
+
import "./chunk-IFPN6TER.js";
|
|
13
|
+
import "./chunk-JT7R45JB.js";
|
|
14
14
|
import "./chunk-FWJYLBO6.js";
|
|
15
15
|
import "./chunk-77WWLBCI.js";
|
|
16
16
|
import "./chunk-M37RITA6.js";
|
|
@@ -6,14 +6,14 @@ import {
|
|
|
6
6
|
listWorkspaces,
|
|
7
7
|
removeWorkspace,
|
|
8
8
|
syncWorkspacesFromThreads
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-TDJ43HUD.js";
|
|
10
|
+
import "./chunk-P5VDPGAN.js";
|
|
11
|
+
import "./chunk-4HJK57XU.js";
|
|
12
|
+
import "./chunk-FUUVPN4A.js";
|
|
13
13
|
import "./chunk-B3SJXYIJ.js";
|
|
14
14
|
import "./chunk-7FD7COKE.js";
|
|
15
15
|
import "./chunk-AE5VBOFE.js";
|
|
16
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-XKNBSYA7.js";
|
|
17
17
|
import "./chunk-NSTQ6QKD.js";
|
|
18
18
|
import "./chunk-KGZBYWZ3.js";
|
|
19
19
|
import "./chunk-7MV3RXSC.js";
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
getPrMeta,
|
|
19
19
|
ghHeadRef,
|
|
20
20
|
ghRepoSelectArgs,
|
|
21
|
+
githubAgentGitEnv,
|
|
21
22
|
isDirty,
|
|
22
23
|
isPlaceholderBranch,
|
|
23
24
|
isSideboardScratchPath,
|
|
@@ -43,8 +44,10 @@ import {
|
|
|
43
44
|
worktreeDisplayLabel,
|
|
44
45
|
worktreeDisplayLabelForGroup,
|
|
45
46
|
worktreeNameFromPath
|
|
46
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-YVVXWWCC.js";
|
|
47
48
|
import "./chunk-FKOIHGKV.js";
|
|
49
|
+
import "./chunk-IFPN6TER.js";
|
|
50
|
+
import "./chunk-JT7R45JB.js";
|
|
48
51
|
import "./chunk-FWJYLBO6.js";
|
|
49
52
|
import "./chunk-77WWLBCI.js";
|
|
50
53
|
import "./chunk-M37RITA6.js";
|
|
@@ -69,6 +72,7 @@ export {
|
|
|
69
72
|
getPrMeta,
|
|
70
73
|
ghHeadRef,
|
|
71
74
|
ghRepoSelectArgs,
|
|
75
|
+
githubAgentGitEnv,
|
|
72
76
|
isDirty,
|
|
73
77
|
isPlaceholderBranch,
|
|
74
78
|
isSideboardScratchPath,
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
getPrMeta,
|
|
21
21
|
ghHeadRef,
|
|
22
22
|
ghRepoSelectArgs,
|
|
23
|
+
githubAgentGitEnv,
|
|
23
24
|
isDirty,
|
|
24
25
|
isPlaceholderBranch,
|
|
25
26
|
isSideboardScratchPath,
|
|
@@ -45,10 +46,12 @@ import {
|
|
|
45
46
|
worktreeDisplayLabel,
|
|
46
47
|
worktreeDisplayLabelForGroup,
|
|
47
48
|
worktreeNameFromPath
|
|
48
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-FUUVPN4A.js";
|
|
49
50
|
import "./chunk-B3SJXYIJ.js";
|
|
50
51
|
import "./chunk-7FD7COKE.js";
|
|
51
52
|
import "./chunk-AE5VBOFE.js";
|
|
53
|
+
import "./chunk-XKNBSYA7.js";
|
|
54
|
+
import "./chunk-NSTQ6QKD.js";
|
|
52
55
|
import "./chunk-KGZBYWZ3.js";
|
|
53
56
|
import "./chunk-7MV3RXSC.js";
|
|
54
57
|
export {
|
|
@@ -71,6 +74,7 @@ export {
|
|
|
71
74
|
getPrMeta,
|
|
72
75
|
ghHeadRef,
|
|
73
76
|
ghRepoSelectArgs,
|
|
77
|
+
githubAgentGitEnv,
|
|
74
78
|
isDirty,
|
|
75
79
|
isPlaceholderBranch,
|
|
76
80
|
isSideboardScratchPath,
|