@sideboard-ai/core 0.1.66 → 0.1.68
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-EWFD765A.js → agents-JBD7IAGK.js} +10 -6
- package/dist/{agents-MD7SCFYX.js → agents-PE3RHQS5.js} +10 -6
- package/dist/{chunk-BBEH2CJE.js → chunk-47RBLBRK.js} +22 -7
- package/dist/{chunk-IFAU2DEY.js → chunk-6Q7H6SMX.js} +22 -7
- package/dist/{chunk-5AG5BUQN.js → chunk-AE5VBOFE.js} +14 -3
- package/dist/{chunk-DZYMNW2A.js → chunk-BTL7EMGT.js} +4 -4
- package/dist/{chunk-TXQ6K2GR.js → chunk-D4DPQ552.js} +14 -3
- package/dist/{chunk-PESJDZTB.js → chunk-DPDGMMGI.js} +2 -2
- package/dist/{chunk-R7GUDEPY.js → chunk-EEBDVLDK.js} +22 -20
- package/dist/{chunk-LRBRQFBU.js → chunk-N5LMEP65.js} +1 -1
- package/dist/{chunk-DNPP7QMK.js → chunk-OICHV4DH.js} +2 -2
- package/dist/{chunk-HTOTTJJX.js → chunk-QQC2D4MY.js} +2 -2
- package/dist/{chunk-I2KGRAXC.js → chunk-REKGFVUX.js} +22 -20
- package/dist/{chunk-YTNLOJPK.js → chunk-ROXEENBT.js} +2 -2
- package/dist/{chunk-EVD4KNKR.js → chunk-VROPG6QF.js} +1 -1
- package/dist/{chunk-AKPEXIKK.js → chunk-VX6ACNXS.js} +1 -1
- package/dist/{connected-teams-CHXO5FFA.js → connected-teams-35EIRJCP.js} +2 -2
- package/dist/{connected-teams-GJTESSTX.js → connected-teams-ZRS53OAT.js} +2 -2
- package/dist/{coordinator-prompt-ILSULI7C.js → coordinator-prompt-HD6IMCKS.js} +3 -3
- package/dist/{coordinator-prompt-E5UGSJES.js → coordinator-prompt-YZYZ5P6P.js} +3 -3
- package/dist/{global-workspace-44UG64NA.js → global-workspace-7P5NG3JZ.js} +4 -4
- package/dist/{global-workspace-5PM5LA6E.js → global-workspace-Z6GF7D2K.js} +4 -4
- package/dist/index.cjs +401 -163
- package/dist/index.d.cts +33 -3
- package/dist/index.d.ts +33 -3
- package/dist/index.js +368 -157
- package/dist/mcp/run-stdio.cjs +397 -163
- package/dist/mcp/run-stdio.js +363 -156
- package/dist/{run-74S2NZWB.js → run-A4RHY7HH.js} +1 -1
- package/dist/{run-JLN5JK7Q.js → run-V2WZUMJA.js} +1 -1
- package/dist/{workspaces-OVBCSS5Y.js → workspaces-BWJNGEE6.js} +5 -5
- package/dist/{workspaces-RXFXQRRF.js → workspaces-O6EZGKQK.js} +5 -5
- package/dist/{worktree-S2N63FLV.js → worktree-VDXLUOWR.js} +2 -2
- package/dist/{worktree-K2JB53R5.js → worktree-ZPSKEZFE.js} +2 -2
- package/package.json +1 -1
package/dist/mcp/run-stdio.cjs
CHANGED
|
@@ -1517,6 +1517,13 @@ function prependPathDir(env, dir) {
|
|
|
1517
1517
|
}
|
|
1518
1518
|
env.PATH = [dir, ...parts].join(import_node_path4.delimiter);
|
|
1519
1519
|
}
|
|
1520
|
+
function conductorBundledBinDir(home = process.env.HOME || process.env.USERPROFILE || (0, import_node_os3.homedir)()) {
|
|
1521
|
+
return (0, import_node_path4.join)(home, "Library", "Application Support", "com.conductor.app", "bin");
|
|
1522
|
+
}
|
|
1523
|
+
function isConductorBundledCli(filePath) {
|
|
1524
|
+
const p = (filePath ?? "").replace(/\\/g, "/");
|
|
1525
|
+
return p.includes("/com.conductor.app/bin/") || p.endsWith("/com.conductor.app/bin");
|
|
1526
|
+
}
|
|
1520
1527
|
function ensureAgentPath(env = process.env) {
|
|
1521
1528
|
const home = env.HOME || env.USERPROFILE || (0, import_node_os3.homedir)();
|
|
1522
1529
|
const current = env.PATH ?? "";
|
|
@@ -1525,7 +1532,9 @@ function ensureAgentPath(env = process.env) {
|
|
|
1525
1532
|
const extras = [
|
|
1526
1533
|
...EXTRA_BIN_DIRS.map((rel) => (0, import_node_path4.join)(home, rel)),
|
|
1527
1534
|
"/opt/homebrew/bin",
|
|
1528
|
-
"/usr/local/bin"
|
|
1535
|
+
"/usr/local/bin",
|
|
1536
|
+
// Keep after Homebrew/npm so a user-installed CLI still wins.
|
|
1537
|
+
conductorBundledBinDir(home)
|
|
1529
1538
|
];
|
|
1530
1539
|
for (const dir of extras.reverse()) {
|
|
1531
1540
|
if (!dir || seen.has(dir) || !(0, import_node_fs4.existsSync)(dir)) continue;
|
|
@@ -1572,7 +1581,7 @@ function withExportedPath(command, pathValue) {
|
|
|
1572
1581
|
const trimmed = command.trim();
|
|
1573
1582
|
if (!trimmed) return trimmed;
|
|
1574
1583
|
if (/^(export\s+PATH=|PATH=)/.test(trimmed)) return trimmed;
|
|
1575
|
-
return `export PATH=${posixShellSingleQuote(pathValue)}
|
|
1584
|
+
return `export PATH=${posixShellSingleQuote(pathValue)} && ${trimmed}`;
|
|
1576
1585
|
}
|
|
1577
1586
|
var import_node_fs4, import_node_child_process, import_node_os3, import_node_path4, EXTRA_BIN_DIRS;
|
|
1578
1587
|
var init_path = __esm({
|
|
@@ -1640,7 +1649,7 @@ async function git(args, cwd, opts) {
|
|
|
1640
1649
|
prefix.push("-c", `${key}=${value}`);
|
|
1641
1650
|
}
|
|
1642
1651
|
}
|
|
1643
|
-
return run("git", [...prefix, ...args], {
|
|
1652
|
+
return run("git", ["--no-pager", ...prefix, ...args], {
|
|
1644
1653
|
cwd,
|
|
1645
1654
|
reject: opts?.reject,
|
|
1646
1655
|
timeoutMs: opts?.timeoutMs,
|
|
@@ -2115,7 +2124,7 @@ async function originGhRepoEnv(cwd) {
|
|
|
2115
2124
|
const slug = await resolveGithubRepoSlug(cwd);
|
|
2116
2125
|
return slug ? { GH_REPO: slug } : {};
|
|
2117
2126
|
}
|
|
2118
|
-
async function resolveDefaultBranch(repoPath) {
|
|
2127
|
+
async function resolveDefaultBranch(repoPath, opts) {
|
|
2119
2128
|
const viaOrigin = await git(
|
|
2120
2129
|
["symbolic-ref", "refs/remotes/origin/HEAD"],
|
|
2121
2130
|
repoPath,
|
|
@@ -2124,22 +2133,24 @@ async function resolveDefaultBranch(repoPath) {
|
|
|
2124
2133
|
if (viaOrigin.exitCode === 0 && viaOrigin.stdout.trim()) {
|
|
2125
2134
|
return viaOrigin.stdout.trim().replace(/^refs\/remotes\/origin\//, "");
|
|
2126
2135
|
}
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2136
|
+
if (opts?.network !== false) {
|
|
2137
|
+
const slug = await resolveGithubRepoSlug(repoPath);
|
|
2138
|
+
const viaGh = await gh(
|
|
2139
|
+
[
|
|
2140
|
+
"repo",
|
|
2141
|
+
"view",
|
|
2142
|
+
...slug ? ["--repo", slug] : [],
|
|
2143
|
+
"--json",
|
|
2144
|
+
"defaultBranchRef",
|
|
2145
|
+
"--jq",
|
|
2146
|
+
".defaultBranchRef.name"
|
|
2147
|
+
],
|
|
2148
|
+
repoPath,
|
|
2149
|
+
{ reject: false, timeoutMs: 8e3 }
|
|
2150
|
+
);
|
|
2151
|
+
if (viaGh.exitCode === 0 && viaGh.stdout.trim()) {
|
|
2152
|
+
return viaGh.stdout.trim();
|
|
2153
|
+
}
|
|
2143
2154
|
}
|
|
2144
2155
|
for (const candidate of ["main", "master"]) {
|
|
2145
2156
|
const check = await git(
|
|
@@ -2791,11 +2802,11 @@ async function listWorktrees(repoPath) {
|
|
|
2791
2802
|
return entries;
|
|
2792
2803
|
}
|
|
2793
2804
|
async function isDirty(worktreePath) {
|
|
2794
|
-
const { stdout } = await git(["status", "--porcelain"
|
|
2805
|
+
const { stdout } = await git(["status", "--porcelain"], worktreePath);
|
|
2795
2806
|
for (const line of stdout.split("\n")) {
|
|
2796
2807
|
if (!line.trim()) continue;
|
|
2797
2808
|
const rel = porcelainStatusPath(line);
|
|
2798
|
-
if (!rel || isSideboardScratchPath(rel)) continue;
|
|
2809
|
+
if (!rel || isSideboardScratchPath(rel) || rel === ".sideboard") continue;
|
|
2799
2810
|
return true;
|
|
2800
2811
|
}
|
|
2801
2812
|
return false;
|
|
@@ -6657,6 +6668,11 @@ async function openInSystemTerminal(command) {
|
|
|
6657
6668
|
`No terminal found to run: ${trimmed}. Install gnome-terminal (or similar), or run the command manually.`
|
|
6658
6669
|
);
|
|
6659
6670
|
}
|
|
6671
|
+
async function whichCli(bin) {
|
|
6672
|
+
const which = await run("which", [bin], { reject: false, timeoutMs: 3e3 });
|
|
6673
|
+
if (which.exitCode !== 0) return null;
|
|
6674
|
+
return which.stdout.trim().split(/\r?\n/).find(Boolean) ?? null;
|
|
6675
|
+
}
|
|
6660
6676
|
async function installAgent(agent) {
|
|
6661
6677
|
const info = getAgentSetupInfo(agent);
|
|
6662
6678
|
if (info.kind === "bundled-sdk" || info.kind === "api-key") {
|
|
@@ -6678,6 +6694,17 @@ async function installAgent(agent) {
|
|
|
6678
6694
|
};
|
|
6679
6695
|
}
|
|
6680
6696
|
enrichPathWithNpmGlobalBin();
|
|
6697
|
+
const cliBin = agent === "cursor" ? null : CLI_BIN[agent];
|
|
6698
|
+
if (cliBin) {
|
|
6699
|
+
const existing = await whichCli(cliBin);
|
|
6700
|
+
if (existing) {
|
|
6701
|
+
return {
|
|
6702
|
+
ok: true,
|
|
6703
|
+
command: existing,
|
|
6704
|
+
message: isConductorBundledCli(existing) ? `Using Conductor\u2019s ${cliBin} at ${existing}. No extra install \u2014 Log in only if auth is missing.` : `Already on PATH: ${existing}`
|
|
6705
|
+
};
|
|
6706
|
+
}
|
|
6707
|
+
}
|
|
6681
6708
|
const result = await run("npm", ["install", "-g", info.npmPackage], { reject: false });
|
|
6682
6709
|
const ok = result.exitCode === 0;
|
|
6683
6710
|
if (!ok) {
|
|
@@ -6704,11 +6731,9 @@ async function installAgent(agent) {
|
|
|
6704
6731
|
}
|
|
6705
6732
|
}
|
|
6706
6733
|
enrichPathWithNpmGlobalBin();
|
|
6707
|
-
const cliBin = agent === "cursor" ? null : CLI_BIN[agent];
|
|
6708
6734
|
let binPath = null;
|
|
6709
6735
|
if (cliBin) {
|
|
6710
|
-
|
|
6711
|
-
binPath = which.exitCode === 0 ? which.stdout.trim().split(/\r?\n/).find(Boolean) ?? null : null;
|
|
6736
|
+
binPath = await whichCli(cliBin);
|
|
6712
6737
|
}
|
|
6713
6738
|
return {
|
|
6714
6739
|
ok: true,
|
|
@@ -6818,6 +6843,7 @@ __export(agents_exports, {
|
|
|
6818
6843
|
claudeAdapter: () => claudeAdapter,
|
|
6819
6844
|
codexAdapter: () => codexAdapter,
|
|
6820
6845
|
coerceOrchestratorAgent: () => coerceOrchestratorAgent,
|
|
6846
|
+
conductorBundledBinDir: () => conductorBundledBinDir,
|
|
6821
6847
|
cursorAdapter: () => cursorAdapter,
|
|
6822
6848
|
cursorSdkMessageToEvents: () => cursorSdkMessageToEvents,
|
|
6823
6849
|
decodeBrightsyTarget: () => decodeBrightsyTarget,
|
|
@@ -6827,6 +6853,7 @@ __export(agents_exports, {
|
|
|
6827
6853
|
getAdapter: () => getAdapter,
|
|
6828
6854
|
getAgentSetupInfo: () => getAgentSetupInfo,
|
|
6829
6855
|
installAgent: () => installAgent,
|
|
6856
|
+
isConductorBundledCli: () => isConductorBundledCli,
|
|
6830
6857
|
isCursorAutoModel: () => isCursorAutoModel,
|
|
6831
6858
|
isOrchestratorCapableAgent: () => isOrchestratorCapableAgent,
|
|
6832
6859
|
isSessionQuotaLimit: () => isSessionQuotaLimit,
|
|
@@ -9719,24 +9746,25 @@ function capPatch(patch, maxHunk) {
|
|
|
9719
9746
|
|
|
9720
9747
|
\u2026 truncated (${patch.length - maxHunk} more chars)`;
|
|
9721
9748
|
}
|
|
9749
|
+
var mergeBaseCache = /* @__PURE__ */ new Map();
|
|
9750
|
+
var MERGE_BASE_TTL_MS = 45e3;
|
|
9722
9751
|
async function resolveMergeBase(worktreePath, base, repoPath) {
|
|
9723
9752
|
const baseRef = await resolveDiffBaseRef(worktreePath, base, repoPath);
|
|
9753
|
+
const cacheKey = `${worktreePath}\0${baseRef}`;
|
|
9754
|
+
const hit = mergeBaseCache.get(cacheKey);
|
|
9755
|
+
if (hit && Date.now() - hit.at < MERGE_BASE_TTL_MS) return hit.value;
|
|
9724
9756
|
const { stdout } = await git(["merge-base", baseRef, "HEAD"], worktreePath, {
|
|
9725
9757
|
reject: false
|
|
9726
9758
|
});
|
|
9727
|
-
const mb = stdout.trim();
|
|
9728
|
-
|
|
9759
|
+
const mb = stdout.trim() || baseRef;
|
|
9760
|
+
mergeBaseCache.set(cacheKey, { at: Date.now(), value: mb });
|
|
9761
|
+
return mb;
|
|
9729
9762
|
}
|
|
9730
9763
|
async function countUnpushedCommits(worktreePath) {
|
|
9731
9764
|
const head = await git(["rev-parse", "--abbrev-ref", "HEAD"], worktreePath, {
|
|
9732
9765
|
reject: false
|
|
9733
9766
|
});
|
|
9734
9767
|
const branch = head.stdout.trim();
|
|
9735
|
-
if (branch && branch !== "HEAD") {
|
|
9736
|
-
await git(["fetch", "origin", branch, "--quiet"], worktreePath, {
|
|
9737
|
-
reject: false
|
|
9738
|
-
});
|
|
9739
|
-
}
|
|
9740
9768
|
const upstream = await git(
|
|
9741
9769
|
["rev-list", "--count", "@{upstream}..HEAD"],
|
|
9742
9770
|
worktreePath,
|
|
@@ -9769,11 +9797,37 @@ function splitCombinedDiff(stdout) {
|
|
|
9769
9797
|
}
|
|
9770
9798
|
return map;
|
|
9771
9799
|
}
|
|
9800
|
+
function syntheticAddPatch(path, content, maxHunk) {
|
|
9801
|
+
const lines = content.split("\n");
|
|
9802
|
+
const body = lines.map((l) => `+${l}`).join("\n");
|
|
9803
|
+
const header = `diff --git a/${path} b/${path}
|
|
9804
|
+
new file mode 100644
|
|
9805
|
+
--- /dev/null
|
|
9806
|
+
+++ b/${path}
|
|
9807
|
+
@@ -0,0 +1,${lines.length} @@
|
|
9808
|
+
`;
|
|
9809
|
+
return {
|
|
9810
|
+
path,
|
|
9811
|
+
status: "A",
|
|
9812
|
+
patch: capPatch(`${header}${body}`, maxHunk),
|
|
9813
|
+
additions: lines.length,
|
|
9814
|
+
deletions: 0
|
|
9815
|
+
};
|
|
9816
|
+
}
|
|
9772
9817
|
async function untrackedPatch(worktreePath, path, maxHunk) {
|
|
9818
|
+
const abs = (0, import_node_path20.join)(worktreePath, path);
|
|
9819
|
+
try {
|
|
9820
|
+
const st = (0, import_node_fs25.statSync)(abs);
|
|
9821
|
+
if (st.isFile() && st.size > maxHunk) {
|
|
9822
|
+
const buf = (0, import_node_fs25.readFileSync)(abs).subarray(0, maxHunk);
|
|
9823
|
+
return syntheticAddPatch(path, buf.toString("utf8"), maxHunk);
|
|
9824
|
+
}
|
|
9825
|
+
} catch {
|
|
9826
|
+
}
|
|
9773
9827
|
const { stdout: patch } = await git(
|
|
9774
|
-
["diff", "--no-index", "--", "/dev/null", path],
|
|
9828
|
+
["diff", "--no-ext-diff", "--no-color", "--no-index", "--", "/dev/null", path],
|
|
9775
9829
|
worktreePath,
|
|
9776
|
-
{ reject: false }
|
|
9830
|
+
{ reject: false, timeoutMs: 4e3 }
|
|
9777
9831
|
);
|
|
9778
9832
|
const normalized = patch.replace(/^diff --git a\/.+? b\/.+?$/m, `diff --git a/${path} b/${path}`).replace(/^--- .*$/m, "--- /dev/null").replace(/^\+\+\+ .*$/m, `+++ b/${path}`);
|
|
9779
9833
|
const addLines = normalized.split("\n").filter((l) => l.startsWith("+") && !l.startsWith("+++")).length;
|
|
@@ -9785,22 +9839,97 @@ async function untrackedPatch(worktreePath, path, maxHunk) {
|
|
|
9785
9839
|
deletions: 0
|
|
9786
9840
|
};
|
|
9787
9841
|
}
|
|
9788
|
-
async function listUntrackedPaths(worktreePath) {
|
|
9789
|
-
const
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
{ reject: false }
|
|
9793
|
-
);
|
|
9842
|
+
async function listUntrackedPaths(worktreePath, path) {
|
|
9843
|
+
const args = ["ls-files", "-z", "--others", "--exclude-standard"];
|
|
9844
|
+
if (path) args.push("--", path);
|
|
9845
|
+
const { stdout } = await git(args, worktreePath, { reject: false });
|
|
9794
9846
|
return stdout.split("\0").filter(Boolean).filter((p) => !isSideboardScratchPath(p));
|
|
9795
9847
|
}
|
|
9796
|
-
async function listUntrackedFiles(worktreePath, maxHunk) {
|
|
9797
|
-
const
|
|
9798
|
-
if (
|
|
9799
|
-
return Promise.all(
|
|
9848
|
+
async function listUntrackedFiles(worktreePath, maxHunk, paths) {
|
|
9849
|
+
const list = paths ?? await listUntrackedPaths(worktreePath);
|
|
9850
|
+
if (list.length === 0) return [];
|
|
9851
|
+
return Promise.all(list.map((path) => untrackedPatch(worktreePath, path, maxHunk)));
|
|
9852
|
+
}
|
|
9853
|
+
function untrackedStubs(paths) {
|
|
9854
|
+
return paths.map((path) => ({
|
|
9855
|
+
path,
|
|
9856
|
+
status: "A",
|
|
9857
|
+
patch: "",
|
|
9858
|
+
additions: 0,
|
|
9859
|
+
deletions: 0
|
|
9860
|
+
}));
|
|
9861
|
+
}
|
|
9862
|
+
function pathspec(path) {
|
|
9863
|
+
return path ? ["--", path] : [];
|
|
9864
|
+
}
|
|
9865
|
+
function gitDiff(args, cwd, opts) {
|
|
9866
|
+
return git(["diff", "--no-ext-diff", "--no-color", ...args], cwd, {
|
|
9867
|
+
reject: false,
|
|
9868
|
+
timeoutMs: opts?.timeoutMs
|
|
9869
|
+
});
|
|
9870
|
+
}
|
|
9871
|
+
function fileFromPatch(path, patch, maxHunk) {
|
|
9872
|
+
let status = "M";
|
|
9873
|
+
if (/^new file mode /m.test(patch) || /^--- \/dev\/null/m.test(patch)) {
|
|
9874
|
+
status = "A";
|
|
9875
|
+
} else if (/^deleted file mode /m.test(patch) || /^\+\+\+ \/dev\/null/m.test(patch)) {
|
|
9876
|
+
status = "D";
|
|
9877
|
+
} else if (/^rename from /m.test(patch)) {
|
|
9878
|
+
status = "R";
|
|
9879
|
+
}
|
|
9880
|
+
const additions = patch.split("\n").filter((l) => l.startsWith("+") && !l.startsWith("+++")).length;
|
|
9881
|
+
const deletions = patch.split("\n").filter((l) => l.startsWith("-") && !l.startsWith("---")).length;
|
|
9882
|
+
return {
|
|
9883
|
+
path,
|
|
9884
|
+
status,
|
|
9885
|
+
patch: capPatch(patch, maxHunk),
|
|
9886
|
+
additions,
|
|
9887
|
+
deletions
|
|
9888
|
+
};
|
|
9889
|
+
}
|
|
9890
|
+
async function gitDiffParts(worktreePath, diffArgs, includePatches, path) {
|
|
9891
|
+
const extra = pathspec(path);
|
|
9892
|
+
if (includePatches) {
|
|
9893
|
+
const diff = await gitDiff([...diffArgs, ...extra], worktreePath, {
|
|
9894
|
+
timeoutMs: 4e3
|
|
9895
|
+
});
|
|
9896
|
+
return { nameStatus: "", numstat: "", combinedDiff: diff.stdout };
|
|
9897
|
+
}
|
|
9898
|
+
const [ns, num2] = await Promise.all([
|
|
9899
|
+
gitDiff(["--name-status", ...diffArgs, ...extra], worktreePath),
|
|
9900
|
+
gitDiff(["--numstat", ...diffArgs, ...extra], worktreePath)
|
|
9901
|
+
]);
|
|
9902
|
+
return {
|
|
9903
|
+
nameStatus: ns.stdout,
|
|
9904
|
+
numstat: num2.stdout,
|
|
9905
|
+
combinedDiff: ""
|
|
9906
|
+
};
|
|
9907
|
+
}
|
|
9908
|
+
function formatStat(files) {
|
|
9909
|
+
if (files.length === 0) return "(no changes)";
|
|
9910
|
+
const additions = files.reduce((n2, f) => n2 + (f.additions ?? 0), 0);
|
|
9911
|
+
const deletions = files.reduce((n2, f) => n2 + (f.deletions ?? 0), 0);
|
|
9912
|
+
const n = files.length;
|
|
9913
|
+
return `${n} file${n === 1 ? "" : "s"} changed, ${additions} insertions(+), ${deletions} deletions(-)`;
|
|
9914
|
+
}
|
|
9915
|
+
function emptyScopeStats() {
|
|
9916
|
+
const z2 = emptyStat();
|
|
9917
|
+
return {
|
|
9918
|
+
commits: z2,
|
|
9919
|
+
uncommitted: z2,
|
|
9920
|
+
staged: z2,
|
|
9921
|
+
unstaged: z2,
|
|
9922
|
+
last_turn: z2
|
|
9923
|
+
};
|
|
9800
9924
|
}
|
|
9801
9925
|
function filesFromDiff(nameStatus, numstat, combinedDiff, maxHunk) {
|
|
9802
|
-
const counts = parseNumstat(numstat);
|
|
9803
9926
|
const patches = splitCombinedDiff(combinedDiff);
|
|
9927
|
+
if (!nameStatus.trim() && patches.size > 0) {
|
|
9928
|
+
return [...patches.entries()].map(
|
|
9929
|
+
([path, patch]) => fileFromPatch(path, patch, maxHunk)
|
|
9930
|
+
);
|
|
9931
|
+
}
|
|
9932
|
+
const counts = parseNumstat(numstat);
|
|
9804
9933
|
const files = [];
|
|
9805
9934
|
for (const { status, path } of parseNameStatus(nameStatus)) {
|
|
9806
9935
|
const n = counts.get(path);
|
|
@@ -9822,11 +9951,11 @@ async function computeScopeStats(worktreePath, mergeBase, lastTurnBase, untracke
|
|
|
9822
9951
|
{ stdout: unstagedNum },
|
|
9823
9952
|
lastTurnNum
|
|
9824
9953
|
] = await Promise.all([
|
|
9825
|
-
mergeBase ?
|
|
9826
|
-
|
|
9827
|
-
|
|
9828
|
-
|
|
9829
|
-
lastTurnBase ?
|
|
9954
|
+
mergeBase ? gitDiff(["--numstat", mergeBase], worktreePath) : Promise.resolve({ stdout: "" }),
|
|
9955
|
+
gitDiff(["--numstat", "HEAD"], worktreePath),
|
|
9956
|
+
gitDiff(["--numstat", "--cached"], worktreePath),
|
|
9957
|
+
gitDiff(["--numstat"], worktreePath),
|
|
9958
|
+
lastTurnBase ? gitDiff(["--numstat", lastTurnBase], worktreePath) : Promise.resolve({ stdout: "" })
|
|
9830
9959
|
]);
|
|
9831
9960
|
return {
|
|
9832
9961
|
commits: mergeBase ? statFromNumstat(commitsNum, untrackedCount) : emptyStat(),
|
|
@@ -9845,7 +9974,7 @@ async function listBranchCommits(worktreePath, repoPath, opts) {
|
|
|
9845
9974
|
if (head.exitCode !== 0) return [];
|
|
9846
9975
|
let base = opts?.base;
|
|
9847
9976
|
try {
|
|
9848
|
-
base = base ?? await resolveDefaultBranch(repoPath);
|
|
9977
|
+
base = base ?? await resolveDefaultBranch(repoPath, { network: false });
|
|
9849
9978
|
} catch {
|
|
9850
9979
|
base = "HEAD";
|
|
9851
9980
|
}
|
|
@@ -9875,7 +10004,121 @@ async function listBranchCommits(worktreePath, repoPath, opts) {
|
|
|
9875
10004
|
}
|
|
9876
10005
|
return commits;
|
|
9877
10006
|
}
|
|
10007
|
+
var SHA_RE = /^[0-9a-f]{7,40}$/i;
|
|
10008
|
+
function emptyPathDiff(scope, base, hasLastTurnBase, commitSha = null) {
|
|
10009
|
+
return {
|
|
10010
|
+
scope,
|
|
10011
|
+
commitSha: scope === "commits" ? commitSha : null,
|
|
10012
|
+
base,
|
|
10013
|
+
files: [],
|
|
10014
|
+
stat: formatStat([]),
|
|
10015
|
+
dirty: false,
|
|
10016
|
+
unpushed: 0,
|
|
10017
|
+
hasLastTurnBase,
|
|
10018
|
+
commits: [],
|
|
10019
|
+
scopeStats: emptyScopeStats()
|
|
10020
|
+
};
|
|
10021
|
+
}
|
|
10022
|
+
async function getPathDiff(worktreePath, repoPath, opts) {
|
|
10023
|
+
const { path, scope, commitSha, lastTurnBase, hasLastTurnBase, includePatches, maxHunk } = opts;
|
|
10024
|
+
if (scope === "last_turn" && !lastTurnBase) {
|
|
10025
|
+
return emptyPathDiff(scope, "last turn", false);
|
|
10026
|
+
}
|
|
10027
|
+
let diffArgs;
|
|
10028
|
+
let labelBase;
|
|
10029
|
+
if (scope === "staged") {
|
|
10030
|
+
diffArgs = ["--cached"];
|
|
10031
|
+
labelBase = "staged";
|
|
10032
|
+
} else if (scope === "unstaged") {
|
|
10033
|
+
diffArgs = [];
|
|
10034
|
+
labelBase = "unstaged";
|
|
10035
|
+
} else if (scope === "uncommitted") {
|
|
10036
|
+
diffArgs = ["HEAD"];
|
|
10037
|
+
labelBase = "HEAD";
|
|
10038
|
+
} else if (scope === "last_turn") {
|
|
10039
|
+
diffArgs = [lastTurnBase];
|
|
10040
|
+
labelBase = "last turn";
|
|
10041
|
+
} else if (scope === "commits" && commitSha) {
|
|
10042
|
+
diffArgs = [`${commitSha}^!`];
|
|
10043
|
+
labelBase = commitSha.slice(0, 7);
|
|
10044
|
+
} else if (scope === "commits" && opts.base && SHA_RE.test(opts.base)) {
|
|
10045
|
+
diffArgs = [opts.base];
|
|
10046
|
+
labelBase = opts.base.slice(0, 7);
|
|
10047
|
+
} else if (scope === "commits") {
|
|
10048
|
+
let base = opts.base;
|
|
10049
|
+
try {
|
|
10050
|
+
base = base ?? await resolveDefaultBranch(repoPath, { network: false });
|
|
10051
|
+
} catch {
|
|
10052
|
+
base = "HEAD";
|
|
10053
|
+
}
|
|
10054
|
+
const mergeBase = await resolveMergeBase(worktreePath, base, repoPath);
|
|
10055
|
+
diffArgs = [mergeBase];
|
|
10056
|
+
labelBase = mergeBase;
|
|
10057
|
+
} else {
|
|
10058
|
+
diffArgs = ["HEAD"];
|
|
10059
|
+
labelBase = "HEAD";
|
|
10060
|
+
}
|
|
10061
|
+
const diff = await gitDiff(
|
|
10062
|
+
includePatches ? [...diffArgs, "--", path] : ["--name-status", ...diffArgs, "--", path],
|
|
10063
|
+
worktreePath,
|
|
10064
|
+
{ timeoutMs: 4e3 }
|
|
10065
|
+
);
|
|
10066
|
+
const filesMap = /* @__PURE__ */ new Map();
|
|
10067
|
+
if (includePatches) {
|
|
10068
|
+
const parsed = filesFromDiff("", "", diff.stdout, maxHunk);
|
|
10069
|
+
for (const file of parsed) filesMap.set(file.path, file);
|
|
10070
|
+
if (diff.stdout.trim() && !filesMap.has(path)) {
|
|
10071
|
+
filesMap.set(path, fileFromPatch(path, diff.stdout, maxHunk));
|
|
10072
|
+
}
|
|
10073
|
+
} else {
|
|
10074
|
+
for (const file of filesFromDiff(diff.stdout, "", "", maxHunk)) {
|
|
10075
|
+
filesMap.set(file.path, file);
|
|
10076
|
+
}
|
|
10077
|
+
}
|
|
10078
|
+
if (filesMap.size === 0) {
|
|
10079
|
+
const maybe = await listUntrackedPaths(worktreePath, path);
|
|
10080
|
+
if (maybe.length > 0) {
|
|
10081
|
+
const extra = includePatches ? await listUntrackedFiles(worktreePath, maxHunk, maybe) : untrackedStubs(maybe);
|
|
10082
|
+
for (const file of extra) filesMap.set(file.path, file);
|
|
10083
|
+
}
|
|
10084
|
+
}
|
|
10085
|
+
const files = [...filesMap.values()].sort((a, b) => a.path.localeCompare(b.path));
|
|
10086
|
+
return {
|
|
10087
|
+
scope,
|
|
10088
|
+
commitSha: scope === "commits" ? commitSha : null,
|
|
10089
|
+
base: labelBase,
|
|
10090
|
+
files,
|
|
10091
|
+
stat: formatStat(files),
|
|
10092
|
+
dirty: files.length > 0,
|
|
10093
|
+
unpushed: 0,
|
|
10094
|
+
hasLastTurnBase,
|
|
10095
|
+
commits: [],
|
|
10096
|
+
scopeStats: emptyScopeStats(),
|
|
10097
|
+
mergeBase: SHA_RE.test(diffArgs[0] ?? "") ? diffArgs[0] : null
|
|
10098
|
+
};
|
|
10099
|
+
}
|
|
9878
10100
|
async function getDiff(worktreePath, repoPath, opts) {
|
|
10101
|
+
const maxHunk = opts?.maxHunkChars ?? 8e3;
|
|
10102
|
+
const scope = opts?.scope ?? "commits";
|
|
10103
|
+
const lastTurnBase = opts?.lastTurnBase?.trim() || null;
|
|
10104
|
+
const hasLastTurnBase = Boolean(lastTurnBase);
|
|
10105
|
+
const commitSha = opts?.commitSha?.trim() || null;
|
|
10106
|
+
const includePatches = opts?.includePatches ?? true;
|
|
10107
|
+
const pathFilter = opts?.path?.trim() || null;
|
|
10108
|
+
const fileOnly = Boolean(pathFilter);
|
|
10109
|
+
const includeMeta = (opts?.includeMeta ?? true) && !fileOnly;
|
|
10110
|
+
if (fileOnly && pathFilter && !includeMeta) {
|
|
10111
|
+
return getPathDiff(worktreePath, repoPath, {
|
|
10112
|
+
path: pathFilter,
|
|
10113
|
+
scope,
|
|
10114
|
+
commitSha,
|
|
10115
|
+
lastTurnBase,
|
|
10116
|
+
hasLastTurnBase,
|
|
10117
|
+
base: opts?.base,
|
|
10118
|
+
includePatches,
|
|
10119
|
+
maxHunk
|
|
10120
|
+
});
|
|
10121
|
+
}
|
|
9879
10122
|
const status = await inspectGitWorktree(worktreePath);
|
|
9880
10123
|
if (status === "missing_worktree") {
|
|
9881
10124
|
throw new Error("Worktree not found");
|
|
@@ -9883,18 +10126,19 @@ async function getDiff(worktreePath, repoPath, opts) {
|
|
|
9883
10126
|
if (status === "not_git") {
|
|
9884
10127
|
throw new Error("Not a Git repository");
|
|
9885
10128
|
}
|
|
9886
|
-
const
|
|
9887
|
-
const
|
|
9888
|
-
const
|
|
9889
|
-
const hasLastTurnBase = Boolean(lastTurnBase);
|
|
9890
|
-
const commitSha = opts?.commitSha?.trim() || null;
|
|
9891
|
-
const head = await git(["rev-parse", "--verify", "HEAD"], worktreePath, {
|
|
10129
|
+
const wantUntracked = opts?.includeUntracked !== void 0 ? opts.includeUntracked : !fileOnly && (scope === "commits" && !commitSha || scope === "uncommitted" || scope === "unstaged" || scope === "last_turn");
|
|
10130
|
+
const needsMergeBase = scope === "commits" && !commitSha || includeMeta;
|
|
10131
|
+
const headP = git(["rev-parse", "--verify", "HEAD"], worktreePath, {
|
|
9892
10132
|
reject: false
|
|
9893
10133
|
});
|
|
10134
|
+
const untrackedP = wantUntracked ? listUntrackedPaths(worktreePath, pathFilter) : Promise.resolve([]);
|
|
10135
|
+
const head = await headP;
|
|
9894
10136
|
const hasHead = head.exitCode === 0;
|
|
9895
|
-
const untrackedPaths = await listUntrackedPaths(worktreePath);
|
|
9896
10137
|
if (!hasHead) {
|
|
9897
|
-
const
|
|
10138
|
+
const untrackedPaths2 = await untrackedP;
|
|
10139
|
+
const files2 = scope === "staged" ? [] : includePatches ? (await listUntrackedFiles(worktreePath, maxHunk, untrackedPaths2)).sort(
|
|
10140
|
+
(a, b) => a.path.localeCompare(b.path)
|
|
10141
|
+
) : untrackedStubs(untrackedPaths2).sort(
|
|
9898
10142
|
(a, b) => a.path.localeCompare(b.path)
|
|
9899
10143
|
);
|
|
9900
10144
|
const untrackedStat = {
|
|
@@ -9908,7 +10152,7 @@ async function getDiff(worktreePath, repoPath, opts) {
|
|
|
9908
10152
|
commitSha: null,
|
|
9909
10153
|
base: "(no commits)",
|
|
9910
10154
|
files: files2,
|
|
9911
|
-
stat: files2
|
|
10155
|
+
stat: formatStat(files2),
|
|
9912
10156
|
dirty: files2.length > 0,
|
|
9913
10157
|
unpushed: 0,
|
|
9914
10158
|
hasLastTurnBase,
|
|
@@ -9922,137 +10166,122 @@ async function getDiff(worktreePath, repoPath, opts) {
|
|
|
9922
10166
|
}
|
|
9923
10167
|
};
|
|
9924
10168
|
}
|
|
9925
|
-
let
|
|
9926
|
-
|
|
9927
|
-
|
|
9928
|
-
|
|
9929
|
-
|
|
10169
|
+
let mergeBase = "HEAD";
|
|
10170
|
+
let baseLabel = "HEAD";
|
|
10171
|
+
if (needsMergeBase) {
|
|
10172
|
+
let base = opts?.base;
|
|
10173
|
+
try {
|
|
10174
|
+
base = base ?? await resolveDefaultBranch(repoPath, { network: false });
|
|
10175
|
+
} catch {
|
|
10176
|
+
base = "HEAD";
|
|
10177
|
+
}
|
|
10178
|
+
mergeBase = await resolveMergeBase(worktreePath, base, repoPath);
|
|
10179
|
+
baseLabel = await resolveDiffBaseRef(worktreePath, base, repoPath);
|
|
9930
10180
|
}
|
|
9931
|
-
|
|
9932
|
-
|
|
9933
|
-
|
|
9934
|
-
|
|
9935
|
-
|
|
9936
|
-
|
|
9937
|
-
|
|
10181
|
+
const includeUntracked = wantUntracked;
|
|
10182
|
+
const metaPromise = includeMeta ? Promise.all([
|
|
10183
|
+
computeScopeStats(
|
|
10184
|
+
worktreePath,
|
|
10185
|
+
mergeBase,
|
|
10186
|
+
lastTurnBase,
|
|
10187
|
+
// Cheap: don't wait on the untracked walk just to pad the badge.
|
|
10188
|
+
0
|
|
10189
|
+
),
|
|
10190
|
+
listBranchCommits(worktreePath, repoPath, { base: baseLabel }),
|
|
10191
|
+
isDirty(worktreePath),
|
|
10192
|
+
countUnpushedCommits(worktreePath)
|
|
10193
|
+
]).then(([scopeStats, commits, dirty, unpushed]) => ({
|
|
10194
|
+
scopeStats,
|
|
10195
|
+
commits,
|
|
10196
|
+
dirty,
|
|
10197
|
+
unpushed
|
|
10198
|
+
})) : Promise.resolve({
|
|
10199
|
+
scopeStats: emptyScopeStats(),
|
|
10200
|
+
commits: [],
|
|
10201
|
+
dirty: false,
|
|
10202
|
+
unpushed: 0
|
|
10203
|
+
});
|
|
10204
|
+
if (scope === "last_turn" && !lastTurnBase) {
|
|
10205
|
+
const meta2 = await metaPromise;
|
|
10206
|
+
return {
|
|
10207
|
+
scope,
|
|
10208
|
+
commitSha: null,
|
|
10209
|
+
base: "last turn",
|
|
10210
|
+
files: [],
|
|
10211
|
+
stat: "(no last agent turn)",
|
|
10212
|
+
dirty: meta2.dirty,
|
|
10213
|
+
unpushed: meta2.unpushed,
|
|
10214
|
+
hasLastTurnBase: false,
|
|
10215
|
+
commits: meta2.commits,
|
|
10216
|
+
scopeStats: meta2.scopeStats
|
|
10217
|
+
};
|
|
9938
10218
|
}
|
|
9939
|
-
|
|
9940
|
-
|
|
9941
|
-
worktreePath,
|
|
9942
|
-
mergeBase,
|
|
9943
|
-
lastTurnBase,
|
|
9944
|
-
untrackedPaths.length
|
|
9945
|
-
);
|
|
9946
|
-
const includeUntracked = scope === "commits" && !commitSha || scope === "uncommitted" || scope === "unstaged" || scope === "last_turn";
|
|
9947
|
-
let nameStatus = "";
|
|
9948
|
-
let numstat = "";
|
|
9949
|
-
let combinedDiff = "";
|
|
9950
|
-
let labelBase = base;
|
|
10219
|
+
let diffArgs;
|
|
10220
|
+
let labelBase = baseLabel;
|
|
9951
10221
|
if (scope === "staged") {
|
|
9952
|
-
|
|
9953
|
-
git(["diff", "--name-status", "--cached"], worktreePath, { reject: false }),
|
|
9954
|
-
git(["diff", "--numstat", "--cached"], worktreePath, { reject: false }),
|
|
9955
|
-
git(["diff", "--cached"], worktreePath, { reject: false })
|
|
9956
|
-
]);
|
|
9957
|
-
nameStatus = ns.stdout;
|
|
9958
|
-
numstat = num2.stdout;
|
|
9959
|
-
combinedDiff = diff.stdout;
|
|
10222
|
+
diffArgs = ["--cached"];
|
|
9960
10223
|
labelBase = "staged";
|
|
9961
10224
|
} else if (scope === "unstaged") {
|
|
9962
|
-
|
|
9963
|
-
git(["diff", "--name-status"], worktreePath, { reject: false }),
|
|
9964
|
-
git(["diff", "--numstat"], worktreePath, { reject: false }),
|
|
9965
|
-
git(["diff"], worktreePath, { reject: false })
|
|
9966
|
-
]);
|
|
9967
|
-
nameStatus = ns.stdout;
|
|
9968
|
-
numstat = num2.stdout;
|
|
9969
|
-
combinedDiff = diff.stdout;
|
|
10225
|
+
diffArgs = [];
|
|
9970
10226
|
labelBase = "unstaged";
|
|
9971
10227
|
} else if (scope === "uncommitted") {
|
|
9972
|
-
|
|
9973
|
-
git(["diff", "--name-status", "HEAD"], worktreePath, { reject: false }),
|
|
9974
|
-
git(["diff", "--numstat", "HEAD"], worktreePath, { reject: false }),
|
|
9975
|
-
git(["diff", "HEAD"], worktreePath, { reject: false })
|
|
9976
|
-
]);
|
|
9977
|
-
nameStatus = ns.stdout;
|
|
9978
|
-
numstat = num2.stdout;
|
|
9979
|
-
combinedDiff = diff.stdout;
|
|
10228
|
+
diffArgs = ["HEAD"];
|
|
9980
10229
|
labelBase = "HEAD";
|
|
9981
10230
|
} else if (scope === "last_turn") {
|
|
9982
|
-
|
|
9983
|
-
const commits2 = await listBranchCommits(worktreePath, repoPath, { base });
|
|
9984
|
-
return {
|
|
9985
|
-
scope,
|
|
9986
|
-
commitSha: null,
|
|
9987
|
-
base: "last turn",
|
|
9988
|
-
files: [],
|
|
9989
|
-
stat: "(no last agent turn)",
|
|
9990
|
-
dirty: await isDirty(worktreePath),
|
|
9991
|
-
unpushed: await countUnpushedCommits(worktreePath),
|
|
9992
|
-
hasLastTurnBase: false,
|
|
9993
|
-
commits: commits2,
|
|
9994
|
-
scopeStats
|
|
9995
|
-
};
|
|
9996
|
-
}
|
|
9997
|
-
const [ns, num2, diff] = await Promise.all([
|
|
9998
|
-
git(["diff", "--name-status", lastTurnBase], worktreePath, { reject: false }),
|
|
9999
|
-
git(["diff", "--numstat", lastTurnBase], worktreePath, { reject: false }),
|
|
10000
|
-
git(["diff", lastTurnBase], worktreePath, { reject: false })
|
|
10001
|
-
]);
|
|
10002
|
-
nameStatus = ns.stdout;
|
|
10003
|
-
numstat = num2.stdout;
|
|
10004
|
-
combinedDiff = diff.stdout;
|
|
10231
|
+
diffArgs = [lastTurnBase];
|
|
10005
10232
|
labelBase = "last turn";
|
|
10006
10233
|
} else if (scope === "commits" && commitSha) {
|
|
10007
|
-
|
|
10008
|
-
const [ns, num2, diff] = await Promise.all([
|
|
10009
|
-
git(["diff", "--name-status", range], worktreePath, { reject: false }),
|
|
10010
|
-
git(["diff", "--numstat", range], worktreePath, { reject: false }),
|
|
10011
|
-
git(["diff", range], worktreePath, { reject: false })
|
|
10012
|
-
]);
|
|
10013
|
-
nameStatus = ns.stdout;
|
|
10014
|
-
numstat = num2.stdout;
|
|
10015
|
-
combinedDiff = diff.stdout;
|
|
10234
|
+
diffArgs = [`${commitSha}^!`];
|
|
10016
10235
|
labelBase = commitSha.slice(0, 7);
|
|
10017
10236
|
} else {
|
|
10018
|
-
|
|
10019
|
-
|
|
10020
|
-
git(["diff", "--numstat", mergeBase], worktreePath, { reject: false }),
|
|
10021
|
-
git(["diff", mergeBase], worktreePath, { reject: false })
|
|
10022
|
-
]);
|
|
10023
|
-
nameStatus = ns.stdout;
|
|
10024
|
-
numstat = num2.stdout;
|
|
10025
|
-
combinedDiff = diff.stdout;
|
|
10026
|
-
labelBase = base;
|
|
10237
|
+
diffArgs = [mergeBase];
|
|
10238
|
+
labelBase = baseLabel;
|
|
10027
10239
|
}
|
|
10028
|
-
const
|
|
10240
|
+
const partsPromise = gitDiffParts(
|
|
10241
|
+
worktreePath,
|
|
10242
|
+
diffArgs,
|
|
10243
|
+
includePatches,
|
|
10244
|
+
pathFilter
|
|
10245
|
+
);
|
|
10246
|
+
const [parts, meta, untrackedPaths] = await Promise.all([
|
|
10247
|
+
partsPromise,
|
|
10248
|
+
metaPromise,
|
|
10249
|
+
untrackedP
|
|
10250
|
+
]);
|
|
10029
10251
|
const filesMap = /* @__PURE__ */ new Map();
|
|
10030
|
-
for (const file of filesFromDiff(
|
|
10252
|
+
for (const file of filesFromDiff(
|
|
10253
|
+
parts.nameStatus,
|
|
10254
|
+
parts.numstat,
|
|
10255
|
+
parts.combinedDiff,
|
|
10256
|
+
maxHunk
|
|
10257
|
+
)) {
|
|
10031
10258
|
filesMap.set(file.path, file);
|
|
10032
10259
|
}
|
|
10033
10260
|
if (includeUntracked) {
|
|
10034
|
-
const
|
|
10035
|
-
for (const file of
|
|
10261
|
+
const extra = includePatches ? await listUntrackedFiles(worktreePath, maxHunk, untrackedPaths) : untrackedStubs(untrackedPaths);
|
|
10262
|
+
for (const file of extra) {
|
|
10036
10263
|
if (!filesMap.has(file.path)) filesMap.set(file.path, file);
|
|
10037
10264
|
}
|
|
10265
|
+
} else if (fileOnly && pathFilter && !filesMap.has(pathFilter)) {
|
|
10266
|
+
const maybe = await listUntrackedPaths(worktreePath, pathFilter);
|
|
10267
|
+
if (maybe.length > 0) {
|
|
10268
|
+
const extra = includePatches ? await listUntrackedFiles(worktreePath, maxHunk, maybe) : untrackedStubs(maybe);
|
|
10269
|
+
for (const file of extra) filesMap.set(file.path, file);
|
|
10270
|
+
}
|
|
10038
10271
|
}
|
|
10039
10272
|
const files = [...filesMap.values()].sort((a, b) => a.path.localeCompare(b.path));
|
|
10040
|
-
const { stdout: statOut } = await git(
|
|
10041
|
-
scope === "staged" ? ["diff", "--stat", "--cached"] : scope === "unstaged" ? ["diff", "--stat"] : scope === "uncommitted" ? ["diff", "--stat", "HEAD"] : scope === "last_turn" && lastTurnBase ? ["diff", "--stat", lastTurnBase] : scope === "commits" && commitSha ? ["diff", "--stat", `${commitSha}^!`] : ["diff", "--stat", mergeBase],
|
|
10042
|
-
worktreePath,
|
|
10043
|
-
{ reject: false }
|
|
10044
|
-
);
|
|
10045
10273
|
return {
|
|
10046
10274
|
scope,
|
|
10047
10275
|
commitSha: scope === "commits" ? commitSha : null,
|
|
10048
10276
|
base: labelBase,
|
|
10049
10277
|
files,
|
|
10050
|
-
stat:
|
|
10051
|
-
dirty:
|
|
10052
|
-
unpushed:
|
|
10278
|
+
stat: formatStat(files),
|
|
10279
|
+
dirty: fileOnly || !includeMeta ? files.length > 0 : meta.dirty,
|
|
10280
|
+
unpushed: meta.unpushed,
|
|
10053
10281
|
hasLastTurnBase,
|
|
10054
|
-
commits,
|
|
10055
|
-
scopeStats
|
|
10282
|
+
commits: meta.commits,
|
|
10283
|
+
scopeStats: meta.scopeStats,
|
|
10284
|
+
mergeBase: needsMergeBase ? mergeBase : null
|
|
10056
10285
|
};
|
|
10057
10286
|
}
|
|
10058
10287
|
async function listWorktreeFiles(worktreePath, opts) {
|
|
@@ -12006,6 +12235,11 @@ var Orchestrator = class {
|
|
|
12006
12235
|
return getDiff(thread.worktreePath, thread.repoPath, {
|
|
12007
12236
|
scope: opts?.scope,
|
|
12008
12237
|
commitSha: opts?.commitSha,
|
|
12238
|
+
base: opts?.base,
|
|
12239
|
+
includePatches: opts?.includePatches,
|
|
12240
|
+
includeMeta: opts?.includeMeta,
|
|
12241
|
+
includeUntracked: opts?.includeUntracked,
|
|
12242
|
+
path: opts?.path,
|
|
12009
12243
|
lastTurnBase: this.turnBaselines.get(thread.id) ?? null
|
|
12010
12244
|
});
|
|
12011
12245
|
}
|