vde-worktree 0.0.3 → 0.0.5
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/README.ja.md +31 -0
- package/README.md +30 -0
- package/dist/index.mjs +313 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.mjs
CHANGED
|
@@ -5,10 +5,11 @@ import { access, appendFile, chmod, cp, mkdir, open, readFile, readdir, rename,
|
|
|
5
5
|
import { homedir, hostname } from "node:os";
|
|
6
6
|
import { dirname, isAbsolute, join, normalize, relative, resolve, sep } from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
|
+
import chalk, { Chalk } from "chalk";
|
|
8
9
|
import { parseArgs } from "citty";
|
|
9
10
|
import { execa } from "execa";
|
|
10
11
|
import stringWidth from "string-width";
|
|
11
|
-
import
|
|
12
|
+
import { getBorderCharacters, table } from "table";
|
|
12
13
|
|
|
13
14
|
//#region src/core/constants.ts
|
|
14
15
|
const SCHEMA_VERSION = 1;
|
|
@@ -1001,7 +1002,7 @@ const RESERVED_FZF_ARGS = new Set([
|
|
|
1001
1002
|
"height",
|
|
1002
1003
|
"border"
|
|
1003
1004
|
]);
|
|
1004
|
-
const sanitizeCandidate = (value) => value.replace(/[\
|
|
1005
|
+
const sanitizeCandidate = (value) => value.replace(/[\r\n]+/g, " ").trim();
|
|
1005
1006
|
const buildFzfInput = (candidates) => {
|
|
1006
1007
|
return candidates.map((candidate) => sanitizeCandidate(candidate)).filter((candidate) => candidate.length > 0).join("\n");
|
|
1007
1008
|
};
|
|
@@ -1152,11 +1153,149 @@ const loadPackageVersion = (requireFn) => {
|
|
|
1152
1153
|
//#region src/cli/index.ts
|
|
1153
1154
|
const EXIT_CODE_CANCELLED = 130;
|
|
1154
1155
|
const optionNamesAllowOptionLikeValue = new Set(["fzfArg", "fzf-arg"]);
|
|
1156
|
+
const CD_FZF_EXTRA_ARGS = [
|
|
1157
|
+
"--delimiter= ",
|
|
1158
|
+
"--with-nth=1",
|
|
1159
|
+
"--preview=printf '%b' {3}",
|
|
1160
|
+
"--preview-window=right,60%,wrap",
|
|
1161
|
+
"--ansi"
|
|
1162
|
+
];
|
|
1155
1163
|
const COMPLETION_SHELLS = ["zsh", "fish"];
|
|
1156
1164
|
const COMPLETION_FILE_BY_SHELL = {
|
|
1157
1165
|
zsh: "zsh/_vw",
|
|
1158
1166
|
fish: "fish/vw.fish"
|
|
1159
1167
|
};
|
|
1168
|
+
const CATPPUCCIN_MOCHA = {
|
|
1169
|
+
rosewater: "#f5e0dc",
|
|
1170
|
+
mauve: "#cba6f7",
|
|
1171
|
+
red: "#f38ba8",
|
|
1172
|
+
peach: "#fab387",
|
|
1173
|
+
yellow: "#f9e2af",
|
|
1174
|
+
green: "#a6e3a1",
|
|
1175
|
+
blue: "#89b4fa",
|
|
1176
|
+
lavender: "#b4befe",
|
|
1177
|
+
sapphire: "#74c7ec",
|
|
1178
|
+
text: "#cdd6f4",
|
|
1179
|
+
subtext0: "#a6adc8",
|
|
1180
|
+
overlay0: "#6c7086"
|
|
1181
|
+
};
|
|
1182
|
+
const identityColor = (value) => value;
|
|
1183
|
+
const createCatppuccinTheme = ({ enabled }) => {
|
|
1184
|
+
if (enabled !== true) return {
|
|
1185
|
+
header: identityColor,
|
|
1186
|
+
branch: identityColor,
|
|
1187
|
+
branchCurrent: identityColor,
|
|
1188
|
+
branchDetached: identityColor,
|
|
1189
|
+
dirty: identityColor,
|
|
1190
|
+
clean: identityColor,
|
|
1191
|
+
merged: identityColor,
|
|
1192
|
+
unmerged: identityColor,
|
|
1193
|
+
unknown: identityColor,
|
|
1194
|
+
base: identityColor,
|
|
1195
|
+
locked: identityColor,
|
|
1196
|
+
path: identityColor,
|
|
1197
|
+
muted: identityColor,
|
|
1198
|
+
value: identityColor,
|
|
1199
|
+
previewLabel: identityColor,
|
|
1200
|
+
previewSection: identityColor
|
|
1201
|
+
};
|
|
1202
|
+
const chalk = new Chalk({ level: 3 });
|
|
1203
|
+
const color = (hex) => (value) => chalk.hex(hex)(value);
|
|
1204
|
+
return {
|
|
1205
|
+
header: color(CATPPUCCIN_MOCHA.rosewater),
|
|
1206
|
+
branch: color(CATPPUCCIN_MOCHA.lavender),
|
|
1207
|
+
branchCurrent: color(CATPPUCCIN_MOCHA.mauve),
|
|
1208
|
+
branchDetached: color(CATPPUCCIN_MOCHA.peach),
|
|
1209
|
+
dirty: color(CATPPUCCIN_MOCHA.peach),
|
|
1210
|
+
clean: color(CATPPUCCIN_MOCHA.green),
|
|
1211
|
+
merged: color(CATPPUCCIN_MOCHA.green),
|
|
1212
|
+
unmerged: color(CATPPUCCIN_MOCHA.red),
|
|
1213
|
+
unknown: color(CATPPUCCIN_MOCHA.yellow),
|
|
1214
|
+
base: color(CATPPUCCIN_MOCHA.blue),
|
|
1215
|
+
locked: color(CATPPUCCIN_MOCHA.red),
|
|
1216
|
+
path: color(CATPPUCCIN_MOCHA.sapphire),
|
|
1217
|
+
muted: color(CATPPUCCIN_MOCHA.overlay0),
|
|
1218
|
+
value: color(CATPPUCCIN_MOCHA.text),
|
|
1219
|
+
previewLabel: color(CATPPUCCIN_MOCHA.mauve),
|
|
1220
|
+
previewSection: color(CATPPUCCIN_MOCHA.rosewater)
|
|
1221
|
+
};
|
|
1222
|
+
};
|
|
1223
|
+
const shouldUseAnsiColors = ({ interactive }) => {
|
|
1224
|
+
return interactive === true;
|
|
1225
|
+
};
|
|
1226
|
+
const colorizeCellContent = ({ cell, color }) => {
|
|
1227
|
+
const matched = /^(\s*)(.*?)(\s*)$/.exec(cell);
|
|
1228
|
+
if (matched === null) return cell;
|
|
1229
|
+
const leftPadding = matched[1] ?? "";
|
|
1230
|
+
const content = matched[2] ?? "";
|
|
1231
|
+
const rightPadding = matched[3] ?? "";
|
|
1232
|
+
if (content.length === 0) return cell;
|
|
1233
|
+
return `${leftPadding}${color(content)}${rightPadding}`;
|
|
1234
|
+
};
|
|
1235
|
+
const colorizeListTableLine = ({ line, theme }) => {
|
|
1236
|
+
if (line.startsWith("┌") || line.startsWith("├") || line.startsWith("└")) return theme.muted(line);
|
|
1237
|
+
if (line.startsWith("│") !== true) return line;
|
|
1238
|
+
const segments = line.split("│");
|
|
1239
|
+
if (segments.length < 3) return line;
|
|
1240
|
+
const cells = segments.slice(1, -1);
|
|
1241
|
+
if (cells.length !== 5) return line;
|
|
1242
|
+
const headers = cells.map((cell) => cell.trim());
|
|
1243
|
+
if (headers[0] === "branch" && headers[1] === "dirty" && headers[2] === "merged" && headers[3] === "locked" && headers[4] === "path") {
|
|
1244
|
+
const nextCells = cells.map((cell) => colorizeCellContent({
|
|
1245
|
+
cell,
|
|
1246
|
+
color: theme.header
|
|
1247
|
+
}));
|
|
1248
|
+
return [
|
|
1249
|
+
segments[0],
|
|
1250
|
+
...nextCells,
|
|
1251
|
+
segments.at(-1) ?? ""
|
|
1252
|
+
].join("│");
|
|
1253
|
+
}
|
|
1254
|
+
const branchCell = cells[0];
|
|
1255
|
+
const dirtyCell = cells[1];
|
|
1256
|
+
const mergedCell = cells[2];
|
|
1257
|
+
const lockedCell = cells[3];
|
|
1258
|
+
const pathCell = cells[4];
|
|
1259
|
+
const branchColor = branchCell.includes("(detached)") === true ? theme.branchDetached : branchCell.trimStart().startsWith("*") ? theme.branchCurrent : theme.branch;
|
|
1260
|
+
const dirtyTrimmed = dirtyCell.trim();
|
|
1261
|
+
const dirtyColor = dirtyTrimmed === "dirty" ? theme.dirty : dirtyTrimmed === "clean" ? theme.clean : theme.value;
|
|
1262
|
+
const mergedTrimmed = mergedCell.trim();
|
|
1263
|
+
const mergedColor = mergedTrimmed === "merged" ? theme.merged : mergedTrimmed === "unmerged" ? theme.unmerged : mergedTrimmed === "-" ? theme.base : theme.unknown;
|
|
1264
|
+
const lockedColor = lockedCell.trim() === "locked" ? theme.locked : theme.muted;
|
|
1265
|
+
const nextCells = [
|
|
1266
|
+
colorizeCellContent({
|
|
1267
|
+
cell: branchCell,
|
|
1268
|
+
color: branchColor
|
|
1269
|
+
}),
|
|
1270
|
+
colorizeCellContent({
|
|
1271
|
+
cell: dirtyCell,
|
|
1272
|
+
color: dirtyColor
|
|
1273
|
+
}),
|
|
1274
|
+
colorizeCellContent({
|
|
1275
|
+
cell: mergedCell,
|
|
1276
|
+
color: mergedColor
|
|
1277
|
+
}),
|
|
1278
|
+
colorizeCellContent({
|
|
1279
|
+
cell: lockedCell,
|
|
1280
|
+
color: lockedColor
|
|
1281
|
+
}),
|
|
1282
|
+
colorizeCellContent({
|
|
1283
|
+
cell: pathCell,
|
|
1284
|
+
color: theme.path
|
|
1285
|
+
})
|
|
1286
|
+
];
|
|
1287
|
+
return [
|
|
1288
|
+
segments[0],
|
|
1289
|
+
...nextCells,
|
|
1290
|
+
segments.at(-1) ?? ""
|
|
1291
|
+
].join("│");
|
|
1292
|
+
};
|
|
1293
|
+
const colorizeListTable = ({ rendered, theme }) => {
|
|
1294
|
+
return rendered.trimEnd().split("\n").map((line) => colorizeListTableLine({
|
|
1295
|
+
line,
|
|
1296
|
+
theme
|
|
1297
|
+
})).join("\n");
|
|
1298
|
+
};
|
|
1160
1299
|
const commandHelpEntries = [
|
|
1161
1300
|
{
|
|
1162
1301
|
name: "init",
|
|
@@ -1407,6 +1546,11 @@ const collectOptionValues = ({ args, optionNames }) => {
|
|
|
1407
1546
|
}
|
|
1408
1547
|
return values;
|
|
1409
1548
|
};
|
|
1549
|
+
const mergeFzfArgs = ({ defaults, extras }) => {
|
|
1550
|
+
const merged = [...defaults];
|
|
1551
|
+
for (const arg of extras) if (merged.includes(arg) !== true) merged.push(arg);
|
|
1552
|
+
return merged;
|
|
1553
|
+
};
|
|
1410
1554
|
const toNumberOption = ({ value, optionName }) => {
|
|
1411
1555
|
if (value === void 0) return;
|
|
1412
1556
|
if (typeof value !== "string") throw createCliError("INVALID_ARGUMENT", { message: `${optionName} must be a number` });
|
|
@@ -1728,10 +1872,123 @@ const formatDisplayPath = (absolutePath) => {
|
|
|
1728
1872
|
if (absolutePath.startsWith(`${homeDirectory}${sep}`)) return `~${absolutePath.slice(homeDirectory.length)}`;
|
|
1729
1873
|
return absolutePath;
|
|
1730
1874
|
};
|
|
1731
|
-
const
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1875
|
+
const encodeCdPreviewField = (value) => {
|
|
1876
|
+
return value.replace(/\\/g, "\\\\").split("\x1B").join("\\033").replace(/\t/g, " ").replace(/\r\n?/g, "\n").replace(/\n/g, "\\n");
|
|
1877
|
+
};
|
|
1878
|
+
const formatMergedDisplayState = ({ mergedOverall, isBaseBranch, baseLabel = "base" }) => {
|
|
1879
|
+
if (isBaseBranch) return baseLabel;
|
|
1880
|
+
if (mergedOverall === true) return "merged";
|
|
1881
|
+
if (mergedOverall === false) return "unmerged";
|
|
1882
|
+
return "unknown";
|
|
1883
|
+
};
|
|
1884
|
+
const formatMergedColor = ({ mergedState, theme }) => {
|
|
1885
|
+
const normalized = mergedState.toLowerCase();
|
|
1886
|
+
if (normalized === "merged") return theme.merged(mergedState);
|
|
1887
|
+
if (normalized === "unmerged") return theme.unmerged(mergedState);
|
|
1888
|
+
if (normalized === "base") return theme.base(mergedState);
|
|
1889
|
+
return theme.unknown(mergedState);
|
|
1890
|
+
};
|
|
1891
|
+
const padToDisplayWidth = ({ value, width }) => {
|
|
1892
|
+
const visibleLength = stringWidth(value);
|
|
1893
|
+
if (visibleLength >= width) return value;
|
|
1894
|
+
return `${value}${" ".repeat(width - visibleLength)}`;
|
|
1895
|
+
};
|
|
1896
|
+
const buildCdBranchLabel = ({ worktree, currentWorktreeRoot }) => {
|
|
1897
|
+
return `${worktree.path === currentWorktreeRoot ? "*" : " "} ${worktree.branch ?? "(detached)"}`;
|
|
1898
|
+
};
|
|
1899
|
+
const buildCdStateSummary = ({ worktree, isBaseBranch, theme }) => {
|
|
1900
|
+
const dirtyLabel = worktree.dirty ? "DIRTY" : "CLEAN";
|
|
1901
|
+
const mergedLabel = formatMergedDisplayState({
|
|
1902
|
+
mergedOverall: worktree.merged.overall,
|
|
1903
|
+
isBaseBranch
|
|
1904
|
+
}).toUpperCase();
|
|
1905
|
+
const lockLabel = worktree.locked.value ? "LOCK" : "OPEN";
|
|
1906
|
+
const dirtyBadge = (worktree.dirty ? theme.unmerged : theme.clean)(padToDisplayWidth({
|
|
1907
|
+
value: dirtyLabel,
|
|
1908
|
+
width: 5
|
|
1909
|
+
}));
|
|
1910
|
+
const mergedBadge = formatMergedColor({
|
|
1911
|
+
mergedState: padToDisplayWidth({
|
|
1912
|
+
value: mergedLabel,
|
|
1913
|
+
width: 8
|
|
1914
|
+
}),
|
|
1915
|
+
theme
|
|
1916
|
+
});
|
|
1917
|
+
const lockBadge = (worktree.locked.value ? theme.locked : theme.muted)(padToDisplayWidth({
|
|
1918
|
+
value: lockLabel,
|
|
1919
|
+
width: 4
|
|
1920
|
+
}));
|
|
1921
|
+
return `${dirtyBadge} ${theme.muted("|")} ${mergedBadge} ${theme.muted("|")} ${lockBadge}`;
|
|
1922
|
+
};
|
|
1923
|
+
const buildCdPreviewText = ({ worktree, baseBranch, theme }) => {
|
|
1924
|
+
const isBaseBranch = typeof worktree.branch === "string" && baseBranch !== null && worktree.branch === baseBranch;
|
|
1925
|
+
const branchLabel = worktree.branch === null ? theme.branchDetached("(detached)") : isBaseBranch ? theme.base(worktree.branch) : theme.branch(worktree.branch);
|
|
1926
|
+
const pathLabel = theme.path(formatDisplayPath(worktree.path));
|
|
1927
|
+
const dirtyValue = worktree.dirty ? theme.unmerged("[DIRTY]") : theme.merged("[CLEAN]");
|
|
1928
|
+
const lockedValue = worktree.locked.value ? theme.locked("[LOCKED]") : theme.clean("[OPEN]");
|
|
1929
|
+
const mergedValue = formatMergedColor({
|
|
1930
|
+
mergedState: formatMergedDisplayState({
|
|
1931
|
+
mergedOverall: worktree.merged.overall,
|
|
1932
|
+
isBaseBranch
|
|
1933
|
+
}).toUpperCase(),
|
|
1934
|
+
theme
|
|
1935
|
+
});
|
|
1936
|
+
const remoteValue = worktree.upstream.remote === null ? theme.muted("none") : theme.value(worktree.upstream.remote ?? "none");
|
|
1937
|
+
const aheadValue = worktree.upstream.ahead === null ? theme.unknown("UNKNOWN") : worktree.upstream.ahead > 0 ? theme.unmerged(String(worktree.upstream.ahead)) : theme.merged("0");
|
|
1938
|
+
const behindValue = worktree.upstream.behind === null ? theme.unknown("UNKNOWN") : worktree.upstream.behind > 0 ? theme.unknown(String(worktree.upstream.behind)) : theme.merged("0");
|
|
1939
|
+
const divider = theme.muted("----------------------------------------");
|
|
1940
|
+
const lines = [
|
|
1941
|
+
theme.previewSection("WORKTREE"),
|
|
1942
|
+
divider,
|
|
1943
|
+
` ${theme.previewLabel("Branch ")}: ${branchLabel}`,
|
|
1944
|
+
` ${theme.previewLabel("Path ")}: ${pathLabel}`,
|
|
1945
|
+
"",
|
|
1946
|
+
theme.previewSection("STATUS"),
|
|
1947
|
+
divider,
|
|
1948
|
+
` ${theme.previewLabel("Dirty ")}: ${dirtyValue}`,
|
|
1949
|
+
` ${theme.previewLabel("Locked ")}: ${lockedValue}`,
|
|
1950
|
+
` ${theme.previewLabel("Merged ")}: ${mergedValue}`,
|
|
1951
|
+
` ${theme.previewLabel("Remote ")}: ${remoteValue}`,
|
|
1952
|
+
` ${theme.previewLabel("Ahead ")}: ${aheadValue}`,
|
|
1953
|
+
` ${theme.previewLabel("Behind ")}: ${behindValue}`
|
|
1954
|
+
];
|
|
1955
|
+
if (worktree.locked.value) {
|
|
1956
|
+
lines.push("");
|
|
1957
|
+
lines.push(theme.previewSection("LOCK"));
|
|
1958
|
+
lines.push(divider);
|
|
1959
|
+
if (typeof worktree.locked.reason === "string" && worktree.locked.reason.length > 0) lines.push(` ${theme.previewLabel("Reason ")}: ${theme.value(worktree.locked.reason)}`);
|
|
1960
|
+
if (typeof worktree.locked.owner === "string" && worktree.locked.owner.length > 0) lines.push(` ${theme.previewLabel("Owner ")}: ${theme.value(worktree.locked.owner)}`);
|
|
1961
|
+
}
|
|
1962
|
+
return lines.join("\n");
|
|
1963
|
+
};
|
|
1964
|
+
const buildCdCandidateLine = ({ worktree, baseBranch, theme, currentWorktreeRoot, branchColumnWidth }) => {
|
|
1965
|
+
const isBaseBranch = typeof worktree.branch === "string" && baseBranch !== null && worktree.branch === baseBranch;
|
|
1966
|
+
const branchLabelPadded = padToDisplayWidth({
|
|
1967
|
+
value: buildCdBranchLabel({
|
|
1968
|
+
worktree,
|
|
1969
|
+
currentWorktreeRoot
|
|
1970
|
+
}),
|
|
1971
|
+
width: branchColumnWidth
|
|
1972
|
+
});
|
|
1973
|
+
const isCurrent = worktree.path === currentWorktreeRoot;
|
|
1974
|
+
return [
|
|
1975
|
+
`${worktree.branch === null ? theme.branchDetached(branchLabelPadded) : isCurrent ? theme.branchCurrent(branchLabelPadded) : isBaseBranch ? theme.base(branchLabelPadded) : theme.branch(branchLabelPadded)} ${buildCdStateSummary({
|
|
1976
|
+
worktree,
|
|
1977
|
+
isBaseBranch,
|
|
1978
|
+
theme
|
|
1979
|
+
})}`,
|
|
1980
|
+
worktree.path,
|
|
1981
|
+
encodeCdPreviewField(buildCdPreviewText({
|
|
1982
|
+
worktree,
|
|
1983
|
+
baseBranch,
|
|
1984
|
+
theme
|
|
1985
|
+
}))
|
|
1986
|
+
].join(" ");
|
|
1987
|
+
};
|
|
1988
|
+
const resolveCdSelectionPath = (selectedLine) => {
|
|
1989
|
+
const rawPath = selectedLine.split(" ")[1];
|
|
1990
|
+
if (typeof rawPath === "string" && rawPath.length > 0) return rawPath;
|
|
1991
|
+
return selectedLine;
|
|
1735
1992
|
};
|
|
1736
1993
|
const containsBranch = ({ branch, worktrees }) => {
|
|
1737
1994
|
return worktrees.some((worktree) => worktree.branch === branch);
|
|
@@ -2169,16 +2426,32 @@ const createCli = (options = {}) => {
|
|
|
2169
2426
|
})));
|
|
2170
2427
|
return EXIT_CODE.OK;
|
|
2171
2428
|
}
|
|
2172
|
-
const
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2429
|
+
const theme = createCatppuccinTheme({ enabled: shouldUseAnsiColors({ interactive: runtime.isInteractive }) });
|
|
2430
|
+
const colorized = colorizeListTable({
|
|
2431
|
+
rendered: table([[
|
|
2432
|
+
"branch",
|
|
2433
|
+
"dirty",
|
|
2434
|
+
"merged",
|
|
2435
|
+
"locked",
|
|
2436
|
+
"path"
|
|
2437
|
+
], ...snapshot.worktrees.map((worktree) => {
|
|
2438
|
+
const mergedState = (worktree.branch !== null && snapshot.baseBranch !== null && worktree.branch === snapshot.baseBranch) === true ? "-" : worktree.merged.overall === true ? "merged" : worktree.merged.overall === false ? "unmerged" : "unknown";
|
|
2439
|
+
return [
|
|
2440
|
+
`${worktree.path === repoContext.currentWorktreeRoot ? "*" : " "} ${worktree.branch ?? "(detached)"}`,
|
|
2441
|
+
worktree.dirty ? "dirty" : "clean",
|
|
2442
|
+
mergedState,
|
|
2443
|
+
worktree.locked.value ? "locked" : "-",
|
|
2444
|
+
formatDisplayPath(worktree.path)
|
|
2445
|
+
];
|
|
2446
|
+
})], {
|
|
2447
|
+
border: getBorderCharacters("norc"),
|
|
2448
|
+
drawHorizontalLine: (lineIndex, rowCount) => {
|
|
2449
|
+
return lineIndex === 0 || lineIndex === 1 || lineIndex === rowCount;
|
|
2450
|
+
}
|
|
2451
|
+
}),
|
|
2452
|
+
theme
|
|
2177
2453
|
});
|
|
2178
|
-
const
|
|
2179
|
-
return Math.max(max, stringWidth(row.branch));
|
|
2180
|
-
}, 0);
|
|
2181
|
-
for (const row of rows) stdout(`${padEndByWidth(row.branch, branchWidth)} ${row.path}`);
|
|
2454
|
+
for (const line of colorized.split("\n")) stdout(line);
|
|
2182
2455
|
return EXIT_CODE.OK;
|
|
2183
2456
|
}
|
|
2184
2457
|
if (command === "status") {
|
|
@@ -3285,15 +3558,33 @@ const createCli = (options = {}) => {
|
|
|
3285
3558
|
min: 0,
|
|
3286
3559
|
max: 0
|
|
3287
3560
|
});
|
|
3288
|
-
const
|
|
3561
|
+
const snapshot = await collectWorktreeSnapshot(repoRoot);
|
|
3562
|
+
const theme = createCatppuccinTheme({ enabled: shouldUseAnsiColors({ interactive: runtime.isInteractive }) });
|
|
3563
|
+
const branchColumnWidth = snapshot.worktrees.reduce((maxWidth, worktree) => {
|
|
3564
|
+
const label = buildCdBranchLabel({
|
|
3565
|
+
worktree,
|
|
3566
|
+
currentWorktreeRoot: repoContext.currentWorktreeRoot
|
|
3567
|
+
});
|
|
3568
|
+
return Math.max(maxWidth, stringWidth(label));
|
|
3569
|
+
}, 0);
|
|
3570
|
+
const candidates = snapshot.worktrees.map((worktree) => buildCdCandidateLine({
|
|
3571
|
+
worktree,
|
|
3572
|
+
baseBranch: snapshot.baseBranch,
|
|
3573
|
+
theme,
|
|
3574
|
+
currentWorktreeRoot: repoContext.currentWorktreeRoot,
|
|
3575
|
+
branchColumnWidth
|
|
3576
|
+
}));
|
|
3289
3577
|
if (candidates.length === 0) throw createCliError("WORKTREE_NOT_FOUND", { message: "No worktree candidates found" });
|
|
3290
3578
|
const promptValue = readStringOption(parsedArgsRecord, "prompt");
|
|
3291
3579
|
const selection = await selectPathWithFzf$1({
|
|
3292
3580
|
candidates,
|
|
3293
3581
|
prompt: typeof promptValue === "string" && promptValue.length > 0 ? promptValue : "worktree> ",
|
|
3294
|
-
fzfExtraArgs:
|
|
3295
|
-
|
|
3296
|
-
|
|
3582
|
+
fzfExtraArgs: mergeFzfArgs({
|
|
3583
|
+
defaults: CD_FZF_EXTRA_ARGS,
|
|
3584
|
+
extras: collectOptionValues({
|
|
3585
|
+
args: beforeDoubleDash,
|
|
3586
|
+
optionNames: ["fzfArg", "fzf-arg"]
|
|
3587
|
+
})
|
|
3297
3588
|
}),
|
|
3298
3589
|
cwd: repoRoot,
|
|
3299
3590
|
isInteractive: () => runtime.isInteractive || process.stderr.isTTY === true
|
|
@@ -3303,16 +3594,17 @@ const createCli = (options = {}) => {
|
|
|
3303
3594
|
throw error;
|
|
3304
3595
|
});
|
|
3305
3596
|
if (selection.status === "cancelled") return EXIT_CODE_CANCELLED;
|
|
3597
|
+
const selectedPath = resolveCdSelectionPath(selection.path);
|
|
3306
3598
|
if (runtime.json) {
|
|
3307
3599
|
stdout(JSON.stringify(buildJsonSuccess({
|
|
3308
3600
|
command,
|
|
3309
3601
|
status: "ok",
|
|
3310
3602
|
repoRoot,
|
|
3311
|
-
details: { path:
|
|
3603
|
+
details: { path: selectedPath }
|
|
3312
3604
|
})));
|
|
3313
3605
|
return EXIT_CODE.OK;
|
|
3314
3606
|
}
|
|
3315
|
-
stdout(
|
|
3607
|
+
stdout(selectedPath);
|
|
3316
3608
|
return EXIT_CODE.OK;
|
|
3317
3609
|
}
|
|
3318
3610
|
throw createCliError("UNKNOWN_COMMAND", { message: `Unknown command: ${command}` });
|