codebase-snapshot 0.9.5 → 0.9.6
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/CHANGELOG.md +46 -0
- package/README.md +4 -1
- package/dist/bin.js +405 -203
- package/dist/{chunk-B336MMNC.js → chunk-3KUL3QRH.js} +379 -222
- package/dist/{chunk-4AHHSNGG.js → chunk-ZKZOGGM3.js} +33 -7
- package/dist/cli.cjs +508 -310
- package/dist/cli.d.cts +7 -1
- package/dist/cli.d.ts +7 -1
- package/dist/cli.js +16 -2
- package/dist/index.cjs +384 -215
- package/dist/index.d.cts +54 -2
- package/dist/index.d.ts +54 -2
- package/dist/index.js +1 -1
- package/dist/mcp.cjs +31 -4
- package/dist/mcp.d.cts +14 -1
- package/dist/mcp.d.ts +14 -1
- package/dist/mcp.js +2 -2
- package/docs/cli.md +19 -2
- package/docs/mcp.md +3 -3
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var childProcess = require('child_process');
|
|
4
|
-
var
|
|
5
|
-
var
|
|
4
|
+
var fs12 = require('fs');
|
|
5
|
+
var path13 = require('path');
|
|
6
6
|
var util = require('util');
|
|
7
7
|
var crypto2 = require('crypto');
|
|
8
8
|
var module$1 = require('module');
|
|
@@ -11,6 +11,7 @@ var readline = require('readline');
|
|
|
11
11
|
var async_hooks = require('async_hooks');
|
|
12
12
|
var os = require('os');
|
|
13
13
|
var ts = require('typescript');
|
|
14
|
+
var https = require('https');
|
|
14
15
|
|
|
15
16
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
17
|
|
|
@@ -33,12 +34,13 @@ function _interopNamespace(e) {
|
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
var childProcess__namespace = /*#__PURE__*/_interopNamespace(childProcess);
|
|
36
|
-
var
|
|
37
|
-
var
|
|
37
|
+
var fs12__namespace = /*#__PURE__*/_interopNamespace(fs12);
|
|
38
|
+
var path13__namespace = /*#__PURE__*/_interopNamespace(path13);
|
|
38
39
|
var crypto2__namespace = /*#__PURE__*/_interopNamespace(crypto2);
|
|
39
40
|
var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
|
|
40
41
|
var os__namespace = /*#__PURE__*/_interopNamespace(os);
|
|
41
42
|
var ts__default = /*#__PURE__*/_interopDefault(ts);
|
|
43
|
+
var https__namespace = /*#__PURE__*/_interopNamespace(https);
|
|
42
44
|
|
|
43
45
|
// src/cli.ts
|
|
44
46
|
var MANIFEST_FILES = [
|
|
@@ -87,15 +89,15 @@ var SKIPPED_WALK_DIRS = /* @__PURE__ */ new Set([
|
|
|
87
89
|
]);
|
|
88
90
|
function readSmallFile(fullPath) {
|
|
89
91
|
try {
|
|
90
|
-
const stats =
|
|
92
|
+
const stats = fs12__namespace.statSync(fullPath);
|
|
91
93
|
if (!stats.isFile() || stats.size > MANIFEST_MAX_BYTES) return null;
|
|
92
|
-
return
|
|
94
|
+
return fs12__namespace.readFileSync(fullPath, "utf8");
|
|
93
95
|
} catch {
|
|
94
96
|
return null;
|
|
95
97
|
}
|
|
96
98
|
}
|
|
97
99
|
function readManifest(cwd, name) {
|
|
98
|
-
return readSmallFile(
|
|
100
|
+
return readSmallFile(path13__namespace.join(cwd, name));
|
|
99
101
|
}
|
|
100
102
|
function dependenciesFromPackageJson(raw) {
|
|
101
103
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -155,7 +157,7 @@ function pnpmWorkspacePatterns(raw) {
|
|
|
155
157
|
function childDirectories(cwd, parent) {
|
|
156
158
|
let entries;
|
|
157
159
|
try {
|
|
158
|
-
entries =
|
|
160
|
+
entries = fs12__namespace.readdirSync(path13__namespace.join(cwd, parent), { withFileTypes: true });
|
|
159
161
|
} catch {
|
|
160
162
|
return [];
|
|
161
163
|
}
|
|
@@ -191,12 +193,12 @@ function scanWorkspacePackages(cwd, patterns) {
|
|
|
191
193
|
const files = /* @__PURE__ */ new Set();
|
|
192
194
|
const dependencies = /* @__PURE__ */ new Set();
|
|
193
195
|
for (const relative11 of workspacePackageDirs(cwd, patterns)) {
|
|
194
|
-
const full =
|
|
196
|
+
const full = path13__namespace.join(cwd, relative11);
|
|
195
197
|
try {
|
|
196
|
-
for (const entry of
|
|
198
|
+
for (const entry of fs12__namespace.readdirSync(full, { withFileTypes: true })) files.add(entry.name);
|
|
197
199
|
} catch {
|
|
198
200
|
}
|
|
199
|
-
const raw = readSmallFile(
|
|
201
|
+
const raw = readSmallFile(path13__namespace.join(full, "package.json"));
|
|
200
202
|
if (raw !== null) {
|
|
201
203
|
for (const name of dependenciesFromPackageJson(raw)) dependencies.add(name);
|
|
202
204
|
}
|
|
@@ -213,7 +215,7 @@ function countMarkdownFiles(cwd) {
|
|
|
213
215
|
directoriesSeen += 1;
|
|
214
216
|
let entries;
|
|
215
217
|
try {
|
|
216
|
-
entries =
|
|
218
|
+
entries = fs12__namespace.readdirSync(current.dir, { withFileTypes: true });
|
|
217
219
|
} catch {
|
|
218
220
|
continue;
|
|
219
221
|
}
|
|
@@ -224,7 +226,7 @@ function countMarkdownFiles(cwd) {
|
|
|
224
226
|
}
|
|
225
227
|
if (!entry.isDirectory() || current.depth >= 2) continue;
|
|
226
228
|
if (entry.name.startsWith(".") || SKIPPED_WALK_DIRS.has(entry.name)) continue;
|
|
227
|
-
queue.push({ dir:
|
|
229
|
+
queue.push({ dir: path13__namespace.join(current.dir, entry.name), depth: current.depth + 1 });
|
|
228
230
|
}
|
|
229
231
|
}
|
|
230
232
|
return count;
|
|
@@ -233,7 +235,7 @@ function buildPresetContext(cwd) {
|
|
|
233
235
|
const files = /* @__PURE__ */ new Set();
|
|
234
236
|
const dirs = /* @__PURE__ */ new Set();
|
|
235
237
|
try {
|
|
236
|
-
for (const entry of
|
|
238
|
+
for (const entry of fs12__namespace.readdirSync(cwd, { withFileTypes: true })) {
|
|
237
239
|
if (entry.isDirectory()) dirs.add(entry.name);
|
|
238
240
|
else if (entry.isFile()) files.add(entry.name);
|
|
239
241
|
}
|
|
@@ -250,7 +252,7 @@ function buildPresetContext(cwd) {
|
|
|
250
252
|
const isWorkspace = files.has("pnpm-workspace.yaml") || files.has("nx.json") || files.has("turbo.json") || files.has("lerna.json") || packageJson !== void 0 && packageJson.includes('"workspaces"') || declaredWorkspaces.length > 0;
|
|
251
253
|
let workspace = { files: /* @__PURE__ */ new Set(), dependencies: /* @__PURE__ */ new Set() };
|
|
252
254
|
if (isWorkspace) {
|
|
253
|
-
const pnpmRaw = files.has("pnpm-workspace.yaml") ? readSmallFile(
|
|
255
|
+
const pnpmRaw = files.has("pnpm-workspace.yaml") ? readSmallFile(path13__namespace.join(cwd, "pnpm-workspace.yaml")) : null;
|
|
254
256
|
const declared = pnpmRaw === null ? [] : pnpmWorkspacePatterns(pnpmRaw);
|
|
255
257
|
const patterns = declared.length > 0 ? declared : declaredWorkspaces.length > 0 ? declaredWorkspaces : DEFAULT_WORKSPACE_PATTERNS;
|
|
256
258
|
workspace = scanWorkspacePackages(cwd, patterns);
|
|
@@ -1525,14 +1527,14 @@ var PRESET_IGNORES = new Set(
|
|
|
1525
1527
|
);
|
|
1526
1528
|
function readLinkTarget(linkPath, fallback) {
|
|
1527
1529
|
try {
|
|
1528
|
-
return
|
|
1530
|
+
return fs12__namespace.readlinkSync(linkPath);
|
|
1529
1531
|
} catch {
|
|
1530
1532
|
return fallback;
|
|
1531
1533
|
}
|
|
1532
1534
|
}
|
|
1533
1535
|
function isInside(root, candidate) {
|
|
1534
|
-
const relative11 =
|
|
1535
|
-
return relative11 === "" || !relative11.startsWith(`..${
|
|
1536
|
+
const relative11 = path13__namespace.relative(root, candidate);
|
|
1537
|
+
return relative11 === "" || !relative11.startsWith(`..${path13__namespace.sep}`) && relative11 !== ".." && !path13__namespace.isAbsolute(relative11);
|
|
1536
1538
|
}
|
|
1537
1539
|
function getGitInfo(cwd, fallbackBranch = "main") {
|
|
1538
1540
|
try {
|
|
@@ -1737,10 +1739,10 @@ function trimUnescapedTrailingSpaces(line) {
|
|
|
1737
1739
|
return line.slice(0, end);
|
|
1738
1740
|
}
|
|
1739
1741
|
function readGitignoreRules(dir) {
|
|
1740
|
-
const gitignorePath2 =
|
|
1742
|
+
const gitignorePath2 = path13__namespace.join(dir, ".gitignore");
|
|
1741
1743
|
let raw;
|
|
1742
1744
|
try {
|
|
1743
|
-
raw =
|
|
1745
|
+
raw = fs12__namespace.readFileSync(gitignorePath2, "utf8");
|
|
1744
1746
|
} catch {
|
|
1745
1747
|
return [];
|
|
1746
1748
|
}
|
|
@@ -1867,7 +1869,7 @@ function isToolOwnedDirName(name) {
|
|
|
1867
1869
|
}
|
|
1868
1870
|
function hasSnapshotMarker(target) {
|
|
1869
1871
|
try {
|
|
1870
|
-
return
|
|
1872
|
+
return fs12__namespace.statSync(target).isDirectory() && fs12__namespace.existsSync(path13__namespace.join(target, ".codebase-snapshot"));
|
|
1871
1873
|
} catch {
|
|
1872
1874
|
return false;
|
|
1873
1875
|
}
|
|
@@ -1881,7 +1883,7 @@ function makeToolOwnedDecider(cwd, toolOwnedPaths) {
|
|
|
1881
1883
|
const prefix = parts.slice(0, depth).join("/");
|
|
1882
1884
|
let hasMarker = markers.get(prefix);
|
|
1883
1885
|
if (hasMarker === void 0) {
|
|
1884
|
-
hasMarker =
|
|
1886
|
+
hasMarker = fs12__namespace.existsSync(path13__namespace.join(cwd, prefix, ".codebase-snapshot"));
|
|
1885
1887
|
markers.set(prefix, hasMarker);
|
|
1886
1888
|
}
|
|
1887
1889
|
if (hasMarker) return true;
|
|
@@ -1896,7 +1898,7 @@ function makeLinkProbe() {
|
|
|
1896
1898
|
let known = cache.get(absolutePath);
|
|
1897
1899
|
if (known === void 0) {
|
|
1898
1900
|
try {
|
|
1899
|
-
known =
|
|
1901
|
+
known = fs12__namespace.lstatSync(absolutePath).isSymbolicLink();
|
|
1900
1902
|
} catch {
|
|
1901
1903
|
known = false;
|
|
1902
1904
|
}
|
|
@@ -1909,7 +1911,7 @@ function dropLinkedDirectories(cwd, candidates, skipped) {
|
|
|
1909
1911
|
const isLink = makeLinkProbe();
|
|
1910
1912
|
let rootReal = cwd;
|
|
1911
1913
|
try {
|
|
1912
|
-
rootReal =
|
|
1914
|
+
rootReal = fs12__namespace.realpathSync(cwd);
|
|
1913
1915
|
} catch {
|
|
1914
1916
|
}
|
|
1915
1917
|
const reported = /* @__PURE__ */ new Set();
|
|
@@ -1919,7 +1921,7 @@ function dropLinkedDirectories(cwd, candidates, skipped) {
|
|
|
1919
1921
|
let linkedDir = null;
|
|
1920
1922
|
for (let depth = 1; depth <= parts.length; depth += 1) {
|
|
1921
1923
|
const prefix = parts.slice(0, depth).join("/");
|
|
1922
|
-
if (isLink(
|
|
1924
|
+
if (isLink(path13__namespace.join(cwd, prefix))) {
|
|
1923
1925
|
linkedDir = prefix;
|
|
1924
1926
|
break;
|
|
1925
1927
|
}
|
|
@@ -1930,10 +1932,10 @@ function dropLinkedDirectories(cwd, candidates, skipped) {
|
|
|
1930
1932
|
}
|
|
1931
1933
|
if (reported.has(linkedDir)) continue;
|
|
1932
1934
|
reported.add(linkedDir);
|
|
1933
|
-
const absolute =
|
|
1935
|
+
const absolute = path13__namespace.join(cwd, linkedDir);
|
|
1934
1936
|
let targetReal = absolute;
|
|
1935
1937
|
try {
|
|
1936
|
-
targetReal =
|
|
1938
|
+
targetReal = fs12__namespace.realpathSync(absolute);
|
|
1937
1939
|
} catch {
|
|
1938
1940
|
}
|
|
1939
1941
|
const target = readLinkTarget(absolute, targetReal);
|
|
@@ -2010,7 +2012,7 @@ function collectFiles(cwd, options = {}) {
|
|
|
2010
2012
|
"Discovery mode is `git`, but git could not list this directory's files. Run inside a working repository, or pass --discovery walk (or auto) to scan the tree directly."
|
|
2011
2013
|
);
|
|
2012
2014
|
}
|
|
2013
|
-
if (
|
|
2015
|
+
if (fs12__namespace.existsSync(path13__namespace.join(cwd, ".git"))) {
|
|
2014
2016
|
throw new Error(
|
|
2015
2017
|
"This directory is a git repository, but git could not list its files. A plain walk honours .gitignore files, but git also applies .git/info/exclude and your global excludes file, includes files that are tracked although a .gitignore now matches them, and treats a submodule as a single entry. Fix the repository (git status should work), run outside git, or pass --discovery walk to accept those differences."
|
|
2016
2018
|
);
|
|
@@ -2069,7 +2071,7 @@ function collectFiles(cwd, options = {}) {
|
|
|
2069
2071
|
}
|
|
2070
2072
|
function rootRealFor(root) {
|
|
2071
2073
|
try {
|
|
2072
|
-
return
|
|
2074
|
+
return fs12__namespace.realpathSync(root);
|
|
2073
2075
|
} catch {
|
|
2074
2076
|
return root;
|
|
2075
2077
|
}
|
|
@@ -2077,18 +2079,18 @@ function rootRealFor(root) {
|
|
|
2077
2079
|
function walkDirectory(dir, baseDir, rootReal, visited, reservedPaths = /* @__PURE__ */ new Set(), parentGitignoreLayers = []) {
|
|
2078
2080
|
const results = { files: [], skipped: [] };
|
|
2079
2081
|
const stack = [];
|
|
2080
|
-
const relativeToBase = (target) =>
|
|
2082
|
+
const relativeToBase = (target) => path13__namespace.relative(baseDir, target).replace(/\\/g, "/") || ".";
|
|
2081
2083
|
const enter = (current, layers) => {
|
|
2082
2084
|
if (visited.has(current)) return false;
|
|
2083
2085
|
visited.add(current);
|
|
2084
2086
|
const localRules = readGitignoreRules(current);
|
|
2085
2087
|
const gitignoreLayers = localRules.length === 0 ? layers : [
|
|
2086
2088
|
...layers,
|
|
2087
|
-
{ prefix:
|
|
2089
|
+
{ prefix: path13__namespace.relative(baseDir, current).replace(/\\/g, "/"), rules: localRules }
|
|
2088
2090
|
];
|
|
2089
2091
|
let entries;
|
|
2090
2092
|
try {
|
|
2091
|
-
entries =
|
|
2093
|
+
entries = fs12__namespace.readdirSync(current, { withFileTypes: true });
|
|
2092
2094
|
} catch {
|
|
2093
2095
|
results.skipped.push({
|
|
2094
2096
|
path: relativeToBase(current),
|
|
@@ -2110,8 +2112,8 @@ function walkDirectory(dir, baseDir, rootReal, visited, reservedPaths = /* @__PU
|
|
|
2110
2112
|
}
|
|
2111
2113
|
const entry = frame.entries[frame.index];
|
|
2112
2114
|
frame.index += 1;
|
|
2113
|
-
const fullPath =
|
|
2114
|
-
const relPath =
|
|
2115
|
+
const fullPath = path13__namespace.join(frame.dir, entry.name);
|
|
2116
|
+
const relPath = path13__namespace.relative(baseDir, fullPath).replace(/\\/g, "/");
|
|
2115
2117
|
if (isToolOwnedDirName(entry.name) && reservedPaths.has(relPath)) continue;
|
|
2116
2118
|
if (DEFAULT_IGNORED_DIRS.includes(entry.name)) {
|
|
2117
2119
|
results.skipped.push({
|
|
@@ -2144,14 +2146,14 @@ function walkDirectory(dir, baseDir, rootReal, visited, reservedPaths = /* @__PU
|
|
|
2144
2146
|
if (entry.isSymbolicLink()) {
|
|
2145
2147
|
let targetReal;
|
|
2146
2148
|
try {
|
|
2147
|
-
targetReal =
|
|
2149
|
+
targetReal = fs12__namespace.realpathSync(fullPath);
|
|
2148
2150
|
} catch {
|
|
2149
2151
|
results.skipped.push({ path: relPath, reason: "read-error", detail: "broken symlink" });
|
|
2150
2152
|
continue;
|
|
2151
2153
|
}
|
|
2152
2154
|
let stats;
|
|
2153
2155
|
try {
|
|
2154
|
-
stats =
|
|
2156
|
+
stats = fs12__namespace.statSync(fullPath);
|
|
2155
2157
|
} catch {
|
|
2156
2158
|
results.skipped.push({ path: relPath, reason: "read-error", detail: "unreadable symlink" });
|
|
2157
2159
|
continue;
|
|
@@ -2204,13 +2206,13 @@ var CONFIG_FILENAMES = [
|
|
|
2204
2206
|
];
|
|
2205
2207
|
function findConfigFile(cwd) {
|
|
2206
2208
|
for (const filename of CONFIG_FILENAMES) {
|
|
2207
|
-
const fullPath =
|
|
2208
|
-
if (
|
|
2209
|
+
const fullPath = path13__namespace.join(cwd, filename);
|
|
2210
|
+
if (fs12__namespace.existsSync(fullPath)) return fullPath;
|
|
2209
2211
|
}
|
|
2210
|
-
const pkgJsonPath =
|
|
2211
|
-
if (!
|
|
2212
|
+
const pkgJsonPath = path13__namespace.join(cwd, "package.json");
|
|
2213
|
+
if (!fs12__namespace.existsSync(pkgJsonPath)) return null;
|
|
2212
2214
|
try {
|
|
2213
|
-
const parsed = JSON.parse(
|
|
2215
|
+
const parsed = JSON.parse(fs12__namespace.readFileSync(pkgJsonPath, "utf8"));
|
|
2214
2216
|
return parsed.snapshot === void 0 ? null : pkgJsonPath;
|
|
2215
2217
|
} catch {
|
|
2216
2218
|
return null;
|
|
@@ -2461,11 +2463,11 @@ async function loadConfigFileDetailed(cwd) {
|
|
|
2461
2463
|
const warnings = [];
|
|
2462
2464
|
const errors = [];
|
|
2463
2465
|
for (const filename of CONFIG_FILENAMES) {
|
|
2464
|
-
const fullPath =
|
|
2465
|
-
if (!
|
|
2466
|
+
const fullPath = path13__namespace.join(cwd, filename);
|
|
2467
|
+
if (!fs12__namespace.existsSync(fullPath)) continue;
|
|
2466
2468
|
if (filename.endsWith(".json") || filename === ".snapshotrc") {
|
|
2467
2469
|
try {
|
|
2468
|
-
const config = parseJsonish(
|
|
2470
|
+
const config = parseJsonish(fs12__namespace.readFileSync(fullPath, "utf8"), fullPath);
|
|
2469
2471
|
if (config === null || typeof config !== "object" || Array.isArray(config)) {
|
|
2470
2472
|
throw new Error(
|
|
2471
2473
|
`${fullPath} does not hold a configuration object (received ${describeValue2(config)}).`
|
|
@@ -2499,10 +2501,10 @@ async function loadConfigFileDetailed(cwd) {
|
|
|
2499
2501
|
continue;
|
|
2500
2502
|
}
|
|
2501
2503
|
}
|
|
2502
|
-
const pkgJsonPath =
|
|
2503
|
-
if (
|
|
2504
|
+
const pkgJsonPath = path13__namespace.join(cwd, "package.json");
|
|
2505
|
+
if (fs12__namespace.existsSync(pkgJsonPath)) {
|
|
2504
2506
|
try {
|
|
2505
|
-
const parsed = parseJsonish(
|
|
2507
|
+
const parsed = parseJsonish(fs12__namespace.readFileSync(pkgJsonPath, "utf8"), pkgJsonPath);
|
|
2506
2508
|
const snapshotKey = parsed.snapshot;
|
|
2507
2509
|
if (snapshotKey && typeof snapshotKey === "object" && !Array.isArray(snapshotKey)) {
|
|
2508
2510
|
return { config: snapshotKey, file: pkgJsonPath, warnings, errors };
|
|
@@ -2670,9 +2672,9 @@ function resolveKindRules(value) {
|
|
|
2670
2672
|
function outputExcludePatterns(cwd, outDir, tmpDir) {
|
|
2671
2673
|
const patterns = [];
|
|
2672
2674
|
for (const dir of [outDir, tmpDir]) {
|
|
2673
|
-
const absolute =
|
|
2674
|
-
const relative11 =
|
|
2675
|
-
if (!relative11 || relative11 === ".." || relative11.startsWith(`..${
|
|
2675
|
+
const absolute = path13__namespace.resolve(cwd, dir);
|
|
2676
|
+
const relative11 = path13__namespace.relative(cwd, absolute);
|
|
2677
|
+
if (!relative11 || relative11 === ".." || relative11.startsWith(`..${path13__namespace.sep}`) || path13__namespace.isAbsolute(relative11)) {
|
|
2676
2678
|
continue;
|
|
2677
2679
|
}
|
|
2678
2680
|
patterns.push(`${relative11.replace(/\\/g, "/")}/**`);
|
|
@@ -2791,11 +2793,11 @@ function resolveCandidateCwd(userConfig, cliOptions, baseDir) {
|
|
|
2791
2793
|
);
|
|
2792
2794
|
}
|
|
2793
2795
|
const candidate = cliOptions?.cwd || userConfig?.cwd || baseDir || process.cwd();
|
|
2794
|
-
const resolved =
|
|
2795
|
-
if (!
|
|
2796
|
+
const resolved = path13__namespace.resolve(candidate);
|
|
2797
|
+
if (!fs12__namespace.existsSync(resolved)) {
|
|
2796
2798
|
throw new Error(`Working directory does not exist: ${resolved}`);
|
|
2797
2799
|
}
|
|
2798
|
-
if (!
|
|
2800
|
+
if (!fs12__namespace.statSync(resolved).isDirectory()) {
|
|
2799
2801
|
throw new Error(`Working directory is not a directory: ${resolved}`);
|
|
2800
2802
|
}
|
|
2801
2803
|
return resolved;
|
|
@@ -3021,7 +3023,7 @@ var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
3021
3023
|
".so"
|
|
3022
3024
|
]);
|
|
3023
3025
|
function isBinaryExtension(filePath) {
|
|
3024
|
-
const ext =
|
|
3026
|
+
const ext = path13__namespace.extname(filePath).toLowerCase();
|
|
3025
3027
|
return BINARY_EXTENSIONS.has(ext);
|
|
3026
3028
|
}
|
|
3027
3029
|
function countControlBytes(buffer) {
|
|
@@ -3188,13 +3190,13 @@ function isBinaryFile(absolutePath) {
|
|
|
3188
3190
|
if (isBinaryExtension(absolutePath)) return true;
|
|
3189
3191
|
let fd;
|
|
3190
3192
|
try {
|
|
3191
|
-
fd =
|
|
3193
|
+
fd = fs12__namespace.openSync(absolutePath, "r");
|
|
3192
3194
|
const buffer = Buffer.alloc(CHUNK);
|
|
3193
3195
|
let sample;
|
|
3194
3196
|
let position = 0;
|
|
3195
3197
|
while (position < BINARY_SCAN_BYTES) {
|
|
3196
3198
|
const wanted = Math.min(CHUNK, BINARY_SCAN_BYTES - position);
|
|
3197
|
-
const bytesRead =
|
|
3199
|
+
const bytesRead = fs12__namespace.readSync(fd, buffer, 0, wanted, position);
|
|
3198
3200
|
if (bytesRead === 0) return false;
|
|
3199
3201
|
const chunk = buffer.subarray(0, bytesRead);
|
|
3200
3202
|
if (sample === void 0) {
|
|
@@ -3212,7 +3214,7 @@ function isBinaryFile(absolutePath) {
|
|
|
3212
3214
|
} finally {
|
|
3213
3215
|
if (fd !== void 0) {
|
|
3214
3216
|
try {
|
|
3215
|
-
|
|
3217
|
+
fs12__namespace.closeSync(fd);
|
|
3216
3218
|
} catch {
|
|
3217
3219
|
}
|
|
3218
3220
|
}
|
|
@@ -3225,33 +3227,33 @@ function maskedPath(value, secretRules) {
|
|
|
3225
3227
|
}
|
|
3226
3228
|
function confineToDirectory(directory, filename) {
|
|
3227
3229
|
if (filename.includes("\0")) return null;
|
|
3228
|
-
if (
|
|
3229
|
-
const base =
|
|
3230
|
-
const resolved =
|
|
3230
|
+
if (path13__namespace.isAbsolute(filename)) return null;
|
|
3231
|
+
const base = path13__namespace.resolve(directory);
|
|
3232
|
+
const resolved = path13__namespace.resolve(base, filename);
|
|
3231
3233
|
const caseInsensitive = process.platform === "win32" || process.platform === "darwin";
|
|
3232
|
-
const prefix = caseInsensitive ? `${base}${
|
|
3234
|
+
const prefix = caseInsensitive ? `${base}${path13__namespace.sep}`.toLowerCase() : `${base}${path13__namespace.sep}`;
|
|
3233
3235
|
const candidate = caseInsensitive ? resolved.toLowerCase() : resolved;
|
|
3234
3236
|
return candidate.startsWith(prefix) ? resolved : null;
|
|
3235
3237
|
}
|
|
3236
3238
|
function findStagingDirectory(config) {
|
|
3237
|
-
const tmpDir =
|
|
3239
|
+
const tmpDir = path13__namespace.resolve(config.cwd, config.tmpDir);
|
|
3238
3240
|
let entries;
|
|
3239
3241
|
try {
|
|
3240
|
-
entries =
|
|
3242
|
+
entries = fs12__namespace.readdirSync(tmpDir);
|
|
3241
3243
|
} catch {
|
|
3242
3244
|
return null;
|
|
3243
3245
|
}
|
|
3244
3246
|
const runs = entries.filter((name) => name.startsWith("run-")).sort();
|
|
3245
3247
|
const newest = runs[runs.length - 1];
|
|
3246
|
-
return newest ?
|
|
3248
|
+
return newest ? path13__namespace.join(tmpDir, newest) : null;
|
|
3247
3249
|
}
|
|
3248
3250
|
function describeMissingManifest(config, manifestPath) {
|
|
3249
|
-
const outDir =
|
|
3250
|
-
const markerPath =
|
|
3251
|
+
const outDir = path13__namespace.resolve(config.cwd, config.outDir);
|
|
3252
|
+
const markerPath = path13__namespace.join(outDir, ".codebase-snapshot");
|
|
3251
3253
|
let marker2 = null;
|
|
3252
3254
|
try {
|
|
3253
|
-
if (
|
|
3254
|
-
const parsed = JSON.parse(
|
|
3255
|
+
if (fs12__namespace.existsSync(markerPath)) {
|
|
3256
|
+
const parsed = JSON.parse(fs12__namespace.readFileSync(markerPath, "utf8"));
|
|
3255
3257
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
3256
3258
|
marker2 = parsed;
|
|
3257
3259
|
}
|
|
@@ -3287,14 +3289,14 @@ function sha256Hex(buffer) {
|
|
|
3287
3289
|
}
|
|
3288
3290
|
var VERIFY_SNIFF_MAX_BYTES = 8 * 1024 * 1024;
|
|
3289
3291
|
function wouldNowBeIncluded(cwd, relativePath, reason) {
|
|
3290
|
-
const absolutePath =
|
|
3292
|
+
const absolutePath = path13__namespace.join(cwd, relativePath);
|
|
3291
3293
|
try {
|
|
3292
|
-
const stats =
|
|
3294
|
+
const stats = fs12__namespace.statSync(absolutePath);
|
|
3293
3295
|
if (!stats.isFile()) return false;
|
|
3294
3296
|
if (isBinaryFile(absolutePath)) return false;
|
|
3295
3297
|
if (reason !== "binary") return true;
|
|
3296
3298
|
if (stats.size > VERIFY_SNIFF_MAX_BYTES) return false;
|
|
3297
|
-
return !decodeText(
|
|
3299
|
+
return !decodeText(fs12__namespace.readFileSync(absolutePath)).binary;
|
|
3298
3300
|
} catch {
|
|
3299
3301
|
return false;
|
|
3300
3302
|
}
|
|
@@ -3352,8 +3354,8 @@ function describeManifestShapeProblem(value) {
|
|
|
3352
3354
|
function validateSnapshot(configInput) {
|
|
3353
3355
|
assertUsableConfigInput(configInput);
|
|
3354
3356
|
const config = isResolvedConfig(configInput) ? normalizeResolvedConfig(configInput) : resolveConfig(configInput);
|
|
3355
|
-
const manifestPath =
|
|
3356
|
-
if (!
|
|
3357
|
+
const manifestPath = path13__namespace.resolve(config.cwd, config.outDir, "manifest.json");
|
|
3358
|
+
if (!fs12__namespace.existsSync(manifestPath)) {
|
|
3357
3359
|
return {
|
|
3358
3360
|
valid: false,
|
|
3359
3361
|
manifestPresent: false,
|
|
@@ -3364,7 +3366,7 @@ function validateSnapshot(configInput) {
|
|
|
3364
3366
|
}
|
|
3365
3367
|
let manifest;
|
|
3366
3368
|
try {
|
|
3367
|
-
manifest = JSON.parse(
|
|
3369
|
+
manifest = JSON.parse(fs12__namespace.readFileSync(manifestPath, "utf8"));
|
|
3368
3370
|
} catch (err) {
|
|
3369
3371
|
return {
|
|
3370
3372
|
valid: false,
|
|
@@ -3386,7 +3388,7 @@ function validateSnapshot(configInput) {
|
|
|
3386
3388
|
}
|
|
3387
3389
|
const drift = emptyDrift();
|
|
3388
3390
|
const warnings = [];
|
|
3389
|
-
const snapshotDir =
|
|
3391
|
+
const snapshotDir = path13__namespace.resolve(config.cwd, config.outDir);
|
|
3390
3392
|
const manifestFileMap = /* @__PURE__ */ new Map();
|
|
3391
3393
|
for (const file of manifest.files) {
|
|
3392
3394
|
if (file && typeof file.relativePath === "string") {
|
|
@@ -3420,7 +3422,7 @@ function validateSnapshot(configInput) {
|
|
|
3420
3422
|
}
|
|
3421
3423
|
let diskHash;
|
|
3422
3424
|
try {
|
|
3423
|
-
diskHash = sha256Hex(
|
|
3425
|
+
diskHash = sha256Hex(fs12__namespace.readFileSync(path13__namespace.join(config.cwd, diskFile)));
|
|
3424
3426
|
} catch (err) {
|
|
3425
3427
|
if (err.code === "ENOENT") {
|
|
3426
3428
|
drift.missingOnDisk.push(diskFile);
|
|
@@ -3444,7 +3446,7 @@ function validateSnapshot(configInput) {
|
|
|
3444
3446
|
}
|
|
3445
3447
|
let statFailure = null;
|
|
3446
3448
|
try {
|
|
3447
|
-
|
|
3449
|
+
fs12__namespace.statSync(confined);
|
|
3448
3450
|
} catch (err) {
|
|
3449
3451
|
statFailure = err;
|
|
3450
3452
|
}
|
|
@@ -3464,7 +3466,7 @@ function validateSnapshot(configInput) {
|
|
|
3464
3466
|
...Object.values(config.budgets.byLayer)
|
|
3465
3467
|
);
|
|
3466
3468
|
const partNames = /* @__PURE__ */ new Set();
|
|
3467
|
-
const partsDir =
|
|
3469
|
+
const partsDir = path13__namespace.join(snapshotDir, "parts");
|
|
3468
3470
|
for (const part of manifest.parts) {
|
|
3469
3471
|
if (!part || typeof part.filename !== "string") continue;
|
|
3470
3472
|
partNames.add(part.filename);
|
|
@@ -3479,7 +3481,7 @@ function validateSnapshot(configInput) {
|
|
|
3479
3481
|
}
|
|
3480
3482
|
let buffer;
|
|
3481
3483
|
try {
|
|
3482
|
-
buffer =
|
|
3484
|
+
buffer = fs12__namespace.readFileSync(partPath);
|
|
3483
3485
|
} catch {
|
|
3484
3486
|
drift.partIssues.push({ part: part.filename, issue: "missing from snapshot/parts" });
|
|
3485
3487
|
continue;
|
|
@@ -3693,9 +3695,9 @@ function validateSnapshot(configInput) {
|
|
|
3693
3695
|
["full-codebase.md", manifest.artifacts?.fullMarkdown]
|
|
3694
3696
|
]) {
|
|
3695
3697
|
if (!artifact) continue;
|
|
3696
|
-
const artifactPath =
|
|
3698
|
+
const artifactPath = path13__namespace.join(snapshotDir, key);
|
|
3697
3699
|
try {
|
|
3698
|
-
const buffer =
|
|
3700
|
+
const buffer = fs12__namespace.readFileSync(artifactPath);
|
|
3699
3701
|
if (sha256Hex(buffer) !== artifact.sha256 || buffer.length !== artifact.byteSize) {
|
|
3700
3702
|
drift.partIssues.push({ part: key, issue: "artifact does not match its recorded digest" });
|
|
3701
3703
|
}
|
|
@@ -3956,14 +3958,14 @@ function compareManifests(before, after) {
|
|
|
3956
3958
|
function loadManifest(target) {
|
|
3957
3959
|
let isDirectory;
|
|
3958
3960
|
try {
|
|
3959
|
-
isDirectory =
|
|
3961
|
+
isDirectory = fs12__namespace.statSync(target).isDirectory();
|
|
3960
3962
|
} catch {
|
|
3961
3963
|
throw new Error(`No snapshot found at ${target}: the path does not exist.`);
|
|
3962
3964
|
}
|
|
3963
|
-
const manifestPath = isDirectory ?
|
|
3965
|
+
const manifestPath = isDirectory ? path13__namespace.join(target, "manifest.json") : target;
|
|
3964
3966
|
let raw;
|
|
3965
3967
|
try {
|
|
3966
|
-
raw =
|
|
3968
|
+
raw = fs12__namespace.readFileSync(manifestPath, "utf8");
|
|
3967
3969
|
} catch {
|
|
3968
3970
|
throw new Error(`Could not read a manifest at ${manifestPath}.`);
|
|
3969
3971
|
}
|
|
@@ -4114,10 +4116,10 @@ var LANGUAGE_BY_BASENAME = {
|
|
|
4114
4116
|
};
|
|
4115
4117
|
function detectLanguage(filePath) {
|
|
4116
4118
|
const normalized = filePath.replace(/\\/g, "/");
|
|
4117
|
-
const base =
|
|
4119
|
+
const base = path13__namespace.posix.basename(normalized);
|
|
4118
4120
|
if (LANGUAGE_BY_BASENAME[base]) return LANGUAGE_BY_BASENAME[base];
|
|
4119
4121
|
if (base === ".env" || base.startsWith(".env.")) return "dotenv";
|
|
4120
|
-
const ext =
|
|
4122
|
+
const ext = path13__namespace.posix.extname(base).toLowerCase();
|
|
4121
4123
|
return LANGUAGE_BY_EXTENSION[ext] ?? "text";
|
|
4122
4124
|
}
|
|
4123
4125
|
|
|
@@ -4159,10 +4161,10 @@ function describeMatcher(matcher) {
|
|
|
4159
4161
|
return String(matcher);
|
|
4160
4162
|
}
|
|
4161
4163
|
function normalizeTarget(cwd, target) {
|
|
4162
|
-
const absolute =
|
|
4163
|
-
const relative11 =
|
|
4164
|
-
if (relative11.startsWith("..") ||
|
|
4165
|
-
return relative11.split(
|
|
4164
|
+
const absolute = path13__namespace.resolve(cwd, target);
|
|
4165
|
+
const relative11 = path13__namespace.relative(cwd, absolute);
|
|
4166
|
+
if (relative11.startsWith("..") || path13__namespace.isAbsolute(relative11)) return target;
|
|
4167
|
+
return relative11.split(path13__namespace.sep).join("/");
|
|
4166
4168
|
}
|
|
4167
4169
|
function findRuleMatch(rules, relativePath) {
|
|
4168
4170
|
return rules.find(
|
|
@@ -4181,20 +4183,20 @@ function findRecordedAncestor(skipped, relative11, maskedPath2) {
|
|
|
4181
4183
|
return nearest;
|
|
4182
4184
|
}
|
|
4183
4185
|
function readManifest2(config) {
|
|
4184
|
-
const manifestPath =
|
|
4186
|
+
const manifestPath = path13__namespace.resolve(config.cwd, config.outDir, "manifest.json");
|
|
4185
4187
|
try {
|
|
4186
|
-
return JSON.parse(
|
|
4188
|
+
return JSON.parse(fs12__namespace.readFileSync(manifestPath, "utf8"));
|
|
4187
4189
|
} catch {
|
|
4188
4190
|
return null;
|
|
4189
4191
|
}
|
|
4190
4192
|
}
|
|
4191
4193
|
function explainPath(config, target) {
|
|
4192
4194
|
const relative11 = normalizeTarget(config.cwd, target);
|
|
4193
|
-
const absolute =
|
|
4195
|
+
const absolute = path13__namespace.join(config.cwd, relative11);
|
|
4194
4196
|
const maskedPath2 = findSecretInPath(relative11, config.secretRules)?.masked ?? relative11;
|
|
4195
4197
|
const result = {
|
|
4196
4198
|
path: maskedPath2,
|
|
4197
|
-
exists:
|
|
4199
|
+
exists: fs12__namespace.existsSync(absolute),
|
|
4198
4200
|
included: false
|
|
4199
4201
|
};
|
|
4200
4202
|
const collection = collectFiles(config.cwd, {
|
|
@@ -4205,7 +4207,7 @@ function explainPath(config, target) {
|
|
|
4205
4207
|
// Same exclusion `generate` applies, so `explain` never says "not-discovered" about a file
|
|
4206
4208
|
// that is only missing because the walker dropped the tool's own output directory.
|
|
4207
4209
|
toolOwnedPaths: [config.outDir, config.tmpDir].map(
|
|
4208
|
-
(directory) =>
|
|
4210
|
+
(directory) => path13__namespace.relative(config.cwd, path13__namespace.resolve(config.cwd, directory)).replace(/\\/g, "/")
|
|
4209
4211
|
).filter((relative12) => relative12.length > 0 && !relative12.startsWith(".."))
|
|
4210
4212
|
});
|
|
4211
4213
|
if (!collection.files.includes(relative11)) {
|
|
@@ -4244,8 +4246,8 @@ function explainPath(config, target) {
|
|
|
4244
4246
|
if (layerRule) result.layerMatch = describeMatcher(layerRule.match);
|
|
4245
4247
|
const kindRule = findRuleMatch(config.kinds, relative11);
|
|
4246
4248
|
if (kindRule) result.kindMatch = describeMatcher(kindRule.match);
|
|
4247
|
-
if (
|
|
4248
|
-
const buffer =
|
|
4249
|
+
if (fs12__namespace.existsSync(absolute) && fs12__namespace.statSync(absolute).isFile()) {
|
|
4250
|
+
const buffer = fs12__namespace.readFileSync(absolute);
|
|
4249
4251
|
const decoded = decodeText(buffer);
|
|
4250
4252
|
if (decoded.binary) {
|
|
4251
4253
|
result.included = false;
|
|
@@ -4304,15 +4306,15 @@ function renderExplainText(result) {
|
|
|
4304
4306
|
function appendGitignoreEntries(cwd, entries) {
|
|
4305
4307
|
const wanted = [...new Set(entries)].filter((entry) => entry.trim().length > 0);
|
|
4306
4308
|
if (wanted.length === 0) return { added: [], note: null };
|
|
4307
|
-
const ignorePath =
|
|
4309
|
+
const ignorePath = path13__namespace.join(cwd, ".gitignore");
|
|
4308
4310
|
const manual = `Add ${wanted.map((entry) => `"${entry}"`).join(" and ")} to your .gitignore yourself.`;
|
|
4309
4311
|
let existing = "";
|
|
4310
4312
|
try {
|
|
4311
|
-
if (
|
|
4312
|
-
if (
|
|
4313
|
+
if (fs12__namespace.existsSync(ignorePath)) {
|
|
4314
|
+
if (fs12__namespace.statSync(ignorePath).isDirectory()) {
|
|
4313
4315
|
return { added: [], note: `${ignorePath} is a directory, so it was not updated. ${manual}` };
|
|
4314
4316
|
}
|
|
4315
|
-
existing =
|
|
4317
|
+
existing = fs12__namespace.readFileSync(ignorePath, "utf8");
|
|
4316
4318
|
}
|
|
4317
4319
|
} catch (err) {
|
|
4318
4320
|
return {
|
|
@@ -4325,7 +4327,7 @@ function appendGitignoreEntries(cwd, entries) {
|
|
|
4325
4327
|
if (added.length === 0) return { added: [], note: null };
|
|
4326
4328
|
const prefix = existing.length === 0 || existing.endsWith("\n") ? "" : "\n";
|
|
4327
4329
|
try {
|
|
4328
|
-
|
|
4330
|
+
fs12__namespace.writeFileSync(ignorePath, `${existing}${prefix}${added.join("\n")}
|
|
4329
4331
|
`, "utf8");
|
|
4330
4332
|
} catch (err) {
|
|
4331
4333
|
return { added: [], note: `${err.message}. ${manual}` };
|
|
@@ -4333,12 +4335,12 @@ function appendGitignoreEntries(cwd, entries) {
|
|
|
4333
4335
|
return { added, note: null };
|
|
4334
4336
|
}
|
|
4335
4337
|
function gitignorePath(cwd, filePath) {
|
|
4336
|
-
return
|
|
4338
|
+
return path13__namespace.relative(cwd, filePath).split(path13__namespace.sep).join("/");
|
|
4337
4339
|
}
|
|
4338
4340
|
|
|
4339
4341
|
// src/version.ts
|
|
4340
4342
|
var GENERATOR_NAME = "codebase-snapshot";
|
|
4341
|
-
var GENERATOR_VERSION = "0.9.
|
|
4343
|
+
var GENERATOR_VERSION = "0.9.6";
|
|
4342
4344
|
var LEGACY_GENERATOR_NAMES = ["@ankurhalder/codebase-snapshot"];
|
|
4343
4345
|
function isOurGeneratorName(name) {
|
|
4344
4346
|
if (typeof name !== "string") return false;
|
|
@@ -4760,10 +4762,10 @@ var CONFIG_CANDIDATES = [
|
|
|
4760
4762
|
];
|
|
4761
4763
|
function chooseConfigFileName(cwd) {
|
|
4762
4764
|
if (!supportsTypeScriptImports()) return "snapshot.config.mjs";
|
|
4763
|
-
const pkgPath =
|
|
4764
|
-
if (!
|
|
4765
|
+
const pkgPath = path13__namespace.join(cwd, "package.json");
|
|
4766
|
+
if (!fs12__namespace.existsSync(pkgPath)) return "snapshot.config.mjs";
|
|
4765
4767
|
try {
|
|
4766
|
-
const parsed = JSON.parse(
|
|
4768
|
+
const parsed = JSON.parse(fs12__namespace.readFileSync(pkgPath, "utf8"));
|
|
4767
4769
|
return parsed.type === "module" ? "snapshot.config.ts" : "snapshot.config.mjs";
|
|
4768
4770
|
} catch {
|
|
4769
4771
|
return "snapshot.config.mjs";
|
|
@@ -4777,7 +4779,7 @@ var SIZE_CHOICES = [
|
|
|
4777
4779
|
];
|
|
4778
4780
|
function packageJsonHasConfig(cwd) {
|
|
4779
4781
|
try {
|
|
4780
|
-
const parsed = JSON.parse(
|
|
4782
|
+
const parsed = JSON.parse(fs12__namespace.readFileSync(path13__namespace.join(cwd, "package.json"), "utf8"));
|
|
4781
4783
|
return typeof parsed.snapshot === "object" && parsed.snapshot !== null && !Array.isArray(parsed.snapshot);
|
|
4782
4784
|
} catch {
|
|
4783
4785
|
return false;
|
|
@@ -4798,7 +4800,7 @@ function artifactAnswers(options) {
|
|
|
4798
4800
|
}
|
|
4799
4801
|
function topLevelDirs(cwd) {
|
|
4800
4802
|
try {
|
|
4801
|
-
return
|
|
4803
|
+
return fs12__namespace.readdirSync(cwd, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules").map((entry) => entry.name).sort();
|
|
4802
4804
|
} catch {
|
|
4803
4805
|
return [];
|
|
4804
4806
|
}
|
|
@@ -4811,7 +4813,7 @@ function describeJsonValue(value) {
|
|
|
4811
4813
|
}
|
|
4812
4814
|
function writeFileOrExplain(target, content) {
|
|
4813
4815
|
try {
|
|
4814
|
-
|
|
4816
|
+
fs12__namespace.writeFileSync(target, content, "utf8");
|
|
4815
4817
|
} catch (err) {
|
|
4816
4818
|
const code = err.code;
|
|
4817
4819
|
const reason = code === "EACCES" || code === "EPERM" || code === "EROFS" ? `permission denied (${code})` : code === "EISDIR" ? "it is a directory" : `${err.message}`;
|
|
@@ -4822,7 +4824,7 @@ function canWriteModuleConfig(name, cwd) {
|
|
|
4822
4824
|
if (name.endsWith(".mjs") || name.endsWith(".ts")) return true;
|
|
4823
4825
|
if (!name.endsWith(".js")) return false;
|
|
4824
4826
|
try {
|
|
4825
|
-
const parsed = JSON.parse(
|
|
4827
|
+
const parsed = JSON.parse(fs12__namespace.readFileSync(path13__namespace.join(cwd, "package.json"), "utf8"));
|
|
4826
4828
|
return parsed.type === "module";
|
|
4827
4829
|
} catch {
|
|
4828
4830
|
return false;
|
|
@@ -4857,19 +4859,19 @@ function serializePackageJson(raw, value) {
|
|
|
4857
4859
|
return `${text2}${raw.endsWith("\n") ? crlf ? "\r\n" : "\n" : ""}`;
|
|
4858
4860
|
}
|
|
4859
4861
|
function updatePackageJson(cwd, notes) {
|
|
4860
|
-
const packagePath =
|
|
4862
|
+
const packagePath = path13__namespace.join(cwd, "package.json");
|
|
4861
4863
|
const unchanged = {
|
|
4862
4864
|
scripts: [],
|
|
4863
4865
|
dependency: { name: GENERATOR_NAME, range: null, added: false }
|
|
4864
4866
|
};
|
|
4865
|
-
if (!
|
|
4867
|
+
if (!fs12__namespace.existsSync(packagePath)) {
|
|
4866
4868
|
notes.push("No package.json found, so npm scripts and the devDependency were not added.");
|
|
4867
4869
|
return unchanged;
|
|
4868
4870
|
}
|
|
4869
4871
|
let raw;
|
|
4870
4872
|
let parsed;
|
|
4871
4873
|
try {
|
|
4872
|
-
raw =
|
|
4874
|
+
raw = fs12__namespace.readFileSync(packagePath, "utf8");
|
|
4873
4875
|
parsed = JSON.parse(raw);
|
|
4874
4876
|
} catch {
|
|
4875
4877
|
notes.push("Could not parse package.json; npm scripts and the devDependency were not added.");
|
|
@@ -5161,7 +5163,7 @@ async function runInit(options) {
|
|
|
5161
5163
|
const configText = renderConfig(answers);
|
|
5162
5164
|
const preferredName = chooseConfigFileName(options.cwd);
|
|
5163
5165
|
const presentConfigs = CONFIG_CANDIDATES.filter(
|
|
5164
|
-
(name) =>
|
|
5166
|
+
(name) => fs12__namespace.existsSync(path13__namespace.join(options.cwd, name))
|
|
5165
5167
|
);
|
|
5166
5168
|
const present = presentConfigs[0] ?? null;
|
|
5167
5169
|
if (presentConfigs.length > 1) {
|
|
@@ -5170,7 +5172,7 @@ async function runInit(options) {
|
|
|
5170
5172
|
);
|
|
5171
5173
|
}
|
|
5172
5174
|
const configName = present !== null && options.force ? present : preferredName;
|
|
5173
|
-
const configPath =
|
|
5175
|
+
const configPath = path13__namespace.join(options.cwd, configName);
|
|
5174
5176
|
const reused = present !== null && options.force !== true && options.reuseConfig === true;
|
|
5175
5177
|
if (reused) notes.push(`Kept the existing ${present} instead of writing a new one.`);
|
|
5176
5178
|
if (options.dryRun) {
|
|
@@ -5203,7 +5205,7 @@ async function runInit(options) {
|
|
|
5203
5205
|
'package.json already defines a "snapshot" config. Remove that key, or re-run with --force to write a config file that takes precedence over it.'
|
|
5204
5206
|
);
|
|
5205
5207
|
}
|
|
5206
|
-
if (
|
|
5208
|
+
if (fs12__namespace.existsSync(configPath) && !options.force && !reused) {
|
|
5207
5209
|
throw new Error(`${configName} already exists. Re-run with --force to replace it.`);
|
|
5208
5210
|
}
|
|
5209
5211
|
if (!reused) writeFileOrExplain(configPath, configText);
|
|
@@ -5225,9 +5227,9 @@ async function runInit(options) {
|
|
|
5225
5227
|
};
|
|
5226
5228
|
}
|
|
5227
5229
|
function describeTarget(cwd) {
|
|
5228
|
-
const relative11 =
|
|
5230
|
+
const relative11 = path13__namespace.relative(process.cwd(), cwd);
|
|
5229
5231
|
if (relative11 === "") return "this directory";
|
|
5230
|
-
if (relative11.startsWith("..") ||
|
|
5232
|
+
if (relative11.startsWith("..") || path13__namespace.isAbsolute(relative11)) return cwd;
|
|
5231
5233
|
return relative11;
|
|
5232
5234
|
}
|
|
5233
5235
|
function firstRunMessage(reason, cwd) {
|
|
@@ -5251,7 +5253,7 @@ function planFirstRun(facts) {
|
|
|
5251
5253
|
var NOT_CONTENT = /* @__PURE__ */ new Set([".git", ".hg", ".svn", ".bzr", ".DS_Store", "Thumbs.db"]);
|
|
5252
5254
|
function isEffectivelyEmpty(cwd) {
|
|
5253
5255
|
try {
|
|
5254
|
-
return
|
|
5256
|
+
return fs12__namespace.readdirSync(cwd).every((entry) => NOT_CONTENT.has(entry));
|
|
5255
5257
|
} catch {
|
|
5256
5258
|
return false;
|
|
5257
5259
|
}
|
|
@@ -5259,7 +5261,7 @@ function isEffectivelyEmpty(cwd) {
|
|
|
5259
5261
|
function hasPriorSnapshot(cwd, outDir) {
|
|
5260
5262
|
let parsed;
|
|
5261
5263
|
try {
|
|
5262
|
-
parsed = JSON.parse(
|
|
5264
|
+
parsed = JSON.parse(fs12__namespace.readFileSync(path13__namespace.join(cwd, outDir, ".codebase-snapshot"), "utf8"));
|
|
5263
5265
|
} catch {
|
|
5264
5266
|
return false;
|
|
5265
5267
|
}
|
|
@@ -5489,9 +5491,9 @@ var JAVA_METHOD = /^\s+(?:public|private|protected)\s+(?:static\s+)?(?:final\s+)
|
|
|
5489
5491
|
var jvmProfile = {
|
|
5490
5492
|
id: "jvm",
|
|
5491
5493
|
extensions: [".java", ".kt", ".kts", ".scala"],
|
|
5492
|
-
summarize(
|
|
5494
|
+
summarize(path19, content) {
|
|
5493
5495
|
const summary = emptySummary();
|
|
5494
|
-
const lower =
|
|
5496
|
+
const lower = path19.toLowerCase();
|
|
5495
5497
|
const isJava = lower.endsWith(".java");
|
|
5496
5498
|
const isKotlin = lower.endsWith(".kt") || lower.endsWith(".kts");
|
|
5497
5499
|
eachLine(content, (line) => {
|
|
@@ -5944,16 +5946,16 @@ function summarizeTypeScriptSource(relativePath, content) {
|
|
|
5944
5946
|
// src/ast/profiles/sfc.ts
|
|
5945
5947
|
var SCRIPT_BLOCK = /<script[^>]*>([\s\S]*?)<\/script>/gi;
|
|
5946
5948
|
var ASTRO_FRONTMATTER = /^\uFEFF?---[ \t]*\r?\n([\s\S]*?)\r?\n---[ \t]*(?=\r?\n|$)/;
|
|
5947
|
-
function componentName(
|
|
5948
|
-
const base =
|
|
5949
|
+
function componentName(path19) {
|
|
5950
|
+
const base = path19.split("/").pop() ?? path19;
|
|
5949
5951
|
return base.replace(/\.[^.]+$/, "");
|
|
5950
5952
|
}
|
|
5951
5953
|
var sfcProfile = {
|
|
5952
5954
|
id: "sfc",
|
|
5953
5955
|
extensions: [".vue", ".svelte", ".astro"],
|
|
5954
|
-
summarize(
|
|
5956
|
+
summarize(path19, content) {
|
|
5955
5957
|
let script = "";
|
|
5956
|
-
if (
|
|
5958
|
+
if (path19.toLowerCase().endsWith(".astro")) {
|
|
5957
5959
|
const frontmatter = ASTRO_FRONTMATTER.exec(content);
|
|
5958
5960
|
if (frontmatter) script += `${frontmatter[1]}
|
|
5959
5961
|
`;
|
|
@@ -5962,7 +5964,7 @@ var sfcProfile = {
|
|
|
5962
5964
|
script += `${match[1]}
|
|
5963
5965
|
`;
|
|
5964
5966
|
}
|
|
5965
|
-
const name = componentName(
|
|
5967
|
+
const name = componentName(path19);
|
|
5966
5968
|
if (!script.trim()) {
|
|
5967
5969
|
const summary2 = emptySummary();
|
|
5968
5970
|
if (name) {
|
|
@@ -5996,15 +5998,15 @@ for (const profile of LANGUAGE_PROFILES) {
|
|
|
5996
5998
|
BY_EXTENSION.set(extension.toLowerCase(), profile);
|
|
5997
5999
|
}
|
|
5998
6000
|
}
|
|
5999
|
-
function profileForPath(
|
|
6000
|
-
const lower =
|
|
6001
|
+
function profileForPath(path19) {
|
|
6002
|
+
const lower = path19.toLowerCase();
|
|
6001
6003
|
const dot = lower.lastIndexOf(".");
|
|
6002
6004
|
if (dot === -1) return null;
|
|
6003
6005
|
return BY_EXTENSION.get(lower.slice(dot)) ?? null;
|
|
6004
6006
|
}
|
|
6005
|
-
function summarizeWithProfile(
|
|
6006
|
-
const profile = profileForPath(
|
|
6007
|
-
return profile ? profile.summarize(
|
|
6007
|
+
function summarizeWithProfile(path19, content) {
|
|
6008
|
+
const profile = profileForPath(path19);
|
|
6009
|
+
return profile ? profile.summarize(path19, content) : null;
|
|
6008
6010
|
}
|
|
6009
6011
|
|
|
6010
6012
|
// src/ast/structured.ts
|
|
@@ -6849,6 +6851,162 @@ function generateProjectTree(filePaths) {
|
|
|
6849
6851
|
const fence = fenceForText(lines.join("\n"), 3);
|
|
6850
6852
|
return ["# Project Tree", "", `${fence}text`, ...lines, fence, ""].join("\n");
|
|
6851
6853
|
}
|
|
6854
|
+
var PACKAGE_LATEST_URL = "https://registry.npmjs.org/codebase-snapshot/latest";
|
|
6855
|
+
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
6856
|
+
var FAILURE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
6857
|
+
var REQUEST_TIMEOUT_MS = 1200;
|
|
6858
|
+
function versionParts(value) {
|
|
6859
|
+
const core = value.trim().replace(/^v/i, "").split("-")[0];
|
|
6860
|
+
return core.split(".").map((part) => {
|
|
6861
|
+
const parsed = Number(part);
|
|
6862
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
6863
|
+
});
|
|
6864
|
+
}
|
|
6865
|
+
function isNewer(candidate, current) {
|
|
6866
|
+
const left = versionParts(candidate);
|
|
6867
|
+
const right = versionParts(current);
|
|
6868
|
+
const length = Math.max(left.length, right.length);
|
|
6869
|
+
for (let index = 0; index < length; index += 1) {
|
|
6870
|
+
const a = left[index] ?? 0;
|
|
6871
|
+
const b = right[index] ?? 0;
|
|
6872
|
+
if (a !== b) return a > b;
|
|
6873
|
+
}
|
|
6874
|
+
return false;
|
|
6875
|
+
}
|
|
6876
|
+
function cacheDirectory(env = process.env, platform = process.platform) {
|
|
6877
|
+
if (platform === "win32") {
|
|
6878
|
+
const base2 = env.LOCALAPPDATA ?? path13__namespace.join(os__namespace.homedir(), "AppData", "Local");
|
|
6879
|
+
return path13__namespace.join(base2, "codebase-snapshot");
|
|
6880
|
+
}
|
|
6881
|
+
if (platform === "darwin") {
|
|
6882
|
+
return path13__namespace.join(os__namespace.homedir(), "Library", "Caches", "codebase-snapshot");
|
|
6883
|
+
}
|
|
6884
|
+
const base = env.XDG_CACHE_HOME ?? path13__namespace.join(os__namespace.homedir(), ".cache");
|
|
6885
|
+
return path13__namespace.join(base, "codebase-snapshot");
|
|
6886
|
+
}
|
|
6887
|
+
function cacheFilePath(env = process.env) {
|
|
6888
|
+
return path13__namespace.join(cacheDirectory(env), "update-check.json");
|
|
6889
|
+
}
|
|
6890
|
+
function shouldCheck(argv, env) {
|
|
6891
|
+
const disabled = ["1", "true", "yes"].includes(
|
|
6892
|
+
String(env.CODEBASE_SNAPSHOT_NO_UPDATE_CHECK ?? "").toLowerCase()
|
|
6893
|
+
);
|
|
6894
|
+
if (disabled) return false;
|
|
6895
|
+
if (env.CI !== void 0 && env.CI !== "" && env.CI !== "false" && env.CI !== "0") return false;
|
|
6896
|
+
const args = argv.map((argument) => argument.toLowerCase());
|
|
6897
|
+
if (args.includes("--no-update-check")) return false;
|
|
6898
|
+
for (const skip of ["mcp", "describe", "skill", "--version", "-v", "--help", "-h"]) {
|
|
6899
|
+
if (args.includes(skip)) return false;
|
|
6900
|
+
}
|
|
6901
|
+
if (args.some((argument) => argument.includes("json"))) return false;
|
|
6902
|
+
return true;
|
|
6903
|
+
}
|
|
6904
|
+
function readCache(file) {
|
|
6905
|
+
let raw;
|
|
6906
|
+
try {
|
|
6907
|
+
raw = fs12__namespace.readFileSync(file, "utf8");
|
|
6908
|
+
} catch {
|
|
6909
|
+
return null;
|
|
6910
|
+
}
|
|
6911
|
+
try {
|
|
6912
|
+
const parsed = JSON.parse(raw);
|
|
6913
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
6914
|
+
const candidate = parsed;
|
|
6915
|
+
if (typeof candidate.checkedAt !== "number") return null;
|
|
6916
|
+
const latest = typeof candidate.latest === "string" ? candidate.latest : null;
|
|
6917
|
+
return { checkedAt: candidate.checkedAt, latest };
|
|
6918
|
+
} catch {
|
|
6919
|
+
return null;
|
|
6920
|
+
}
|
|
6921
|
+
}
|
|
6922
|
+
function writeCache(file, entry) {
|
|
6923
|
+
try {
|
|
6924
|
+
fs12__namespace.mkdirSync(path13__namespace.dirname(file), { recursive: true });
|
|
6925
|
+
fs12__namespace.writeFileSync(file, `${JSON.stringify(entry)}
|
|
6926
|
+
`, "utf8");
|
|
6927
|
+
} catch {
|
|
6928
|
+
}
|
|
6929
|
+
}
|
|
6930
|
+
function fetchLatestVersion(url = PACKAGE_LATEST_URL, timeoutMs = REQUEST_TIMEOUT_MS) {
|
|
6931
|
+
return new Promise((resolve9) => {
|
|
6932
|
+
let settled = false;
|
|
6933
|
+
const finish = (value) => {
|
|
6934
|
+
if (settled) return;
|
|
6935
|
+
settled = true;
|
|
6936
|
+
resolve9(value);
|
|
6937
|
+
};
|
|
6938
|
+
const request = https__namespace.get(
|
|
6939
|
+
url,
|
|
6940
|
+
{
|
|
6941
|
+
headers: {
|
|
6942
|
+
accept: "application/json",
|
|
6943
|
+
"user-agent": "codebase-snapshot (update check)"
|
|
6944
|
+
}
|
|
6945
|
+
},
|
|
6946
|
+
(response) => {
|
|
6947
|
+
if (response.statusCode !== 200) {
|
|
6948
|
+
response.resume();
|
|
6949
|
+
finish(null);
|
|
6950
|
+
return;
|
|
6951
|
+
}
|
|
6952
|
+
let body = "";
|
|
6953
|
+
response.setEncoding("utf8");
|
|
6954
|
+
response.on("data", (chunk) => {
|
|
6955
|
+
body += chunk;
|
|
6956
|
+
if (body.length > 64 * 1024) {
|
|
6957
|
+
request.destroy();
|
|
6958
|
+
finish(null);
|
|
6959
|
+
}
|
|
6960
|
+
});
|
|
6961
|
+
response.on("end", () => {
|
|
6962
|
+
try {
|
|
6963
|
+
const parsed = JSON.parse(body);
|
|
6964
|
+
finish(typeof parsed.version === "string" ? parsed.version : null);
|
|
6965
|
+
} catch {
|
|
6966
|
+
finish(null);
|
|
6967
|
+
}
|
|
6968
|
+
});
|
|
6969
|
+
}
|
|
6970
|
+
);
|
|
6971
|
+
request.on("error", () => finish(null));
|
|
6972
|
+
request.setTimeout(timeoutMs, () => {
|
|
6973
|
+
request.destroy();
|
|
6974
|
+
finish(null);
|
|
6975
|
+
});
|
|
6976
|
+
});
|
|
6977
|
+
}
|
|
6978
|
+
async function checkForUpdate(options) {
|
|
6979
|
+
if (options.enabled === false) return null;
|
|
6980
|
+
const now = options.now ?? (() => Date.now());
|
|
6981
|
+
const fetchLatest = options.fetchLatest ?? fetchLatestVersion;
|
|
6982
|
+
let latest = null;
|
|
6983
|
+
try {
|
|
6984
|
+
const cached = readCache(options.cacheFile);
|
|
6985
|
+
let needsFetch = cached === null;
|
|
6986
|
+
if (cached) {
|
|
6987
|
+
const age = now() - cached.checkedAt;
|
|
6988
|
+
if (cached.latest === null) {
|
|
6989
|
+
needsFetch = age >= FAILURE_INTERVAL_MS;
|
|
6990
|
+
} else {
|
|
6991
|
+
latest = cached.latest;
|
|
6992
|
+
needsFetch = age >= CHECK_INTERVAL_MS;
|
|
6993
|
+
}
|
|
6994
|
+
}
|
|
6995
|
+
if (needsFetch) {
|
|
6996
|
+
const fetched = await fetchLatest(PACKAGE_LATEST_URL, REQUEST_TIMEOUT_MS);
|
|
6997
|
+
writeCache(options.cacheFile, { checkedAt: now(), latest: fetched });
|
|
6998
|
+
latest = fetched;
|
|
6999
|
+
}
|
|
7000
|
+
} catch {
|
|
7001
|
+
return null;
|
|
7002
|
+
}
|
|
7003
|
+
if (!latest) return null;
|
|
7004
|
+
return isNewer(latest, options.current) ? { current: options.current, latest } : null;
|
|
7005
|
+
}
|
|
7006
|
+
function formatUpdateNotice(notice) {
|
|
7007
|
+
return `\u2191 codebase-snapshot ${notice.latest} is available \u2014 you have ${notice.current}.
|
|
7008
|
+
npm install -g codebase-snapshot`;
|
|
7009
|
+
}
|
|
6852
7010
|
|
|
6853
7011
|
// src/index.ts
|
|
6854
7012
|
var SCHEMA_VERSION = "3.0.0";
|
|
@@ -6930,13 +7088,13 @@ function buildImportResolver(files) {
|
|
|
6930
7088
|
const relativePath = file.relativePath;
|
|
6931
7089
|
remember(byPath, relativePath, relativePath);
|
|
6932
7090
|
remember(byPathFolded, relativePath.toLowerCase(), relativePath);
|
|
6933
|
-
const extension =
|
|
7091
|
+
const extension = path13__namespace.posix.extname(relativePath);
|
|
6934
7092
|
if (!SOURCE_EXTENSIONS.has(extension)) continue;
|
|
6935
7093
|
const stem = relativePath.slice(0, -extension.length);
|
|
6936
7094
|
remember(byStem, stem, relativePath);
|
|
6937
7095
|
remember(byStemFolded, stem.toLowerCase(), relativePath);
|
|
6938
|
-
if (
|
|
6939
|
-
const directory =
|
|
7096
|
+
if (path13__namespace.posix.basename(stem) === "index") {
|
|
7097
|
+
const directory = path13__namespace.posix.dirname(stem);
|
|
6940
7098
|
remember(byStem, directory, relativePath);
|
|
6941
7099
|
remember(byStemFolded, directory.toLowerCase(), relativePath);
|
|
6942
7100
|
}
|
|
@@ -6945,8 +7103,8 @@ function buildImportResolver(files) {
|
|
|
6945
7103
|
}
|
|
6946
7104
|
function resolveSpecifier(fromFile, specifier, resolver) {
|
|
6947
7105
|
if (!RELATIVE_SPECIFIER.test(specifier)) return null;
|
|
6948
|
-
const joined =
|
|
6949
|
-
|
|
7106
|
+
const joined = path13__namespace.posix.normalize(
|
|
7107
|
+
path13__namespace.posix.join(path13__namespace.posix.dirname(fromFile), specifier)
|
|
6950
7108
|
);
|
|
6951
7109
|
const exact = (key) => resolver.byPath.get(key) ?? resolver.byPathFolded.get(key.toLowerCase()) ?? null;
|
|
6952
7110
|
const direct = exact(joined);
|
|
@@ -7039,11 +7197,11 @@ function verifyInMemory(files, parts, maxPartBytes) {
|
|
|
7039
7197
|
return errors;
|
|
7040
7198
|
}
|
|
7041
7199
|
function resolveSafeOutputDirs(config) {
|
|
7042
|
-
const cwd =
|
|
7043
|
-
const outDir =
|
|
7044
|
-
const tmpDir =
|
|
7045
|
-
const root =
|
|
7046
|
-
const contains = (parent, child) => child === parent || child.startsWith(`${parent}${
|
|
7200
|
+
const cwd = path13__namespace.resolve(config.cwd);
|
|
7201
|
+
const outDir = path13__namespace.resolve(cwd, config.outDir);
|
|
7202
|
+
const tmpDir = path13__namespace.resolve(cwd, config.tmpDir);
|
|
7203
|
+
const root = path13__namespace.parse(cwd).root;
|
|
7204
|
+
const contains = (parent, child) => child === parent || child.startsWith(`${parent}${path13__namespace.sep}`);
|
|
7047
7205
|
const reject = (reason) => {
|
|
7048
7206
|
throw new Error(
|
|
7049
7207
|
`Refusing to generate: ${reason}. outDir=${outDir} tmpDir=${tmpDir} cwd=${cwd}`
|
|
@@ -7099,14 +7257,14 @@ function listEntries(dir) {
|
|
|
7099
7257
|
const walk = (absolute, prefix) => {
|
|
7100
7258
|
let children;
|
|
7101
7259
|
try {
|
|
7102
|
-
children =
|
|
7260
|
+
children = fs12__namespace.readdirSync(absolute, { withFileTypes: true });
|
|
7103
7261
|
} catch {
|
|
7104
7262
|
return;
|
|
7105
7263
|
}
|
|
7106
7264
|
for (const child of children) {
|
|
7107
7265
|
const relative11 = prefix === "" ? child.name : `${prefix}/${child.name}`;
|
|
7108
7266
|
entries.push(relative11);
|
|
7109
|
-
if (child.isDirectory()) walk(
|
|
7267
|
+
if (child.isDirectory()) walk(path13__namespace.join(absolute, child.name), relative11);
|
|
7110
7268
|
}
|
|
7111
7269
|
};
|
|
7112
7270
|
walk(dir, "");
|
|
@@ -7123,28 +7281,28 @@ function markerPayload(dir, state, id, createdAt) {
|
|
|
7123
7281
|
pid: process.pid,
|
|
7124
7282
|
entries: listEntries(dir)
|
|
7125
7283
|
};
|
|
7126
|
-
const manifestPath =
|
|
7127
|
-
if (
|
|
7128
|
-
marker2.manifestSha256 = sha256Hex2(
|
|
7284
|
+
const manifestPath = path13__namespace.join(dir, "manifest.json");
|
|
7285
|
+
if (fs12__namespace.existsSync(manifestPath)) {
|
|
7286
|
+
marker2.manifestSha256 = sha256Hex2(fs12__namespace.readFileSync(manifestPath));
|
|
7129
7287
|
}
|
|
7130
7288
|
return marker2;
|
|
7131
7289
|
}
|
|
7132
7290
|
function writeOwnershipMarker(dir, marker2) {
|
|
7133
|
-
|
|
7134
|
-
|
|
7291
|
+
fs12__namespace.writeFileSync(
|
|
7292
|
+
path13__namespace.join(dir, OWNERSHIP_MARKER),
|
|
7135
7293
|
`${JSON.stringify(marker2, null, 2)}
|
|
7136
7294
|
`,
|
|
7137
7295
|
"utf8"
|
|
7138
7296
|
);
|
|
7139
7297
|
}
|
|
7140
7298
|
function readOwnershipMarker(dir) {
|
|
7141
|
-
const markerPath =
|
|
7142
|
-
if (!
|
|
7299
|
+
const markerPath = path13__namespace.join(dir, OWNERSHIP_MARKER);
|
|
7300
|
+
if (!fs12__namespace.existsSync(markerPath)) {
|
|
7143
7301
|
return { marker: null, problem: "it holds no .codebase-snapshot marker" };
|
|
7144
7302
|
}
|
|
7145
7303
|
let raw;
|
|
7146
7304
|
try {
|
|
7147
|
-
raw =
|
|
7305
|
+
raw = fs12__namespace.readFileSync(markerPath, "utf8");
|
|
7148
7306
|
} catch {
|
|
7149
7307
|
return { marker: null, problem: "its .codebase-snapshot marker could not be read" };
|
|
7150
7308
|
}
|
|
@@ -7212,11 +7370,11 @@ function assessSnapshotDirectory(dir) {
|
|
|
7212
7370
|
marker: marker2
|
|
7213
7371
|
};
|
|
7214
7372
|
}
|
|
7215
|
-
const manifestPath =
|
|
7216
|
-
if (
|
|
7373
|
+
const manifestPath = path13__namespace.join(dir, "manifest.json");
|
|
7374
|
+
if (fs12__namespace.existsSync(manifestPath)) {
|
|
7217
7375
|
let raw;
|
|
7218
7376
|
try {
|
|
7219
|
-
raw =
|
|
7377
|
+
raw = fs12__namespace.readFileSync(manifestPath, "utf8");
|
|
7220
7378
|
} catch {
|
|
7221
7379
|
return {
|
|
7222
7380
|
owned: false,
|
|
@@ -7298,13 +7456,13 @@ function containsNoFiles(dir) {
|
|
|
7298
7456
|
const current = pending.pop();
|
|
7299
7457
|
let entries;
|
|
7300
7458
|
try {
|
|
7301
|
-
entries =
|
|
7459
|
+
entries = fs12__namespace.readdirSync(current, { withFileTypes: true });
|
|
7302
7460
|
} catch {
|
|
7303
7461
|
return false;
|
|
7304
7462
|
}
|
|
7305
7463
|
for (const entry of entries) {
|
|
7306
7464
|
if (entry.isDirectory()) {
|
|
7307
|
-
pending.push(
|
|
7465
|
+
pending.push(path13__namespace.join(current, entry.name));
|
|
7308
7466
|
} else if (!IGNORABLE_ENTRIES.has(entry.name)) {
|
|
7309
7467
|
return false;
|
|
7310
7468
|
}
|
|
@@ -7313,13 +7471,13 @@ function containsNoFiles(dir) {
|
|
|
7313
7471
|
return true;
|
|
7314
7472
|
}
|
|
7315
7473
|
function assertReplaceable(target, label, secretRules) {
|
|
7316
|
-
if (!
|
|
7317
|
-
if (!
|
|
7474
|
+
if (!fs12__namespace.existsSync(target)) return;
|
|
7475
|
+
if (!fs12__namespace.statSync(target).isDirectory()) {
|
|
7318
7476
|
throw new Error(
|
|
7319
7477
|
`Refusing to write into ${label} ${target}: it exists but is not a directory.`
|
|
7320
7478
|
);
|
|
7321
7479
|
}
|
|
7322
|
-
const entries =
|
|
7480
|
+
const entries = fs12__namespace.readdirSync(target);
|
|
7323
7481
|
if (entries.length === 0) return;
|
|
7324
7482
|
if (entries.every((name) => IGNORABLE_ENTRIES.has(name))) return;
|
|
7325
7483
|
if (containsNoFiles(target)) return;
|
|
@@ -7339,18 +7497,18 @@ function assertReplaceable(target, label, secretRules) {
|
|
|
7339
7497
|
);
|
|
7340
7498
|
}
|
|
7341
7499
|
function assertStagingRootUsable(tmpDir, secretRules) {
|
|
7342
|
-
if (!
|
|
7343
|
-
if (!
|
|
7500
|
+
if (!fs12__namespace.existsSync(tmpDir)) return;
|
|
7501
|
+
if (!fs12__namespace.statSync(tmpDir).isDirectory()) {
|
|
7344
7502
|
throw new Error(`Refusing to write into tmpDir ${tmpDir}: it exists but is not a directory.`);
|
|
7345
7503
|
}
|
|
7346
|
-
const entries =
|
|
7504
|
+
const entries = fs12__namespace.readdirSync(tmpDir);
|
|
7347
7505
|
if (entries.length === 0) return;
|
|
7348
7506
|
const foreign = entries.filter((name) => {
|
|
7349
|
-
const full =
|
|
7507
|
+
const full = path13__namespace.join(tmpDir, name);
|
|
7350
7508
|
if (!name.startsWith(RUN_DIR_PREFIX)) return true;
|
|
7351
7509
|
let stats;
|
|
7352
7510
|
try {
|
|
7353
|
-
stats =
|
|
7511
|
+
stats = fs12__namespace.statSync(full);
|
|
7354
7512
|
} catch {
|
|
7355
7513
|
return true;
|
|
7356
7514
|
}
|
|
@@ -7358,7 +7516,7 @@ function assertStagingRootUsable(tmpDir, secretRules) {
|
|
|
7358
7516
|
const { marker: marker2 } = readOwnershipMarker(full);
|
|
7359
7517
|
if (marker2) return false;
|
|
7360
7518
|
try {
|
|
7361
|
-
return
|
|
7519
|
+
return fs12__namespace.readdirSync(full).length > 0;
|
|
7362
7520
|
} catch {
|
|
7363
7521
|
return true;
|
|
7364
7522
|
}
|
|
@@ -7373,13 +7531,13 @@ function assertStagingRootUsable(tmpDir, secretRules) {
|
|
|
7373
7531
|
function cleanStaleRunDirs(tmpDir) {
|
|
7374
7532
|
let entries;
|
|
7375
7533
|
try {
|
|
7376
|
-
entries =
|
|
7534
|
+
entries = fs12__namespace.readdirSync(tmpDir);
|
|
7377
7535
|
} catch {
|
|
7378
7536
|
return;
|
|
7379
7537
|
}
|
|
7380
7538
|
for (const name of entries) {
|
|
7381
7539
|
if (!name.startsWith(RUN_DIR_PREFIX)) continue;
|
|
7382
|
-
const full =
|
|
7540
|
+
const full = path13__namespace.join(tmpDir, name);
|
|
7383
7541
|
const { marker: marker2 } = readOwnershipMarker(full);
|
|
7384
7542
|
if (marker2) {
|
|
7385
7543
|
const created = Date.parse(marker2.createdAt);
|
|
@@ -7387,33 +7545,33 @@ function cleanStaleRunDirs(tmpDir) {
|
|
|
7387
7545
|
const abandoned = typeof marker2.pid === "number" && !isProcessAlive(marker2.pid);
|
|
7388
7546
|
if (aged || abandoned) {
|
|
7389
7547
|
try {
|
|
7390
|
-
|
|
7548
|
+
fs12__namespace.rmSync(full, { recursive: true, force: true });
|
|
7391
7549
|
} catch {
|
|
7392
7550
|
}
|
|
7393
7551
|
}
|
|
7394
7552
|
continue;
|
|
7395
7553
|
}
|
|
7396
7554
|
try {
|
|
7397
|
-
if (
|
|
7555
|
+
if (fs12__namespace.readdirSync(full).length === 0) fs12__namespace.rmSync(full, { recursive: true, force: true });
|
|
7398
7556
|
} catch {
|
|
7399
7557
|
}
|
|
7400
7558
|
}
|
|
7401
7559
|
}
|
|
7402
7560
|
function removeIfEmpty(dir) {
|
|
7403
7561
|
try {
|
|
7404
|
-
if (
|
|
7562
|
+
if (fs12__namespace.readdirSync(dir).length === 0) fs12__namespace.rmSync(dir, { recursive: true, force: true });
|
|
7405
7563
|
} catch {
|
|
7406
7564
|
}
|
|
7407
7565
|
}
|
|
7408
7566
|
function ensureParentDirectory(target, label) {
|
|
7409
|
-
const parent =
|
|
7410
|
-
if (
|
|
7567
|
+
const parent = path13__namespace.dirname(target);
|
|
7568
|
+
if (fs12__namespace.existsSync(parent) && !fs12__namespace.statSync(parent).isDirectory()) {
|
|
7411
7569
|
throw new Error(
|
|
7412
7570
|
`Refusing to create ${label} ${target}: ${parent} exists but is not a directory.`
|
|
7413
7571
|
);
|
|
7414
7572
|
}
|
|
7415
7573
|
try {
|
|
7416
|
-
|
|
7574
|
+
fs12__namespace.mkdirSync(parent, { recursive: true });
|
|
7417
7575
|
} catch (err) {
|
|
7418
7576
|
throw new Error(
|
|
7419
7577
|
`Refusing to create ${label} ${target}: its parent ${parent} could not be created (${err.message}).`
|
|
@@ -7422,7 +7580,7 @@ function ensureParentDirectory(target, label) {
|
|
|
7422
7580
|
}
|
|
7423
7581
|
function acquireRunLock(stagingRoot) {
|
|
7424
7582
|
const key = lockKeyFor(stagingRoot);
|
|
7425
|
-
const lockPath =
|
|
7583
|
+
const lockPath = path13__namespace.join(os__namespace.tmpdir(), `codebase-snapshot-${key}.lock`);
|
|
7426
7584
|
const payload = `${JSON.stringify({
|
|
7427
7585
|
pid: process.pid,
|
|
7428
7586
|
stagingRoot,
|
|
@@ -7431,22 +7589,22 @@ function acquireRunLock(stagingRoot) {
|
|
|
7431
7589
|
`;
|
|
7432
7590
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
7433
7591
|
try {
|
|
7434
|
-
const handle =
|
|
7592
|
+
const handle = fs12__namespace.openSync(lockPath, "wx");
|
|
7435
7593
|
try {
|
|
7436
|
-
|
|
7594
|
+
fs12__namespace.writeSync(handle, payload);
|
|
7437
7595
|
} finally {
|
|
7438
|
-
|
|
7596
|
+
fs12__namespace.closeSync(handle);
|
|
7439
7597
|
}
|
|
7440
7598
|
return () => {
|
|
7441
7599
|
try {
|
|
7442
|
-
|
|
7600
|
+
fs12__namespace.rmSync(lockPath, { force: true });
|
|
7443
7601
|
} catch {
|
|
7444
7602
|
}
|
|
7445
7603
|
};
|
|
7446
7604
|
} catch (err) {
|
|
7447
7605
|
if (err.code !== "EEXIST") throw err;
|
|
7448
7606
|
if (attempt === 0 && lockOwnerIsGone(lockPath)) {
|
|
7449
|
-
|
|
7607
|
+
fs12__namespace.rmSync(lockPath, { force: true });
|
|
7450
7608
|
continue;
|
|
7451
7609
|
}
|
|
7452
7610
|
throw new Error(
|
|
@@ -7459,7 +7617,7 @@ function acquireRunLock(stagingRoot) {
|
|
|
7459
7617
|
function lockKeyFor(stagingRoot) {
|
|
7460
7618
|
let key = stagingRoot;
|
|
7461
7619
|
try {
|
|
7462
|
-
key =
|
|
7620
|
+
key = fs12__namespace.realpathSync(stagingRoot);
|
|
7463
7621
|
} catch {
|
|
7464
7622
|
}
|
|
7465
7623
|
if (process.platform === "win32" || process.platform === "darwin") key = key.toLowerCase();
|
|
@@ -7468,7 +7626,7 @@ function lockKeyFor(stagingRoot) {
|
|
|
7468
7626
|
function lockOwnerIsGone(lockPath) {
|
|
7469
7627
|
let raw;
|
|
7470
7628
|
try {
|
|
7471
|
-
raw =
|
|
7629
|
+
raw = fs12__namespace.readFileSync(lockPath, "utf8");
|
|
7472
7630
|
} catch {
|
|
7473
7631
|
return false;
|
|
7474
7632
|
}
|
|
@@ -7488,12 +7646,12 @@ function lockOwnerIsGone(lockPath) {
|
|
|
7488
7646
|
}
|
|
7489
7647
|
function writeManifestAtomically(manifestPath, manifest) {
|
|
7490
7648
|
const tempPath = `${manifestPath}.${process.pid}.tmp`;
|
|
7491
|
-
|
|
7649
|
+
fs12__namespace.writeFileSync(tempPath, JSON.stringify(manifest, null, 2), "utf8");
|
|
7492
7650
|
try {
|
|
7493
|
-
|
|
7651
|
+
fs12__namespace.renameSync(tempPath, manifestPath);
|
|
7494
7652
|
} catch (err) {
|
|
7495
7653
|
try {
|
|
7496
|
-
|
|
7654
|
+
fs12__namespace.rmSync(tempPath, { force: true });
|
|
7497
7655
|
} catch {
|
|
7498
7656
|
}
|
|
7499
7657
|
throw err;
|
|
@@ -7516,31 +7674,31 @@ function swapIntoPlace(stagingDir, outDir) {
|
|
|
7516
7674
|
}
|
|
7517
7675
|
function swapOnce(stagingDir, outDir) {
|
|
7518
7676
|
const backupDir = `${outDir}.backup-${process.pid}-${Date.now()}`;
|
|
7519
|
-
const hadPrevious =
|
|
7520
|
-
if (hadPrevious)
|
|
7677
|
+
const hadPrevious = fs12__namespace.existsSync(outDir);
|
|
7678
|
+
if (hadPrevious) fs12__namespace.renameSync(outDir, backupDir);
|
|
7521
7679
|
try {
|
|
7522
7680
|
try {
|
|
7523
|
-
|
|
7681
|
+
fs12__namespace.renameSync(stagingDir, outDir);
|
|
7524
7682
|
} catch (err) {
|
|
7525
7683
|
if (err.code !== "EXDEV") throw err;
|
|
7526
7684
|
const partialDir = `${outDir}.partial-${process.pid}-${Date.now()}`;
|
|
7527
7685
|
try {
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7686
|
+
fs12__namespace.cpSync(stagingDir, partialDir, { recursive: true });
|
|
7687
|
+
fs12__namespace.renameSync(partialDir, outDir);
|
|
7688
|
+
fs12__namespace.rmSync(stagingDir, { recursive: true, force: true });
|
|
7531
7689
|
} catch (copyErr) {
|
|
7532
7690
|
try {
|
|
7533
|
-
|
|
7691
|
+
fs12__namespace.rmSync(partialDir, { recursive: true, force: true });
|
|
7534
7692
|
} catch {
|
|
7535
7693
|
}
|
|
7536
7694
|
throw copyErr;
|
|
7537
7695
|
}
|
|
7538
7696
|
}
|
|
7539
|
-
if (hadPrevious)
|
|
7697
|
+
if (hadPrevious) fs12__namespace.rmSync(backupDir, { recursive: true, force: true });
|
|
7540
7698
|
} catch (err) {
|
|
7541
|
-
if (hadPrevious &&
|
|
7542
|
-
if (
|
|
7543
|
-
|
|
7699
|
+
if (hadPrevious && fs12__namespace.existsSync(backupDir)) {
|
|
7700
|
+
if (fs12__namespace.existsSync(outDir)) fs12__namespace.rmSync(outDir, { recursive: true, force: true });
|
|
7701
|
+
fs12__namespace.renameSync(backupDir, outDir);
|
|
7544
7702
|
}
|
|
7545
7703
|
throw err;
|
|
7546
7704
|
}
|
|
@@ -7635,7 +7793,7 @@ function generateSnapshot(configInput, options) {
|
|
|
7635
7793
|
// first run cannot have marked them yet, so the name alone keeps a run from recording its own
|
|
7636
7794
|
// output — but only at these exact paths, not at every directory that shares the name.
|
|
7637
7795
|
toolOwnedPaths: [config.outDir, config.tmpDir].map(
|
|
7638
|
-
(directory) =>
|
|
7796
|
+
(directory) => path13__namespace.relative(config.cwd, path13__namespace.resolve(config.cwd, directory)).replace(/\\/g, "/")
|
|
7639
7797
|
).filter((relative11) => relative11.length > 0 && !relative11.startsWith(".."))
|
|
7640
7798
|
});
|
|
7641
7799
|
const files = [];
|
|
@@ -7656,12 +7814,12 @@ function generateSnapshot(configInput, options) {
|
|
|
7656
7814
|
let totalSizeBytes = 0;
|
|
7657
7815
|
let largeFileCount = 0;
|
|
7658
7816
|
for (const relativePath of collection.files) {
|
|
7659
|
-
const absolutePath =
|
|
7817
|
+
const absolutePath = path13__namespace.join(config.cwd, relativePath);
|
|
7660
7818
|
let stats;
|
|
7661
7819
|
try {
|
|
7662
|
-
stats =
|
|
7820
|
+
stats = fs12__namespace.statSync(absolutePath);
|
|
7663
7821
|
if (!stats.isFile()) {
|
|
7664
|
-
const nestedRepository = stats.isDirectory() &&
|
|
7822
|
+
const nestedRepository = stats.isDirectory() && fs12__namespace.existsSync(path13__namespace.join(absolutePath, ".git"));
|
|
7665
7823
|
skipped.push(
|
|
7666
7824
|
nestedRepository ? {
|
|
7667
7825
|
path: relativePath,
|
|
@@ -7681,7 +7839,7 @@ function generateSnapshot(configInput, options) {
|
|
|
7681
7839
|
}
|
|
7682
7840
|
let buffer;
|
|
7683
7841
|
try {
|
|
7684
|
-
buffer =
|
|
7842
|
+
buffer = fs12__namespace.readFileSync(absolutePath);
|
|
7685
7843
|
} catch {
|
|
7686
7844
|
skipped.push({ path: relativePath, reason: "read-error" });
|
|
7687
7845
|
continue;
|
|
@@ -8011,12 +8169,12 @@ function generateSnapshot(configInput, options) {
|
|
|
8011
8169
|
let stagingDir = null;
|
|
8012
8170
|
try {
|
|
8013
8171
|
ensureParentDirectory(outDir, "outDir");
|
|
8014
|
-
|
|
8172
|
+
fs12__namespace.mkdirSync(tmpDir, { recursive: true });
|
|
8015
8173
|
cleanStaleRunDirs(tmpDir);
|
|
8016
8174
|
const snapshotId = crypto2__namespace.randomUUID();
|
|
8017
8175
|
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
8018
|
-
stagingDir =
|
|
8019
|
-
|
|
8176
|
+
stagingDir = path13__namespace.join(tmpDir, `${RUN_DIR_PREFIX}${process.pid}-${snapshotId.slice(0, 8)}`);
|
|
8177
|
+
fs12__namespace.mkdirSync(stagingDir);
|
|
8020
8178
|
writeOwnershipMarker(stagingDir, {
|
|
8021
8179
|
generator: GENERATOR_NAME,
|
|
8022
8180
|
version: GENERATOR_VERSION,
|
|
@@ -8026,41 +8184,41 @@ function generateSnapshot(configInput, options) {
|
|
|
8026
8184
|
id: snapshotId,
|
|
8027
8185
|
pid: process.pid
|
|
8028
8186
|
});
|
|
8029
|
-
const partsDir =
|
|
8030
|
-
const reportsDir =
|
|
8031
|
-
if (artifacts.parts)
|
|
8187
|
+
const partsDir = path13__namespace.join(stagingDir, "parts");
|
|
8188
|
+
const reportsDir = path13__namespace.join(stagingDir, "reports");
|
|
8189
|
+
if (artifacts.parts) fs12__namespace.mkdirSync(partsDir, { recursive: true });
|
|
8032
8190
|
if (artifacts.navigation || artifacts.projectTree || artifacts.audit) {
|
|
8033
|
-
|
|
8191
|
+
fs12__namespace.mkdirSync(reportsDir, { recursive: true });
|
|
8034
8192
|
}
|
|
8035
8193
|
if (artifacts.parts) {
|
|
8036
8194
|
for (const part of parts) {
|
|
8037
|
-
|
|
8195
|
+
fs12__namespace.writeFileSync(path13__namespace.join(partsDir, part.filename), part.markdown, "utf8");
|
|
8038
8196
|
}
|
|
8039
8197
|
}
|
|
8040
8198
|
if (projectTree !== null) {
|
|
8041
|
-
|
|
8199
|
+
fs12__namespace.writeFileSync(path13__namespace.join(reportsDir, "project-tree.md"), projectTree, "utf8");
|
|
8042
8200
|
}
|
|
8043
8201
|
if (artifacts.navigation) {
|
|
8044
|
-
|
|
8202
|
+
fs12__namespace.writeFileSync(path13__namespace.join(reportsDir, "navigation.md"), generateNavigation(manifest), "utf8");
|
|
8045
8203
|
}
|
|
8046
8204
|
if (artifacts.audit) {
|
|
8047
|
-
|
|
8048
|
-
|
|
8205
|
+
fs12__namespace.writeFileSync(
|
|
8206
|
+
path13__namespace.join(reportsDir, "audit.md"),
|
|
8049
8207
|
generateAuditReport(manifest, secretFindings, config.secretRules),
|
|
8050
8208
|
"utf8"
|
|
8051
8209
|
);
|
|
8052
8210
|
}
|
|
8053
8211
|
if (artifacts.readme) {
|
|
8054
|
-
|
|
8212
|
+
fs12__namespace.writeFileSync(path13__namespace.join(stagingDir, "README.md"), generateReadme(manifest, artifacts), "utf8");
|
|
8055
8213
|
}
|
|
8056
8214
|
if (artifacts.manifest) {
|
|
8057
|
-
|
|
8215
|
+
fs12__namespace.writeFileSync(path13__namespace.join(stagingDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf8");
|
|
8058
8216
|
}
|
|
8059
8217
|
if (monolithJson !== null) {
|
|
8060
|
-
|
|
8218
|
+
fs12__namespace.writeFileSync(path13__namespace.join(stagingDir, "full-codebase.json"), monolithJson, "utf8");
|
|
8061
8219
|
}
|
|
8062
8220
|
if (monolithMarkdown !== null) {
|
|
8063
|
-
|
|
8221
|
+
fs12__namespace.writeFileSync(path13__namespace.join(stagingDir, "full-codebase.md"), monolithMarkdown, "utf8");
|
|
8064
8222
|
}
|
|
8065
8223
|
writeOwnershipMarker(stagingDir, markerPayload(stagingDir, "complete", snapshotId, createdAt));
|
|
8066
8224
|
swapIntoPlace(stagingDir, outDir);
|
|
@@ -8069,7 +8227,7 @@ function generateSnapshot(configInput, options) {
|
|
|
8069
8227
|
const pendingHook = runAfterGenerate(config, manifest);
|
|
8070
8228
|
const shipHookState = () => {
|
|
8071
8229
|
if (artifacts.manifest && manifest.warnings.length !== warningsBeforeHook) {
|
|
8072
|
-
writeManifestAtomically(
|
|
8230
|
+
writeManifestAtomically(path13__namespace.join(outDir, "manifest.json"), manifest);
|
|
8073
8231
|
}
|
|
8074
8232
|
writeOwnershipMarker(outDir, markerPayload(outDir, "complete", snapshotId, createdAt));
|
|
8075
8233
|
};
|
|
@@ -8092,7 +8250,7 @@ function generateSnapshot(configInput, options) {
|
|
|
8092
8250
|
} catch (err) {
|
|
8093
8251
|
if (stagingDir !== null) {
|
|
8094
8252
|
try {
|
|
8095
|
-
|
|
8253
|
+
fs12__namespace.rmSync(stagingDir, { recursive: true, force: true });
|
|
8096
8254
|
} catch {
|
|
8097
8255
|
}
|
|
8098
8256
|
}
|
|
@@ -8189,9 +8347,9 @@ function foldForComparison(value) {
|
|
|
8189
8347
|
return process.platform === "win32" || process.platform === "darwin" ? value.toLowerCase() : value;
|
|
8190
8348
|
}
|
|
8191
8349
|
function canonicalPath(value) {
|
|
8192
|
-
const absolute =
|
|
8350
|
+
const absolute = path13__namespace.resolve(value);
|
|
8193
8351
|
try {
|
|
8194
|
-
return
|
|
8352
|
+
return fs12__namespace.realpathSync(absolute);
|
|
8195
8353
|
} catch {
|
|
8196
8354
|
return absolute;
|
|
8197
8355
|
}
|
|
@@ -8199,17 +8357,17 @@ function canonicalPath(value) {
|
|
|
8199
8357
|
function isInside2(parent, child) {
|
|
8200
8358
|
const foldedParent = foldForComparison(parent);
|
|
8201
8359
|
const foldedChild = foldForComparison(child);
|
|
8202
|
-
return foldedChild === foldedParent || foldedChild.startsWith(`${foldedParent}${
|
|
8360
|
+
return foldedChild === foldedParent || foldedChild.startsWith(`${foldedParent}${path13__namespace.sep}`);
|
|
8203
8361
|
}
|
|
8204
8362
|
function resolveRoot(requested, context) {
|
|
8205
8363
|
if (requested !== void 0 && (typeof requested !== "string" || requested.trim().length === 0)) {
|
|
8206
8364
|
return { ok: false, message: '"root" must be a non-empty string when provided.' };
|
|
8207
8365
|
}
|
|
8208
8366
|
const wanted = typeof requested === "string" ? requested.trim() : context.cwd;
|
|
8209
|
-
const absolute =
|
|
8367
|
+
const absolute = path13__namespace.resolve(context.cwd, wanted);
|
|
8210
8368
|
let stats;
|
|
8211
8369
|
try {
|
|
8212
|
-
stats =
|
|
8370
|
+
stats = fs12__namespace.statSync(absolute);
|
|
8213
8371
|
} catch {
|
|
8214
8372
|
return { ok: false, message: `"${wanted}" does not exist, so it cannot be a repository root.` };
|
|
8215
8373
|
}
|
|
@@ -8260,14 +8418,14 @@ async function openWorkspace(root, overrides = {}) {
|
|
|
8260
8418
|
}
|
|
8261
8419
|
var manifestCache = /* @__PURE__ */ new Map();
|
|
8262
8420
|
function manifestPathFor(workspace) {
|
|
8263
|
-
return
|
|
8421
|
+
return path13__namespace.resolve(workspace.root, workspace.config.outDir, "manifest.json");
|
|
8264
8422
|
}
|
|
8265
8423
|
function readManifest3(workspace) {
|
|
8266
8424
|
const file = manifestPathFor(workspace);
|
|
8267
|
-
const shown =
|
|
8425
|
+
const shown = path13__namespace.relative(workspace.root, file).split(path13__namespace.sep).join("/") || file;
|
|
8268
8426
|
let stats;
|
|
8269
8427
|
try {
|
|
8270
|
-
stats =
|
|
8428
|
+
stats = fs12__namespace.statSync(file);
|
|
8271
8429
|
} catch {
|
|
8272
8430
|
return {
|
|
8273
8431
|
ok: false,
|
|
@@ -8281,7 +8439,7 @@ function readManifest3(workspace) {
|
|
|
8281
8439
|
}
|
|
8282
8440
|
let raw;
|
|
8283
8441
|
try {
|
|
8284
|
-
raw =
|
|
8442
|
+
raw = fs12__namespace.readFileSync(file, "utf8");
|
|
8285
8443
|
} catch (error) {
|
|
8286
8444
|
return {
|
|
8287
8445
|
ok: false,
|
|
@@ -8339,7 +8497,7 @@ function formatBytes(bytes) {
|
|
|
8339
8497
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
8340
8498
|
}
|
|
8341
8499
|
function relativeFor(workspace, absolute) {
|
|
8342
|
-
return
|
|
8500
|
+
return path13__namespace.relative(workspace.root, absolute).split(path13__namespace.sep).join("/");
|
|
8343
8501
|
}
|
|
8344
8502
|
function capped(values, limit = 20) {
|
|
8345
8503
|
return { count: values.length, sample: values.slice(0, limit) };
|
|
@@ -8358,12 +8516,12 @@ function summarizeDrift(drift) {
|
|
|
8358
8516
|
function toRelativePath(root, value) {
|
|
8359
8517
|
const cleaned = value.trim();
|
|
8360
8518
|
if (cleaned.length === 0) return null;
|
|
8361
|
-
if (!
|
|
8519
|
+
if (!path13__namespace.isAbsolute(cleaned)) {
|
|
8362
8520
|
return cleaned.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
8363
8521
|
}
|
|
8364
|
-
const relative11 =
|
|
8365
|
-
if (relative11.startsWith("..") ||
|
|
8366
|
-
return relative11.split(
|
|
8522
|
+
const relative11 = path13__namespace.relative(root, cleaned);
|
|
8523
|
+
if (relative11.startsWith("..") || path13__namespace.isAbsolute(relative11)) return null;
|
|
8524
|
+
return relative11.split(path13__namespace.sep).join("/");
|
|
8367
8525
|
}
|
|
8368
8526
|
function symbolsOf(entry) {
|
|
8369
8527
|
const summary = entry.summary;
|
|
@@ -8574,7 +8732,7 @@ var generateTool = {
|
|
|
8574
8732
|
return failure(error instanceof Error ? error.message : String(error));
|
|
8575
8733
|
}
|
|
8576
8734
|
forgetManifest(manifestPathFor(workspace));
|
|
8577
|
-
const written = relativeFor(workspace,
|
|
8735
|
+
const written = relativeFor(workspace, path13__namespace.resolve(workspace.root, workspace.config.outDir));
|
|
8578
8736
|
const lines = [
|
|
8579
8737
|
`Wrote ${written}/`,
|
|
8580
8738
|
`Files: ${manifest.counts.totalFiles} included, ${manifest.counts.skippedCount} skipped, ${plural(manifest.counts.partsCount, "part")}`,
|
|
@@ -8839,10 +8997,10 @@ var readTool = {
|
|
|
8839
8997
|
`${relativePath} is not in the snapshot. Call snapshot_locate to find the path, or snapshot_explain to learn why it was excluded.`
|
|
8840
8998
|
);
|
|
8841
8999
|
}
|
|
8842
|
-
const partPath =
|
|
9000
|
+
const partPath = path13__namespace.resolve(workspace.root, workspace.config.outDir, "parts", entry.part);
|
|
8843
9001
|
let partText;
|
|
8844
9002
|
try {
|
|
8845
|
-
partText =
|
|
9003
|
+
partText = fs12__namespace.readFileSync(partPath, "utf8");
|
|
8846
9004
|
} catch {
|
|
8847
9005
|
return failure(
|
|
8848
9006
|
`${entry.part} could not be read, so the snapshot is damaged. Run snapshot_generate to rebuild it.`
|
|
@@ -9100,6 +9258,7 @@ var VALIDATE_OPTIONS = [
|
|
|
9100
9258
|
"no-config",
|
|
9101
9259
|
"discovery",
|
|
9102
9260
|
"format",
|
|
9261
|
+
"no-update-check",
|
|
9103
9262
|
"mode",
|
|
9104
9263
|
"help",
|
|
9105
9264
|
"version"
|
|
@@ -9123,6 +9282,7 @@ var COMMAND_OPTION_SCOPE = {
|
|
|
9123
9282
|
"watch",
|
|
9124
9283
|
"autopilot",
|
|
9125
9284
|
"no-install",
|
|
9285
|
+
"no-update-check",
|
|
9126
9286
|
"help",
|
|
9127
9287
|
"version"
|
|
9128
9288
|
],
|
|
@@ -9138,6 +9298,7 @@ var COMMAND_OPTION_SCOPE = {
|
|
|
9138
9298
|
"skip-artifacts",
|
|
9139
9299
|
"only-artifacts",
|
|
9140
9300
|
"no-config",
|
|
9301
|
+
"no-update-check",
|
|
9141
9302
|
"format",
|
|
9142
9303
|
"mode",
|
|
9143
9304
|
"help",
|
|
@@ -9155,12 +9316,13 @@ var COMMAND_OPTION_SCOPE = {
|
|
|
9155
9316
|
"only-artifacts",
|
|
9156
9317
|
"no-config",
|
|
9157
9318
|
"discovery",
|
|
9319
|
+
"no-update-check",
|
|
9158
9320
|
"format",
|
|
9159
9321
|
"mode",
|
|
9160
9322
|
"help",
|
|
9161
9323
|
"version"
|
|
9162
9324
|
],
|
|
9163
|
-
diff: ["format", "mode", "no-config", "help", "version"],
|
|
9325
|
+
diff: ["format", "mode", "no-config", "no-update-check", "help", "version"],
|
|
9164
9326
|
describe: ["format", "mode", "help", "version"],
|
|
9165
9327
|
init: [
|
|
9166
9328
|
"cwd",
|
|
@@ -9175,6 +9337,7 @@ var COMMAND_OPTION_SCOPE = {
|
|
|
9175
9337
|
"yes",
|
|
9176
9338
|
"force",
|
|
9177
9339
|
"dry-run",
|
|
9340
|
+
"no-update-check",
|
|
9178
9341
|
"format",
|
|
9179
9342
|
"mode",
|
|
9180
9343
|
"help",
|
|
@@ -9198,6 +9361,7 @@ var COMMAND_OPTION_SCOPE = {
|
|
|
9198
9361
|
"force",
|
|
9199
9362
|
"no-install",
|
|
9200
9363
|
"dry-run",
|
|
9364
|
+
"no-update-check",
|
|
9201
9365
|
"format",
|
|
9202
9366
|
"mode",
|
|
9203
9367
|
"help",
|
|
@@ -9630,6 +9794,13 @@ function buildAgentContract() {
|
|
|
9630
9794
|
default: false,
|
|
9631
9795
|
appliesTo: optionAppliesTo("no-install"),
|
|
9632
9796
|
summary: "Skip installing the dependency before generating: `setup`, or `generate --autopilot` (CI, offline, or a lockfile you do not want a package manager to touch)."
|
|
9797
|
+
},
|
|
9798
|
+
{
|
|
9799
|
+
flag: "--no-update-check",
|
|
9800
|
+
type: "boolean",
|
|
9801
|
+
default: false,
|
|
9802
|
+
appliesTo: optionAppliesTo("no-update-check"),
|
|
9803
|
+
summary: "Skip the once-a-day check for a newer published version. The check is already skipped when stdout is not a terminal, in CI, in a JSON invocation, and in `mcp`, which makes no network requests."
|
|
9633
9804
|
}
|
|
9634
9805
|
],
|
|
9635
9806
|
presets: PRESETS.map((preset) => ({
|
|
@@ -9917,17 +10088,17 @@ var LEGACY_AGENTS_MARKER = "<!-- codebase-snapshot:skill:start -->";
|
|
|
9917
10088
|
function targetPath(cwd, target) {
|
|
9918
10089
|
switch (target) {
|
|
9919
10090
|
case "claude":
|
|
9920
|
-
return
|
|
10091
|
+
return path13__namespace.join(cwd, ".claude", "skills", SKILL_NAME, "SKILL.md");
|
|
9921
10092
|
case "cursor":
|
|
9922
|
-
return
|
|
10093
|
+
return path13__namespace.join(cwd, ".cursor", "rules", `${SKILL_NAME}.mdc`);
|
|
9923
10094
|
}
|
|
9924
10095
|
}
|
|
9925
10096
|
function assertWritableInsideRepository(cwd, filePath) {
|
|
9926
|
-
const root =
|
|
9927
|
-
const shown =
|
|
10097
|
+
const root = fs12__namespace.realpathSync(cwd);
|
|
10098
|
+
const shown = path13__namespace.relative(root, filePath) || filePath;
|
|
9928
10099
|
let stat = null;
|
|
9929
10100
|
try {
|
|
9930
|
-
stat =
|
|
10101
|
+
stat = fs12__namespace.lstatSync(filePath);
|
|
9931
10102
|
} catch {
|
|
9932
10103
|
stat = null;
|
|
9933
10104
|
}
|
|
@@ -9943,32 +10114,32 @@ function assertWritableInsideRepository(cwd, filePath) {
|
|
|
9943
10114
|
}
|
|
9944
10115
|
let existing = filePath;
|
|
9945
10116
|
const missing = [];
|
|
9946
|
-
while (!
|
|
9947
|
-
missing.unshift(
|
|
9948
|
-
const parent =
|
|
10117
|
+
while (!fs12__namespace.existsSync(existing)) {
|
|
10118
|
+
missing.unshift(path13__namespace.basename(existing));
|
|
10119
|
+
const parent = path13__namespace.dirname(existing);
|
|
9949
10120
|
if (parent === existing) break;
|
|
9950
10121
|
existing = parent;
|
|
9951
10122
|
}
|
|
9952
|
-
const realAncestor =
|
|
9953
|
-
const resolved = missing.length === 0 ? realAncestor :
|
|
9954
|
-
if (resolved !== root && !resolved.startsWith(`${root}${
|
|
10123
|
+
const realAncestor = fs12__namespace.realpathSync(existing);
|
|
10124
|
+
const resolved = missing.length === 0 ? realAncestor : path13__namespace.join(realAncestor, ...missing);
|
|
10125
|
+
if (resolved !== root && !resolved.startsWith(`${root}${path13__namespace.sep}`)) {
|
|
9955
10126
|
throw new Error(
|
|
9956
10127
|
`${REFUSED}: ${shown} resolves outside the repository (${resolved}). Move it back inside ${root}, or remove the link, and run again.`
|
|
9957
10128
|
);
|
|
9958
10129
|
}
|
|
9959
10130
|
}
|
|
9960
10131
|
function writeIfChanged(target, filePath, content) {
|
|
9961
|
-
const existing =
|
|
10132
|
+
const existing = fs12__namespace.existsSync(filePath) ? fs12__namespace.readFileSync(filePath, "utf8") : null;
|
|
9962
10133
|
if (existing === content) return { target, path: filePath, action: "unchanged" };
|
|
9963
|
-
|
|
9964
|
-
|
|
10134
|
+
fs12__namespace.mkdirSync(path13__namespace.dirname(filePath), { recursive: true });
|
|
10135
|
+
fs12__namespace.writeFileSync(filePath, content, "utf8");
|
|
9965
10136
|
return { target, path: filePath, action: existing === null ? "created" : "updated" };
|
|
9966
10137
|
}
|
|
9967
10138
|
function legacyAgentsNote(cwd) {
|
|
9968
|
-
const filePath =
|
|
10139
|
+
const filePath = path13__namespace.join(cwd, "AGENTS.md");
|
|
9969
10140
|
try {
|
|
9970
|
-
if (!
|
|
9971
|
-
if (!
|
|
10141
|
+
if (!fs12__namespace.existsSync(filePath)) return null;
|
|
10142
|
+
if (!fs12__namespace.readFileSync(filePath, "utf8").includes(LEGACY_AGENTS_MARKER)) return null;
|
|
9972
10143
|
} catch {
|
|
9973
10144
|
return null;
|
|
9974
10145
|
}
|
|
@@ -9980,9 +10151,9 @@ function installSkill(cwd, target = "all") {
|
|
|
9980
10151
|
const notes = [];
|
|
9981
10152
|
const wanted = target === "all" ? ["claude", "cursor"] : [target];
|
|
9982
10153
|
for (const item of wanted) assertWritableInsideRepository(cwd, targetPath(cwd, item));
|
|
9983
|
-
const createsSomething = wanted.some((item) => !
|
|
10154
|
+
const createsSomething = wanted.some((item) => !fs12__namespace.existsSync(targetPath(cwd, item)));
|
|
9984
10155
|
if (createsSomething) {
|
|
9985
|
-
assertWritableInsideRepository(cwd,
|
|
10156
|
+
assertWritableInsideRepository(cwd, path13__namespace.join(cwd, ".gitignore"));
|
|
9986
10157
|
}
|
|
9987
10158
|
for (const item of wanted) {
|
|
9988
10159
|
written.push(writeIfChanged(item, targetPath(cwd, item), skill));
|
|
@@ -10117,52 +10288,52 @@ function validateArguments(schema, value) {
|
|
|
10117
10288
|
}
|
|
10118
10289
|
return problems;
|
|
10119
10290
|
}
|
|
10120
|
-
function checkValue(
|
|
10291
|
+
function checkValue(path19, schema, value) {
|
|
10121
10292
|
if (schema.enum && !schema.enum.includes(value)) {
|
|
10122
|
-
return [`"${
|
|
10293
|
+
return [`"${path19}" must be one of: ${schema.enum.join(", ")}`];
|
|
10123
10294
|
}
|
|
10124
10295
|
switch (schema.type) {
|
|
10125
10296
|
case "string": {
|
|
10126
|
-
if (typeof value !== "string") return [`"${
|
|
10297
|
+
if (typeof value !== "string") return [`"${path19}" must be a string`];
|
|
10127
10298
|
const problems = [];
|
|
10128
10299
|
if (schema.minLength !== void 0 && value.length < schema.minLength) {
|
|
10129
|
-
problems.push(`"${
|
|
10300
|
+
problems.push(`"${path19}" must be at least ${schema.minLength} character(s)`);
|
|
10130
10301
|
}
|
|
10131
10302
|
if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
|
|
10132
|
-
problems.push(`"${
|
|
10303
|
+
problems.push(`"${path19}" must be at most ${schema.maxLength} character(s)`);
|
|
10133
10304
|
}
|
|
10134
10305
|
return problems;
|
|
10135
10306
|
}
|
|
10136
10307
|
case "number":
|
|
10137
10308
|
case "integer": {
|
|
10138
10309
|
if (typeof value !== "number" || Number.isNaN(value)) {
|
|
10139
|
-
return [`"${
|
|
10310
|
+
return [`"${path19}" must be a number`];
|
|
10140
10311
|
}
|
|
10141
10312
|
if (schema.type === "integer" && !Number.isInteger(value)) {
|
|
10142
|
-
return [`"${
|
|
10313
|
+
return [`"${path19}" must be an integer`];
|
|
10143
10314
|
}
|
|
10144
10315
|
const problems = [];
|
|
10145
10316
|
if (schema.minimum !== void 0 && value < schema.minimum) {
|
|
10146
|
-
problems.push(`"${
|
|
10317
|
+
problems.push(`"${path19}" must be >= ${schema.minimum}`);
|
|
10147
10318
|
}
|
|
10148
10319
|
if (schema.maximum !== void 0 && value > schema.maximum) {
|
|
10149
|
-
problems.push(`"${
|
|
10320
|
+
problems.push(`"${path19}" must be <= ${schema.maximum}`);
|
|
10150
10321
|
}
|
|
10151
10322
|
return problems;
|
|
10152
10323
|
}
|
|
10153
10324
|
case "boolean":
|
|
10154
|
-
return typeof value === "boolean" ? [] : [`"${
|
|
10325
|
+
return typeof value === "boolean" ? [] : [`"${path19}" must be a boolean`];
|
|
10155
10326
|
case "array": {
|
|
10156
|
-
if (!Array.isArray(value)) return [`"${
|
|
10327
|
+
if (!Array.isArray(value)) return [`"${path19}" must be an array`];
|
|
10157
10328
|
if (!schema.items) return [];
|
|
10158
10329
|
const problems = [];
|
|
10159
10330
|
value.forEach((item, index) => {
|
|
10160
|
-
problems.push(...checkValue(`${
|
|
10331
|
+
problems.push(...checkValue(`${path19}[${index}]`, schema.items, item));
|
|
10161
10332
|
});
|
|
10162
10333
|
return problems;
|
|
10163
10334
|
}
|
|
10164
10335
|
case "object":
|
|
10165
|
-
return isJsonObject(value) ? [] : [`"${
|
|
10336
|
+
return isJsonObject(value) ? [] : [`"${path19}" must be an object`];
|
|
10166
10337
|
default:
|
|
10167
10338
|
return [];
|
|
10168
10339
|
}
|
|
@@ -10176,6 +10347,18 @@ function applyDefaults(schema, value) {
|
|
|
10176
10347
|
}
|
|
10177
10348
|
return out;
|
|
10178
10349
|
}
|
|
10350
|
+
function coerceNumericStrings(schema, value) {
|
|
10351
|
+
const out = { ...value };
|
|
10352
|
+
for (const [key, propertySchema] of Object.entries(schema.properties)) {
|
|
10353
|
+
const raw = out[key];
|
|
10354
|
+
if (typeof raw !== "string") continue;
|
|
10355
|
+
if (propertySchema.type !== "number" && propertySchema.type !== "integer") continue;
|
|
10356
|
+
if (raw.trim().length === 0) continue;
|
|
10357
|
+
const parsed = Number(raw);
|
|
10358
|
+
if (Number.isFinite(parsed)) out[key] = parsed;
|
|
10359
|
+
}
|
|
10360
|
+
return out;
|
|
10361
|
+
}
|
|
10179
10362
|
|
|
10180
10363
|
// src/mcp/server.ts
|
|
10181
10364
|
function capabilities() {
|
|
@@ -10264,7 +10447,8 @@ function createMcpServer(options) {
|
|
|
10264
10447
|
if (!isJsonObject(rawArguments)) {
|
|
10265
10448
|
return errorResponse(id, ERROR_CODES.invalidParams, '"arguments" must be a JSON object.');
|
|
10266
10449
|
}
|
|
10267
|
-
const
|
|
10450
|
+
const supplied = coerceNumericStrings(tool.inputSchema, rawArguments);
|
|
10451
|
+
const problems = validateArguments(tool.inputSchema, supplied);
|
|
10268
10452
|
if (problems.length > 0) {
|
|
10269
10453
|
return ok(
|
|
10270
10454
|
id,
|
|
@@ -10276,7 +10460,7 @@ function createMcpServer(options) {
|
|
|
10276
10460
|
modern
|
|
10277
10461
|
);
|
|
10278
10462
|
}
|
|
10279
|
-
const args = applyDefaults(tool.inputSchema,
|
|
10463
|
+
const args = applyDefaults(tool.inputSchema, supplied);
|
|
10280
10464
|
let outcome;
|
|
10281
10465
|
try {
|
|
10282
10466
|
outcome = await tool.handler(args, options.context);
|
|
@@ -10474,7 +10658,7 @@ async function workspaceFor(context) {
|
|
|
10474
10658
|
}
|
|
10475
10659
|
function readFileIfPresent(file) {
|
|
10476
10660
|
try {
|
|
10477
|
-
return
|
|
10661
|
+
return fs12__namespace.readFileSync(file, "utf8");
|
|
10478
10662
|
} catch {
|
|
10479
10663
|
return null;
|
|
10480
10664
|
}
|
|
@@ -10553,7 +10737,7 @@ function buildResourceProvider() {
|
|
|
10553
10737
|
const report = REPORT_URIS.get(uri);
|
|
10554
10738
|
if (report) {
|
|
10555
10739
|
const text2 = readFileIfPresent(
|
|
10556
|
-
|
|
10740
|
+
path13__namespace.resolve(workspace.root, workspace.config.outDir, "reports", report.file)
|
|
10557
10741
|
);
|
|
10558
10742
|
if (text2 === null) return null;
|
|
10559
10743
|
return { uri, mimeType: "text/markdown", text: capUtf8(text2, MAX_RESOURCE_BYTES).text };
|
|
@@ -10572,7 +10756,7 @@ function buildResourceProvider() {
|
|
|
10572
10756
|
const part = read.manifest.parts.find((candidate) => candidate.index === index);
|
|
10573
10757
|
if (!part) return null;
|
|
10574
10758
|
const text2 = readFileIfPresent(
|
|
10575
|
-
|
|
10759
|
+
path13__namespace.resolve(workspace.root, workspace.config.outDir, "parts", part.filename)
|
|
10576
10760
|
);
|
|
10577
10761
|
if (text2 === null) return null;
|
|
10578
10762
|
return { uri, mimeType: "text/markdown", text: capUtf8(text2, MAX_RESOURCE_BYTES).text };
|
|
@@ -10810,6 +10994,7 @@ var CLI_OPTIONS = {
|
|
|
10810
10994
|
install: { type: "boolean" },
|
|
10811
10995
|
"no-install": { type: "boolean" },
|
|
10812
10996
|
target: { type: "string" },
|
|
10997
|
+
"no-update-check": { type: "boolean" },
|
|
10813
10998
|
help: { type: "boolean", short: "h" },
|
|
10814
10999
|
version: { type: "boolean", short: "v" }
|
|
10815
11000
|
};
|
|
@@ -10884,6 +11069,8 @@ Options:
|
|
|
10884
11069
|
--install Write the skill into the repository instead of printing
|
|
10885
11070
|
--target <name> claude | cursor | all (default: all)
|
|
10886
11071
|
|
|
11072
|
+
--no-update-check Skip the daily check for a newer published version
|
|
11073
|
+
|
|
10887
11074
|
-h, --help Display this help message
|
|
10888
11075
|
-v, --version Display version
|
|
10889
11076
|
|
|
@@ -10960,10 +11147,10 @@ function parseCliArgs(argv) {
|
|
|
10960
11147
|
}
|
|
10961
11148
|
if (values.cwd !== void 0) {
|
|
10962
11149
|
const target = String(values.cwd);
|
|
10963
|
-
if (!
|
|
11150
|
+
if (!fs12__namespace.existsSync(target)) {
|
|
10964
11151
|
throw new UsageError(`--cwd directory does not exist: ${target}`);
|
|
10965
11152
|
}
|
|
10966
|
-
if (!
|
|
11153
|
+
if (!fs12__namespace.statSync(target).isDirectory()) {
|
|
10967
11154
|
throw new UsageError(`--cwd is not a directory: ${target}`);
|
|
10968
11155
|
}
|
|
10969
11156
|
}
|
|
@@ -11109,7 +11296,7 @@ function parseCliArgs(argv) {
|
|
|
11109
11296
|
install: values.install === true,
|
|
11110
11297
|
noInstall: values["no-install"] === true,
|
|
11111
11298
|
target: values.target === void 0 ? void 0 : String(values.target),
|
|
11112
|
-
cwd: values.cwd === void 0 ? process.cwd() :
|
|
11299
|
+
cwd: values.cwd === void 0 ? process.cwd() : path13__namespace.resolve(String(values.cwd)),
|
|
11113
11300
|
outDir: values["out-dir"] === void 0 ? void 0 : String(values["out-dir"]),
|
|
11114
11301
|
includeMonolith: values["include-monolith"] === true || onlyNamesMonolith === true ? true : void 0,
|
|
11115
11302
|
includeSensitiveFiles: values["include-sensitive-files"] === true ? true : void 0,
|
|
@@ -11166,24 +11353,24 @@ function splitList(value) {
|
|
|
11166
11353
|
return value.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
11167
11354
|
}
|
|
11168
11355
|
function displayOutPath(cwd, outDir, ...segments) {
|
|
11169
|
-
const absolute =
|
|
11170
|
-
const relative11 =
|
|
11171
|
-
if (relative11 && !relative11.startsWith("..") && !
|
|
11356
|
+
const absolute = path13__namespace.resolve(cwd, outDir, ...segments);
|
|
11357
|
+
const relative11 = path13__namespace.relative(cwd, absolute);
|
|
11358
|
+
if (relative11 && !relative11.startsWith("..") && !path13__namespace.isAbsolute(relative11)) return relative11;
|
|
11172
11359
|
return absolute;
|
|
11173
11360
|
}
|
|
11174
11361
|
function nextStepHint(cwd, scriptsAddedNow) {
|
|
11175
11362
|
let hasScript = scriptsAddedNow;
|
|
11176
11363
|
if (!hasScript) {
|
|
11177
11364
|
try {
|
|
11178
|
-
const parsed = JSON.parse(
|
|
11365
|
+
const parsed = JSON.parse(fs12__namespace.readFileSync(path13__namespace.join(cwd, "package.json"), "utf8"));
|
|
11179
11366
|
hasScript = typeof parsed.scripts?.snapshot === "string";
|
|
11180
11367
|
} catch {
|
|
11181
11368
|
hasScript = false;
|
|
11182
11369
|
}
|
|
11183
11370
|
}
|
|
11184
11371
|
if (!hasScript) return `npx ${GENERATOR_NAME} generate`;
|
|
11185
|
-
const bin =
|
|
11186
|
-
const installed =
|
|
11372
|
+
const bin = path13__namespace.join(cwd, "node_modules", ".bin", "codebase-snapshot");
|
|
11373
|
+
const installed = fs12__namespace.existsSync(bin) || fs12__namespace.existsSync(`${bin}.cmd`);
|
|
11187
11374
|
return installed ? "npm run snapshot" : "npm install && npm run snapshot";
|
|
11188
11375
|
}
|
|
11189
11376
|
function presetSummary(init) {
|
|
@@ -11213,7 +11400,7 @@ async function runInitCommand(invocation) {
|
|
|
11213
11400
|
info(result.configText);
|
|
11214
11401
|
return 0;
|
|
11215
11402
|
}
|
|
11216
|
-
info(`\u2705 Created ${
|
|
11403
|
+
info(`\u2705 Created ${path13__namespace.basename(result.configPath)} (${presetSummary(result)})`);
|
|
11217
11404
|
if (result.scripts.length > 0) info(` Added npm scripts: ${result.scripts.join(", ")}`);
|
|
11218
11405
|
if (result.dependency.added && result.dependency.range !== null) {
|
|
11219
11406
|
info(` Added devDependency: ${result.dependency.name} ${result.dependency.range}`);
|
|
@@ -11233,7 +11420,7 @@ async function runInitCommand(invocation) {
|
|
|
11233
11420
|
}
|
|
11234
11421
|
}
|
|
11235
11422
|
function detectPackageManager(cwd) {
|
|
11236
|
-
const has = (name) =>
|
|
11423
|
+
const has = (name) => fs12__namespace.existsSync(path13__namespace.join(cwd, name));
|
|
11237
11424
|
if (has("bun.lockb") || has("bun.lock")) return { name: "bun", command: "bun", args: ["install"] };
|
|
11238
11425
|
if (has("pnpm-lock.yaml")) return { name: "pnpm", command: "pnpm", args: ["install"] };
|
|
11239
11426
|
if (has("yarn.lock")) return { name: "yarn", command: "yarn", args: ["install"] };
|
|
@@ -11322,7 +11509,7 @@ async function runSetupCommand(invocation, options = {}) {
|
|
|
11322
11509
|
}
|
|
11323
11510
|
info("\n\u{1F9EA} Dry run \u2014 setup would:");
|
|
11324
11511
|
info(
|
|
11325
|
-
` 1. ${init.reused ? `keep ${
|
|
11512
|
+
` 1. ${init.reused ? `keep ${path13__namespace.basename(init.configPath)}` : `write ${path13__namespace.basename(init.configPath)} (preset: ${init.preset})`}`
|
|
11326
11513
|
);
|
|
11327
11514
|
info(" 2. add the npm scripts, the devDependency and the .gitignore entries");
|
|
11328
11515
|
if (manager !== null) info(` 3. install with ${manager}`);
|
|
@@ -11334,9 +11521,9 @@ async function runSetupCommand(invocation, options = {}) {
|
|
|
11334
11521
|
if (invocation.format !== "json") {
|
|
11335
11522
|
if (!interactive) info(`\u{1F680} Setup for: ${invocation.cwd}`);
|
|
11336
11523
|
if (init.reused) {
|
|
11337
|
-
info(`\u267B Keeping ${
|
|
11524
|
+
info(`\u267B Keeping ${path13__namespace.basename(init.configPath)} (${presetSummary(init)})`);
|
|
11338
11525
|
} else {
|
|
11339
|
-
info(`\u2705 Created ${
|
|
11526
|
+
info(`\u2705 Created ${path13__namespace.basename(init.configPath)} (${presetSummary(init)})`);
|
|
11340
11527
|
}
|
|
11341
11528
|
if (init.scripts.length > 0) info(` Added npm scripts: ${init.scripts.join(", ")}`);
|
|
11342
11529
|
if (init.dependency.added && init.dependency.range !== null) {
|
|
@@ -11444,7 +11631,7 @@ function runSkillCommand(invocation) {
|
|
|
11444
11631
|
}
|
|
11445
11632
|
info(`\u2705 Agent skill installed (${SKILL_NAME}):`);
|
|
11446
11633
|
for (const item of result.written) {
|
|
11447
|
-
const shown =
|
|
11634
|
+
const shown = path13__namespace.relative(invocation.cwd, item.path) || item.path;
|
|
11448
11635
|
info(` - ${item.action.padEnd(9)} ${shown}`);
|
|
11449
11636
|
}
|
|
11450
11637
|
if (result.gitignored.length > 0) {
|
|
@@ -11508,6 +11695,17 @@ function requestsJsonFormat(argv) {
|
|
|
11508
11695
|
return format === "json";
|
|
11509
11696
|
}
|
|
11510
11697
|
async function main(argv = process.argv.slice(2)) {
|
|
11698
|
+
const pending = process.stdout.isTTY === true && shouldCheck(argv, process.env) ? checkForUpdate({ current: GENERATOR_VERSION, cacheFile: cacheFilePath() }) : null;
|
|
11699
|
+
const code = await runCommand(argv);
|
|
11700
|
+
if (pending) {
|
|
11701
|
+
const notice = await pending;
|
|
11702
|
+
if (notice) process.stderr.write(`
|
|
11703
|
+
${formatUpdateNotice(notice)}
|
|
11704
|
+
`);
|
|
11705
|
+
}
|
|
11706
|
+
return code;
|
|
11707
|
+
}
|
|
11708
|
+
async function runCommand(argv) {
|
|
11511
11709
|
let invocation;
|
|
11512
11710
|
try {
|
|
11513
11711
|
invocation = parseCliArgs(argv);
|
|
@@ -11540,7 +11738,7 @@ ${USAGE}
|
|
|
11540
11738
|
return runSkillCommand(invocation);
|
|
11541
11739
|
}
|
|
11542
11740
|
if (invocation.command === "mcp") {
|
|
11543
|
-
return await runStdioServer({ cwd:
|
|
11741
|
+
return await runStdioServer({ cwd: path13__namespace.resolve(invocation.cwd) });
|
|
11544
11742
|
}
|
|
11545
11743
|
if (invocation.command === "setup") {
|
|
11546
11744
|
return runSetupCommand(invocation);
|
|
@@ -11557,7 +11755,7 @@ ${USAGE}
|
|
|
11557
11755
|
warn("\u274C The config file could not be read. Fix it, or delete it to use the defaults.");
|
|
11558
11756
|
return 1;
|
|
11559
11757
|
}
|
|
11560
|
-
if (loaded.file) info(`\u2699 Using config ${
|
|
11758
|
+
if (loaded.file) info(`\u2699 Using config ${path13__namespace.relative(process.cwd(), loaded.file) || loaded.file}`);
|
|
11561
11759
|
const resolved = resolveConfig(
|
|
11562
11760
|
loaded.config,
|
|
11563
11761
|
{
|
|
@@ -11579,10 +11777,10 @@ ${USAGE}
|
|
|
11579
11777
|
if (invocation.command === "validate") {
|
|
11580
11778
|
const result = validateSnapshot(resolved);
|
|
11581
11779
|
if (result.valid) {
|
|
11582
|
-
const manifestPath =
|
|
11780
|
+
const manifestPath = path13__namespace.resolve(resolved.cwd, resolved.outDir, "manifest.json");
|
|
11583
11781
|
let manifest;
|
|
11584
11782
|
try {
|
|
11585
|
-
manifest = JSON.parse(
|
|
11783
|
+
manifest = JSON.parse(fs12__namespace.readFileSync(manifestPath, "utf8"));
|
|
11586
11784
|
} catch {
|
|
11587
11785
|
manifest = void 0;
|
|
11588
11786
|
}
|
|
@@ -11595,13 +11793,13 @@ ${USAGE}
|
|
|
11595
11793
|
return result.valid ? 0 : 1;
|
|
11596
11794
|
}
|
|
11597
11795
|
if (invocation.command === "report") {
|
|
11598
|
-
const manifestPath =
|
|
11599
|
-
if (!
|
|
11796
|
+
const manifestPath = path13__namespace.resolve(resolved.cwd, resolved.outDir, "manifest.json");
|
|
11797
|
+
if (!fs12__namespace.existsSync(manifestPath)) {
|
|
11600
11798
|
return fail(invocation.format, `Manifest not found at ${manifestPath}. Run generate first.`);
|
|
11601
11799
|
}
|
|
11602
11800
|
let manifest;
|
|
11603
11801
|
try {
|
|
11604
|
-
manifest = JSON.parse(
|
|
11802
|
+
manifest = JSON.parse(fs12__namespace.readFileSync(manifestPath, "utf8"));
|
|
11605
11803
|
} catch (err) {
|
|
11606
11804
|
return fail(invocation.format, `Could not read ${manifestPath}: ${err.message}`);
|
|
11607
11805
|
}
|
|
@@ -11765,20 +11963,20 @@ function finishWatchRun(state, now) {
|
|
|
11765
11963
|
};
|
|
11766
11964
|
}
|
|
11767
11965
|
function comparablePath(value) {
|
|
11768
|
-
const absolute =
|
|
11966
|
+
const absolute = path13__namespace.resolve(value);
|
|
11769
11967
|
return process.platform === "win32" ? absolute.toLowerCase() : absolute;
|
|
11770
11968
|
}
|
|
11771
11969
|
function isSameOrInside(parent, candidate) {
|
|
11772
|
-
const relative11 =
|
|
11773
|
-
return relative11 === "" || relative11 !== ".." && !relative11.startsWith(`..${
|
|
11970
|
+
const relative11 = path13__namespace.relative(parent, candidate);
|
|
11971
|
+
return relative11 === "" || relative11 !== ".." && !relative11.startsWith(`..${path13__namespace.sep}`) && !path13__namespace.isAbsolute(relative11);
|
|
11774
11972
|
}
|
|
11775
11973
|
function isGeneratedWatchPath(candidate, paths) {
|
|
11776
|
-
const absolute = comparablePath(
|
|
11777
|
-
const outDir = comparablePath(
|
|
11778
|
-
const tmpDir = comparablePath(
|
|
11974
|
+
const absolute = comparablePath(path13__namespace.resolve(paths.cwd, candidate));
|
|
11975
|
+
const outDir = comparablePath(path13__namespace.resolve(paths.cwd, paths.outDir));
|
|
11976
|
+
const tmpDir = comparablePath(path13__namespace.resolve(paths.cwd, paths.tmpDir));
|
|
11779
11977
|
if (isSameOrInside(outDir, absolute) || isSameOrInside(tmpDir, absolute)) return true;
|
|
11780
|
-
const parent =
|
|
11781
|
-
if (parent ===
|
|
11978
|
+
const parent = path13__namespace.dirname(absolute);
|
|
11979
|
+
if (parent === path13__namespace.dirname(outDir) && path13__namespace.basename(absolute).startsWith(`${path13__namespace.basename(outDir)}.backup-`)) {
|
|
11782
11980
|
return true;
|
|
11783
11981
|
}
|
|
11784
11982
|
return absolute.split(/[\\/]+/).some((segment) => VCS_SEGMENTS.has(segment));
|
|
@@ -11795,8 +11993,8 @@ function decideWatchEvent(state, event, paths) {
|
|
|
11795
11993
|
return { state, action: "schedule" };
|
|
11796
11994
|
}
|
|
11797
11995
|
async function runWatchLoop(invocation, resolved) {
|
|
11798
|
-
const outDir =
|
|
11799
|
-
const tmpDir =
|
|
11996
|
+
const outDir = path13__namespace.resolve(resolved.cwd, resolved.outDir);
|
|
11997
|
+
const tmpDir = path13__namespace.resolve(resolved.cwd, resolved.tmpDir);
|
|
11800
11998
|
const paths = { cwd: resolved.cwd, outDir, tmpDir };
|
|
11801
11999
|
let state = initialWatchState();
|
|
11802
12000
|
let timer = null;
|
|
@@ -11861,11 +12059,11 @@ async function runWatchLoop(invocation, resolved) {
|
|
|
11861
12059
|
};
|
|
11862
12060
|
info("\u{1F440} Watching for changes. Press Ctrl+C to stop.");
|
|
11863
12061
|
void regenerate();
|
|
11864
|
-
const watcher =
|
|
12062
|
+
const watcher = fs12__namespace.watch(resolved.cwd, { recursive: true }, (_event, filename) => {
|
|
11865
12063
|
const decision = decideWatchEvent(
|
|
11866
12064
|
state,
|
|
11867
12065
|
{
|
|
11868
|
-
path: filename ?
|
|
12066
|
+
path: filename ? path13__namespace.resolve(resolved.cwd, filename.toString()) : null,
|
|
11869
12067
|
now: performance.now()
|
|
11870
12068
|
},
|
|
11871
12069
|
paths
|
|
@@ -11893,7 +12091,7 @@ async function runWatchLoop(invocation, resolved) {
|
|
|
11893
12091
|
return 0;
|
|
11894
12092
|
}
|
|
11895
12093
|
var entryFile = process.argv[1] ?? "";
|
|
11896
|
-
var entryName =
|
|
12094
|
+
var entryName = path13__namespace.basename(entryFile).toLowerCase();
|
|
11897
12095
|
var invokedDirectly = entryName === "cli.js" || entryName === "cli.cjs";
|
|
11898
12096
|
if (invokedDirectly) {
|
|
11899
12097
|
void main().then(
|