@youtyan/code-viewer 0.8.5 → 0.8.7
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.md +10 -8
- package/dist/code-viewer.js +210 -783
- package/package.json +1 -1
- package/web/app.js +139 -33
package/dist/code-viewer.js
CHANGED
|
@@ -996,11 +996,13 @@ function setTimedCacheEntry(cache, key, value, now = Date.now(), maxEntries = MA
|
|
|
996
996
|
cache.delete(oldest);
|
|
997
997
|
}
|
|
998
998
|
}
|
|
999
|
+
function fileSignatureFromStats(stats) {
|
|
1000
|
+
const inode = stats.ino ?? 0;
|
|
1001
|
+
return `state:file|size:${stats.size}|mtime:${stats.mtimeMs}|ctime:${stats.ctimeMs}|ino:${inode}`;
|
|
1002
|
+
}
|
|
999
1003
|
function worktreeFileSignature(path, cwd) {
|
|
1000
1004
|
try {
|
|
1001
|
-
|
|
1002
|
-
const inode = "ino" in stats ? stats.ino : 0;
|
|
1003
|
-
return `state:file|size:${stats.size}|mtime:${stats.mtimeMs}|ctime:${stats.ctimeMs}|ino:${inode}`;
|
|
1005
|
+
return fileSignatureFromStats(lstatSync(join3(cwd, path)));
|
|
1004
1006
|
} catch {
|
|
1005
1007
|
return "state:missing";
|
|
1006
1008
|
}
|
|
@@ -1407,17 +1409,15 @@ var init_runtime = () => {};
|
|
|
1407
1409
|
|
|
1408
1410
|
// web-src/server/git.ts
|
|
1409
1411
|
import {
|
|
1410
|
-
closeSync,
|
|
1411
1412
|
existsSync,
|
|
1412
1413
|
lstatSync as lstatSync2,
|
|
1413
|
-
openSync,
|
|
1414
1414
|
readdirSync,
|
|
1415
1415
|
readFileSync,
|
|
1416
1416
|
readlinkSync,
|
|
1417
|
-
readSync,
|
|
1418
1417
|
realpathSync as realpathSync2,
|
|
1419
1418
|
statSync as statSync2
|
|
1420
1419
|
} from "node:fs";
|
|
1420
|
+
import { open, stat } from "node:fs/promises";
|
|
1421
1421
|
import { dirname as dirname3, join as join4, posix, relative as relative2 } from "node:path";
|
|
1422
1422
|
function normalizeBlameRef(ref, base) {
|
|
1423
1423
|
const rawRef = ref || "worktree";
|
|
@@ -1449,18 +1449,13 @@ function resolveGitArgs(args) {
|
|
|
1449
1449
|
return [commandForExternal("git"), ...args.slice(1)];
|
|
1450
1450
|
}
|
|
1451
1451
|
function gitFailureMessage(res, fallback) {
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
return
|
|
1452
|
+
const message = isCommandNotFoundResult("git", res) ? commandNotFoundDetail("git") : res.stderr?.trim() || fallback;
|
|
1453
|
+
console.error(`[code-viewer] ${fallback} (git exit ${res.code}): ${message}`);
|
|
1454
|
+
return message;
|
|
1455
1455
|
}
|
|
1456
1456
|
function gitFailureResult(res, fallback) {
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
}
|
|
1460
|
-
return {
|
|
1461
|
-
error: commandNotFoundDetail("git"),
|
|
1462
|
-
status: 503
|
|
1463
|
-
};
|
|
1457
|
+
const error = gitFailureMessage(res, fallback);
|
|
1458
|
+
return isCommandNotFoundResult("git", res) ? { error, status: 503 } : { error };
|
|
1464
1459
|
}
|
|
1465
1460
|
function runGitRefLookup(args, cwd) {
|
|
1466
1461
|
const res = run(args, cwd);
|
|
@@ -1485,9 +1480,6 @@ function repoRootResult(cwd) {
|
|
|
1485
1480
|
return { kind: "outside" };
|
|
1486
1481
|
return { kind: "error", error: stderr || "git rev-parse failed" };
|
|
1487
1482
|
}
|
|
1488
|
-
function currentBranch(cwd) {
|
|
1489
|
-
return runGitRefLookup(["git", "rev-parse", "--abbrev-ref", "HEAD"], cwd);
|
|
1490
|
-
}
|
|
1491
1483
|
function currentBranchAsync(cwd) {
|
|
1492
1484
|
return runGitRefLookupAsync(["git", "rev-parse", "--abbrev-ref", "HEAD"], cwd);
|
|
1493
1485
|
}
|
|
@@ -1555,9 +1547,6 @@ async function repoStatusMapAsync(cwd, now = Date.now()) {
|
|
|
1555
1547
|
setTimedCacheEntry(repoStatusMapCache, cwd, { map }, now);
|
|
1556
1548
|
return map;
|
|
1557
1549
|
}
|
|
1558
|
-
function show(ref, path, cwd) {
|
|
1559
|
-
return run(["git", "show", `${ref}:${path}`], cwd);
|
|
1560
|
-
}
|
|
1561
1550
|
function showAsync(ref, path, cwd) {
|
|
1562
1551
|
return runGitAsync(["git", "show", `${ref}:${path}`], cwd);
|
|
1563
1552
|
}
|
|
@@ -1849,12 +1838,6 @@ function parseRemoteWebUrl(remote) {
|
|
|
1849
1838
|
return `https://${httpUrl[1]}/${httpUrl[2]}`;
|
|
1850
1839
|
return null;
|
|
1851
1840
|
}
|
|
1852
|
-
function remoteWebUrl(cwd) {
|
|
1853
|
-
const res = run(["git", "remote", "get-url", "origin"], cwd);
|
|
1854
|
-
if (res.code !== 0)
|
|
1855
|
-
return null;
|
|
1856
|
-
return parseRemoteWebUrl(res.stdout.trim());
|
|
1857
|
-
}
|
|
1858
1841
|
async function remoteWebUrlAsync(cwd) {
|
|
1859
1842
|
const res = await runGitAsync(["git", "remote", "get-url", "origin"], cwd);
|
|
1860
1843
|
if (res.code !== 0)
|
|
@@ -1923,60 +1906,6 @@ function historyQueryArgs(query) {
|
|
|
1923
1906
|
shaTerm: /^[0-9a-f]{4,40}$/i.test(trimmed) ? trimmed : ""
|
|
1924
1907
|
};
|
|
1925
1908
|
}
|
|
1926
|
-
function commitHistory(cwd, options) {
|
|
1927
|
-
const ref = (options.ref || "HEAD").trim();
|
|
1928
|
-
if (!ref || ref.startsWith("-") || ref.includes("\x00"))
|
|
1929
|
-
return { commits: [], hasMore: false, error: "invalid ref" };
|
|
1930
|
-
const verified = run(["git", "rev-parse", "--verify", `${ref}^{commit}`], cwd);
|
|
1931
|
-
if (verified.code !== 0)
|
|
1932
|
-
return {
|
|
1933
|
-
commits: [],
|
|
1934
|
-
hasMore: false,
|
|
1935
|
-
...gitFailureResult(verified, "unknown ref")
|
|
1936
|
-
};
|
|
1937
|
-
const skip = Math.max(0, Math.floor(options.skip) || 0);
|
|
1938
|
-
const limit = Math.max(1, Math.min(Math.floor(options.limit) || 1, MAX_HISTORY_LIMIT));
|
|
1939
|
-
const { filterArgs, pathspec, shaTerm } = historyQueryArgs(options.query || "");
|
|
1940
|
-
const pathFilter = (options.path || "").trim();
|
|
1941
|
-
const pathArgs = [];
|
|
1942
|
-
if (pathFilter && !pathFilter.includes("\x00") && !pathFilter.startsWith("-")) {
|
|
1943
|
-
if (!pathFilter.endsWith("/"))
|
|
1944
|
-
pathArgs.push("--follow");
|
|
1945
|
-
pathArgs.push("--", pathFilter);
|
|
1946
|
-
}
|
|
1947
|
-
const res = run([
|
|
1948
|
-
"git",
|
|
1949
|
-
"log",
|
|
1950
|
-
"-z",
|
|
1951
|
-
`--skip=${skip}`,
|
|
1952
|
-
`--max-count=${limit + 1}`,
|
|
1953
|
-
`--format=${HISTORY_FORMAT}`,
|
|
1954
|
-
...filterArgs,
|
|
1955
|
-
verified.stdout.trim(),
|
|
1956
|
-
...pathspec,
|
|
1957
|
-
...pathArgs
|
|
1958
|
-
], cwd);
|
|
1959
|
-
if (res.code !== 0)
|
|
1960
|
-
return {
|
|
1961
|
-
commits: [],
|
|
1962
|
-
hasMore: false,
|
|
1963
|
-
...gitFailureResult(res, "git log failed")
|
|
1964
|
-
};
|
|
1965
|
-
let parsed = parseHistoryLog(res.stdout);
|
|
1966
|
-
if (shaTerm && skip === 0) {
|
|
1967
|
-
const bySha = run(["git", "rev-parse", "--verify", `${shaTerm}^{commit}`], cwd);
|
|
1968
|
-
const sha = bySha.code === 0 ? bySha.stdout.trim() : "";
|
|
1969
|
-
if (sha) {
|
|
1970
|
-
const single = run(["git", "log", "-z", "-1", `--format=${HISTORY_FORMAT}`, sha], cwd);
|
|
1971
|
-
if (single.code === 0) {
|
|
1972
|
-
const hit = parseHistoryLog(single.stdout);
|
|
1973
|
-
parsed = [...hit, ...parsed.filter((c) => c.sha !== sha)];
|
|
1974
|
-
}
|
|
1975
|
-
}
|
|
1976
|
-
}
|
|
1977
|
-
const hasMore = parsed.length > limit;
|
|
1978
|
-
return { commits: hasMore ? parsed.slice(0, limit) : parsed, hasMore };
|
|
1979
|
-
}
|
|
1980
1909
|
async function commitHistoryAsync(cwd, options) {
|
|
1981
1910
|
const ref = (options.ref || "HEAD").trim();
|
|
1982
1911
|
if (!ref || ref.startsWith("-") || ref.includes("\x00"))
|
|
@@ -2031,50 +1960,6 @@ async function commitHistoryAsync(cwd, options) {
|
|
|
2031
1960
|
const hasMore = parsed.length > limit;
|
|
2032
1961
|
return { commits: hasMore ? parsed.slice(0, limit) : parsed, hasMore };
|
|
2033
1962
|
}
|
|
2034
|
-
function nameStatusResult(args, cwd) {
|
|
2035
|
-
const res = run([
|
|
2036
|
-
"git",
|
|
2037
|
-
"-c",
|
|
2038
|
-
"core.quotepath=false",
|
|
2039
|
-
"diff",
|
|
2040
|
-
"--no-color",
|
|
2041
|
-
"--no-ext-diff",
|
|
2042
|
-
"--find-renames",
|
|
2043
|
-
"--name-status",
|
|
2044
|
-
"-z",
|
|
2045
|
-
...args
|
|
2046
|
-
], cwd);
|
|
2047
|
-
if (res.code !== 0) {
|
|
2048
|
-
return {
|
|
2049
|
-
files: [],
|
|
2050
|
-
error: gitFailureMessage(res, "git diff --name-status failed")
|
|
2051
|
-
};
|
|
2052
|
-
}
|
|
2053
|
-
const parts = res.stdout.split("\x00");
|
|
2054
|
-
const files = [];
|
|
2055
|
-
for (let i = 0;i < parts.length; ) {
|
|
2056
|
-
const status = parts[i++];
|
|
2057
|
-
if (!status)
|
|
2058
|
-
break;
|
|
2059
|
-
const kind = status[0];
|
|
2060
|
-
if (kind === "R" || kind === "C") {
|
|
2061
|
-
const oldPath = parts[i++] || "";
|
|
2062
|
-
const path = parts[i++] || "";
|
|
2063
|
-
if (path)
|
|
2064
|
-
files.push({
|
|
2065
|
-
status: kind,
|
|
2066
|
-
old_path: oldPath,
|
|
2067
|
-
path,
|
|
2068
|
-
similarity: Number(status.slice(1)) || undefined
|
|
2069
|
-
});
|
|
2070
|
-
} else {
|
|
2071
|
-
const path = parts[i++] || "";
|
|
2072
|
-
if (path)
|
|
2073
|
-
files.push({ status: kind, path });
|
|
2074
|
-
}
|
|
2075
|
-
}
|
|
2076
|
-
return { files };
|
|
2077
|
-
}
|
|
2078
1963
|
async function nameStatusResultAsync(args, cwd) {
|
|
2079
1964
|
const res = await runGitAsync([
|
|
2080
1965
|
"git",
|
|
@@ -2119,49 +2004,6 @@ async function nameStatusResultAsync(args, cwd) {
|
|
|
2119
2004
|
}
|
|
2120
2005
|
return { files };
|
|
2121
2006
|
}
|
|
2122
|
-
function numstatZResult(args, cwd) {
|
|
2123
|
-
const res = run([
|
|
2124
|
-
"git",
|
|
2125
|
-
"-c",
|
|
2126
|
-
"core.quotepath=false",
|
|
2127
|
-
"diff",
|
|
2128
|
-
"--no-color",
|
|
2129
|
-
"--no-ext-diff",
|
|
2130
|
-
"--find-renames",
|
|
2131
|
-
"--numstat",
|
|
2132
|
-
"-z",
|
|
2133
|
-
...args
|
|
2134
|
-
], cwd);
|
|
2135
|
-
if (res.code !== 0) {
|
|
2136
|
-
return {
|
|
2137
|
-
files: [],
|
|
2138
|
-
error: gitFailureMessage(res, "git diff --numstat failed")
|
|
2139
|
-
};
|
|
2140
|
-
}
|
|
2141
|
-
const parts = res.stdout.split("\x00");
|
|
2142
|
-
const files = [];
|
|
2143
|
-
for (let i = 0;i < parts.length; ) {
|
|
2144
|
-
const rec = parts[i++];
|
|
2145
|
-
if (!rec)
|
|
2146
|
-
break;
|
|
2147
|
-
const match = rec.match(/^(\S+)\t(\S+)\t(.*)$/);
|
|
2148
|
-
if (!match)
|
|
2149
|
-
break;
|
|
2150
|
-
const [, add, del, rest] = match;
|
|
2151
|
-
const binary = add === "-" && del === "-";
|
|
2152
|
-
const additions = binary ? 0 : Number(add) || 0;
|
|
2153
|
-
const deletions = binary ? 0 : Number(del) || 0;
|
|
2154
|
-
if (rest === "") {
|
|
2155
|
-
const oldPath = parts[i++] || "";
|
|
2156
|
-
const path = parts[i++] || "";
|
|
2157
|
-
if (path)
|
|
2158
|
-
files.push({ old_path: oldPath, path, additions, deletions, binary });
|
|
2159
|
-
} else {
|
|
2160
|
-
files.push({ path: rest, additions, deletions, binary });
|
|
2161
|
-
}
|
|
2162
|
-
}
|
|
2163
|
-
return { files };
|
|
2164
|
-
}
|
|
2165
2007
|
async function numstatZResultAsync(args, cwd) {
|
|
2166
2008
|
const res = await runGitAsync([
|
|
2167
2009
|
"git",
|
|
@@ -2218,8 +2060,8 @@ function isGitInternalPath(path) {
|
|
|
2218
2060
|
function syntheticUncommittedBlameFromWorktree(cwd, path) {
|
|
2219
2061
|
const filePath = join4(cwd, path);
|
|
2220
2062
|
try {
|
|
2221
|
-
const
|
|
2222
|
-
if (!
|
|
2063
|
+
const stat2 = statSync2(filePath);
|
|
2064
|
+
if (!stat2.isFile())
|
|
2223
2065
|
return { lines: [], commits: {}, error: "not a file" };
|
|
2224
2066
|
const text = readFileSync(filePath, "utf8");
|
|
2225
2067
|
const normalized = text.replace(/\r\n/g, `
|
|
@@ -2255,98 +2097,6 @@ function syntheticUncommittedBlameFromWorktree(cwd, path) {
|
|
|
2255
2097
|
return { lines: [], commits: {}, error: "file not readable" };
|
|
2256
2098
|
}
|
|
2257
2099
|
}
|
|
2258
|
-
function blame(cwd, options) {
|
|
2259
|
-
const path = options.path;
|
|
2260
|
-
if (!path || path.includes("\x00") || path.startsWith("-")) {
|
|
2261
|
-
return { lines: [], commits: {}, error: "invalid path" };
|
|
2262
|
-
}
|
|
2263
|
-
const normalized = normalizeBlameRef(options.ref, options.base);
|
|
2264
|
-
const args = ["git", "blame", "--porcelain"];
|
|
2265
|
-
if (normalized.base === "HEAD") {
|
|
2266
|
-
if (normalized.ref.startsWith("-") || normalized.ref.includes("\x00"))
|
|
2267
|
-
return { lines: [], commits: {}, error: "invalid ref" };
|
|
2268
|
-
args.push(normalized.ref);
|
|
2269
|
-
}
|
|
2270
|
-
args.push("--", path);
|
|
2271
|
-
const res = run(args, cwd);
|
|
2272
|
-
if (res.code !== 0) {
|
|
2273
|
-
if (isCommandNotFoundResult("git", res)) {
|
|
2274
|
-
return {
|
|
2275
|
-
lines: [],
|
|
2276
|
-
commits: {},
|
|
2277
|
-
error: commandNotFoundDetail("git"),
|
|
2278
|
-
status: 503
|
|
2279
|
-
};
|
|
2280
|
-
}
|
|
2281
|
-
if (normalized.base === "worktree") {
|
|
2282
|
-
return syntheticUncommittedBlameFromWorktree(cwd, path);
|
|
2283
|
-
}
|
|
2284
|
-
return {
|
|
2285
|
-
lines: [],
|
|
2286
|
-
commits: {},
|
|
2287
|
-
error: res.stderr.trim() || "blame failed"
|
|
2288
|
-
};
|
|
2289
|
-
}
|
|
2290
|
-
const lines = [];
|
|
2291
|
-
const commits = {};
|
|
2292
|
-
const rawLines = res.stdout.split(`
|
|
2293
|
-
`);
|
|
2294
|
-
let i = 0;
|
|
2295
|
-
while (i < rawLines.length) {
|
|
2296
|
-
const headerLine = rawLines[i];
|
|
2297
|
-
if (!headerLine) {
|
|
2298
|
-
i++;
|
|
2299
|
-
continue;
|
|
2300
|
-
}
|
|
2301
|
-
const headerMatch = /^([0-9a-f]{40}) (\d+) (\d+)(?: (\d+))?$/.exec(headerLine);
|
|
2302
|
-
if (!headerMatch) {
|
|
2303
|
-
i++;
|
|
2304
|
-
continue;
|
|
2305
|
-
}
|
|
2306
|
-
const sha = headerMatch[1];
|
|
2307
|
-
const finalLine = Number(headerMatch[3]);
|
|
2308
|
-
i++;
|
|
2309
|
-
let commit = commits[sha];
|
|
2310
|
-
if (!commit) {
|
|
2311
|
-
commit = {
|
|
2312
|
-
sha,
|
|
2313
|
-
author: "",
|
|
2314
|
-
authorMail: "",
|
|
2315
|
-
authorTime: 0,
|
|
2316
|
-
summary: "",
|
|
2317
|
-
isUncommitted: sha === BLAME_ZERO_SHA
|
|
2318
|
-
};
|
|
2319
|
-
commits[sha] = commit;
|
|
2320
|
-
}
|
|
2321
|
-
while (i < rawLines.length && !rawLines[i].startsWith("\t")) {
|
|
2322
|
-
const metaLine = rawLines[i++];
|
|
2323
|
-
if (!metaLine)
|
|
2324
|
-
continue;
|
|
2325
|
-
const sp = metaLine.indexOf(" ");
|
|
2326
|
-
const key = sp >= 0 ? metaLine.slice(0, sp) : metaLine;
|
|
2327
|
-
const val = sp >= 0 ? metaLine.slice(sp + 1) : "";
|
|
2328
|
-
if (key === "author" && !commit.author)
|
|
2329
|
-
commit.author = val;
|
|
2330
|
-
else if (key === "author-mail" && !commit.authorMail)
|
|
2331
|
-
commit.authorMail = val.replace(/^</, "").replace(/>$/, "");
|
|
2332
|
-
else if (key === "author-time" && !commit.authorTime)
|
|
2333
|
-
commit.authorTime = Number(val) || 0;
|
|
2334
|
-
else if (key === "summary" && !commit.summary)
|
|
2335
|
-
commit.summary = val;
|
|
2336
|
-
}
|
|
2337
|
-
if (i < rawLines.length && rawLines[i].startsWith("\t"))
|
|
2338
|
-
i++;
|
|
2339
|
-
if (Number.isFinite(finalLine) && finalLine > 0) {
|
|
2340
|
-
lines.push({
|
|
2341
|
-
lineNo: finalLine,
|
|
2342
|
-
sha,
|
|
2343
|
-
isUncommitted: sha === BLAME_ZERO_SHA
|
|
2344
|
-
});
|
|
2345
|
-
}
|
|
2346
|
-
}
|
|
2347
|
-
lines.sort((a, b) => a.lineNo - b.lineNo);
|
|
2348
|
-
return { lines, commits };
|
|
2349
|
-
}
|
|
2350
2100
|
async function blameAsync(cwd, options) {
|
|
2351
2101
|
const path = options.path;
|
|
2352
2102
|
if (!path || path.includes("\x00") || path.startsWith("-")) {
|
|
@@ -2439,16 +2189,6 @@ async function blameAsync(cwd, options) {
|
|
|
2439
2189
|
lines.sort((a, b) => a.lineNo - b.lineNo);
|
|
2440
2190
|
return { lines, commits };
|
|
2441
2191
|
}
|
|
2442
|
-
function untracked(cwd, path = "") {
|
|
2443
|
-
const args = ["git", "ls-files", "--others", "--exclude-standard"];
|
|
2444
|
-
if (path)
|
|
2445
|
-
args.push("--", `${path}/`);
|
|
2446
|
-
const res = run(args, cwd);
|
|
2447
|
-
if (res.code !== 0)
|
|
2448
|
-
return [];
|
|
2449
|
-
return res.stdout.split(`
|
|
2450
|
-
`).filter(Boolean).filter((entry) => !isToolInternalPath(entry));
|
|
2451
|
-
}
|
|
2452
2192
|
async function untrackedAsync(cwd, path = "") {
|
|
2453
2193
|
const args = ["git", "ls-files", "--others", "--exclude-standard"];
|
|
2454
2194
|
if (path)
|
|
@@ -2474,18 +2214,6 @@ function omittedWorktreeDirectoryReason(name, omitDirNames) {
|
|
|
2474
2214
|
return "internal";
|
|
2475
2215
|
return omitDirNames.matches(name) ? "heavy" : undefined;
|
|
2476
2216
|
}
|
|
2477
|
-
function worktreeSubmodulePaths(cwd) {
|
|
2478
|
-
if (!existsSync(join4(cwd, ".gitmodules")))
|
|
2479
|
-
return new Set;
|
|
2480
|
-
const res = run(["git", "config", "--file", ".gitmodules", "--get-regexp", "\\.path$"], cwd);
|
|
2481
|
-
if (res.code !== 0)
|
|
2482
|
-
return new Set;
|
|
2483
|
-
return new Set(res.stdout.split(`
|
|
2484
|
-
`).map((line) => {
|
|
2485
|
-
const split = line.indexOf(" ");
|
|
2486
|
-
return split >= 0 ? normalizeTreePath(line.slice(split + 1)) : "";
|
|
2487
|
-
}).filter(Boolean));
|
|
2488
|
-
}
|
|
2489
2217
|
async function worktreeSubmodulePathsAsync(cwd) {
|
|
2490
2218
|
if (!existsSync(join4(cwd, ".gitmodules")))
|
|
2491
2219
|
return new Set;
|
|
@@ -2522,8 +2250,8 @@ function resolveWorktreeSymlinkTarget(cwd, full) {
|
|
|
2522
2250
|
let symlink_target_type = "missing";
|
|
2523
2251
|
if (realpathWithinRepo(cwd, full, false) !== null) {
|
|
2524
2252
|
try {
|
|
2525
|
-
const
|
|
2526
|
-
symlink_target_type =
|
|
2253
|
+
const stat2 = statSync2(full);
|
|
2254
|
+
symlink_target_type = stat2.isDirectory() ? "tree" : stat2.isFile() ? "blob" : "missing";
|
|
2527
2255
|
} catch {
|
|
2528
2256
|
symlink_target_type = "missing";
|
|
2529
2257
|
}
|
|
@@ -2565,83 +2293,6 @@ function worktreeEntryFromDirent(cwd, base, dir, name, isDirectory, isSymlink, o
|
|
|
2565
2293
|
children_omitted_reason: omittedReason
|
|
2566
2294
|
} : baseEntry;
|
|
2567
2295
|
}
|
|
2568
|
-
function worktreeFilesystemEntries(cwd, path, recursive, omitDirNames = DEFAULT_WORKTREE_OMIT_DIR_NAMES, excludeNames = []) {
|
|
2569
|
-
const base = normalizeTreePath(path);
|
|
2570
|
-
const root = join4(cwd, base);
|
|
2571
|
-
if (realpathWithinRepo(cwd, root, true) === null)
|
|
2572
|
-
return [];
|
|
2573
|
-
const omitDirNameSet = compileNamePatterns(omitDirNames);
|
|
2574
|
-
const excludeNameSet = compileNamePatterns(excludeNames);
|
|
2575
|
-
const submodulePaths = worktreeSubmodulePaths(cwd);
|
|
2576
|
-
let directEntries;
|
|
2577
|
-
try {
|
|
2578
|
-
const dirents = readdirSync(root, { withFileTypes: true });
|
|
2579
|
-
directEntries = sortTreeEntries(dirents.map((entry) => worktreeEntryFromDirent(cwd, base, root, entry.name, entry.isDirectory(), entry.isSymbolicLink(), omitDirNameSet, excludeNameSet, submodulePaths)).filter((entry) => entry.path));
|
|
2580
|
-
} catch {
|
|
2581
|
-
return [];
|
|
2582
|
-
}
|
|
2583
|
-
if (!recursive)
|
|
2584
|
-
return directEntries;
|
|
2585
|
-
const fileEntries = [];
|
|
2586
|
-
let truncated = false;
|
|
2587
|
-
const pushRecursiveEntry = (entry) => {
|
|
2588
|
-
if (fileEntries.length >= WORKTREE_RECURSIVE_ENTRY_LIMIT) {
|
|
2589
|
-
if (!truncated) {
|
|
2590
|
-
fileEntries.push({
|
|
2591
|
-
name: "more...",
|
|
2592
|
-
path: "__code_viewer_truncated__",
|
|
2593
|
-
type: "tree",
|
|
2594
|
-
children_omitted: true,
|
|
2595
|
-
children_omitted_reason: "truncated"
|
|
2596
|
-
});
|
|
2597
|
-
truncated = true;
|
|
2598
|
-
}
|
|
2599
|
-
return false;
|
|
2600
|
-
}
|
|
2601
|
-
fileEntries.push(entry);
|
|
2602
|
-
return true;
|
|
2603
|
-
};
|
|
2604
|
-
const walk = (dir, prefix, depth) => {
|
|
2605
|
-
if (truncated)
|
|
2606
|
-
return;
|
|
2607
|
-
if (depth >= WORKTREE_RECURSIVE_DEPTH_LIMIT)
|
|
2608
|
-
return;
|
|
2609
|
-
let entries;
|
|
2610
|
-
try {
|
|
2611
|
-
entries = readdirSync(dir, { withFileTypes: true });
|
|
2612
|
-
} catch {
|
|
2613
|
-
return;
|
|
2614
|
-
}
|
|
2615
|
-
for (const entry of entries) {
|
|
2616
|
-
if (excludeNameSet.matches(entry.name))
|
|
2617
|
-
continue;
|
|
2618
|
-
const entryPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
2619
|
-
const full = join4(dir, entry.name);
|
|
2620
|
-
if (entry.isDirectory()) {
|
|
2621
|
-
const omittedReason = omittedWorktreeDirectoryReason(entry.name, omitDirNameSet);
|
|
2622
|
-
if (omittedReason) {
|
|
2623
|
-
if (!pushRecursiveEntry({
|
|
2624
|
-
name: entry.name,
|
|
2625
|
-
path: entryPath,
|
|
2626
|
-
type: "tree",
|
|
2627
|
-
children_omitted: true,
|
|
2628
|
-
children_omitted_reason: omittedReason
|
|
2629
|
-
}))
|
|
2630
|
-
return;
|
|
2631
|
-
continue;
|
|
2632
|
-
}
|
|
2633
|
-
if (hasDotGitEntry(full))
|
|
2634
|
-
continue;
|
|
2635
|
-
walk(full, entryPath, depth + 1);
|
|
2636
|
-
} else if (entry.isFile() || entry.isSymbolicLink()) {
|
|
2637
|
-
if (!pushRecursiveEntry(recursiveWorktreeFileEntry(cwd, full, entry.name, entryPath, entry.isSymbolicLink())))
|
|
2638
|
-
return;
|
|
2639
|
-
}
|
|
2640
|
-
}
|
|
2641
|
-
};
|
|
2642
|
-
walk(root, base, 0);
|
|
2643
|
-
return combineDirectAndRecursiveFiles(directEntries, fileEntries.sort((a, b) => a.path.localeCompare(b.path)));
|
|
2644
|
-
}
|
|
2645
2296
|
async function worktreeFilesystemEntriesAsync(cwd, path, recursive, omitDirNames = DEFAULT_WORKTREE_OMIT_DIR_NAMES, excludeNames = []) {
|
|
2646
2297
|
const base = normalizeTreePath(path);
|
|
2647
2298
|
const root = join4(cwd, base);
|
|
@@ -2747,25 +2398,6 @@ function parseLsTreeRecord(rec, allowedTypes) {
|
|
|
2747
2398
|
...mode === LS_TREE_SYMLINK_MODE ? { is_symlink: true } : {}
|
|
2748
2399
|
};
|
|
2749
2400
|
}
|
|
2750
|
-
function gitTreeEntries(ref, path, cwd, recursive) {
|
|
2751
|
-
const base = normalizeTreePath(path);
|
|
2752
|
-
const args = ["git", "-c", "core.quotepath=false", "ls-tree"];
|
|
2753
|
-
if (recursive)
|
|
2754
|
-
args.push("-r");
|
|
2755
|
-
args.push("-z", "--full-tree", ref, "--");
|
|
2756
|
-
if (base)
|
|
2757
|
-
args.push(`${base}/`);
|
|
2758
|
-
const res = run(args, cwd);
|
|
2759
|
-
if (res.code !== 0)
|
|
2760
|
-
return { code: res.code, entries: [], stderr: res.stderr };
|
|
2761
|
-
const allowedTypes = recursive ? "blob|commit" : "tree|blob|commit";
|
|
2762
|
-
let entries = res.stdout.split("\x00").filter(Boolean).map((rec) => parseLsTreeRecord(rec, allowedTypes)).filter((entry) => !!entry);
|
|
2763
|
-
if (recursive)
|
|
2764
|
-
entries.sort((a, b) => a.path.localeCompare(b.path));
|
|
2765
|
-
else
|
|
2766
|
-
entries = sortTreeEntries(entries);
|
|
2767
|
-
return { code: 0, entries, stderr: "" };
|
|
2768
|
-
}
|
|
2769
2401
|
async function gitTreeEntriesAsync(ref, path, cwd, recursive) {
|
|
2770
2402
|
const base = normalizeTreePath(path);
|
|
2771
2403
|
const args = ["git", "-c", "core.quotepath=false", "ls-tree"];
|
|
@@ -2778,40 +2410,19 @@ async function gitTreeEntriesAsync(ref, path, cwd, recursive) {
|
|
|
2778
2410
|
if (res.code !== 0)
|
|
2779
2411
|
return { code: res.code, entries: [], stderr: res.stderr };
|
|
2780
2412
|
const allowedTypes = recursive ? "blob|commit" : "tree|blob|commit";
|
|
2781
|
-
let entries = res.stdout.split("\x00").filter(Boolean).map((rec) => parseLsTreeRecord(rec, allowedTypes)).filter((entry) => !!entry);
|
|
2782
|
-
if (recursive)
|
|
2783
|
-
entries.sort((a, b) => a.path.localeCompare(b.path));
|
|
2784
|
-
else
|
|
2785
|
-
entries = sortTreeEntries(entries);
|
|
2786
|
-
return { code: 0, entries, stderr: "" };
|
|
2787
|
-
}
|
|
2788
|
-
function combineDirectAndRecursiveFiles(directEntries, fileEntries) {
|
|
2789
|
-
const seen = new Set(directEntries.map((entry) => entry.path));
|
|
2790
|
-
return [
|
|
2791
|
-
...directEntries,
|
|
2792
|
-
...fileEntries.filter((entry) => !seen.has(entry.path))
|
|
2793
|
-
];
|
|
2794
|
-
}
|
|
2795
|
-
function listTree(ref, path, cwd, options = {}) {
|
|
2796
|
-
const base = normalizeTreePath(path);
|
|
2797
|
-
if (ref === "worktree") {
|
|
2798
|
-
return {
|
|
2799
|
-
code: 0,
|
|
2800
|
-
entries: worktreeFilesystemEntries(cwd, base, !!options.recursive, options.omitDirNames, options.excludeNames),
|
|
2801
|
-
stderr: ""
|
|
2802
|
-
};
|
|
2803
|
-
}
|
|
2804
|
-
const direct = gitTreeEntries(ref, base, cwd, false);
|
|
2805
|
-
if (direct.code !== 0 || !options.recursive)
|
|
2806
|
-
return direct;
|
|
2807
|
-
const recursive = gitTreeEntries(ref, base, cwd, true);
|
|
2808
|
-
if (recursive.code !== 0)
|
|
2809
|
-
return recursive;
|
|
2810
|
-
return {
|
|
2811
|
-
code: 0,
|
|
2812
|
-
entries: combineDirectAndRecursiveFiles(direct.entries, recursive.entries),
|
|
2813
|
-
stderr: ""
|
|
2814
|
-
};
|
|
2413
|
+
let entries = res.stdout.split("\x00").filter(Boolean).map((rec) => parseLsTreeRecord(rec, allowedTypes)).filter((entry) => !!entry);
|
|
2414
|
+
if (recursive)
|
|
2415
|
+
entries.sort((a, b) => a.path.localeCompare(b.path));
|
|
2416
|
+
else
|
|
2417
|
+
entries = sortTreeEntries(entries);
|
|
2418
|
+
return { code: 0, entries, stderr: "" };
|
|
2419
|
+
}
|
|
2420
|
+
function combineDirectAndRecursiveFiles(directEntries, fileEntries) {
|
|
2421
|
+
const seen = new Set(directEntries.map((entry) => entry.path));
|
|
2422
|
+
return [
|
|
2423
|
+
...directEntries,
|
|
2424
|
+
...fileEntries.filter((entry) => !seen.has(entry.path))
|
|
2425
|
+
];
|
|
2815
2426
|
}
|
|
2816
2427
|
async function listTreeAsync(ref, path, cwd, options = {}) {
|
|
2817
2428
|
const base = normalizeTreePath(path);
|
|
@@ -2840,121 +2451,97 @@ async function listTreeResultAsync(ref, path, cwd, options = {}) {
|
|
|
2840
2451
|
return { entries: result.entries };
|
|
2841
2452
|
return { entries: [], ...gitFailureResult(result, "git ls-tree failed") };
|
|
2842
2453
|
}
|
|
2843
|
-
function
|
|
2844
|
-
return
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
let scan;
|
|
2853
|
-
if (fileExists) {
|
|
2854
|
-
try {
|
|
2855
|
-
scan = scanFileBinaryAndNewlines(full);
|
|
2856
|
-
} catch {
|
|
2857
|
-
return [];
|
|
2858
|
-
}
|
|
2859
|
-
} else {
|
|
2860
|
-
return [];
|
|
2861
|
-
}
|
|
2862
|
-
return [
|
|
2863
|
-
{
|
|
2864
|
-
path,
|
|
2865
|
-
status: "A",
|
|
2866
|
-
additions: scan.binary ? 0 : scan.newlines,
|
|
2867
|
-
deletions: 0,
|
|
2868
|
-
binary: scan.binary,
|
|
2869
|
-
untracked: true
|
|
2870
|
-
}
|
|
2871
|
-
];
|
|
2872
|
-
});
|
|
2873
|
-
}
|
|
2874
|
-
async function untrackedMetaAsync(cwd) {
|
|
2875
|
-
const paths = await untrackedAsync(cwd);
|
|
2876
|
-
return paths.flatMap((path) => {
|
|
2877
|
-
const full = join4(cwd, path);
|
|
2878
|
-
let fileExists = false;
|
|
2879
|
-
try {
|
|
2880
|
-
fileExists = existsSync(full) && statSync2(full).isFile();
|
|
2881
|
-
} catch {
|
|
2882
|
-
fileExists = false;
|
|
2883
|
-
}
|
|
2884
|
-
let scan;
|
|
2885
|
-
if (fileExists) {
|
|
2886
|
-
try {
|
|
2887
|
-
scan = scanFileBinaryAndNewlines(full);
|
|
2888
|
-
} catch {
|
|
2889
|
-
return [];
|
|
2890
|
-
}
|
|
2891
|
-
} else {
|
|
2892
|
-
return [];
|
|
2893
|
-
}
|
|
2894
|
-
return [
|
|
2895
|
-
{
|
|
2896
|
-
path,
|
|
2897
|
-
status: "A",
|
|
2898
|
-
additions: scan.binary ? 0 : scan.newlines,
|
|
2899
|
-
deletions: 0,
|
|
2900
|
-
binary: scan.binary,
|
|
2901
|
-
untracked: true
|
|
2902
|
-
}
|
|
2903
|
-
];
|
|
2904
|
-
});
|
|
2454
|
+
function untrackedFileMeta(path, scan) {
|
|
2455
|
+
return {
|
|
2456
|
+
path,
|
|
2457
|
+
status: "A",
|
|
2458
|
+
additions: scan.binary ? 0 : scan.newlines,
|
|
2459
|
+
deletions: 0,
|
|
2460
|
+
binary: scan.binary,
|
|
2461
|
+
untracked: true
|
|
2462
|
+
};
|
|
2905
2463
|
}
|
|
2906
|
-
function
|
|
2907
|
-
const
|
|
2464
|
+
async function scanFileBinaryAndNewlinesAsync(full) {
|
|
2465
|
+
const handle = await open(full, "r");
|
|
2908
2466
|
const buffer = Buffer.allocUnsafe(64 * 1024);
|
|
2909
2467
|
let newlines = 0;
|
|
2910
2468
|
let inspected = 0;
|
|
2911
2469
|
try {
|
|
2912
2470
|
while (true) {
|
|
2913
|
-
const
|
|
2914
|
-
if (
|
|
2471
|
+
const { bytesRead } = await handle.read(buffer, 0, buffer.length, null);
|
|
2472
|
+
if (bytesRead <= 0)
|
|
2915
2473
|
break;
|
|
2916
|
-
const binaryProbeBytes = Math.min(
|
|
2474
|
+
const binaryProbeBytes = Math.min(bytesRead, Math.max(0, 8192 - inspected));
|
|
2917
2475
|
for (let i = 0;i < binaryProbeBytes; i++) {
|
|
2918
2476
|
if (buffer[i] === 0)
|
|
2919
2477
|
return { binary: true, newlines: 0 };
|
|
2920
2478
|
}
|
|
2921
|
-
inspected +=
|
|
2922
|
-
for (let i = 0;i <
|
|
2479
|
+
inspected += bytesRead;
|
|
2480
|
+
for (let i = 0;i < bytesRead; i++) {
|
|
2923
2481
|
if (buffer[i] === 10)
|
|
2924
2482
|
newlines++;
|
|
2925
2483
|
}
|
|
2926
2484
|
}
|
|
2927
2485
|
} finally {
|
|
2928
|
-
|
|
2486
|
+
await handle.close();
|
|
2929
2487
|
}
|
|
2930
2488
|
return { binary: false, newlines };
|
|
2931
2489
|
}
|
|
2932
|
-
function
|
|
2933
|
-
const
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
const
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2490
|
+
async function untrackedMetaAsync(cwd) {
|
|
2491
|
+
const paths = await untrackedAsync(cwd);
|
|
2492
|
+
const previous = untrackedScanCache.get(cwd);
|
|
2493
|
+
const next = new Map;
|
|
2494
|
+
const results = new Array(paths.length).fill(null);
|
|
2495
|
+
let cursor = 0;
|
|
2496
|
+
const worker = async () => {
|
|
2497
|
+
while (cursor < paths.length) {
|
|
2498
|
+
const index = cursor++;
|
|
2499
|
+
const path = paths[index];
|
|
2500
|
+
const full = join4(cwd, path);
|
|
2501
|
+
let stats;
|
|
2502
|
+
try {
|
|
2503
|
+
stats = await stat(full);
|
|
2504
|
+
} catch {
|
|
2505
|
+
continue;
|
|
2506
|
+
}
|
|
2507
|
+
if (!stats.isFile())
|
|
2508
|
+
continue;
|
|
2509
|
+
const signature = fileSignatureFromStats(stats);
|
|
2510
|
+
const cached = previous?.get(path);
|
|
2511
|
+
let scan;
|
|
2512
|
+
if (cached && cached.signature === signature) {
|
|
2513
|
+
scan = cached.scan;
|
|
2514
|
+
} else {
|
|
2515
|
+
try {
|
|
2516
|
+
scan = await scanFileBinaryAndNewlinesAsync(full);
|
|
2517
|
+
} catch {
|
|
2518
|
+
continue;
|
|
2519
|
+
}
|
|
2520
|
+
}
|
|
2521
|
+
next.set(path, { signature, scan });
|
|
2522
|
+
results[index] = untrackedFileMeta(path, scan);
|
|
2523
|
+
}
|
|
2951
2524
|
};
|
|
2525
|
+
await Promise.all(Array.from({
|
|
2526
|
+
length: Math.min(UNTRACKED_SCAN_CONCURRENCY, Math.max(1, paths.length))
|
|
2527
|
+
}, () => worker()));
|
|
2528
|
+
untrackedScanCache.set(cwd, next);
|
|
2529
|
+
return results.filter((meta) => meta !== null);
|
|
2952
2530
|
}
|
|
2953
2531
|
async function fileMetaResultAsync(args, cwd, includeUntracked = false) {
|
|
2954
|
-
|
|
2532
|
+
let ns;
|
|
2533
|
+
let nm;
|
|
2534
|
+
if (args.includes("--")) {
|
|
2535
|
+
[ns, nm] = await Promise.all([
|
|
2536
|
+
nameStatusResultAsync(args, cwd),
|
|
2537
|
+
numstatZResultAsync(args, cwd)
|
|
2538
|
+
]);
|
|
2539
|
+
} else {
|
|
2540
|
+
ns = await nameStatusResultAsync(args, cwd);
|
|
2541
|
+
nm = await numstatZResultAsync(args, cwd);
|
|
2542
|
+
}
|
|
2955
2543
|
if (ns.error)
|
|
2956
2544
|
return { files: [], error: ns.error };
|
|
2957
|
-
const nm = await numstatZResultAsync(args, cwd);
|
|
2958
2545
|
if (nm.error)
|
|
2959
2546
|
return { files: [], error: nm.error };
|
|
2960
2547
|
const byPath = new Map(nm.files.map((file) => [file.path, file]));
|
|
@@ -2971,25 +2558,6 @@ async function fileMetaResultAsync(args, cwd, includeUntracked = false) {
|
|
|
2971
2558
|
files: includeUntracked ? files.concat(await untrackedMetaAsync(cwd)) : files
|
|
2972
2559
|
};
|
|
2973
2560
|
}
|
|
2974
|
-
function fileDiffText(args, path, cwd) {
|
|
2975
|
-
const paths = Array.isArray(path) ? path : [path];
|
|
2976
|
-
const res = run([
|
|
2977
|
-
"git",
|
|
2978
|
-
"-c",
|
|
2979
|
-
"core.quotepath=false",
|
|
2980
|
-
"diff",
|
|
2981
|
-
"--no-color",
|
|
2982
|
-
"--no-ext-diff",
|
|
2983
|
-
"--find-renames",
|
|
2984
|
-
...args,
|
|
2985
|
-
"--",
|
|
2986
|
-
...paths
|
|
2987
|
-
], cwd);
|
|
2988
|
-
if (isCommandNotFoundResult("git", res)) {
|
|
2989
|
-
return { ...res, stderr: commandNotFoundDetail("git"), status: 503 };
|
|
2990
|
-
}
|
|
2991
|
-
return res;
|
|
2992
|
-
}
|
|
2993
2561
|
async function fileDiffTextAsync(args, path, cwd) {
|
|
2994
2562
|
const paths = Array.isArray(path) ? path : [path];
|
|
2995
2563
|
const res = await runGitAsync([
|
|
@@ -3009,24 +2577,6 @@ async function fileDiffTextAsync(args, path, cwd) {
|
|
|
3009
2577
|
}
|
|
3010
2578
|
return res;
|
|
3011
2579
|
}
|
|
3012
|
-
function untrackedFileDiff(extras, path, cwd) {
|
|
3013
|
-
const res = run([
|
|
3014
|
-
"git",
|
|
3015
|
-
"-c",
|
|
3016
|
-
"core.quotepath=false",
|
|
3017
|
-
"diff",
|
|
3018
|
-
"--no-color",
|
|
3019
|
-
"--no-ext-diff",
|
|
3020
|
-
"--no-index",
|
|
3021
|
-
...extras,
|
|
3022
|
-
"/dev/null",
|
|
3023
|
-
path
|
|
3024
|
-
], cwd);
|
|
3025
|
-
if (isCommandNotFoundResult("git", res)) {
|
|
3026
|
-
return { ...res, stderr: commandNotFoundDetail("git"), status: 503 };
|
|
3027
|
-
}
|
|
3028
|
-
return res;
|
|
3029
|
-
}
|
|
3030
2580
|
async function untrackedFileDiffAsync(extras, path, cwd) {
|
|
3031
2581
|
const res = await runGitAsync([
|
|
3032
2582
|
"git",
|
|
@@ -3122,7 +2672,7 @@ function truncateToNHunks(diffText, n, maxLines = Number.POSITIVE_INFINITY) {
|
|
|
3122
2672
|
lineTruncated
|
|
3123
2673
|
};
|
|
3124
2674
|
}
|
|
3125
|
-
var BLAME_ZERO_SHA = "0000000000000000000000000000000000000000", WORKTREE_RECURSIVE_DEPTH_LIMIT = 32, WORKTREE_RECURSIVE_ENTRY_LIMIT = 50000, DEFAULT_REF_COMMIT_LIMIT = 100, MAX_REF_COMMIT_LIMIT = 500, COMMIT_FORMAT = "%H%x00%s%x00%an%x00%aI", ALWAYS_WORKTREE_OMIT_DIR_NAMES, DEFAULT_WORKTREE_OMIT_DIR_NAMES, GIT_COMMAND_TIMEOUT_MS = 20000, repoStatusMapCache, HISTORY_FORMAT = "%H%x00%s%x00%an%x00%aI%x00%P%x00%b", MAX_HISTORY_LIMIT = 200, LS_TREE_SYMLINK_MODE = "120000";
|
|
2675
|
+
var BLAME_ZERO_SHA = "0000000000000000000000000000000000000000", WORKTREE_RECURSIVE_DEPTH_LIMIT = 32, WORKTREE_RECURSIVE_ENTRY_LIMIT = 50000, DEFAULT_REF_COMMIT_LIMIT = 100, MAX_REF_COMMIT_LIMIT = 500, COMMIT_FORMAT = "%H%x00%s%x00%an%x00%aI", ALWAYS_WORKTREE_OMIT_DIR_NAMES, DEFAULT_WORKTREE_OMIT_DIR_NAMES, GIT_COMMAND_TIMEOUT_MS = 20000, repoStatusMapCache, HISTORY_FORMAT = "%H%x00%s%x00%an%x00%aI%x00%P%x00%b", MAX_HISTORY_LIMIT = 200, LS_TREE_SYMLINK_MODE = "120000", untrackedScanCache, UNTRACKED_SCAN_CONCURRENCY = 8;
|
|
3126
2676
|
var init_git = __esm(() => {
|
|
3127
2677
|
init_cache();
|
|
3128
2678
|
init_command_resolver();
|
|
@@ -3174,6 +2724,7 @@ var init_git = __esm(() => {
|
|
|
3174
2724
|
"obj"
|
|
3175
2725
|
];
|
|
3176
2726
|
repoStatusMapCache = new Map;
|
|
2727
|
+
untrackedScanCache = new Map;
|
|
3177
2728
|
});
|
|
3178
2729
|
|
|
3179
2730
|
// web-src/server/server-registry.ts
|
|
@@ -4417,16 +3968,11 @@ __export(exports_file_cli, {
|
|
|
4417
3968
|
safeWorktreePathFromRoot: () => safeWorktreePathFromRoot,
|
|
4418
3969
|
runFileCli: () => runFileCli,
|
|
4419
3970
|
readShowTextAsync: () => readShowTextAsync,
|
|
4420
|
-
readShowText: () => readShowText,
|
|
4421
3971
|
parseFileArgs: () => parseFileArgs,
|
|
4422
3972
|
buildFileShowReportAsync: () => buildFileShowReportAsync,
|
|
4423
|
-
buildFileShowReport: () => buildFileShowReport,
|
|
4424
3973
|
buildFileHistoryReportAsync: () => buildFileHistoryReportAsync,
|
|
4425
|
-
buildFileHistoryReport: () => buildFileHistoryReport,
|
|
4426
3974
|
buildFileDiffReportAsync: () => buildFileDiffReportAsync,
|
|
4427
|
-
buildFileDiffReport: () => buildFileDiffReport,
|
|
4428
3975
|
buildFileBlameReportAsync: () => buildFileBlameReportAsync,
|
|
4429
|
-
buildFileBlameReport: () => buildFileBlameReport,
|
|
4430
3976
|
FILE_HISTORY_HARD_CAP: () => FILE_HISTORY_HARD_CAP,
|
|
4431
3977
|
FILE_HELP: () => FILE_HELP,
|
|
4432
3978
|
FILE_DIFF_LINE_HARD_CAP: () => FILE_DIFF_LINE_HARD_CAP,
|
|
@@ -4643,14 +4189,14 @@ function parseFileArgs(argv) {
|
|
|
4643
4189
|
if (oldPathError)
|
|
4644
4190
|
return { ok: false, error: oldPathError };
|
|
4645
4191
|
}
|
|
4646
|
-
const
|
|
4647
|
-
if (
|
|
4192
|
+
const untracked = flags.has("--untracked");
|
|
4193
|
+
if (untracked && rawFrom !== undefined) {
|
|
4648
4194
|
return {
|
|
4649
4195
|
ok: false,
|
|
4650
4196
|
error: "--untracked cannot be combined with --from"
|
|
4651
4197
|
};
|
|
4652
4198
|
}
|
|
4653
|
-
if (
|
|
4199
|
+
if (untracked && to !== "worktree") {
|
|
4654
4200
|
return {
|
|
4655
4201
|
ok: false,
|
|
4656
4202
|
error: "--untracked requires --to worktree (or --to omitted)"
|
|
@@ -4694,7 +4240,7 @@ function parseFileArgs(argv) {
|
|
|
4694
4240
|
...oldPathRaw !== undefined ? { oldPath: oldPathRaw } : {},
|
|
4695
4241
|
from,
|
|
4696
4242
|
to,
|
|
4697
|
-
untracked
|
|
4243
|
+
untracked,
|
|
4698
4244
|
ignoreWs,
|
|
4699
4245
|
ignoreBlank,
|
|
4700
4246
|
mode: full ? "full" : "preview",
|
|
@@ -4726,19 +4272,6 @@ function formatBlameText(result) {
|
|
|
4726
4272
|
function formatHistoryText(commits) {
|
|
4727
4273
|
return commits.map((c) => `${c.sha.slice(0, 8)} ${c.when} ${c.author} ${c.subject}`);
|
|
4728
4274
|
}
|
|
4729
|
-
function buildFileBlameReport(root, command) {
|
|
4730
|
-
const result = blame(root, {
|
|
4731
|
-
path: command.path,
|
|
4732
|
-
ref: command.ref,
|
|
4733
|
-
base: command.base
|
|
4734
|
-
});
|
|
4735
|
-
return {
|
|
4736
|
-
path: command.path,
|
|
4737
|
-
ref: command.ref,
|
|
4738
|
-
base: command.base,
|
|
4739
|
-
result
|
|
4740
|
-
};
|
|
4741
|
-
}
|
|
4742
4275
|
async function buildFileBlameReportAsync(root, command) {
|
|
4743
4276
|
const result = await blameAsync(root, {
|
|
4744
4277
|
path: command.path,
|
|
@@ -4752,23 +4285,6 @@ async function buildFileBlameReportAsync(root, command) {
|
|
|
4752
4285
|
result
|
|
4753
4286
|
};
|
|
4754
4287
|
}
|
|
4755
|
-
function buildFileHistoryReport(root, command) {
|
|
4756
|
-
const result = commitHistory(root, {
|
|
4757
|
-
ref: command.ref,
|
|
4758
|
-
skip: command.skip,
|
|
4759
|
-
limit: command.limit,
|
|
4760
|
-
query: command.query,
|
|
4761
|
-
path: command.path
|
|
4762
|
-
});
|
|
4763
|
-
return {
|
|
4764
|
-
path: command.path,
|
|
4765
|
-
ref: command.ref,
|
|
4766
|
-
limit: command.limit,
|
|
4767
|
-
skip: command.skip,
|
|
4768
|
-
...command.query !== undefined ? { query: command.query } : {},
|
|
4769
|
-
result
|
|
4770
|
-
};
|
|
4771
|
-
}
|
|
4772
4288
|
async function buildFileHistoryReportAsync(root, command) {
|
|
4773
4289
|
const result = await commitHistoryAsync(root, {
|
|
4774
4290
|
ref: command.ref,
|
|
@@ -4786,8 +4302,8 @@ async function buildFileHistoryReportAsync(root, command) {
|
|
|
4786
4302
|
result
|
|
4787
4303
|
};
|
|
4788
4304
|
}
|
|
4789
|
-
function runBlame(root, command) {
|
|
4790
|
-
const report =
|
|
4305
|
+
async function runBlame(root, command) {
|
|
4306
|
+
const report = await buildFileBlameReportAsync(root, command);
|
|
4791
4307
|
if (command.json) {
|
|
4792
4308
|
console.log(JSON.stringify(report, null, 2));
|
|
4793
4309
|
} else {
|
|
@@ -4799,8 +4315,8 @@ function runBlame(root, command) {
|
|
|
4799
4315
|
process.exit(1);
|
|
4800
4316
|
}
|
|
4801
4317
|
}
|
|
4802
|
-
function runHistory(root, command) {
|
|
4803
|
-
const report =
|
|
4318
|
+
async function runHistory(root, command) {
|
|
4319
|
+
const report = await buildFileHistoryReportAsync(root, command);
|
|
4804
4320
|
if (command.json) {
|
|
4805
4321
|
console.log(JSON.stringify(report, null, 2));
|
|
4806
4322
|
} else if (report.result.commits.length === 0) {
|
|
@@ -4852,28 +4368,6 @@ function safeWorktreePathFromRoot(root, path) {
|
|
|
4852
4368
|
return null;
|
|
4853
4369
|
}
|
|
4854
4370
|
}
|
|
4855
|
-
function readShowText(root, command) {
|
|
4856
|
-
if (command.ref !== "worktree" && command.ref !== "") {
|
|
4857
|
-
return show(command.ref, command.path, root);
|
|
4858
|
-
}
|
|
4859
|
-
const full = safeWorktreePathFromRoot(root, command.path);
|
|
4860
|
-
if (!full) {
|
|
4861
|
-
return {
|
|
4862
|
-
code: 1,
|
|
4863
|
-
stdout: "",
|
|
4864
|
-
stderr: "file not found or forbidden"
|
|
4865
|
-
};
|
|
4866
|
-
}
|
|
4867
|
-
try {
|
|
4868
|
-
const stat = statSync3(full);
|
|
4869
|
-
if (!stat.isFile()) {
|
|
4870
|
-
return { code: 1, stdout: "", stderr: "not a file" };
|
|
4871
|
-
}
|
|
4872
|
-
return { code: 0, stdout: readFileSync4(full, "utf8"), stderr: "" };
|
|
4873
|
-
} catch {
|
|
4874
|
-
return { code: 1, stdout: "", stderr: "file not readable" };
|
|
4875
|
-
}
|
|
4876
|
-
}
|
|
4877
4371
|
async function readShowTextAsync(root, command) {
|
|
4878
4372
|
if (command.ref !== "worktree" && command.ref !== "") {
|
|
4879
4373
|
return showAsync(command.ref, command.path, root);
|
|
@@ -4887,8 +4381,8 @@ async function readShowTextAsync(root, command) {
|
|
|
4887
4381
|
};
|
|
4888
4382
|
}
|
|
4889
4383
|
try {
|
|
4890
|
-
const
|
|
4891
|
-
if (!
|
|
4384
|
+
const stat2 = statSync3(full);
|
|
4385
|
+
if (!stat2.isFile()) {
|
|
4892
4386
|
return { code: 1, stdout: "", stderr: "not a file" };
|
|
4893
4387
|
}
|
|
4894
4388
|
return { code: 0, stdout: readFileSync4(full, "utf8"), stderr: "" };
|
|
@@ -4896,33 +4390,6 @@ async function readShowTextAsync(root, command) {
|
|
|
4896
4390
|
return { code: 1, stdout: "", stderr: "file not readable" };
|
|
4897
4391
|
}
|
|
4898
4392
|
}
|
|
4899
|
-
function buildFileShowReport(root, command) {
|
|
4900
|
-
const res = readShowText(root, command);
|
|
4901
|
-
if (res.code !== 0) {
|
|
4902
|
-
const detail = res.stderr.trim() || `git show exited with code ${res.code}`;
|
|
4903
|
-
return {
|
|
4904
|
-
path: command.path,
|
|
4905
|
-
ref: command.ref,
|
|
4906
|
-
...command.start !== undefined ? { start: command.start } : {},
|
|
4907
|
-
...command.end !== undefined ? { end: command.end } : {},
|
|
4908
|
-
totalLines: 0,
|
|
4909
|
-
complete: false,
|
|
4910
|
-
text: "",
|
|
4911
|
-
error: detail
|
|
4912
|
-
};
|
|
4913
|
-
}
|
|
4914
|
-
const sliced = sliceLines(res.stdout, command.start, command.end);
|
|
4915
|
-
return {
|
|
4916
|
-
path: command.path,
|
|
4917
|
-
ref: command.ref,
|
|
4918
|
-
...command.start !== undefined ? { start: command.start } : {},
|
|
4919
|
-
...command.end !== undefined ? { end: command.end } : {},
|
|
4920
|
-
totalLines: sliced.total,
|
|
4921
|
-
complete: sliced.complete,
|
|
4922
|
-
text: sliced.lines.join(`
|
|
4923
|
-
`)
|
|
4924
|
-
};
|
|
4925
|
-
}
|
|
4926
4393
|
async function buildFileShowReportAsync(root, command) {
|
|
4927
4394
|
const res = await readShowTextAsync(root, command);
|
|
4928
4395
|
if (res.code !== 0) {
|
|
@@ -4950,8 +4417,8 @@ async function buildFileShowReportAsync(root, command) {
|
|
|
4950
4417
|
`)
|
|
4951
4418
|
};
|
|
4952
4419
|
}
|
|
4953
|
-
function runShow(root, command) {
|
|
4954
|
-
const report =
|
|
4420
|
+
async function runShow(root, command) {
|
|
4421
|
+
const report = await buildFileShowReportAsync(root, command);
|
|
4955
4422
|
if (report.error !== undefined) {
|
|
4956
4423
|
if (command.json) {
|
|
4957
4424
|
console.log(JSON.stringify(report, null, 2));
|
|
@@ -4974,64 +4441,6 @@ function buildFileDiffRangeArgs(from, to) {
|
|
|
4974
4441
|
refs.push(to);
|
|
4975
4442
|
return refs;
|
|
4976
4443
|
}
|
|
4977
|
-
function buildFileDiffReport(root, command) {
|
|
4978
|
-
const base = {
|
|
4979
|
-
path: command.path,
|
|
4980
|
-
...command.oldPath !== undefined ? { old_path: command.oldPath } : {},
|
|
4981
|
-
from: command.untracked ? "/dev/null" : command.from,
|
|
4982
|
-
to: command.to,
|
|
4983
|
-
untracked: command.untracked,
|
|
4984
|
-
ignore_ws: command.ignoreWs,
|
|
4985
|
-
ignore_blank: command.ignoreBlank,
|
|
4986
|
-
mode: command.mode,
|
|
4987
|
-
max_hunks: command.mode === "preview" ? command.maxHunks : null,
|
|
4988
|
-
max_lines: command.mode === "preview" ? command.maxLines : null,
|
|
4989
|
-
diff: "",
|
|
4990
|
-
hunk_count: 0,
|
|
4991
|
-
rendered_hunk_count: 0,
|
|
4992
|
-
line_count: 0,
|
|
4993
|
-
truncated: false,
|
|
4994
|
-
binary: false
|
|
4995
|
-
};
|
|
4996
|
-
if (!command.untracked && isSameWorktreeRange({ from: command.from, to: command.to })) {
|
|
4997
|
-
return base;
|
|
4998
|
-
}
|
|
4999
|
-
const extras = [];
|
|
5000
|
-
if (command.ignoreWs)
|
|
5001
|
-
extras.push("-w");
|
|
5002
|
-
if (command.ignoreBlank)
|
|
5003
|
-
extras.push("--ignore-blank-lines");
|
|
5004
|
-
let diffText = "";
|
|
5005
|
-
let errText = "";
|
|
5006
|
-
if (command.untracked) {
|
|
5007
|
-
const res = untrackedFileDiff(extras, command.path, root);
|
|
5008
|
-
diffText = res.stdout || "";
|
|
5009
|
-
if (res.code !== 0)
|
|
5010
|
-
errText = res.stderr.trim();
|
|
5011
|
-
} else {
|
|
5012
|
-
const args = [
|
|
5013
|
-
...extras,
|
|
5014
|
-
...buildFileDiffRangeArgs(command.from, command.to)
|
|
5015
|
-
];
|
|
5016
|
-
const paths = command.oldPath !== undefined ? [command.oldPath, command.path] : command.path;
|
|
5017
|
-
const res = fileDiffText(args, paths, root);
|
|
5018
|
-
diffText = res.stdout || "";
|
|
5019
|
-
if (res.code !== 0)
|
|
5020
|
-
errText = res.stderr.trim();
|
|
5021
|
-
}
|
|
5022
|
-
const truncated = command.mode === "preview" ? truncateToNHunks(diffText, command.maxHunks, command.maxLines) : truncateToNHunks(diffText, 1e9);
|
|
5023
|
-
const previewTruncated = command.mode === "preview" && (truncated.totalHunks > truncated.renderedHunks || truncated.lineTruncated);
|
|
5024
|
-
return {
|
|
5025
|
-
...base,
|
|
5026
|
-
diff: truncated.text,
|
|
5027
|
-
hunk_count: truncated.totalHunks,
|
|
5028
|
-
rendered_hunk_count: truncated.renderedHunks,
|
|
5029
|
-
line_count: truncated.lineCount,
|
|
5030
|
-
truncated: previewTruncated,
|
|
5031
|
-
binary: diffText.includes("Binary files"),
|
|
5032
|
-
...errText ? { error: errText } : {}
|
|
5033
|
-
};
|
|
5034
|
-
}
|
|
5035
4444
|
async function buildFileDiffReportAsync(root, command) {
|
|
5036
4445
|
const base = {
|
|
5037
4446
|
path: command.path,
|
|
@@ -5090,8 +4499,8 @@ async function buildFileDiffReportAsync(root, command) {
|
|
|
5090
4499
|
...errText ? { error: errText } : {}
|
|
5091
4500
|
};
|
|
5092
4501
|
}
|
|
5093
|
-
function runDiff(root, command) {
|
|
5094
|
-
const report =
|
|
4502
|
+
async function runDiff(root, command) {
|
|
4503
|
+
const report = await buildFileDiffReportAsync(root, command);
|
|
5095
4504
|
if (command.json) {
|
|
5096
4505
|
console.log(JSON.stringify(report, null, 2));
|
|
5097
4506
|
} else if (report.diff.length > 0) {
|
|
@@ -10049,18 +9458,18 @@ function formatRecentText(commits) {
|
|
|
10049
9458
|
}
|
|
10050
9459
|
return lines;
|
|
10051
9460
|
}
|
|
10052
|
-
function buildStatusReport(opts) {
|
|
9461
|
+
async function buildStatusReport(opts) {
|
|
10053
9462
|
const { root, ref, limit } = opts;
|
|
10054
|
-
const stagedResult =
|
|
10055
|
-
const changedResult =
|
|
10056
|
-
const worktreeFallbackResult = isMissingDiffBaseError(changedResult.error) ?
|
|
9463
|
+
const stagedResult = await fileMetaResultAsync(["--cached"], root, false);
|
|
9464
|
+
const changedResult = await fileMetaResultAsync(["HEAD"], root, true);
|
|
9465
|
+
const worktreeFallbackResult = isMissingDiffBaseError(changedResult.error) ? await fileMetaResultAsync([], root, true) : null;
|
|
10057
9466
|
const stagedFiles = stagedResult.files;
|
|
10058
9467
|
const changedFiles = changedResult.error ? worktreeFallbackResult ? mergeMissingByPath(worktreeFallbackResult.files, stagedFiles) : [] : mergeMissingByPath(changedResult.files, stagedFiles);
|
|
10059
9468
|
const changed = buildGroup(changedFiles, worktreeFallbackResult ? worktreeFallbackResult.error || stagedResult.error : changedResult.error || stagedResult.error);
|
|
10060
9469
|
const staged = buildGroup(stagedFiles, stagedResult.error);
|
|
10061
|
-
const history =
|
|
10062
|
-
const branch =
|
|
10063
|
-
const remote =
|
|
9470
|
+
const history = await commitHistoryAsync(root, { ref, skip: 0, limit });
|
|
9471
|
+
const branch = await currentBranchAsync(root);
|
|
9472
|
+
const remote = await remoteWebUrlAsync(root);
|
|
10064
9473
|
const registry = readServerRegistry(root);
|
|
10065
9474
|
const serverUrl = registry?.url ?? null;
|
|
10066
9475
|
const nextCommands = buildNextCommands(changed, staged, serverUrl);
|
|
@@ -10098,7 +9507,7 @@ function formatStatusReportText(report) {
|
|
|
10098
9507
|
return lines.join(`
|
|
10099
9508
|
`);
|
|
10100
9509
|
}
|
|
10101
|
-
function runStatusCli(argv) {
|
|
9510
|
+
async function runStatusCli(argv) {
|
|
10102
9511
|
const parsed = parseStatusArgs(argv);
|
|
10103
9512
|
if (parsed.ok === false) {
|
|
10104
9513
|
console.error(parsed.error);
|
|
@@ -10124,7 +9533,7 @@ function runStatusCli(argv) {
|
|
|
10124
9533
|
process.exit(1);
|
|
10125
9534
|
}
|
|
10126
9535
|
const root = resolveRepoRoot(cwd);
|
|
10127
|
-
const report = buildStatusReport({
|
|
9536
|
+
const report = await buildStatusReport({
|
|
10128
9537
|
root,
|
|
10129
9538
|
ref: command.ref,
|
|
10130
9539
|
limit: command.limit
|
|
@@ -14805,26 +14214,26 @@ function hasControlCharacter(value) {
|
|
|
14805
14214
|
|
|
14806
14215
|
// web-src/server/database/discovery.ts
|
|
14807
14216
|
import {
|
|
14808
|
-
closeSync
|
|
14217
|
+
closeSync,
|
|
14809
14218
|
existsSync as existsSync6,
|
|
14810
|
-
openSync
|
|
14811
|
-
readSync
|
|
14219
|
+
openSync,
|
|
14220
|
+
readSync,
|
|
14812
14221
|
realpathSync as realpathSync5,
|
|
14813
14222
|
statSync as statSync4
|
|
14814
14223
|
} from "node:fs";
|
|
14815
|
-
import { lstat, open, readdir, readFile as readFile2, stat } from "node:fs/promises";
|
|
14224
|
+
import { lstat, open as open2, readdir, readFile as readFile2, stat as stat2 } from "node:fs/promises";
|
|
14816
14225
|
import { basename, join as join9, relative as relative4 } from "node:path";
|
|
14817
14226
|
function isSqliteFile(fullPath) {
|
|
14818
14227
|
try {
|
|
14819
|
-
const
|
|
14820
|
-
if (!
|
|
14228
|
+
const stat3 = statSync4(fullPath);
|
|
14229
|
+
if (!stat3.isFile() || stat3.size < 16)
|
|
14821
14230
|
return false;
|
|
14822
14231
|
const buf = Buffer.alloc(16);
|
|
14823
|
-
const fd =
|
|
14232
|
+
const fd = openSync(fullPath, "r");
|
|
14824
14233
|
try {
|
|
14825
|
-
|
|
14234
|
+
readSync(fd, buf, 0, 16, 0);
|
|
14826
14235
|
} finally {
|
|
14827
|
-
|
|
14236
|
+
closeSync(fd);
|
|
14828
14237
|
}
|
|
14829
14238
|
return buf.toString("utf8", 0, 16) === SQLITE_MAGIC;
|
|
14830
14239
|
} catch {
|
|
@@ -14833,10 +14242,10 @@ function isSqliteFile(fullPath) {
|
|
|
14833
14242
|
}
|
|
14834
14243
|
async function isSqliteFileAsync(fullPath) {
|
|
14835
14244
|
try {
|
|
14836
|
-
const fileStat = await
|
|
14245
|
+
const fileStat = await stat2(fullPath);
|
|
14837
14246
|
if (!fileStat.isFile() || fileStat.size < 16)
|
|
14838
14247
|
return false;
|
|
14839
|
-
const file = await
|
|
14248
|
+
const file = await open2(fullPath, "r");
|
|
14840
14249
|
try {
|
|
14841
14250
|
const buf = Buffer.alloc(16);
|
|
14842
14251
|
await file.read(buf, 0, 16, 0);
|
|
@@ -15300,7 +14709,7 @@ function cloneDockerDiscoveryResult(result) {
|
|
|
15300
14709
|
}
|
|
15301
14710
|
async function pathExistsAsync(path) {
|
|
15302
14711
|
try {
|
|
15303
|
-
await
|
|
14712
|
+
await stat2(path);
|
|
15304
14713
|
return true;
|
|
15305
14714
|
} catch {
|
|
15306
14715
|
return false;
|
|
@@ -15649,6 +15058,7 @@ function startWorktreeUpdateWatch(options) {
|
|
|
15649
15058
|
const initialScanAsync = options.initialScanMode === "async" || (!options.watch || options.watch === nodeWatch) && !options.readdirSync;
|
|
15650
15059
|
const initialScanQueue = [];
|
|
15651
15060
|
let initialScanTimer = null;
|
|
15061
|
+
let processingInitialScan = false;
|
|
15652
15062
|
const pendingPathInspections = new Map;
|
|
15653
15063
|
let pathInspectionTimer = null;
|
|
15654
15064
|
let timer = null;
|
|
@@ -15736,8 +15146,14 @@ function startWorktreeUpdateWatch(options) {
|
|
|
15736
15146
|
return;
|
|
15737
15147
|
}
|
|
15738
15148
|
const next = initialScanQueue.shift();
|
|
15739
|
-
if (next)
|
|
15740
|
-
|
|
15149
|
+
if (next) {
|
|
15150
|
+
processingInitialScan = true;
|
|
15151
|
+
try {
|
|
15152
|
+
watchDirectory(next, true);
|
|
15153
|
+
} finally {
|
|
15154
|
+
processingInitialScan = false;
|
|
15155
|
+
}
|
|
15156
|
+
}
|
|
15741
15157
|
if (watchers.size >= maxWatchedDirectories) {
|
|
15742
15158
|
reportWatchLimit();
|
|
15743
15159
|
initialScanQueue.length = 0;
|
|
@@ -15755,7 +15171,7 @@ function startWorktreeUpdateWatch(options) {
|
|
|
15755
15171
|
if (children.length > remaining)
|
|
15756
15172
|
reportWatchLimit();
|
|
15757
15173
|
initialScanQueue.push(...children.slice(0, remaining));
|
|
15758
|
-
if (!initialScanTimer)
|
|
15174
|
+
if (!initialScanTimer && !processingInitialScan)
|
|
15759
15175
|
initialScanTimer = setTimer(processInitialScanQueue, 5000);
|
|
15760
15176
|
};
|
|
15761
15177
|
const processChangedPath = (changed, fullChangedPath) => {
|
|
@@ -17334,7 +16750,7 @@ function createDockerAdapterCache(maxEntries = DEFAULT_MAX_DOCKER_ADAPTER_CACHE,
|
|
|
17334
16750
|
}
|
|
17335
16751
|
}
|
|
17336
16752
|
return {
|
|
17337
|
-
async getOrOpenAsync(key,
|
|
16753
|
+
async getOrOpenAsync(key, open3) {
|
|
17338
16754
|
prune();
|
|
17339
16755
|
const cached = cache.get(key);
|
|
17340
16756
|
if (cached) {
|
|
@@ -17348,7 +16764,7 @@ function createDockerAdapterCache(maxEntries = DEFAULT_MAX_DOCKER_ADAPTER_CACHE,
|
|
|
17348
16764
|
closed: false,
|
|
17349
16765
|
promise: undefined
|
|
17350
16766
|
};
|
|
17351
|
-
pendingEntry.promise = Promise.resolve().then(
|
|
16767
|
+
pendingEntry.promise = Promise.resolve().then(open3).then((adapter) => {
|
|
17352
16768
|
if (pendingEntry.closed) {
|
|
17353
16769
|
adapter.close();
|
|
17354
16770
|
} else {
|
|
@@ -21646,27 +21062,27 @@ async function checkSqlite(cwd) {
|
|
|
21646
21062
|
const status = await describeSqliteDriver();
|
|
21647
21063
|
const rows = [sqliteStatusToRow(status)];
|
|
21648
21064
|
if (status.kind === "ok") {
|
|
21649
|
-
const
|
|
21650
|
-
if (
|
|
21065
|
+
const open3 = await trySnapshotDbOpen(cwd);
|
|
21066
|
+
if (open3.kind === "skipped") {
|
|
21651
21067
|
rows.push({
|
|
21652
21068
|
id: "sqlite.snapshot-open",
|
|
21653
21069
|
title: "Snapshot DB open smoke test",
|
|
21654
21070
|
status: "ok",
|
|
21655
21071
|
detail: "Skipped (snapshot DB will be created on first use)"
|
|
21656
21072
|
});
|
|
21657
|
-
} else if (
|
|
21073
|
+
} else if (open3.kind === "ok") {
|
|
21658
21074
|
rows.push({
|
|
21659
21075
|
id: "sqlite.snapshot-open",
|
|
21660
21076
|
title: "Snapshot DB open smoke test",
|
|
21661
21077
|
status: "ok",
|
|
21662
|
-
detail: `Opened ${
|
|
21078
|
+
detail: `Opened ${open3.path}`
|
|
21663
21079
|
});
|
|
21664
21080
|
} else {
|
|
21665
21081
|
rows.push({
|
|
21666
21082
|
id: "sqlite.snapshot-open",
|
|
21667
21083
|
title: "Snapshot DB open failed",
|
|
21668
21084
|
status: "error",
|
|
21669
|
-
detail:
|
|
21085
|
+
detail: open3.message,
|
|
21670
21086
|
hint: "The snapshot DB exists but could not be opened. Inspect file permissions, possible corruption, or another process holding the file."
|
|
21671
21087
|
});
|
|
21672
21088
|
}
|
|
@@ -21715,8 +21131,8 @@ function checkSnapshotStore(cwd) {
|
|
|
21715
21131
|
}
|
|
21716
21132
|
let dbDetail = dbPath;
|
|
21717
21133
|
try {
|
|
21718
|
-
const
|
|
21719
|
-
dbDetail = `${dbPath} (${
|
|
21134
|
+
const stat3 = statSync5(dbPath);
|
|
21135
|
+
dbDetail = `${dbPath} (${stat3.size.toLocaleString()} bytes)`;
|
|
21720
21136
|
} catch {
|
|
21721
21137
|
dbDetail = `${dbPath} (not created yet — created on first snapshot)`;
|
|
21722
21138
|
}
|
|
@@ -23330,7 +22746,8 @@ var init_journal2 = __esm(() => {
|
|
|
23330
22746
|
});
|
|
23331
22747
|
|
|
23332
22748
|
// web-src/server/search-service.ts
|
|
23333
|
-
import { existsSync as existsSync7,
|
|
22749
|
+
import { existsSync as existsSync7, realpathSync as realpathSync6 } from "node:fs";
|
|
22750
|
+
import { lstat as lstat2, readFile as readFile3 } from "node:fs/promises";
|
|
23334
22751
|
import { join as join18, relative as relative7 } from "node:path";
|
|
23335
22752
|
async function rgAvailableAsync(cwd) {
|
|
23336
22753
|
if (rgAvailableCache !== null)
|
|
@@ -23382,12 +22799,12 @@ function safeWorktreePath(env, path) {
|
|
|
23382
22799
|
function filterCallerPaths(env, paths) {
|
|
23383
22800
|
return paths.filter((path) => isSafePath(path) && !isGitInternalPath(path) && !isSkippableSearchPath(path, env.omitDirNames, env.excludeNames));
|
|
23384
22801
|
}
|
|
23385
|
-
function grepWorktreeFallback(env, query, max, paths) {
|
|
23386
|
-
const candidates = paths.length ? paths :
|
|
22802
|
+
async function grepWorktreeFallback(env, query, max, paths) {
|
|
22803
|
+
const candidates = paths.length ? paths : (await listTreeAsync("worktree", "", env.cwd, {
|
|
23387
22804
|
recursive: true,
|
|
23388
22805
|
omitDirNames: env.omitDirNames,
|
|
23389
22806
|
excludeNames: env.excludeNames
|
|
23390
|
-
}).entries.map((entry) => entry.path);
|
|
22807
|
+
})).entries.map((entry) => entry.path);
|
|
23391
22808
|
const matches = [];
|
|
23392
22809
|
for (const path of candidates) {
|
|
23393
22810
|
if (matches.length >= max)
|
|
@@ -23397,17 +22814,17 @@ function grepWorktreeFallback(env, query, max, paths) {
|
|
|
23397
22814
|
const full = safeWorktreePath(env, path);
|
|
23398
22815
|
if (!full)
|
|
23399
22816
|
continue;
|
|
23400
|
-
let
|
|
22817
|
+
let stat3;
|
|
23401
22818
|
try {
|
|
23402
|
-
|
|
22819
|
+
stat3 = await lstat2(full);
|
|
23403
22820
|
} catch {
|
|
23404
22821
|
continue;
|
|
23405
22822
|
}
|
|
23406
|
-
if (!
|
|
22823
|
+
if (!stat3.isFile() || stat3.isSymbolicLink() || stat3.size > GREP_MAX_FILE_BYTES)
|
|
23407
22824
|
continue;
|
|
23408
22825
|
let data;
|
|
23409
22826
|
try {
|
|
23410
|
-
data =
|
|
22827
|
+
data = await readFile3(full);
|
|
23411
22828
|
} catch {
|
|
23412
22829
|
continue;
|
|
23413
22830
|
}
|
|
@@ -23447,7 +22864,7 @@ async function grepWorktreeAsync(env, req) {
|
|
|
23447
22864
|
matches: []
|
|
23448
22865
|
};
|
|
23449
22866
|
}
|
|
23450
|
-
const matches = grepWorktreeFallback(env, req.query, req.max, paths);
|
|
22867
|
+
const matches = await grepWorktreeFallback(env, req.query, req.max, paths);
|
|
23451
22868
|
return {
|
|
23452
22869
|
ref: "worktree",
|
|
23453
22870
|
engine: "fallback",
|
|
@@ -23553,7 +22970,7 @@ var init_search_service = __esm(() => {
|
|
|
23553
22970
|
});
|
|
23554
22971
|
|
|
23555
22972
|
// web-src/server/mcp.ts
|
|
23556
|
-
import { readFileSync as
|
|
22973
|
+
import { readFileSync as readFileSync7 } from "node:fs";
|
|
23557
22974
|
import { join as join19 } from "node:path";
|
|
23558
22975
|
function defaultMcpTools(options = {}) {
|
|
23559
22976
|
return [
|
|
@@ -24051,7 +23468,7 @@ function defaultMcpTools(options = {}) {
|
|
|
24051
23468
|
}
|
|
24052
23469
|
];
|
|
24053
23470
|
}
|
|
24054
|
-
function runStatusTool(input, defaultCwd) {
|
|
23471
|
+
async function runStatusTool(input, defaultCwd) {
|
|
24055
23472
|
const params = isPlainObject(input) ? input : {};
|
|
24056
23473
|
const cwdRaw = params.cwd;
|
|
24057
23474
|
const refRaw = params.ref;
|
|
@@ -24092,7 +23509,7 @@ function runStatusTool(input, defaultCwd) {
|
|
|
24092
23509
|
return { text: resolved.error, isError: true };
|
|
24093
23510
|
}
|
|
24094
23511
|
try {
|
|
24095
|
-
const report = buildStatusReport({ root: resolved.root, ref, limit });
|
|
23512
|
+
const report = await buildStatusReport({ root: resolved.root, ref, limit });
|
|
24096
23513
|
return {
|
|
24097
23514
|
text: JSON.stringify(report, null, 2),
|
|
24098
23515
|
isError: !!(report.changed.error || report.staged.error)
|
|
@@ -24365,14 +23782,14 @@ async function runFileDiffTool(input, defaultCwd) {
|
|
|
24365
23782
|
if (untrackedRaw !== undefined && typeof untrackedRaw !== "boolean") {
|
|
24366
23783
|
return { text: "untracked must be a boolean", isError: true };
|
|
24367
23784
|
}
|
|
24368
|
-
const
|
|
24369
|
-
if (
|
|
23785
|
+
const untracked = untrackedRaw === true;
|
|
23786
|
+
if (untracked && params.from !== undefined) {
|
|
24370
23787
|
return {
|
|
24371
23788
|
text: "untracked cannot be combined with from",
|
|
24372
23789
|
isError: true
|
|
24373
23790
|
};
|
|
24374
23791
|
}
|
|
24375
|
-
if (
|
|
23792
|
+
if (untracked && toParsed.ref !== "worktree") {
|
|
24376
23793
|
return {
|
|
24377
23794
|
text: "untracked requires to='worktree' (or omitted)",
|
|
24378
23795
|
isError: true
|
|
@@ -24420,7 +23837,7 @@ async function runFileDiffTool(input, defaultCwd) {
|
|
|
24420
23837
|
...oldPath !== undefined ? { oldPath } : {},
|
|
24421
23838
|
from: fromParsed.ref,
|
|
24422
23839
|
to: toParsed.ref,
|
|
24423
|
-
untracked
|
|
23840
|
+
untracked,
|
|
24424
23841
|
ignoreWs,
|
|
24425
23842
|
ignoreBlank,
|
|
24426
23843
|
mode,
|
|
@@ -25028,7 +24445,7 @@ var init_mcp = __esm(() => {
|
|
|
25028
24445
|
init_search_cli();
|
|
25029
24446
|
init_search_service();
|
|
25030
24447
|
init_status_cli();
|
|
25031
|
-
PACKAGE_VERSION = JSON.parse(
|
|
24448
|
+
PACKAGE_VERSION = JSON.parse(readFileSync7(join19(ROOT, "package.json"), "utf8")).version;
|
|
25032
24449
|
MCP_SERVER_INFO = {
|
|
25033
24450
|
name: "code-viewer",
|
|
25034
24451
|
title: "code-viewer",
|
|
@@ -25109,13 +24526,13 @@ var init_state_route = __esm(() => {
|
|
|
25109
24526
|
// web-src/server/preview.ts
|
|
25110
24527
|
var exports_preview = {};
|
|
25111
24528
|
import {
|
|
25112
|
-
closeSync as
|
|
24529
|
+
closeSync as closeSync2,
|
|
25113
24530
|
constants as constants3,
|
|
25114
24531
|
existsSync as existsSync8,
|
|
25115
|
-
lstatSync as
|
|
24532
|
+
lstatSync as lstatSync4,
|
|
25116
24533
|
mkdirSync as mkdirSync4,
|
|
25117
|
-
openSync as
|
|
25118
|
-
readFileSync as
|
|
24534
|
+
openSync as openSync2,
|
|
24535
|
+
readFileSync as readFileSync8,
|
|
25119
24536
|
realpathSync as realpathSync7,
|
|
25120
24537
|
renameSync,
|
|
25121
24538
|
statSync as statSync6,
|
|
@@ -25356,7 +24773,7 @@ function staticFile(pathname) {
|
|
|
25356
24773
|
const full = join20(WEB_ROOT, spec[0]);
|
|
25357
24774
|
if (!existsSync8(full))
|
|
25358
24775
|
return text("not found", 404);
|
|
25359
|
-
return new Response(
|
|
24776
|
+
return new Response(readFileSync8(full), {
|
|
25360
24777
|
headers: { "Content-Type": spec[1], "Cache-Control": "no-store" }
|
|
25361
24778
|
});
|
|
25362
24779
|
}
|
|
@@ -25413,7 +24830,7 @@ function buildQuery(params) {
|
|
|
25413
24830
|
const s = q.toString();
|
|
25414
24831
|
return s ? `?${s}` : "";
|
|
25415
24832
|
}
|
|
25416
|
-
function fileToMeta(file, range, extraQs) {
|
|
24833
|
+
function fileToMeta(file, range, extraQs, responseGeneration) {
|
|
25417
24834
|
const sizeClass = classify(file);
|
|
25418
24835
|
const q = {
|
|
25419
24836
|
path: file.path,
|
|
@@ -25421,6 +24838,7 @@ function fileToMeta(file, range, extraQs) {
|
|
|
25421
24838
|
status: file.status,
|
|
25422
24839
|
from: range.from,
|
|
25423
24840
|
to: range.to,
|
|
24841
|
+
generation: responseGeneration,
|
|
25424
24842
|
...extraQs
|
|
25425
24843
|
};
|
|
25426
24844
|
if (file.untracked)
|
|
@@ -25459,7 +24877,7 @@ async function computePayload(extras, range, pathFilter = "", responseGeneration
|
|
|
25459
24877
|
};
|
|
25460
24878
|
}
|
|
25461
24879
|
const { args, refs } = buildRangeArgs(range);
|
|
25462
|
-
const fullArgs = [...extras, ...args];
|
|
24880
|
+
const fullArgs = pathFilter ? [...extras, ...args, "--", pathFilter] : [...extras, ...args];
|
|
25463
24881
|
const metaResult = await fileMetaResultAsync(fullArgs, cwd, false);
|
|
25464
24882
|
const files = metaResult.files;
|
|
25465
24883
|
if (!metaResult.error && includeUntracked(range, refs)) {
|
|
@@ -25477,7 +24895,7 @@ async function computePayload(extras, range, pathFilter = "", responseGeneration
|
|
|
25477
24895
|
if (e === "--ignore-blank-lines")
|
|
25478
24896
|
extraQs.ignore_blank = "1";
|
|
25479
24897
|
}
|
|
25480
|
-
const meta = filteredFiles.map((file) => fileToMeta(file, range, extraQs));
|
|
24898
|
+
const meta = filteredFiles.map((file) => fileToMeta(file, range, extraQs, responseGeneration));
|
|
25481
24899
|
const totals = meta.reduce((acc, file) => {
|
|
25482
24900
|
acc.additions += file.additions || 0;
|
|
25483
24901
|
acc.deletions += file.deletions || 0;
|
|
@@ -25496,7 +24914,7 @@ async function computePayload(extras, range, pathFilter = "", responseGeneration
|
|
|
25496
24914
|
};
|
|
25497
24915
|
}
|
|
25498
24916
|
async function handleDiffJson(url) {
|
|
25499
|
-
|
|
24917
|
+
let responseGeneration = generation;
|
|
25500
24918
|
const extras = [];
|
|
25501
24919
|
if (url.searchParams.get("ignore_ws") === "1")
|
|
25502
24920
|
extras.push("-w");
|
|
@@ -25522,9 +24940,15 @@ async function handleDiffJson(url) {
|
|
|
25522
24940
|
const requestSequence = ++diffMetaRequestSequence;
|
|
25523
24941
|
latestDiffMetaRequest.set(key, requestSequence);
|
|
25524
24942
|
try {
|
|
25525
|
-
|
|
25526
|
-
if (latestDiffMetaRequest.get(key) !== requestSequence
|
|
24943
|
+
let payload = await computePayload(extras, range, path, responseGeneration);
|
|
24944
|
+
if (latestDiffMetaRequest.get(key) !== requestSequence)
|
|
25527
24945
|
return json2(payload);
|
|
24946
|
+
if (responseGeneration !== generation) {
|
|
24947
|
+
responseGeneration = generation;
|
|
24948
|
+
payload = await computePayload(extras, range, path, responseGeneration);
|
|
24949
|
+
if (latestDiffMetaRequest.get(key) !== requestSequence || responseGeneration !== generation)
|
|
24950
|
+
return json2(payload);
|
|
24951
|
+
}
|
|
25528
24952
|
const sig = JSON.stringify({ ...payload, generation: undefined });
|
|
25529
24953
|
if (noCache && (!cached || cached.sig !== sig)) {
|
|
25530
24954
|
generation++;
|
|
@@ -25631,11 +25055,11 @@ function worktreeFileMetadata(path, knownSize) {
|
|
|
25631
25055
|
if (!full)
|
|
25632
25056
|
return {};
|
|
25633
25057
|
try {
|
|
25634
|
-
const
|
|
25058
|
+
const stat3 = statSync6(full);
|
|
25635
25059
|
return {
|
|
25636
|
-
size: knownSize ??
|
|
25637
|
-
created_at: isoDate(
|
|
25638
|
-
updated_at: isoDate(
|
|
25060
|
+
size: knownSize ?? stat3.size,
|
|
25061
|
+
created_at: isoDate(stat3.birthtimeMs),
|
|
25062
|
+
updated_at: isoDate(stat3.mtimeMs)
|
|
25639
25063
|
};
|
|
25640
25064
|
} catch {
|
|
25641
25065
|
return {};
|
|
@@ -25656,10 +25080,10 @@ async function directoryMetadata(target, path) {
|
|
|
25656
25080
|
if (!full)
|
|
25657
25081
|
return {};
|
|
25658
25082
|
try {
|
|
25659
|
-
const
|
|
25083
|
+
const stat3 = statSync6(full);
|
|
25660
25084
|
return {
|
|
25661
|
-
created_at: isoDate(
|
|
25662
|
-
updated_at: isoDate(
|
|
25085
|
+
created_at: isoDate(stat3.birthtimeMs),
|
|
25086
|
+
updated_at: isoDate(stat3.mtimeMs)
|
|
25663
25087
|
};
|
|
25664
25088
|
} catch {
|
|
25665
25089
|
return {};
|
|
@@ -25704,7 +25128,7 @@ async function readReadme(target, dirPath) {
|
|
|
25704
25128
|
if (!full)
|
|
25705
25129
|
continue;
|
|
25706
25130
|
try {
|
|
25707
|
-
return { path, text:
|
|
25131
|
+
return { path, text: readFileSync8(full, "utf8") };
|
|
25708
25132
|
} catch {
|
|
25709
25133
|
continue;
|
|
25710
25134
|
}
|
|
@@ -25993,7 +25417,7 @@ async function handleFileBlame(url) {
|
|
|
25993
25417
|
return json2({ ...result, base, ref, generation: responseGeneration });
|
|
25994
25418
|
}
|
|
25995
25419
|
async function handleFileDiff(url) {
|
|
25996
|
-
const
|
|
25420
|
+
const serverGenerationAtRequest = generation;
|
|
25997
25421
|
const path = url.searchParams.get("path") || "";
|
|
25998
25422
|
if (!safePath(path))
|
|
25999
25423
|
return text("invalid path", 400);
|
|
@@ -26007,6 +25431,9 @@ async function handleFileDiff(url) {
|
|
|
26007
25431
|
from: url.searchParams.get("from") || "",
|
|
26008
25432
|
to: url.searchParams.get("to") || ""
|
|
26009
25433
|
};
|
|
25434
|
+
const requestedGeneration = Number(url.searchParams.get("generation"));
|
|
25435
|
+
const usesWorktree = !range.from || range.from === "worktree" || !range.to || range.to === "worktree";
|
|
25436
|
+
const responseGeneration = !usesWorktree && Number.isSafeInteger(requestedGeneration) && requestedGeneration > 0 ? requestedGeneration : serverGenerationAtRequest;
|
|
26010
25437
|
if (isSameWorktreeRange(range)) {
|
|
26011
25438
|
return json2({
|
|
26012
25439
|
path,
|
|
@@ -26060,7 +25487,7 @@ async function handleFileDiff(url) {
|
|
|
26060
25487
|
errStatus = res.status ?? 500;
|
|
26061
25488
|
}
|
|
26062
25489
|
}
|
|
26063
|
-
if (!errText &&
|
|
25490
|
+
if (!errText && serverGenerationAtRequest === generation)
|
|
26064
25491
|
setTimedCacheEntry(fileCache, cacheKey, { diffText });
|
|
26065
25492
|
}
|
|
26066
25493
|
if (errStatus)
|
|
@@ -26085,8 +25512,8 @@ async function handleFileDiff(url) {
|
|
|
26085
25512
|
}
|
|
26086
25513
|
function worktreeLineIndexSignature(full) {
|
|
26087
25514
|
try {
|
|
26088
|
-
const
|
|
26089
|
-
return `size:${
|
|
25515
|
+
const stat3 = statSync6(full);
|
|
25516
|
+
return `size:${stat3.size}|mtime:${stat3.mtimeMs}|ctime:${stat3.ctimeMs}|ino:${stat3.ino || 0}`;
|
|
26090
25517
|
} catch {
|
|
26091
25518
|
return null;
|
|
26092
25519
|
}
|
|
@@ -26101,10 +25528,10 @@ async function getWorktreeLineIndex(full) {
|
|
|
26101
25528
|
lineIndexCache.set(full, cached);
|
|
26102
25529
|
return cached.index;
|
|
26103
25530
|
}
|
|
26104
|
-
const
|
|
26105
|
-
if (
|
|
25531
|
+
const stat3 = statSync6(full);
|
|
25532
|
+
if (stat3.size > LINE_INDEX_MAX_FILE_BYTES)
|
|
26106
25533
|
return null;
|
|
26107
|
-
const index = await buildLineOffsetIndexFromStream(fileReadableStream(full),
|
|
25534
|
+
const index = await buildLineOffsetIndexFromStream(fileReadableStream(full), stat3.size);
|
|
26108
25535
|
lineIndexCache.delete(full);
|
|
26109
25536
|
lineIndexCache.set(full, { signature, index });
|
|
26110
25537
|
while (lineIndexCache.size > 32) {
|
|
@@ -26476,11 +25903,11 @@ async function handleUploadFiles(req) {
|
|
|
26476
25903
|
const written = [];
|
|
26477
25904
|
try {
|
|
26478
25905
|
for (const upload of uploads) {
|
|
26479
|
-
const fd =
|
|
25906
|
+
const fd = openSync2(upload.target, uploadOpenFlags(), 420);
|
|
26480
25907
|
try {
|
|
26481
25908
|
writeFileSync2(fd, new Uint8Array(await upload.file.arrayBuffer()));
|
|
26482
25909
|
} finally {
|
|
26483
|
-
|
|
25910
|
+
closeSync2(fd);
|
|
26484
25911
|
}
|
|
26485
25912
|
written.push(upload.target);
|
|
26486
25913
|
}
|
|
@@ -26600,7 +26027,7 @@ function moveMacPathIntoTrash(path) {
|
|
|
26600
26027
|
}
|
|
26601
26028
|
}
|
|
26602
26029
|
async function movePathToTrash(path) {
|
|
26603
|
-
|
|
26030
|
+
lstatSync4(path);
|
|
26604
26031
|
if (process.platform === "darwin") {
|
|
26605
26032
|
return moveMacPathIntoTrash(path);
|
|
26606
26033
|
}
|
|
@@ -27393,7 +26820,7 @@ var init_preview = __esm(async () => {
|
|
|
27393
26820
|
init_state_store();
|
|
27394
26821
|
init_worktree_watcher();
|
|
27395
26822
|
WEB_ROOT = join20(ROOT, "web");
|
|
27396
|
-
VERSION = JSON.parse(
|
|
26823
|
+
VERSION = JSON.parse(readFileSync8(join20(ROOT, "package.json"), "utf8")).version;
|
|
27397
26824
|
DEFAULT_ARGS = ["HEAD"];
|
|
27398
26825
|
WATCHED_ASSET_FILES = ["index.html", "style.css", "app.js"];
|
|
27399
26826
|
LINE_INDEX_MAX_FILE_BYTES = 256 * 1024 * 1024;
|
|
@@ -27679,7 +27106,7 @@ if (process.argv[2] === "agent-help") {
|
|
|
27679
27106
|
await runFileCli2(process.argv.slice(3));
|
|
27680
27107
|
} else if (process.argv[2] === "status") {
|
|
27681
27108
|
const { runStatusCli: runStatusCli2 } = await Promise.resolve().then(() => (init_status_cli(), exports_status_cli));
|
|
27682
|
-
runStatusCli2(process.argv.slice(3));
|
|
27109
|
+
await runStatusCli2(process.argv.slice(3));
|
|
27683
27110
|
} else if (process.argv[2] === "skill") {
|
|
27684
27111
|
const { runSkillCli: runSkillCli2 } = await Promise.resolve().then(() => (init_skill_cli(), exports_skill_cli));
|
|
27685
27112
|
runSkillCli2(process.argv.slice(3));
|