codebase-snapshot 0.9.4 → 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 +84 -0
- package/README.md +4 -1
- package/dist/bin.js +594 -304
- package/dist/{chunk-FCWD4LY7.js → chunk-3KUL3QRH.js} +564 -318
- package/dist/{chunk-EWZYK3VX.js → chunk-ZKZOGGM3.js} +33 -7
- package/dist/cli.cjs +697 -411
- package/dist/cli.d.cts +7 -1
- package/dist/cli.d.ts +7 -1
- package/dist/cli.js +19 -6
- package/dist/index.cjs +570 -312
- 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 +29 -2
- package/docs/mcp.md +3 -3
- package/package.json +1 -1
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import * as crypto from 'crypto';
|
|
2
2
|
import { createHash } from 'crypto';
|
|
3
3
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
4
|
-
import * as
|
|
4
|
+
import * as fs12 from 'fs';
|
|
5
5
|
import * as os from 'os';
|
|
6
|
-
import * as
|
|
6
|
+
import * as path13 from 'path';
|
|
7
7
|
import ts from 'typescript';
|
|
8
8
|
import { createRequire } from 'module';
|
|
9
9
|
import { pathToFileURL } from 'url';
|
|
10
10
|
import * as childProcess from 'child_process';
|
|
11
|
+
import * as https from 'https';
|
|
11
12
|
import * as readline from 'readline';
|
|
12
13
|
|
|
13
14
|
// src/index.ts
|
|
@@ -234,9 +235,9 @@ var JAVA_METHOD = /^\s+(?:public|private|protected)\s+(?:static\s+)?(?:final\s+)
|
|
|
234
235
|
var jvmProfile = {
|
|
235
236
|
id: "jvm",
|
|
236
237
|
extensions: [".java", ".kt", ".kts", ".scala"],
|
|
237
|
-
summarize(
|
|
238
|
+
summarize(path14, content) {
|
|
238
239
|
const summary = emptySummary();
|
|
239
|
-
const lower =
|
|
240
|
+
const lower = path14.toLowerCase();
|
|
240
241
|
const isJava = lower.endsWith(".java");
|
|
241
242
|
const isKotlin = lower.endsWith(".kt") || lower.endsWith(".kts");
|
|
242
243
|
eachLine(content, (line) => {
|
|
@@ -689,16 +690,16 @@ function summarizeTypeScriptSource(relativePath, content) {
|
|
|
689
690
|
// src/ast/profiles/sfc.ts
|
|
690
691
|
var SCRIPT_BLOCK = /<script[^>]*>([\s\S]*?)<\/script>/gi;
|
|
691
692
|
var ASTRO_FRONTMATTER = /^\uFEFF?---[ \t]*\r?\n([\s\S]*?)\r?\n---[ \t]*(?=\r?\n|$)/;
|
|
692
|
-
function componentName(
|
|
693
|
-
const base =
|
|
693
|
+
function componentName(path14) {
|
|
694
|
+
const base = path14.split("/").pop() ?? path14;
|
|
694
695
|
return base.replace(/\.[^.]+$/, "");
|
|
695
696
|
}
|
|
696
697
|
var sfcProfile = {
|
|
697
698
|
id: "sfc",
|
|
698
699
|
extensions: [".vue", ".svelte", ".astro"],
|
|
699
|
-
summarize(
|
|
700
|
+
summarize(path14, content) {
|
|
700
701
|
let script = "";
|
|
701
|
-
if (
|
|
702
|
+
if (path14.toLowerCase().endsWith(".astro")) {
|
|
702
703
|
const frontmatter = ASTRO_FRONTMATTER.exec(content);
|
|
703
704
|
if (frontmatter) script += `${frontmatter[1]}
|
|
704
705
|
`;
|
|
@@ -707,7 +708,7 @@ var sfcProfile = {
|
|
|
707
708
|
script += `${match[1]}
|
|
708
709
|
`;
|
|
709
710
|
}
|
|
710
|
-
const name = componentName(
|
|
711
|
+
const name = componentName(path14);
|
|
711
712
|
if (!script.trim()) {
|
|
712
713
|
const summary2 = emptySummary();
|
|
713
714
|
if (name) {
|
|
@@ -741,15 +742,15 @@ for (const profile of LANGUAGE_PROFILES) {
|
|
|
741
742
|
BY_EXTENSION.set(extension.toLowerCase(), profile);
|
|
742
743
|
}
|
|
743
744
|
}
|
|
744
|
-
function profileForPath(
|
|
745
|
-
const lower =
|
|
745
|
+
function profileForPath(path14) {
|
|
746
|
+
const lower = path14.toLowerCase();
|
|
746
747
|
const dot = lower.lastIndexOf(".");
|
|
747
748
|
if (dot === -1) return null;
|
|
748
749
|
return BY_EXTENSION.get(lower.slice(dot)) ?? null;
|
|
749
750
|
}
|
|
750
|
-
function summarizeWithProfile(
|
|
751
|
-
const profile = profileForPath(
|
|
752
|
-
return profile ? profile.summarize(
|
|
751
|
+
function summarizeWithProfile(path14, content) {
|
|
752
|
+
const profile = profileForPath(path14);
|
|
753
|
+
return profile ? profile.summarize(path14, content) : null;
|
|
753
754
|
}
|
|
754
755
|
|
|
755
756
|
// src/ast/structured.ts
|
|
@@ -920,15 +921,15 @@ var SKIPPED_WALK_DIRS = /* @__PURE__ */ new Set([
|
|
|
920
921
|
]);
|
|
921
922
|
function readSmallFile(fullPath) {
|
|
922
923
|
try {
|
|
923
|
-
const stats =
|
|
924
|
+
const stats = fs12.statSync(fullPath);
|
|
924
925
|
if (!stats.isFile() || stats.size > MANIFEST_MAX_BYTES) return null;
|
|
925
|
-
return
|
|
926
|
+
return fs12.readFileSync(fullPath, "utf8");
|
|
926
927
|
} catch {
|
|
927
928
|
return null;
|
|
928
929
|
}
|
|
929
930
|
}
|
|
930
931
|
function readManifest(cwd, name) {
|
|
931
|
-
return readSmallFile(
|
|
932
|
+
return readSmallFile(path13.join(cwd, name));
|
|
932
933
|
}
|
|
933
934
|
function dependenciesFromPackageJson(raw) {
|
|
934
935
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -988,7 +989,7 @@ function pnpmWorkspacePatterns(raw) {
|
|
|
988
989
|
function childDirectories(cwd, parent) {
|
|
989
990
|
let entries;
|
|
990
991
|
try {
|
|
991
|
-
entries =
|
|
992
|
+
entries = fs12.readdirSync(path13.join(cwd, parent), { withFileTypes: true });
|
|
992
993
|
} catch {
|
|
993
994
|
return [];
|
|
994
995
|
}
|
|
@@ -1024,12 +1025,12 @@ function scanWorkspacePackages(cwd, patterns) {
|
|
|
1024
1025
|
const files = /* @__PURE__ */ new Set();
|
|
1025
1026
|
const dependencies = /* @__PURE__ */ new Set();
|
|
1026
1027
|
for (const relative7 of workspacePackageDirs(cwd, patterns)) {
|
|
1027
|
-
const full =
|
|
1028
|
+
const full = path13.join(cwd, relative7);
|
|
1028
1029
|
try {
|
|
1029
|
-
for (const entry of
|
|
1030
|
+
for (const entry of fs12.readdirSync(full, { withFileTypes: true })) files.add(entry.name);
|
|
1030
1031
|
} catch {
|
|
1031
1032
|
}
|
|
1032
|
-
const raw = readSmallFile(
|
|
1033
|
+
const raw = readSmallFile(path13.join(full, "package.json"));
|
|
1033
1034
|
if (raw !== null) {
|
|
1034
1035
|
for (const name of dependenciesFromPackageJson(raw)) dependencies.add(name);
|
|
1035
1036
|
}
|
|
@@ -1046,7 +1047,7 @@ function countMarkdownFiles(cwd) {
|
|
|
1046
1047
|
directoriesSeen += 1;
|
|
1047
1048
|
let entries;
|
|
1048
1049
|
try {
|
|
1049
|
-
entries =
|
|
1050
|
+
entries = fs12.readdirSync(current.dir, { withFileTypes: true });
|
|
1050
1051
|
} catch {
|
|
1051
1052
|
continue;
|
|
1052
1053
|
}
|
|
@@ -1057,7 +1058,7 @@ function countMarkdownFiles(cwd) {
|
|
|
1057
1058
|
}
|
|
1058
1059
|
if (!entry.isDirectory() || current.depth >= 2) continue;
|
|
1059
1060
|
if (entry.name.startsWith(".") || SKIPPED_WALK_DIRS.has(entry.name)) continue;
|
|
1060
|
-
queue.push({ dir:
|
|
1061
|
+
queue.push({ dir: path13.join(current.dir, entry.name), depth: current.depth + 1 });
|
|
1061
1062
|
}
|
|
1062
1063
|
}
|
|
1063
1064
|
return count;
|
|
@@ -1066,7 +1067,7 @@ function buildPresetContext(cwd) {
|
|
|
1066
1067
|
const files = /* @__PURE__ */ new Set();
|
|
1067
1068
|
const dirs = /* @__PURE__ */ new Set();
|
|
1068
1069
|
try {
|
|
1069
|
-
for (const entry of
|
|
1070
|
+
for (const entry of fs12.readdirSync(cwd, { withFileTypes: true })) {
|
|
1070
1071
|
if (entry.isDirectory()) dirs.add(entry.name);
|
|
1071
1072
|
else if (entry.isFile()) files.add(entry.name);
|
|
1072
1073
|
}
|
|
@@ -1083,7 +1084,7 @@ function buildPresetContext(cwd) {
|
|
|
1083
1084
|
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;
|
|
1084
1085
|
let workspace = { files: /* @__PURE__ */ new Set(), dependencies: /* @__PURE__ */ new Set() };
|
|
1085
1086
|
if (isWorkspace) {
|
|
1086
|
-
const pnpmRaw = files.has("pnpm-workspace.yaml") ? readSmallFile(
|
|
1087
|
+
const pnpmRaw = files.has("pnpm-workspace.yaml") ? readSmallFile(path13.join(cwd, "pnpm-workspace.yaml")) : null;
|
|
1087
1088
|
const declared = pnpmRaw === null ? [] : pnpmWorkspacePatterns(pnpmRaw);
|
|
1088
1089
|
const patterns = declared.length > 0 ? declared : declaredWorkspaces.length > 0 ? declaredWorkspaces : DEFAULT_WORKSPACE_PATTERNS;
|
|
1089
1090
|
workspace = scanWorkspacePackages(cwd, patterns);
|
|
@@ -2358,14 +2359,14 @@ var PRESET_IGNORES = new Set(
|
|
|
2358
2359
|
);
|
|
2359
2360
|
function readLinkTarget(linkPath, fallback) {
|
|
2360
2361
|
try {
|
|
2361
|
-
return
|
|
2362
|
+
return fs12.readlinkSync(linkPath);
|
|
2362
2363
|
} catch {
|
|
2363
2364
|
return fallback;
|
|
2364
2365
|
}
|
|
2365
2366
|
}
|
|
2366
2367
|
function isInside(root, candidate) {
|
|
2367
|
-
const relative7 =
|
|
2368
|
-
return relative7 === "" || !relative7.startsWith(`..${
|
|
2368
|
+
const relative7 = path13.relative(root, candidate);
|
|
2369
|
+
return relative7 === "" || !relative7.startsWith(`..${path13.sep}`) && relative7 !== ".." && !path13.isAbsolute(relative7);
|
|
2369
2370
|
}
|
|
2370
2371
|
function getGitInfo(cwd, fallbackBranch = "main") {
|
|
2371
2372
|
try {
|
|
@@ -2570,10 +2571,10 @@ function trimUnescapedTrailingSpaces(line) {
|
|
|
2570
2571
|
return line.slice(0, end);
|
|
2571
2572
|
}
|
|
2572
2573
|
function readGitignoreRules(dir) {
|
|
2573
|
-
const gitignorePath2 =
|
|
2574
|
+
const gitignorePath2 = path13.join(dir, ".gitignore");
|
|
2574
2575
|
let raw;
|
|
2575
2576
|
try {
|
|
2576
|
-
raw =
|
|
2577
|
+
raw = fs12.readFileSync(gitignorePath2, "utf8");
|
|
2577
2578
|
} catch {
|
|
2578
2579
|
return [];
|
|
2579
2580
|
}
|
|
@@ -2700,7 +2701,7 @@ function isToolOwnedDirName(name) {
|
|
|
2700
2701
|
}
|
|
2701
2702
|
function hasSnapshotMarker(target) {
|
|
2702
2703
|
try {
|
|
2703
|
-
return
|
|
2704
|
+
return fs12.statSync(target).isDirectory() && fs12.existsSync(path13.join(target, ".codebase-snapshot"));
|
|
2704
2705
|
} catch {
|
|
2705
2706
|
return false;
|
|
2706
2707
|
}
|
|
@@ -2714,7 +2715,7 @@ function makeToolOwnedDecider(cwd, toolOwnedPaths) {
|
|
|
2714
2715
|
const prefix = parts.slice(0, depth).join("/");
|
|
2715
2716
|
let hasMarker = markers.get(prefix);
|
|
2716
2717
|
if (hasMarker === void 0) {
|
|
2717
|
-
hasMarker =
|
|
2718
|
+
hasMarker = fs12.existsSync(path13.join(cwd, prefix, ".codebase-snapshot"));
|
|
2718
2719
|
markers.set(prefix, hasMarker);
|
|
2719
2720
|
}
|
|
2720
2721
|
if (hasMarker) return true;
|
|
@@ -2729,7 +2730,7 @@ function makeLinkProbe() {
|
|
|
2729
2730
|
let known = cache.get(absolutePath);
|
|
2730
2731
|
if (known === void 0) {
|
|
2731
2732
|
try {
|
|
2732
|
-
known =
|
|
2733
|
+
known = fs12.lstatSync(absolutePath).isSymbolicLink();
|
|
2733
2734
|
} catch {
|
|
2734
2735
|
known = false;
|
|
2735
2736
|
}
|
|
@@ -2742,7 +2743,7 @@ function dropLinkedDirectories(cwd, candidates, skipped) {
|
|
|
2742
2743
|
const isLink = makeLinkProbe();
|
|
2743
2744
|
let rootReal = cwd;
|
|
2744
2745
|
try {
|
|
2745
|
-
rootReal =
|
|
2746
|
+
rootReal = fs12.realpathSync(cwd);
|
|
2746
2747
|
} catch {
|
|
2747
2748
|
}
|
|
2748
2749
|
const reported = /* @__PURE__ */ new Set();
|
|
@@ -2752,7 +2753,7 @@ function dropLinkedDirectories(cwd, candidates, skipped) {
|
|
|
2752
2753
|
let linkedDir = null;
|
|
2753
2754
|
for (let depth = 1; depth <= parts.length; depth += 1) {
|
|
2754
2755
|
const prefix = parts.slice(0, depth).join("/");
|
|
2755
|
-
if (isLink(
|
|
2756
|
+
if (isLink(path13.join(cwd, prefix))) {
|
|
2756
2757
|
linkedDir = prefix;
|
|
2757
2758
|
break;
|
|
2758
2759
|
}
|
|
@@ -2763,10 +2764,10 @@ function dropLinkedDirectories(cwd, candidates, skipped) {
|
|
|
2763
2764
|
}
|
|
2764
2765
|
if (reported.has(linkedDir)) continue;
|
|
2765
2766
|
reported.add(linkedDir);
|
|
2766
|
-
const absolute =
|
|
2767
|
+
const absolute = path13.join(cwd, linkedDir);
|
|
2767
2768
|
let targetReal = absolute;
|
|
2768
2769
|
try {
|
|
2769
|
-
targetReal =
|
|
2770
|
+
targetReal = fs12.realpathSync(absolute);
|
|
2770
2771
|
} catch {
|
|
2771
2772
|
}
|
|
2772
2773
|
const target = readLinkTarget(absolute, targetReal);
|
|
@@ -2843,7 +2844,7 @@ function collectFiles(cwd, options = {}) {
|
|
|
2843
2844
|
"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."
|
|
2844
2845
|
);
|
|
2845
2846
|
}
|
|
2846
|
-
if (
|
|
2847
|
+
if (fs12.existsSync(path13.join(cwd, ".git"))) {
|
|
2847
2848
|
throw new Error(
|
|
2848
2849
|
"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."
|
|
2849
2850
|
);
|
|
@@ -2902,7 +2903,7 @@ function collectFiles(cwd, options = {}) {
|
|
|
2902
2903
|
}
|
|
2903
2904
|
function rootRealFor(root) {
|
|
2904
2905
|
try {
|
|
2905
|
-
return
|
|
2906
|
+
return fs12.realpathSync(root);
|
|
2906
2907
|
} catch {
|
|
2907
2908
|
return root;
|
|
2908
2909
|
}
|
|
@@ -2910,18 +2911,18 @@ function rootRealFor(root) {
|
|
|
2910
2911
|
function walkDirectory(dir, baseDir, rootReal, visited, reservedPaths = /* @__PURE__ */ new Set(), parentGitignoreLayers = []) {
|
|
2911
2912
|
const results = { files: [], skipped: [] };
|
|
2912
2913
|
const stack = [];
|
|
2913
|
-
const relativeToBase = (target) =>
|
|
2914
|
+
const relativeToBase = (target) => path13.relative(baseDir, target).replace(/\\/g, "/") || ".";
|
|
2914
2915
|
const enter = (current, layers) => {
|
|
2915
2916
|
if (visited.has(current)) return false;
|
|
2916
2917
|
visited.add(current);
|
|
2917
2918
|
const localRules = readGitignoreRules(current);
|
|
2918
2919
|
const gitignoreLayers = localRules.length === 0 ? layers : [
|
|
2919
2920
|
...layers,
|
|
2920
|
-
{ prefix:
|
|
2921
|
+
{ prefix: path13.relative(baseDir, current).replace(/\\/g, "/"), rules: localRules }
|
|
2921
2922
|
];
|
|
2922
2923
|
let entries;
|
|
2923
2924
|
try {
|
|
2924
|
-
entries =
|
|
2925
|
+
entries = fs12.readdirSync(current, { withFileTypes: true });
|
|
2925
2926
|
} catch {
|
|
2926
2927
|
results.skipped.push({
|
|
2927
2928
|
path: relativeToBase(current),
|
|
@@ -2943,8 +2944,8 @@ function walkDirectory(dir, baseDir, rootReal, visited, reservedPaths = /* @__PU
|
|
|
2943
2944
|
}
|
|
2944
2945
|
const entry = frame.entries[frame.index];
|
|
2945
2946
|
frame.index += 1;
|
|
2946
|
-
const fullPath =
|
|
2947
|
-
const relPath =
|
|
2947
|
+
const fullPath = path13.join(frame.dir, entry.name);
|
|
2948
|
+
const relPath = path13.relative(baseDir, fullPath).replace(/\\/g, "/");
|
|
2948
2949
|
if (isToolOwnedDirName(entry.name) && reservedPaths.has(relPath)) continue;
|
|
2949
2950
|
if (DEFAULT_IGNORED_DIRS.includes(entry.name)) {
|
|
2950
2951
|
results.skipped.push({
|
|
@@ -2977,14 +2978,14 @@ function walkDirectory(dir, baseDir, rootReal, visited, reservedPaths = /* @__PU
|
|
|
2977
2978
|
if (entry.isSymbolicLink()) {
|
|
2978
2979
|
let targetReal;
|
|
2979
2980
|
try {
|
|
2980
|
-
targetReal =
|
|
2981
|
+
targetReal = fs12.realpathSync(fullPath);
|
|
2981
2982
|
} catch {
|
|
2982
2983
|
results.skipped.push({ path: relPath, reason: "read-error", detail: "broken symlink" });
|
|
2983
2984
|
continue;
|
|
2984
2985
|
}
|
|
2985
2986
|
let stats;
|
|
2986
2987
|
try {
|
|
2987
|
-
stats =
|
|
2988
|
+
stats = fs12.statSync(fullPath);
|
|
2988
2989
|
} catch {
|
|
2989
2990
|
results.skipped.push({ path: relPath, reason: "read-error", detail: "unreadable symlink" });
|
|
2990
2991
|
continue;
|
|
@@ -3039,13 +3040,13 @@ var CONFIG_FILENAMES = [
|
|
|
3039
3040
|
];
|
|
3040
3041
|
function findConfigFile(cwd) {
|
|
3041
3042
|
for (const filename of CONFIG_FILENAMES) {
|
|
3042
|
-
const fullPath =
|
|
3043
|
-
if (
|
|
3043
|
+
const fullPath = path13.join(cwd, filename);
|
|
3044
|
+
if (fs12.existsSync(fullPath)) return fullPath;
|
|
3044
3045
|
}
|
|
3045
|
-
const pkgJsonPath =
|
|
3046
|
-
if (!
|
|
3046
|
+
const pkgJsonPath = path13.join(cwd, "package.json");
|
|
3047
|
+
if (!fs12.existsSync(pkgJsonPath)) return null;
|
|
3047
3048
|
try {
|
|
3048
|
-
const parsed = JSON.parse(
|
|
3049
|
+
const parsed = JSON.parse(fs12.readFileSync(pkgJsonPath, "utf8"));
|
|
3049
3050
|
return parsed.snapshot === void 0 ? null : pkgJsonPath;
|
|
3050
3051
|
} catch {
|
|
3051
3052
|
return null;
|
|
@@ -3296,11 +3297,11 @@ async function loadConfigFileDetailed(cwd) {
|
|
|
3296
3297
|
const warnings = [];
|
|
3297
3298
|
const errors = [];
|
|
3298
3299
|
for (const filename of CONFIG_FILENAMES) {
|
|
3299
|
-
const fullPath =
|
|
3300
|
-
if (!
|
|
3300
|
+
const fullPath = path13.join(cwd, filename);
|
|
3301
|
+
if (!fs12.existsSync(fullPath)) continue;
|
|
3301
3302
|
if (filename.endsWith(".json") || filename === ".snapshotrc") {
|
|
3302
3303
|
try {
|
|
3303
|
-
const config = parseJsonish(
|
|
3304
|
+
const config = parseJsonish(fs12.readFileSync(fullPath, "utf8"), fullPath);
|
|
3304
3305
|
if (config === null || typeof config !== "object" || Array.isArray(config)) {
|
|
3305
3306
|
throw new Error(
|
|
3306
3307
|
`${fullPath} does not hold a configuration object (received ${describeValue2(config)}).`
|
|
@@ -3334,10 +3335,10 @@ async function loadConfigFileDetailed(cwd) {
|
|
|
3334
3335
|
continue;
|
|
3335
3336
|
}
|
|
3336
3337
|
}
|
|
3337
|
-
const pkgJsonPath =
|
|
3338
|
-
if (
|
|
3338
|
+
const pkgJsonPath = path13.join(cwd, "package.json");
|
|
3339
|
+
if (fs12.existsSync(pkgJsonPath)) {
|
|
3339
3340
|
try {
|
|
3340
|
-
const parsed = parseJsonish(
|
|
3341
|
+
const parsed = parseJsonish(fs12.readFileSync(pkgJsonPath, "utf8"), pkgJsonPath);
|
|
3341
3342
|
const snapshotKey = parsed.snapshot;
|
|
3342
3343
|
if (snapshotKey && typeof snapshotKey === "object" && !Array.isArray(snapshotKey)) {
|
|
3343
3344
|
return { config: snapshotKey, file: pkgJsonPath, warnings, errors };
|
|
@@ -3360,7 +3361,7 @@ async function loadConfigFile(cwd) {
|
|
|
3360
3361
|
const loaded = await loadConfigFileDetailed(cwd);
|
|
3361
3362
|
if (loaded.config && loaded.file && typeof loaded.config === "object") {
|
|
3362
3363
|
Object.defineProperty(loaded.config, CONFIG_DIR_SYMBOL, {
|
|
3363
|
-
value:
|
|
3364
|
+
value: path13.dirname(loaded.file),
|
|
3364
3365
|
enumerable: false,
|
|
3365
3366
|
configurable: true
|
|
3366
3367
|
});
|
|
@@ -3519,9 +3520,9 @@ function resolveKindRules(value) {
|
|
|
3519
3520
|
function outputExcludePatterns(cwd, outDir, tmpDir) {
|
|
3520
3521
|
const patterns = [];
|
|
3521
3522
|
for (const dir of [outDir, tmpDir]) {
|
|
3522
|
-
const absolute =
|
|
3523
|
-
const relative7 =
|
|
3524
|
-
if (!relative7 || relative7 === ".." || relative7.startsWith(`..${
|
|
3523
|
+
const absolute = path13.resolve(cwd, dir);
|
|
3524
|
+
const relative7 = path13.relative(cwd, absolute);
|
|
3525
|
+
if (!relative7 || relative7 === ".." || relative7.startsWith(`..${path13.sep}`) || path13.isAbsolute(relative7)) {
|
|
3525
3526
|
continue;
|
|
3526
3527
|
}
|
|
3527
3528
|
patterns.push(`${relative7.replace(/\\/g, "/")}/**`);
|
|
@@ -3640,11 +3641,11 @@ function resolveCandidateCwd(userConfig, cliOptions, baseDir) {
|
|
|
3640
3641
|
);
|
|
3641
3642
|
}
|
|
3642
3643
|
const candidate = cliOptions?.cwd || userConfig?.cwd || baseDir || process.cwd();
|
|
3643
|
-
const resolved =
|
|
3644
|
-
if (!
|
|
3644
|
+
const resolved = path13.resolve(candidate);
|
|
3645
|
+
if (!fs12.existsSync(resolved)) {
|
|
3645
3646
|
throw new Error(`Working directory does not exist: ${resolved}`);
|
|
3646
3647
|
}
|
|
3647
|
-
if (!
|
|
3648
|
+
if (!fs12.statSync(resolved).isDirectory()) {
|
|
3648
3649
|
throw new Error(`Working directory is not a directory: ${resolved}`);
|
|
3649
3650
|
}
|
|
3650
3651
|
return resolved;
|
|
@@ -4668,7 +4669,7 @@ var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
4668
4669
|
".so"
|
|
4669
4670
|
]);
|
|
4670
4671
|
function isBinaryExtension(filePath) {
|
|
4671
|
-
const ext =
|
|
4672
|
+
const ext = path13.extname(filePath).toLowerCase();
|
|
4672
4673
|
return BINARY_EXTENSIONS.has(ext);
|
|
4673
4674
|
}
|
|
4674
4675
|
function isBinaryBuffer(buffer) {
|
|
@@ -4838,13 +4839,13 @@ function isBinaryFile(absolutePath) {
|
|
|
4838
4839
|
if (isBinaryExtension(absolutePath)) return true;
|
|
4839
4840
|
let fd;
|
|
4840
4841
|
try {
|
|
4841
|
-
fd =
|
|
4842
|
+
fd = fs12.openSync(absolutePath, "r");
|
|
4842
4843
|
const buffer = Buffer.alloc(CHUNK);
|
|
4843
4844
|
let sample;
|
|
4844
4845
|
let position = 0;
|
|
4845
4846
|
while (position < BINARY_SCAN_BYTES) {
|
|
4846
4847
|
const wanted = Math.min(CHUNK, BINARY_SCAN_BYTES - position);
|
|
4847
|
-
const bytesRead =
|
|
4848
|
+
const bytesRead = fs12.readSync(fd, buffer, 0, wanted, position);
|
|
4848
4849
|
if (bytesRead === 0) return false;
|
|
4849
4850
|
const chunk = buffer.subarray(0, bytesRead);
|
|
4850
4851
|
if (sample === void 0) {
|
|
@@ -4862,7 +4863,7 @@ function isBinaryFile(absolutePath) {
|
|
|
4862
4863
|
} finally {
|
|
4863
4864
|
if (fd !== void 0) {
|
|
4864
4865
|
try {
|
|
4865
|
-
|
|
4866
|
+
fs12.closeSync(fd);
|
|
4866
4867
|
} catch {
|
|
4867
4868
|
}
|
|
4868
4869
|
}
|
|
@@ -4922,10 +4923,10 @@ var LANGUAGE_BY_BASENAME = {
|
|
|
4922
4923
|
};
|
|
4923
4924
|
function detectLanguage(filePath) {
|
|
4924
4925
|
const normalized = filePath.replace(/\\/g, "/");
|
|
4925
|
-
const base =
|
|
4926
|
+
const base = path13.posix.basename(normalized);
|
|
4926
4927
|
if (LANGUAGE_BY_BASENAME[base]) return LANGUAGE_BY_BASENAME[base];
|
|
4927
4928
|
if (base === ".env" || base.startsWith(".env.")) return "dotenv";
|
|
4928
|
-
const ext =
|
|
4929
|
+
const ext = path13.posix.extname(base).toLowerCase();
|
|
4929
4930
|
return LANGUAGE_BY_EXTENSION[ext] ?? "text";
|
|
4930
4931
|
}
|
|
4931
4932
|
function maskedPath(value, secretRules) {
|
|
@@ -4933,33 +4934,33 @@ function maskedPath(value, secretRules) {
|
|
|
4933
4934
|
}
|
|
4934
4935
|
function confineToDirectory(directory, filename) {
|
|
4935
4936
|
if (filename.includes("\0")) return null;
|
|
4936
|
-
if (
|
|
4937
|
-
const base =
|
|
4938
|
-
const resolved =
|
|
4937
|
+
if (path13.isAbsolute(filename)) return null;
|
|
4938
|
+
const base = path13.resolve(directory);
|
|
4939
|
+
const resolved = path13.resolve(base, filename);
|
|
4939
4940
|
const caseInsensitive = process.platform === "win32" || process.platform === "darwin";
|
|
4940
|
-
const prefix = caseInsensitive ? `${base}${
|
|
4941
|
+
const prefix = caseInsensitive ? `${base}${path13.sep}`.toLowerCase() : `${base}${path13.sep}`;
|
|
4941
4942
|
const candidate = caseInsensitive ? resolved.toLowerCase() : resolved;
|
|
4942
4943
|
return candidate.startsWith(prefix) ? resolved : null;
|
|
4943
4944
|
}
|
|
4944
4945
|
function findStagingDirectory(config) {
|
|
4945
|
-
const tmpDir =
|
|
4946
|
+
const tmpDir = path13.resolve(config.cwd, config.tmpDir);
|
|
4946
4947
|
let entries;
|
|
4947
4948
|
try {
|
|
4948
|
-
entries =
|
|
4949
|
+
entries = fs12.readdirSync(tmpDir);
|
|
4949
4950
|
} catch {
|
|
4950
4951
|
return null;
|
|
4951
4952
|
}
|
|
4952
4953
|
const runs = entries.filter((name) => name.startsWith("run-")).sort();
|
|
4953
4954
|
const newest = runs[runs.length - 1];
|
|
4954
|
-
return newest ?
|
|
4955
|
+
return newest ? path13.join(tmpDir, newest) : null;
|
|
4955
4956
|
}
|
|
4956
4957
|
function describeMissingManifest(config, manifestPath) {
|
|
4957
|
-
const outDir =
|
|
4958
|
-
const markerPath =
|
|
4958
|
+
const outDir = path13.resolve(config.cwd, config.outDir);
|
|
4959
|
+
const markerPath = path13.join(outDir, ".codebase-snapshot");
|
|
4959
4960
|
let marker2 = null;
|
|
4960
4961
|
try {
|
|
4961
|
-
if (
|
|
4962
|
-
const parsed = JSON.parse(
|
|
4962
|
+
if (fs12.existsSync(markerPath)) {
|
|
4963
|
+
const parsed = JSON.parse(fs12.readFileSync(markerPath, "utf8"));
|
|
4963
4964
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
4964
4965
|
marker2 = parsed;
|
|
4965
4966
|
}
|
|
@@ -4995,14 +4996,14 @@ function sha256Hex(buffer) {
|
|
|
4995
4996
|
}
|
|
4996
4997
|
var VERIFY_SNIFF_MAX_BYTES = 8 * 1024 * 1024;
|
|
4997
4998
|
function wouldNowBeIncluded(cwd, relativePath, reason) {
|
|
4998
|
-
const absolutePath =
|
|
4999
|
+
const absolutePath = path13.join(cwd, relativePath);
|
|
4999
5000
|
try {
|
|
5000
|
-
const stats =
|
|
5001
|
+
const stats = fs12.statSync(absolutePath);
|
|
5001
5002
|
if (!stats.isFile()) return false;
|
|
5002
5003
|
if (isBinaryFile(absolutePath)) return false;
|
|
5003
5004
|
if (reason !== "binary") return true;
|
|
5004
5005
|
if (stats.size > VERIFY_SNIFF_MAX_BYTES) return false;
|
|
5005
|
-
return !decodeText(
|
|
5006
|
+
return !decodeText(fs12.readFileSync(absolutePath)).binary;
|
|
5006
5007
|
} catch {
|
|
5007
5008
|
return false;
|
|
5008
5009
|
}
|
|
@@ -5060,8 +5061,8 @@ function describeManifestShapeProblem(value) {
|
|
|
5060
5061
|
function validateSnapshot(configInput) {
|
|
5061
5062
|
assertUsableConfigInput(configInput);
|
|
5062
5063
|
const config = isResolvedConfig(configInput) ? normalizeResolvedConfig(configInput) : resolveConfig(configInput);
|
|
5063
|
-
const manifestPath =
|
|
5064
|
-
if (!
|
|
5064
|
+
const manifestPath = path13.resolve(config.cwd, config.outDir, "manifest.json");
|
|
5065
|
+
if (!fs12.existsSync(manifestPath)) {
|
|
5065
5066
|
return {
|
|
5066
5067
|
valid: false,
|
|
5067
5068
|
manifestPresent: false,
|
|
@@ -5072,7 +5073,7 @@ function validateSnapshot(configInput) {
|
|
|
5072
5073
|
}
|
|
5073
5074
|
let manifest;
|
|
5074
5075
|
try {
|
|
5075
|
-
manifest = JSON.parse(
|
|
5076
|
+
manifest = JSON.parse(fs12.readFileSync(manifestPath, "utf8"));
|
|
5076
5077
|
} catch (err) {
|
|
5077
5078
|
return {
|
|
5078
5079
|
valid: false,
|
|
@@ -5094,7 +5095,7 @@ function validateSnapshot(configInput) {
|
|
|
5094
5095
|
}
|
|
5095
5096
|
const drift = emptyDrift();
|
|
5096
5097
|
const warnings = [];
|
|
5097
|
-
const snapshotDir =
|
|
5098
|
+
const snapshotDir = path13.resolve(config.cwd, config.outDir);
|
|
5098
5099
|
const manifestFileMap = /* @__PURE__ */ new Map();
|
|
5099
5100
|
for (const file of manifest.files) {
|
|
5100
5101
|
if (file && typeof file.relativePath === "string") {
|
|
@@ -5128,7 +5129,7 @@ function validateSnapshot(configInput) {
|
|
|
5128
5129
|
}
|
|
5129
5130
|
let diskHash;
|
|
5130
5131
|
try {
|
|
5131
|
-
diskHash = sha256Hex(
|
|
5132
|
+
diskHash = sha256Hex(fs12.readFileSync(path13.join(config.cwd, diskFile)));
|
|
5132
5133
|
} catch (err) {
|
|
5133
5134
|
if (err.code === "ENOENT") {
|
|
5134
5135
|
drift.missingOnDisk.push(diskFile);
|
|
@@ -5152,7 +5153,7 @@ function validateSnapshot(configInput) {
|
|
|
5152
5153
|
}
|
|
5153
5154
|
let statFailure = null;
|
|
5154
5155
|
try {
|
|
5155
|
-
|
|
5156
|
+
fs12.statSync(confined);
|
|
5156
5157
|
} catch (err) {
|
|
5157
5158
|
statFailure = err;
|
|
5158
5159
|
}
|
|
@@ -5172,7 +5173,7 @@ function validateSnapshot(configInput) {
|
|
|
5172
5173
|
...Object.values(config.budgets.byLayer)
|
|
5173
5174
|
);
|
|
5174
5175
|
const partNames = /* @__PURE__ */ new Set();
|
|
5175
|
-
const partsDir =
|
|
5176
|
+
const partsDir = path13.join(snapshotDir, "parts");
|
|
5176
5177
|
for (const part of manifest.parts) {
|
|
5177
5178
|
if (!part || typeof part.filename !== "string") continue;
|
|
5178
5179
|
partNames.add(part.filename);
|
|
@@ -5187,7 +5188,7 @@ function validateSnapshot(configInput) {
|
|
|
5187
5188
|
}
|
|
5188
5189
|
let buffer;
|
|
5189
5190
|
try {
|
|
5190
|
-
buffer =
|
|
5191
|
+
buffer = fs12.readFileSync(partPath);
|
|
5191
5192
|
} catch {
|
|
5192
5193
|
drift.partIssues.push({ part: part.filename, issue: "missing from snapshot/parts" });
|
|
5193
5194
|
continue;
|
|
@@ -5401,9 +5402,9 @@ function validateSnapshot(configInput) {
|
|
|
5401
5402
|
["full-codebase.md", manifest.artifacts?.fullMarkdown]
|
|
5402
5403
|
]) {
|
|
5403
5404
|
if (!artifact) continue;
|
|
5404
|
-
const artifactPath =
|
|
5405
|
+
const artifactPath = path13.join(snapshotDir, key);
|
|
5405
5406
|
try {
|
|
5406
|
-
const buffer =
|
|
5407
|
+
const buffer = fs12.readFileSync(artifactPath);
|
|
5407
5408
|
if (sha256Hex(buffer) !== artifact.sha256 || buffer.length !== artifact.byteSize) {
|
|
5408
5409
|
drift.partIssues.push({ part: key, issue: "artifact does not match its recorded digest" });
|
|
5409
5410
|
}
|
|
@@ -5473,12 +5474,168 @@ function validateSnapshot(configInput) {
|
|
|
5473
5474
|
|
|
5474
5475
|
// src/version.ts
|
|
5475
5476
|
var GENERATOR_NAME = "codebase-snapshot";
|
|
5476
|
-
var GENERATOR_VERSION = "0.9.
|
|
5477
|
+
var GENERATOR_VERSION = "0.9.6";
|
|
5477
5478
|
var LEGACY_GENERATOR_NAMES = ["@ankurhalder/codebase-snapshot"];
|
|
5478
5479
|
function isOurGeneratorName(name) {
|
|
5479
5480
|
if (typeof name !== "string") return false;
|
|
5480
5481
|
return name === GENERATOR_NAME || LEGACY_GENERATOR_NAMES.includes(name);
|
|
5481
5482
|
}
|
|
5483
|
+
var PACKAGE_LATEST_URL = "https://registry.npmjs.org/codebase-snapshot/latest";
|
|
5484
|
+
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
5485
|
+
var FAILURE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
5486
|
+
var REQUEST_TIMEOUT_MS = 1200;
|
|
5487
|
+
function versionParts(value) {
|
|
5488
|
+
const core = value.trim().replace(/^v/i, "").split("-")[0];
|
|
5489
|
+
return core.split(".").map((part) => {
|
|
5490
|
+
const parsed = Number(part);
|
|
5491
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
5492
|
+
});
|
|
5493
|
+
}
|
|
5494
|
+
function isNewer(candidate, current) {
|
|
5495
|
+
const left = versionParts(candidate);
|
|
5496
|
+
const right = versionParts(current);
|
|
5497
|
+
const length = Math.max(left.length, right.length);
|
|
5498
|
+
for (let index = 0; index < length; index += 1) {
|
|
5499
|
+
const a = left[index] ?? 0;
|
|
5500
|
+
const b = right[index] ?? 0;
|
|
5501
|
+
if (a !== b) return a > b;
|
|
5502
|
+
}
|
|
5503
|
+
return false;
|
|
5504
|
+
}
|
|
5505
|
+
function cacheDirectory(env = process.env, platform = process.platform) {
|
|
5506
|
+
if (platform === "win32") {
|
|
5507
|
+
const base2 = env.LOCALAPPDATA ?? path13.join(os.homedir(), "AppData", "Local");
|
|
5508
|
+
return path13.join(base2, "codebase-snapshot");
|
|
5509
|
+
}
|
|
5510
|
+
if (platform === "darwin") {
|
|
5511
|
+
return path13.join(os.homedir(), "Library", "Caches", "codebase-snapshot");
|
|
5512
|
+
}
|
|
5513
|
+
const base = env.XDG_CACHE_HOME ?? path13.join(os.homedir(), ".cache");
|
|
5514
|
+
return path13.join(base, "codebase-snapshot");
|
|
5515
|
+
}
|
|
5516
|
+
function cacheFilePath(env = process.env) {
|
|
5517
|
+
return path13.join(cacheDirectory(env), "update-check.json");
|
|
5518
|
+
}
|
|
5519
|
+
function shouldCheck(argv, env) {
|
|
5520
|
+
const disabled = ["1", "true", "yes"].includes(
|
|
5521
|
+
String(env.CODEBASE_SNAPSHOT_NO_UPDATE_CHECK ?? "").toLowerCase()
|
|
5522
|
+
);
|
|
5523
|
+
if (disabled) return false;
|
|
5524
|
+
if (env.CI !== void 0 && env.CI !== "" && env.CI !== "false" && env.CI !== "0") return false;
|
|
5525
|
+
const args = argv.map((argument) => argument.toLowerCase());
|
|
5526
|
+
if (args.includes("--no-update-check")) return false;
|
|
5527
|
+
for (const skip of ["mcp", "describe", "skill", "--version", "-v", "--help", "-h"]) {
|
|
5528
|
+
if (args.includes(skip)) return false;
|
|
5529
|
+
}
|
|
5530
|
+
if (args.some((argument) => argument.includes("json"))) return false;
|
|
5531
|
+
return true;
|
|
5532
|
+
}
|
|
5533
|
+
function readCache(file) {
|
|
5534
|
+
let raw;
|
|
5535
|
+
try {
|
|
5536
|
+
raw = fs12.readFileSync(file, "utf8");
|
|
5537
|
+
} catch {
|
|
5538
|
+
return null;
|
|
5539
|
+
}
|
|
5540
|
+
try {
|
|
5541
|
+
const parsed = JSON.parse(raw);
|
|
5542
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
5543
|
+
const candidate = parsed;
|
|
5544
|
+
if (typeof candidate.checkedAt !== "number") return null;
|
|
5545
|
+
const latest = typeof candidate.latest === "string" ? candidate.latest : null;
|
|
5546
|
+
return { checkedAt: candidate.checkedAt, latest };
|
|
5547
|
+
} catch {
|
|
5548
|
+
return null;
|
|
5549
|
+
}
|
|
5550
|
+
}
|
|
5551
|
+
function writeCache(file, entry) {
|
|
5552
|
+
try {
|
|
5553
|
+
fs12.mkdirSync(path13.dirname(file), { recursive: true });
|
|
5554
|
+
fs12.writeFileSync(file, `${JSON.stringify(entry)}
|
|
5555
|
+
`, "utf8");
|
|
5556
|
+
} catch {
|
|
5557
|
+
}
|
|
5558
|
+
}
|
|
5559
|
+
function fetchLatestVersion(url = PACKAGE_LATEST_URL, timeoutMs = REQUEST_TIMEOUT_MS) {
|
|
5560
|
+
return new Promise((resolve5) => {
|
|
5561
|
+
let settled = false;
|
|
5562
|
+
const finish = (value) => {
|
|
5563
|
+
if (settled) return;
|
|
5564
|
+
settled = true;
|
|
5565
|
+
resolve5(value);
|
|
5566
|
+
};
|
|
5567
|
+
const request = https.get(
|
|
5568
|
+
url,
|
|
5569
|
+
{
|
|
5570
|
+
headers: {
|
|
5571
|
+
accept: "application/json",
|
|
5572
|
+
"user-agent": "codebase-snapshot (update check)"
|
|
5573
|
+
}
|
|
5574
|
+
},
|
|
5575
|
+
(response) => {
|
|
5576
|
+
if (response.statusCode !== 200) {
|
|
5577
|
+
response.resume();
|
|
5578
|
+
finish(null);
|
|
5579
|
+
return;
|
|
5580
|
+
}
|
|
5581
|
+
let body = "";
|
|
5582
|
+
response.setEncoding("utf8");
|
|
5583
|
+
response.on("data", (chunk) => {
|
|
5584
|
+
body += chunk;
|
|
5585
|
+
if (body.length > 64 * 1024) {
|
|
5586
|
+
request.destroy();
|
|
5587
|
+
finish(null);
|
|
5588
|
+
}
|
|
5589
|
+
});
|
|
5590
|
+
response.on("end", () => {
|
|
5591
|
+
try {
|
|
5592
|
+
const parsed = JSON.parse(body);
|
|
5593
|
+
finish(typeof parsed.version === "string" ? parsed.version : null);
|
|
5594
|
+
} catch {
|
|
5595
|
+
finish(null);
|
|
5596
|
+
}
|
|
5597
|
+
});
|
|
5598
|
+
}
|
|
5599
|
+
);
|
|
5600
|
+
request.on("error", () => finish(null));
|
|
5601
|
+
request.setTimeout(timeoutMs, () => {
|
|
5602
|
+
request.destroy();
|
|
5603
|
+
finish(null);
|
|
5604
|
+
});
|
|
5605
|
+
});
|
|
5606
|
+
}
|
|
5607
|
+
async function checkForUpdate(options) {
|
|
5608
|
+
if (options.enabled === false) return null;
|
|
5609
|
+
const now = options.now ?? (() => Date.now());
|
|
5610
|
+
const fetchLatest = options.fetchLatest ?? fetchLatestVersion;
|
|
5611
|
+
let latest = null;
|
|
5612
|
+
try {
|
|
5613
|
+
const cached = readCache(options.cacheFile);
|
|
5614
|
+
let needsFetch = cached === null;
|
|
5615
|
+
if (cached) {
|
|
5616
|
+
const age = now() - cached.checkedAt;
|
|
5617
|
+
if (cached.latest === null) {
|
|
5618
|
+
needsFetch = age >= FAILURE_INTERVAL_MS;
|
|
5619
|
+
} else {
|
|
5620
|
+
latest = cached.latest;
|
|
5621
|
+
needsFetch = age >= CHECK_INTERVAL_MS;
|
|
5622
|
+
}
|
|
5623
|
+
}
|
|
5624
|
+
if (needsFetch) {
|
|
5625
|
+
const fetched = await fetchLatest(PACKAGE_LATEST_URL, REQUEST_TIMEOUT_MS);
|
|
5626
|
+
writeCache(options.cacheFile, { checkedAt: now(), latest: fetched });
|
|
5627
|
+
latest = fetched;
|
|
5628
|
+
}
|
|
5629
|
+
} catch {
|
|
5630
|
+
return null;
|
|
5631
|
+
}
|
|
5632
|
+
if (!latest) return null;
|
|
5633
|
+
return isNewer(latest, options.current) ? { current: options.current, latest } : null;
|
|
5634
|
+
}
|
|
5635
|
+
function formatUpdateNotice(notice) {
|
|
5636
|
+
return `\u2191 codebase-snapshot ${notice.latest} is available \u2014 you have ${notice.current}.
|
|
5637
|
+
npm install -g codebase-snapshot`;
|
|
5638
|
+
}
|
|
5482
5639
|
function describeMatcher(matcher) {
|
|
5483
5640
|
if (typeof matcher === "string") return matcher;
|
|
5484
5641
|
if (matcher instanceof RegExp) return String(matcher);
|
|
@@ -5488,10 +5645,10 @@ function describeMatcher(matcher) {
|
|
|
5488
5645
|
return String(matcher);
|
|
5489
5646
|
}
|
|
5490
5647
|
function normalizeTarget(cwd, target) {
|
|
5491
|
-
const absolute =
|
|
5492
|
-
const relative7 =
|
|
5493
|
-
if (relative7.startsWith("..") ||
|
|
5494
|
-
return relative7.split(
|
|
5648
|
+
const absolute = path13.resolve(cwd, target);
|
|
5649
|
+
const relative7 = path13.relative(cwd, absolute);
|
|
5650
|
+
if (relative7.startsWith("..") || path13.isAbsolute(relative7)) return target;
|
|
5651
|
+
return relative7.split(path13.sep).join("/");
|
|
5495
5652
|
}
|
|
5496
5653
|
function findRuleMatch(rules, relativePath) {
|
|
5497
5654
|
return rules.find(
|
|
@@ -5510,20 +5667,20 @@ function findRecordedAncestor(skipped, relative7, maskedPath2) {
|
|
|
5510
5667
|
return nearest;
|
|
5511
5668
|
}
|
|
5512
5669
|
function readManifest2(config) {
|
|
5513
|
-
const manifestPath =
|
|
5670
|
+
const manifestPath = path13.resolve(config.cwd, config.outDir, "manifest.json");
|
|
5514
5671
|
try {
|
|
5515
|
-
return JSON.parse(
|
|
5672
|
+
return JSON.parse(fs12.readFileSync(manifestPath, "utf8"));
|
|
5516
5673
|
} catch {
|
|
5517
5674
|
return null;
|
|
5518
5675
|
}
|
|
5519
5676
|
}
|
|
5520
5677
|
function explainPath(config, target) {
|
|
5521
5678
|
const relative7 = normalizeTarget(config.cwd, target);
|
|
5522
|
-
const absolute =
|
|
5679
|
+
const absolute = path13.join(config.cwd, relative7);
|
|
5523
5680
|
const maskedPath2 = findSecretInPath(relative7, config.secretRules)?.masked ?? relative7;
|
|
5524
5681
|
const result = {
|
|
5525
5682
|
path: maskedPath2,
|
|
5526
|
-
exists:
|
|
5683
|
+
exists: fs12.existsSync(absolute),
|
|
5527
5684
|
included: false
|
|
5528
5685
|
};
|
|
5529
5686
|
const collection = collectFiles(config.cwd, {
|
|
@@ -5534,7 +5691,7 @@ function explainPath(config, target) {
|
|
|
5534
5691
|
// Same exclusion `generate` applies, so `explain` never says "not-discovered" about a file
|
|
5535
5692
|
// that is only missing because the walker dropped the tool's own output directory.
|
|
5536
5693
|
toolOwnedPaths: [config.outDir, config.tmpDir].map(
|
|
5537
|
-
(directory) =>
|
|
5694
|
+
(directory) => path13.relative(config.cwd, path13.resolve(config.cwd, directory)).replace(/\\/g, "/")
|
|
5538
5695
|
).filter((relative8) => relative8.length > 0 && !relative8.startsWith(".."))
|
|
5539
5696
|
});
|
|
5540
5697
|
if (!collection.files.includes(relative7)) {
|
|
@@ -5573,8 +5730,8 @@ function explainPath(config, target) {
|
|
|
5573
5730
|
if (layerRule) result.layerMatch = describeMatcher(layerRule.match);
|
|
5574
5731
|
const kindRule = findRuleMatch(config.kinds, relative7);
|
|
5575
5732
|
if (kindRule) result.kindMatch = describeMatcher(kindRule.match);
|
|
5576
|
-
if (
|
|
5577
|
-
const buffer =
|
|
5733
|
+
if (fs12.existsSync(absolute) && fs12.statSync(absolute).isFile()) {
|
|
5734
|
+
const buffer = fs12.readFileSync(absolute);
|
|
5578
5735
|
const decoded = decodeText(buffer);
|
|
5579
5736
|
if (decoded.binary) {
|
|
5580
5737
|
result.included = false;
|
|
@@ -5822,14 +5979,14 @@ function compareManifests(before, after) {
|
|
|
5822
5979
|
function loadManifest(target) {
|
|
5823
5980
|
let isDirectory;
|
|
5824
5981
|
try {
|
|
5825
|
-
isDirectory =
|
|
5982
|
+
isDirectory = fs12.statSync(target).isDirectory();
|
|
5826
5983
|
} catch {
|
|
5827
5984
|
throw new Error(`No snapshot found at ${target}: the path does not exist.`);
|
|
5828
5985
|
}
|
|
5829
|
-
const manifestPath = isDirectory ?
|
|
5986
|
+
const manifestPath = isDirectory ? path13.join(target, "manifest.json") : target;
|
|
5830
5987
|
let raw;
|
|
5831
5988
|
try {
|
|
5832
|
-
raw =
|
|
5989
|
+
raw = fs12.readFileSync(manifestPath, "utf8");
|
|
5833
5990
|
} catch {
|
|
5834
5991
|
throw new Error(`Could not read a manifest at ${manifestPath}.`);
|
|
5835
5992
|
}
|
|
@@ -5886,15 +6043,15 @@ function renderDiffText(diff) {
|
|
|
5886
6043
|
function appendGitignoreEntries(cwd, entries) {
|
|
5887
6044
|
const wanted = [...new Set(entries)].filter((entry) => entry.trim().length > 0);
|
|
5888
6045
|
if (wanted.length === 0) return { added: [], note: null };
|
|
5889
|
-
const ignorePath =
|
|
6046
|
+
const ignorePath = path13.join(cwd, ".gitignore");
|
|
5890
6047
|
const manual = `Add ${wanted.map((entry) => `"${entry}"`).join(" and ")} to your .gitignore yourself.`;
|
|
5891
6048
|
let existing = "";
|
|
5892
6049
|
try {
|
|
5893
|
-
if (
|
|
5894
|
-
if (
|
|
6050
|
+
if (fs12.existsSync(ignorePath)) {
|
|
6051
|
+
if (fs12.statSync(ignorePath).isDirectory()) {
|
|
5895
6052
|
return { added: [], note: `${ignorePath} is a directory, so it was not updated. ${manual}` };
|
|
5896
6053
|
}
|
|
5897
|
-
existing =
|
|
6054
|
+
existing = fs12.readFileSync(ignorePath, "utf8");
|
|
5898
6055
|
}
|
|
5899
6056
|
} catch (err) {
|
|
5900
6057
|
return {
|
|
@@ -5907,7 +6064,7 @@ function appendGitignoreEntries(cwd, entries) {
|
|
|
5907
6064
|
if (added.length === 0) return { added: [], note: null };
|
|
5908
6065
|
const prefix = existing.length === 0 || existing.endsWith("\n") ? "" : "\n";
|
|
5909
6066
|
try {
|
|
5910
|
-
|
|
6067
|
+
fs12.writeFileSync(ignorePath, `${existing}${prefix}${added.join("\n")}
|
|
5911
6068
|
`, "utf8");
|
|
5912
6069
|
} catch (err) {
|
|
5913
6070
|
return { added: [], note: `${err.message}. ${manual}` };
|
|
@@ -5915,7 +6072,7 @@ function appendGitignoreEntries(cwd, entries) {
|
|
|
5915
6072
|
return { added, note: null };
|
|
5916
6073
|
}
|
|
5917
6074
|
function gitignorePath(cwd, filePath) {
|
|
5918
|
-
return
|
|
6075
|
+
return path13.relative(cwd, filePath).split(path13.sep).join("/");
|
|
5919
6076
|
}
|
|
5920
6077
|
|
|
5921
6078
|
// src/wizard/config-template.ts
|
|
@@ -6049,6 +6206,12 @@ var PromptCancelled = class extends Error {
|
|
|
6049
6206
|
this.name = "PromptCancelled";
|
|
6050
6207
|
}
|
|
6051
6208
|
};
|
|
6209
|
+
var PromptBack = class extends Error {
|
|
6210
|
+
constructor() {
|
|
6211
|
+
super("Prompt back");
|
|
6212
|
+
this.name = "PromptBack";
|
|
6213
|
+
}
|
|
6214
|
+
};
|
|
6052
6215
|
function defaultIO() {
|
|
6053
6216
|
return { input: process.stdin, output: process.stdout };
|
|
6054
6217
|
}
|
|
@@ -6072,35 +6235,40 @@ function choiceLine(choice, active) {
|
|
|
6072
6235
|
const hint = choice.hint ? ` ${choice.hint}` : "";
|
|
6073
6236
|
return ` ${marker(active)} ${choice.label}${hint}`;
|
|
6074
6237
|
}
|
|
6075
|
-
function
|
|
6238
|
+
function listFooter(base, allowBack) {
|
|
6239
|
+
return allowBack ? `${base} \xB7 \u2190 back` : base;
|
|
6240
|
+
}
|
|
6241
|
+
function renderSelect(message, choices, index, allowBack = false) {
|
|
6076
6242
|
const lines = [`\u25C6 ${message}`, ""];
|
|
6077
6243
|
choices.forEach((choice, position) => lines.push(choiceLine(choice, position === index)));
|
|
6078
|
-
lines.push("", "
|
|
6244
|
+
lines.push("", ` ${listFooter("\u2191\u2193 move \xB7 enter select", allowBack)}`);
|
|
6079
6245
|
return lines.join("\n");
|
|
6080
6246
|
}
|
|
6081
|
-
function renderMultiSelect(message, choices, index, selected) {
|
|
6247
|
+
function renderMultiSelect(message, choices, index, selected, allowBack = false) {
|
|
6082
6248
|
const lines = [`\u25C6 ${message}`, ""];
|
|
6083
6249
|
choices.forEach((choice, position) => {
|
|
6084
6250
|
const box = selected.has(position) ? "\u25FC" : "\u25FB";
|
|
6085
6251
|
const hint = choice.hint ? ` ${choice.hint}` : "";
|
|
6086
6252
|
lines.push(` ${marker(position === index)} ${box} ${choice.label}${hint}`);
|
|
6087
6253
|
});
|
|
6088
|
-
lines.push("", "
|
|
6254
|
+
lines.push("", ` ${listFooter("\u2191\u2193 move \xB7 space toggle \xB7 enter confirm", allowBack)}`);
|
|
6089
6255
|
return lines.join("\n");
|
|
6090
6256
|
}
|
|
6091
|
-
function renderConfirm(message, value) {
|
|
6257
|
+
function renderConfirm(message, value, allowBack = false) {
|
|
6258
|
+
const footer = allowBack ? "\u2190\u2192 or y/n \xB7 enter confirm \xB7 b back" : "\u2190\u2192 or y/n \xB7 enter confirm";
|
|
6092
6259
|
return [
|
|
6093
6260
|
`\u25C6 ${message}`,
|
|
6094
6261
|
"",
|
|
6095
6262
|
` ${marker(value)} Yes`,
|
|
6096
6263
|
` ${marker(!value)} No`,
|
|
6097
6264
|
"",
|
|
6098
|
-
|
|
6265
|
+
` ${footer}`
|
|
6099
6266
|
].join("\n");
|
|
6100
6267
|
}
|
|
6101
|
-
function renderText(message, value, error) {
|
|
6268
|
+
function renderText(message, value, error, allowBack = false) {
|
|
6102
6269
|
const lines = [`\u25C6 ${message}`, "", ` ${value || "\u258F"}`];
|
|
6103
6270
|
if (error) lines.push("", ` \u2716 ${error}`);
|
|
6271
|
+
if (allowBack) lines.push("", " enter confirm \xB7 \u2190 back");
|
|
6104
6272
|
return lines.join("\n");
|
|
6105
6273
|
}
|
|
6106
6274
|
function keyReader(input) {
|
|
@@ -6149,14 +6317,18 @@ var Frame = class {
|
|
|
6149
6317
|
function isCancel(key) {
|
|
6150
6318
|
return key.ctrl === true && key.name === "c" || key.ctrl === true && key.name === "d";
|
|
6151
6319
|
}
|
|
6320
|
+
function isListBack(key, allowBack) {
|
|
6321
|
+
return allowBack && (key.name === "left" || key.name === "b");
|
|
6322
|
+
}
|
|
6152
6323
|
async function select(io, message, choices, options = {}) {
|
|
6153
6324
|
if (choices.length === 0) throw new Error("select() requires at least one choice.");
|
|
6325
|
+
const allowBack = options.allowBack === true;
|
|
6154
6326
|
const fallbackIndex = Math.max(
|
|
6155
6327
|
0,
|
|
6156
6328
|
choices.findIndex((choice) => choice.value === options.defaultValue)
|
|
6157
6329
|
);
|
|
6158
6330
|
if (!isInteractive(io)) {
|
|
6159
|
-
io.output.write(`${renderSelect(message, choices, fallbackIndex)}
|
|
6331
|
+
io.output.write(`${renderSelect(message, choices, fallbackIndex, allowBack)}
|
|
6160
6332
|
`);
|
|
6161
6333
|
return choices[fallbackIndex].value;
|
|
6162
6334
|
}
|
|
@@ -6165,9 +6337,10 @@ async function select(io, message, choices, options = {}) {
|
|
|
6165
6337
|
let index = fallbackIndex;
|
|
6166
6338
|
try {
|
|
6167
6339
|
for (; ; ) {
|
|
6168
|
-
frame.draw(renderSelect(message, choices, index));
|
|
6340
|
+
frame.draw(renderSelect(message, choices, index, allowBack));
|
|
6169
6341
|
const key = await reader.next();
|
|
6170
6342
|
if (isCancel(key)) throw new PromptCancelled();
|
|
6343
|
+
if (isListBack(key, allowBack)) throw new PromptBack();
|
|
6171
6344
|
if (key.name === "up") index = moveSelection(index, -1, choices.length);
|
|
6172
6345
|
else if (key.name === "down") index = moveSelection(index, 1, choices.length);
|
|
6173
6346
|
else if (key.name === "return" || key.name === "enter") {
|
|
@@ -6176,18 +6349,22 @@ async function select(io, message, choices, options = {}) {
|
|
|
6176
6349
|
} else if (key.name === "j") index = moveSelection(index, 1, choices.length);
|
|
6177
6350
|
else if (key.name === "k") index = moveSelection(index, -1, choices.length);
|
|
6178
6351
|
}
|
|
6352
|
+
} catch (error) {
|
|
6353
|
+
frame.erase();
|
|
6354
|
+
throw error;
|
|
6179
6355
|
} finally {
|
|
6180
6356
|
reader.close();
|
|
6181
6357
|
}
|
|
6182
6358
|
}
|
|
6183
6359
|
async function multiSelect(io, message, choices, options = {}) {
|
|
6360
|
+
const allowBack = options.allowBack === true;
|
|
6184
6361
|
const selected = /* @__PURE__ */ new Set();
|
|
6185
6362
|
choices.forEach((choice, position) => {
|
|
6186
6363
|
if (options.defaults?.includes(choice.value)) selected.add(position);
|
|
6187
6364
|
});
|
|
6188
6365
|
const result = () => choices.filter((_, position) => selected.has(position)).map((choice) => choice.value);
|
|
6189
6366
|
if (!isInteractive(io)) {
|
|
6190
|
-
io.output.write(`${renderMultiSelect(message, choices, 0, selected)}
|
|
6367
|
+
io.output.write(`${renderMultiSelect(message, choices, 0, selected, allowBack)}
|
|
6191
6368
|
`);
|
|
6192
6369
|
return result();
|
|
6193
6370
|
}
|
|
@@ -6196,9 +6373,10 @@ async function multiSelect(io, message, choices, options = {}) {
|
|
|
6196
6373
|
let index = 0;
|
|
6197
6374
|
try {
|
|
6198
6375
|
for (; ; ) {
|
|
6199
|
-
frame.draw(renderMultiSelect(message, choices, index, selected));
|
|
6376
|
+
frame.draw(renderMultiSelect(message, choices, index, selected, allowBack));
|
|
6200
6377
|
const key = await reader.next();
|
|
6201
6378
|
if (isCancel(key)) throw new PromptCancelled();
|
|
6379
|
+
if (isListBack(key, allowBack)) throw new PromptBack();
|
|
6202
6380
|
if (key.name === "up") index = moveSelection(index, -1, choices.length);
|
|
6203
6381
|
else if (key.name === "down") index = moveSelection(index, 1, choices.length);
|
|
6204
6382
|
else if (key.name === "space") {
|
|
@@ -6213,14 +6391,18 @@ async function multiSelect(io, message, choices, options = {}) {
|
|
|
6213
6391
|
return result();
|
|
6214
6392
|
}
|
|
6215
6393
|
}
|
|
6394
|
+
} catch (error) {
|
|
6395
|
+
frame.erase();
|
|
6396
|
+
throw error;
|
|
6216
6397
|
} finally {
|
|
6217
6398
|
reader.close();
|
|
6218
6399
|
}
|
|
6219
6400
|
}
|
|
6220
6401
|
async function confirm(io, message, options = {}) {
|
|
6402
|
+
const allowBack = options.allowBack === true;
|
|
6221
6403
|
let value = options.defaultValue ?? true;
|
|
6222
6404
|
if (!isInteractive(io)) {
|
|
6223
|
-
io.output.write(`${renderConfirm(message, value)}
|
|
6405
|
+
io.output.write(`${renderConfirm(message, value, allowBack)}
|
|
6224
6406
|
`);
|
|
6225
6407
|
return value;
|
|
6226
6408
|
}
|
|
@@ -6228,9 +6410,10 @@ async function confirm(io, message, options = {}) {
|
|
|
6228
6410
|
const reader = keyReader(io.input);
|
|
6229
6411
|
try {
|
|
6230
6412
|
for (; ; ) {
|
|
6231
|
-
frame.draw(renderConfirm(message, value));
|
|
6413
|
+
frame.draw(renderConfirm(message, value, allowBack));
|
|
6232
6414
|
const key = await reader.next();
|
|
6233
6415
|
if (isCancel(key)) throw new PromptCancelled();
|
|
6416
|
+
if (allowBack && key.name === "b") throw new PromptBack();
|
|
6234
6417
|
if (key.name === "up" || key.name === "left") value = true;
|
|
6235
6418
|
else if (key.name === "down" || key.name === "right") value = false;
|
|
6236
6419
|
else if (key.name === "y") value = true;
|
|
@@ -6240,14 +6423,18 @@ async function confirm(io, message, options = {}) {
|
|
|
6240
6423
|
return value;
|
|
6241
6424
|
}
|
|
6242
6425
|
}
|
|
6426
|
+
} catch (error) {
|
|
6427
|
+
frame.erase();
|
|
6428
|
+
throw error;
|
|
6243
6429
|
} finally {
|
|
6244
6430
|
reader.close();
|
|
6245
6431
|
}
|
|
6246
6432
|
}
|
|
6247
6433
|
async function text(io, message, options = {}) {
|
|
6434
|
+
const allowBack = options.allowBack === true;
|
|
6248
6435
|
const fallback = options.defaultValue ?? "";
|
|
6249
6436
|
if (!isInteractive(io)) {
|
|
6250
|
-
io.output.write(`${renderText(message, fallback)}
|
|
6437
|
+
io.output.write(`${renderText(message, fallback, void 0, allowBack)}
|
|
6251
6438
|
`);
|
|
6252
6439
|
return fallback;
|
|
6253
6440
|
}
|
|
@@ -6257,9 +6444,10 @@ async function text(io, message, options = {}) {
|
|
|
6257
6444
|
let error;
|
|
6258
6445
|
try {
|
|
6259
6446
|
for (; ; ) {
|
|
6260
|
-
frame.draw(renderText(message, value, error));
|
|
6447
|
+
frame.draw(renderText(message, value, error, allowBack));
|
|
6261
6448
|
const key = await reader.next();
|
|
6262
6449
|
if (isCancel(key)) throw new PromptCancelled();
|
|
6450
|
+
if (allowBack && key.name === "left") throw new PromptBack();
|
|
6263
6451
|
error = void 0;
|
|
6264
6452
|
if (key.name === "return" || key.name === "enter") {
|
|
6265
6453
|
const problem = options.validate ? options.validate(value) : null;
|
|
@@ -6280,6 +6468,9 @@ async function text(io, message, options = {}) {
|
|
|
6280
6468
|
}
|
|
6281
6469
|
if (_isPrintable(key)) value += _keyText(key);
|
|
6282
6470
|
}
|
|
6471
|
+
} catch (error_) {
|
|
6472
|
+
frame.erase();
|
|
6473
|
+
throw error_;
|
|
6283
6474
|
} finally {
|
|
6284
6475
|
reader.close();
|
|
6285
6476
|
}
|
|
@@ -6303,10 +6494,10 @@ var CONFIG_CANDIDATES = [
|
|
|
6303
6494
|
];
|
|
6304
6495
|
function chooseConfigFileName(cwd) {
|
|
6305
6496
|
if (!supportsTypeScriptImports()) return "snapshot.config.mjs";
|
|
6306
|
-
const pkgPath =
|
|
6307
|
-
if (!
|
|
6497
|
+
const pkgPath = path13.join(cwd, "package.json");
|
|
6498
|
+
if (!fs12.existsSync(pkgPath)) return "snapshot.config.mjs";
|
|
6308
6499
|
try {
|
|
6309
|
-
const parsed = JSON.parse(
|
|
6500
|
+
const parsed = JSON.parse(fs12.readFileSync(pkgPath, "utf8"));
|
|
6310
6501
|
return parsed.type === "module" ? "snapshot.config.ts" : "snapshot.config.mjs";
|
|
6311
6502
|
} catch {
|
|
6312
6503
|
return "snapshot.config.mjs";
|
|
@@ -6320,7 +6511,7 @@ var SIZE_CHOICES = [
|
|
|
6320
6511
|
];
|
|
6321
6512
|
function packageJsonHasConfig(cwd) {
|
|
6322
6513
|
try {
|
|
6323
|
-
const parsed = JSON.parse(
|
|
6514
|
+
const parsed = JSON.parse(fs12.readFileSync(path13.join(cwd, "package.json"), "utf8"));
|
|
6324
6515
|
return typeof parsed.snapshot === "object" && parsed.snapshot !== null && !Array.isArray(parsed.snapshot);
|
|
6325
6516
|
} catch {
|
|
6326
6517
|
return false;
|
|
@@ -6341,7 +6532,7 @@ function artifactAnswers(options) {
|
|
|
6341
6532
|
}
|
|
6342
6533
|
function topLevelDirs(cwd) {
|
|
6343
6534
|
try {
|
|
6344
|
-
return
|
|
6535
|
+
return fs12.readdirSync(cwd, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules").map((entry) => entry.name).sort();
|
|
6345
6536
|
} catch {
|
|
6346
6537
|
return [];
|
|
6347
6538
|
}
|
|
@@ -6354,7 +6545,7 @@ function describeJsonValue(value) {
|
|
|
6354
6545
|
}
|
|
6355
6546
|
function writeFileOrExplain(target, content) {
|
|
6356
6547
|
try {
|
|
6357
|
-
|
|
6548
|
+
fs12.writeFileSync(target, content, "utf8");
|
|
6358
6549
|
} catch (err) {
|
|
6359
6550
|
const code = err.code;
|
|
6360
6551
|
const reason = code === "EACCES" || code === "EPERM" || code === "EROFS" ? `permission denied (${code})` : code === "EISDIR" ? "it is a directory" : `${err.message}`;
|
|
@@ -6365,7 +6556,7 @@ function canWriteModuleConfig(name, cwd) {
|
|
|
6365
6556
|
if (name.endsWith(".mjs") || name.endsWith(".ts")) return true;
|
|
6366
6557
|
if (!name.endsWith(".js")) return false;
|
|
6367
6558
|
try {
|
|
6368
|
-
const parsed = JSON.parse(
|
|
6559
|
+
const parsed = JSON.parse(fs12.readFileSync(path13.join(cwd, "package.json"), "utf8"));
|
|
6369
6560
|
return parsed.type === "module";
|
|
6370
6561
|
} catch {
|
|
6371
6562
|
return false;
|
|
@@ -6400,19 +6591,19 @@ function serializePackageJson(raw, value) {
|
|
|
6400
6591
|
return `${text2}${raw.endsWith("\n") ? crlf ? "\r\n" : "\n" : ""}`;
|
|
6401
6592
|
}
|
|
6402
6593
|
function updatePackageJson(cwd, notes) {
|
|
6403
|
-
const packagePath =
|
|
6594
|
+
const packagePath = path13.join(cwd, "package.json");
|
|
6404
6595
|
const unchanged = {
|
|
6405
6596
|
scripts: [],
|
|
6406
6597
|
dependency: { name: GENERATOR_NAME, range: null, added: false }
|
|
6407
6598
|
};
|
|
6408
|
-
if (!
|
|
6599
|
+
if (!fs12.existsSync(packagePath)) {
|
|
6409
6600
|
notes.push("No package.json found, so npm scripts and the devDependency were not added.");
|
|
6410
6601
|
return unchanged;
|
|
6411
6602
|
}
|
|
6412
6603
|
let raw;
|
|
6413
6604
|
let parsed;
|
|
6414
6605
|
try {
|
|
6415
|
-
raw =
|
|
6606
|
+
raw = fs12.readFileSync(packagePath, "utf8");
|
|
6416
6607
|
parsed = JSON.parse(raw);
|
|
6417
6608
|
} catch {
|
|
6418
6609
|
notes.push("Could not parse package.json; npm scripts and the devDependency were not added.");
|
|
@@ -6536,98 +6727,108 @@ async function runInit(options) {
|
|
|
6536
6727
|
{ value: "walk", label: "Go through each setting", hint: "every question starts on its default" },
|
|
6537
6728
|
{ value: "choose", label: "Pick a different preset", hint: "everything else stays at the defaults" }
|
|
6538
6729
|
];
|
|
6539
|
-
const
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
{
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
]
|
|
6566
|
-
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
|
|
6578
|
-
|
|
6579
|
-
|
|
6730
|
+
const baseInclude = [...answers.include];
|
|
6731
|
+
const baseExclude = [...answers.excludePatterns];
|
|
6732
|
+
let lastScope = "all";
|
|
6733
|
+
const artifactChoices = [
|
|
6734
|
+
{ value: "readme", label: "README.md", hint: "orientation page" },
|
|
6735
|
+
{ value: "manifest", label: "manifest.json", hint: "required by validate and report" },
|
|
6736
|
+
{ value: "parts", label: "parts/", hint: "the code payload" },
|
|
6737
|
+
{ value: "navigation", label: "reports/navigation.md", hint: "file \u2192 part index" },
|
|
6738
|
+
{ value: "projectTree", label: "reports/project-tree.md", hint: "ASCII tree" },
|
|
6739
|
+
{ value: "audit", label: "reports/audit.md", hint: "security and health findings" },
|
|
6740
|
+
{ value: "monolith", label: "full-codebase.json + .md", hint: "roughly doubles output" }
|
|
6741
|
+
];
|
|
6742
|
+
const scopeStep = async () => {
|
|
6743
|
+
for (; ; ) {
|
|
6744
|
+
const scope = await select(
|
|
6745
|
+
io,
|
|
6746
|
+
"What should go into the snapshot?",
|
|
6747
|
+
[
|
|
6748
|
+
{ value: "all", label: "Everything the scanner finds", hint: "recommended \xB7 respects .gitignore" },
|
|
6749
|
+
{ value: "folders", label: "Only specific folders\u2026" },
|
|
6750
|
+
{ value: "no-tests", label: "Everything, but skip tests" },
|
|
6751
|
+
{ value: "custom", label: "Let me write glob patterns" }
|
|
6752
|
+
],
|
|
6753
|
+
{ defaultValue: lastScope, allowBack: true }
|
|
6754
|
+
);
|
|
6755
|
+
lastScope = scope;
|
|
6756
|
+
answers.include = [...baseInclude];
|
|
6757
|
+
answers.excludePatterns = [...baseExclude];
|
|
6758
|
+
try {
|
|
6759
|
+
if (scope === "folders") {
|
|
6760
|
+
const dirs = topLevelDirs(options.cwd).slice(0, 40);
|
|
6761
|
+
if (dirs.length === 0) {
|
|
6762
|
+
notes.push("No top-level directories found; the snapshot will include everything.");
|
|
6763
|
+
} else {
|
|
6764
|
+
const chosen = await multiSelect(
|
|
6765
|
+
io,
|
|
6766
|
+
"Select folders",
|
|
6767
|
+
dirs.map((name) => ({ value: name, label: `${name}/` })),
|
|
6768
|
+
{ defaults: dirs, allowBack: true }
|
|
6769
|
+
);
|
|
6770
|
+
answers.include = chosen.map((name) => `${name}/**`);
|
|
6771
|
+
}
|
|
6772
|
+
} else if (scope === "no-tests") {
|
|
6773
|
+
answers.excludePatterns = [...baseExclude, "**/*.test.*", "**/*.spec.*", "tests", "test"];
|
|
6774
|
+
} else if (scope === "custom") {
|
|
6775
|
+
const raw = await text(io, "Glob patterns to include (comma separated)", {
|
|
6776
|
+
defaultValue: baseInclude.join(", "),
|
|
6777
|
+
allowBack: true
|
|
6778
|
+
});
|
|
6779
|
+
answers.include = raw.split(",").map((value) => value.trim()).filter(Boolean);
|
|
6780
|
+
}
|
|
6781
|
+
return;
|
|
6782
|
+
} catch (error) {
|
|
6783
|
+
if (error instanceof PromptBack) continue;
|
|
6784
|
+
throw error;
|
|
6580
6785
|
}
|
|
6581
|
-
} else if (scope === "no-tests") {
|
|
6582
|
-
answers.excludePatterns = [
|
|
6583
|
-
...answers.excludePatterns,
|
|
6584
|
-
"**/*.test.*",
|
|
6585
|
-
"**/*.spec.*",
|
|
6586
|
-
"tests",
|
|
6587
|
-
"test"
|
|
6588
|
-
];
|
|
6589
|
-
} else if (scope === "custom") {
|
|
6590
|
-
const raw = await text(io, "Glob patterns to include (comma separated)", {
|
|
6591
|
-
defaultValue: ""
|
|
6592
|
-
});
|
|
6593
|
-
answers.include = raw.split(",").map((value) => value.trim()).filter(Boolean);
|
|
6594
6786
|
}
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
validate: (value) => parseByteSize(value) === void 0 ? "Not a valid size." : null
|
|
6787
|
+
};
|
|
6788
|
+
const sizeStep = async () => {
|
|
6789
|
+
for (; ; ) {
|
|
6790
|
+
const currentBudget = String(answers.maxPartBytes);
|
|
6791
|
+
const sizeChoice = await select(io, "How large should each part be?", SIZE_CHOICES, {
|
|
6792
|
+
defaultValue: SIZE_CHOICES.some((choice) => choice.value === currentBudget) ? currentBudget : "custom",
|
|
6793
|
+
allowBack: true
|
|
6603
6794
|
});
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6795
|
+
if (sizeChoice !== "custom") {
|
|
6796
|
+
answers.maxPartBytes = sizeChoice;
|
|
6797
|
+
return;
|
|
6798
|
+
}
|
|
6799
|
+
try {
|
|
6800
|
+
const raw = await text(io, "Part size (e.g. 150k, 1.5mb, 900000)", {
|
|
6801
|
+
defaultValue: currentBudget,
|
|
6802
|
+
validate: (value) => parseByteSize(value) === void 0 ? "Not a valid size." : null,
|
|
6803
|
+
allowBack: true
|
|
6804
|
+
});
|
|
6805
|
+
answers.maxPartBytes = parseByteSize(raw) ?? answers.maxPartBytes;
|
|
6806
|
+
return;
|
|
6807
|
+
} catch (error) {
|
|
6808
|
+
if (error instanceof PromptBack) continue;
|
|
6809
|
+
throw error;
|
|
6810
|
+
}
|
|
6607
6811
|
}
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
{ value: "parts", label: "parts/", hint: "the code payload" },
|
|
6612
|
-
{ value: "navigation", label: "reports/navigation.md", hint: "file \u2192 part index" },
|
|
6613
|
-
{ value: "projectTree", label: "reports/project-tree.md", hint: "ASCII tree" },
|
|
6614
|
-
{ value: "audit", label: "reports/audit.md", hint: "security and health findings" },
|
|
6615
|
-
{ value: "monolith", label: "full-codebase.json + .md", hint: "roughly doubles output" }
|
|
6616
|
-
];
|
|
6617
|
-
const presetEnabled = ARTIFACT_NAMES.filter((name) => answers.artifacts[name]);
|
|
6812
|
+
};
|
|
6813
|
+
const artifactsStep = async () => {
|
|
6814
|
+
const enabled = ARTIFACT_NAMES.filter((name) => answers.artifacts[name]);
|
|
6618
6815
|
const selectedArtifacts = await multiSelect(
|
|
6619
6816
|
io,
|
|
6620
6817
|
"Which artifacts should be generated?",
|
|
6621
6818
|
artifactChoices,
|
|
6622
|
-
{ defaults:
|
|
6819
|
+
{ defaults: enabled, allowBack: true }
|
|
6623
6820
|
);
|
|
6624
6821
|
for (const name of ARTIFACT_NAMES) answers.artifacts[name] = selectedArtifacts.includes(name);
|
|
6625
|
-
|
|
6822
|
+
};
|
|
6823
|
+
const credentialsStep = async () => {
|
|
6626
6824
|
answers.includeSensitiveFiles = await confirm(
|
|
6627
6825
|
io,
|
|
6628
|
-
"Include credential files (.env, *.pem,
|
|
6629
|
-
{ defaultValue:
|
|
6826
|
+
"Include credential files (.env, *.pem, *.npmrc, *.ssh/)?",
|
|
6827
|
+
{ defaultValue: answers.includeSensitiveFiles, allowBack: true }
|
|
6630
6828
|
);
|
|
6829
|
+
};
|
|
6830
|
+
const reviewStep = async () => {
|
|
6831
|
+
const enabledCount = ARTIFACT_NAMES.filter((name) => answers.artifacts[name]).length;
|
|
6631
6832
|
io.output.write("\n Review\n\n");
|
|
6632
6833
|
io.output.write(` project ${answers.preset}
|
|
6633
6834
|
`);
|
|
@@ -6642,14 +6843,59 @@ async function runInit(options) {
|
|
|
6642
6843
|
`);
|
|
6643
6844
|
io.output.write(" Will write snapshot.config with your answers, plus every other setting\n");
|
|
6644
6845
|
io.output.write(" at its default \u2014 so nothing is hidden behind the docs.\n\n");
|
|
6645
|
-
const proceed = await confirm(io, "Write this and continue?", {
|
|
6646
|
-
|
|
6846
|
+
const proceed = await confirm(io, "Write this and continue?", {
|
|
6847
|
+
defaultValue: true,
|
|
6848
|
+
allowBack: true
|
|
6849
|
+
});
|
|
6850
|
+
if (!proceed) throw new PromptBack();
|
|
6851
|
+
};
|
|
6852
|
+
const walk = async () => {
|
|
6853
|
+
const steps = [scopeStep, sizeStep, artifactsStep, credentialsStep, reviewStep];
|
|
6854
|
+
let index = 0;
|
|
6855
|
+
while (index < steps.length) {
|
|
6856
|
+
try {
|
|
6857
|
+
await steps[index]();
|
|
6858
|
+
index += 1;
|
|
6859
|
+
} catch (error) {
|
|
6860
|
+
if (!(error instanceof PromptBack)) throw error;
|
|
6861
|
+
if (index === 0) return false;
|
|
6862
|
+
index -= 1;
|
|
6863
|
+
io.output.write("\n");
|
|
6864
|
+
}
|
|
6865
|
+
}
|
|
6866
|
+
return true;
|
|
6867
|
+
};
|
|
6868
|
+
for (; ; ) {
|
|
6869
|
+
const pace = await select(io, "How should I set this up?", paceChoices, {
|
|
6870
|
+
defaultValue: fallback ? "choose" : "recommended"
|
|
6871
|
+
});
|
|
6872
|
+
if (pace === "choose") {
|
|
6873
|
+
try {
|
|
6874
|
+
answers.preset = await select(
|
|
6875
|
+
io,
|
|
6876
|
+
"What kind of project is this?",
|
|
6877
|
+
listPresetNames().map(
|
|
6878
|
+
(name) => resolvePresetChoice(fallback ? null : detected.presetName, name)
|
|
6879
|
+
),
|
|
6880
|
+
{ defaultValue: answers.preset, allowBack: true }
|
|
6881
|
+
);
|
|
6882
|
+
} catch (error) {
|
|
6883
|
+
if (error instanceof PromptBack) continue;
|
|
6884
|
+
throw error;
|
|
6885
|
+
}
|
|
6886
|
+
const chosen = detectPreset(options.cwd, answers.preset);
|
|
6887
|
+
answers.preset = chosen.presetName;
|
|
6888
|
+
reason = null;
|
|
6889
|
+
fallback = false;
|
|
6890
|
+
}
|
|
6891
|
+
if (pace === "walk" && !await walk()) continue;
|
|
6892
|
+
break;
|
|
6647
6893
|
}
|
|
6648
6894
|
}
|
|
6649
6895
|
const configText = renderConfig(answers);
|
|
6650
6896
|
const preferredName = chooseConfigFileName(options.cwd);
|
|
6651
6897
|
const presentConfigs = CONFIG_CANDIDATES.filter(
|
|
6652
|
-
(name) =>
|
|
6898
|
+
(name) => fs12.existsSync(path13.join(options.cwd, name))
|
|
6653
6899
|
);
|
|
6654
6900
|
const present = presentConfigs[0] ?? null;
|
|
6655
6901
|
if (presentConfigs.length > 1) {
|
|
@@ -6658,7 +6904,7 @@ async function runInit(options) {
|
|
|
6658
6904
|
);
|
|
6659
6905
|
}
|
|
6660
6906
|
const configName = present !== null && options.force ? present : preferredName;
|
|
6661
|
-
const configPath =
|
|
6907
|
+
const configPath = path13.join(options.cwd, configName);
|
|
6662
6908
|
const reused = present !== null && options.force !== true && options.reuseConfig === true;
|
|
6663
6909
|
if (reused) notes.push(`Kept the existing ${present} instead of writing a new one.`);
|
|
6664
6910
|
if (options.dryRun) {
|
|
@@ -6691,7 +6937,7 @@ async function runInit(options) {
|
|
|
6691
6937
|
'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.'
|
|
6692
6938
|
);
|
|
6693
6939
|
}
|
|
6694
|
-
if (
|
|
6940
|
+
if (fs12.existsSync(configPath) && !options.force && !reused) {
|
|
6695
6941
|
throw new Error(`${configName} already exists. Re-run with --force to replace it.`);
|
|
6696
6942
|
}
|
|
6697
6943
|
if (!reused) writeFileOrExplain(configPath, configText);
|
|
@@ -6713,9 +6959,9 @@ async function runInit(options) {
|
|
|
6713
6959
|
};
|
|
6714
6960
|
}
|
|
6715
6961
|
function describeTarget(cwd) {
|
|
6716
|
-
const relative7 =
|
|
6962
|
+
const relative7 = path13.relative(process.cwd(), cwd);
|
|
6717
6963
|
if (relative7 === "") return "this directory";
|
|
6718
|
-
if (relative7.startsWith("..") ||
|
|
6964
|
+
if (relative7.startsWith("..") || path13.isAbsolute(relative7)) return cwd;
|
|
6719
6965
|
return relative7;
|
|
6720
6966
|
}
|
|
6721
6967
|
function firstRunMessage(reason, cwd) {
|
|
@@ -6739,7 +6985,7 @@ function planFirstRun(facts) {
|
|
|
6739
6985
|
var NOT_CONTENT = /* @__PURE__ */ new Set([".git", ".hg", ".svn", ".bzr", ".DS_Store", "Thumbs.db"]);
|
|
6740
6986
|
function isEffectivelyEmpty(cwd) {
|
|
6741
6987
|
try {
|
|
6742
|
-
return
|
|
6988
|
+
return fs12.readdirSync(cwd).every((entry) => NOT_CONTENT.has(entry));
|
|
6743
6989
|
} catch {
|
|
6744
6990
|
return false;
|
|
6745
6991
|
}
|
|
@@ -6747,7 +6993,7 @@ function isEffectivelyEmpty(cwd) {
|
|
|
6747
6993
|
function hasPriorSnapshot(cwd, outDir) {
|
|
6748
6994
|
let parsed;
|
|
6749
6995
|
try {
|
|
6750
|
-
parsed = JSON.parse(
|
|
6996
|
+
parsed = JSON.parse(fs12.readFileSync(path13.join(cwd, outDir, ".codebase-snapshot"), "utf8"));
|
|
6751
6997
|
} catch {
|
|
6752
6998
|
return false;
|
|
6753
6999
|
}
|
|
@@ -6835,13 +7081,13 @@ function buildImportResolver(files) {
|
|
|
6835
7081
|
const relativePath = file.relativePath;
|
|
6836
7082
|
remember(byPath, relativePath, relativePath);
|
|
6837
7083
|
remember(byPathFolded, relativePath.toLowerCase(), relativePath);
|
|
6838
|
-
const extension =
|
|
7084
|
+
const extension = path13.posix.extname(relativePath);
|
|
6839
7085
|
if (!SOURCE_EXTENSIONS.has(extension)) continue;
|
|
6840
7086
|
const stem = relativePath.slice(0, -extension.length);
|
|
6841
7087
|
remember(byStem, stem, relativePath);
|
|
6842
7088
|
remember(byStemFolded, stem.toLowerCase(), relativePath);
|
|
6843
|
-
if (
|
|
6844
|
-
const directory =
|
|
7089
|
+
if (path13.posix.basename(stem) === "index") {
|
|
7090
|
+
const directory = path13.posix.dirname(stem);
|
|
6845
7091
|
remember(byStem, directory, relativePath);
|
|
6846
7092
|
remember(byStemFolded, directory.toLowerCase(), relativePath);
|
|
6847
7093
|
}
|
|
@@ -6850,8 +7096,8 @@ function buildImportResolver(files) {
|
|
|
6850
7096
|
}
|
|
6851
7097
|
function resolveSpecifier(fromFile, specifier, resolver) {
|
|
6852
7098
|
if (!RELATIVE_SPECIFIER.test(specifier)) return null;
|
|
6853
|
-
const joined =
|
|
6854
|
-
|
|
7099
|
+
const joined = path13.posix.normalize(
|
|
7100
|
+
path13.posix.join(path13.posix.dirname(fromFile), specifier)
|
|
6855
7101
|
);
|
|
6856
7102
|
const exact = (key) => resolver.byPath.get(key) ?? resolver.byPathFolded.get(key.toLowerCase()) ?? null;
|
|
6857
7103
|
const direct = exact(joined);
|
|
@@ -6944,11 +7190,11 @@ function verifyInMemory(files, parts, maxPartBytes) {
|
|
|
6944
7190
|
return errors;
|
|
6945
7191
|
}
|
|
6946
7192
|
function resolveSafeOutputDirs(config) {
|
|
6947
|
-
const cwd =
|
|
6948
|
-
const outDir =
|
|
6949
|
-
const tmpDir =
|
|
6950
|
-
const root =
|
|
6951
|
-
const contains = (parent, child) => child === parent || child.startsWith(`${parent}${
|
|
7193
|
+
const cwd = path13.resolve(config.cwd);
|
|
7194
|
+
const outDir = path13.resolve(cwd, config.outDir);
|
|
7195
|
+
const tmpDir = path13.resolve(cwd, config.tmpDir);
|
|
7196
|
+
const root = path13.parse(cwd).root;
|
|
7197
|
+
const contains = (parent, child) => child === parent || child.startsWith(`${parent}${path13.sep}`);
|
|
6952
7198
|
const reject = (reason) => {
|
|
6953
7199
|
throw new Error(
|
|
6954
7200
|
`Refusing to generate: ${reason}. outDir=${outDir} tmpDir=${tmpDir} cwd=${cwd}`
|
|
@@ -7004,14 +7250,14 @@ function listEntries(dir) {
|
|
|
7004
7250
|
const walk = (absolute, prefix) => {
|
|
7005
7251
|
let children;
|
|
7006
7252
|
try {
|
|
7007
|
-
children =
|
|
7253
|
+
children = fs12.readdirSync(absolute, { withFileTypes: true });
|
|
7008
7254
|
} catch {
|
|
7009
7255
|
return;
|
|
7010
7256
|
}
|
|
7011
7257
|
for (const child of children) {
|
|
7012
7258
|
const relative7 = prefix === "" ? child.name : `${prefix}/${child.name}`;
|
|
7013
7259
|
entries.push(relative7);
|
|
7014
|
-
if (child.isDirectory()) walk(
|
|
7260
|
+
if (child.isDirectory()) walk(path13.join(absolute, child.name), relative7);
|
|
7015
7261
|
}
|
|
7016
7262
|
};
|
|
7017
7263
|
walk(dir, "");
|
|
@@ -7028,28 +7274,28 @@ function markerPayload(dir, state, id, createdAt) {
|
|
|
7028
7274
|
pid: process.pid,
|
|
7029
7275
|
entries: listEntries(dir)
|
|
7030
7276
|
};
|
|
7031
|
-
const manifestPath =
|
|
7032
|
-
if (
|
|
7033
|
-
marker2.manifestSha256 = sha256Hex2(
|
|
7277
|
+
const manifestPath = path13.join(dir, "manifest.json");
|
|
7278
|
+
if (fs12.existsSync(manifestPath)) {
|
|
7279
|
+
marker2.manifestSha256 = sha256Hex2(fs12.readFileSync(manifestPath));
|
|
7034
7280
|
}
|
|
7035
7281
|
return marker2;
|
|
7036
7282
|
}
|
|
7037
7283
|
function writeOwnershipMarker(dir, marker2) {
|
|
7038
|
-
|
|
7039
|
-
|
|
7284
|
+
fs12.writeFileSync(
|
|
7285
|
+
path13.join(dir, OWNERSHIP_MARKER),
|
|
7040
7286
|
`${JSON.stringify(marker2, null, 2)}
|
|
7041
7287
|
`,
|
|
7042
7288
|
"utf8"
|
|
7043
7289
|
);
|
|
7044
7290
|
}
|
|
7045
7291
|
function readOwnershipMarker(dir) {
|
|
7046
|
-
const markerPath =
|
|
7047
|
-
if (!
|
|
7292
|
+
const markerPath = path13.join(dir, OWNERSHIP_MARKER);
|
|
7293
|
+
if (!fs12.existsSync(markerPath)) {
|
|
7048
7294
|
return { marker: null, problem: "it holds no .codebase-snapshot marker" };
|
|
7049
7295
|
}
|
|
7050
7296
|
let raw;
|
|
7051
7297
|
try {
|
|
7052
|
-
raw =
|
|
7298
|
+
raw = fs12.readFileSync(markerPath, "utf8");
|
|
7053
7299
|
} catch {
|
|
7054
7300
|
return { marker: null, problem: "its .codebase-snapshot marker could not be read" };
|
|
7055
7301
|
}
|
|
@@ -7117,11 +7363,11 @@ function assessSnapshotDirectory(dir) {
|
|
|
7117
7363
|
marker: marker2
|
|
7118
7364
|
};
|
|
7119
7365
|
}
|
|
7120
|
-
const manifestPath =
|
|
7121
|
-
if (
|
|
7366
|
+
const manifestPath = path13.join(dir, "manifest.json");
|
|
7367
|
+
if (fs12.existsSync(manifestPath)) {
|
|
7122
7368
|
let raw;
|
|
7123
7369
|
try {
|
|
7124
|
-
raw =
|
|
7370
|
+
raw = fs12.readFileSync(manifestPath, "utf8");
|
|
7125
7371
|
} catch {
|
|
7126
7372
|
return {
|
|
7127
7373
|
owned: false,
|
|
@@ -7203,13 +7449,13 @@ function containsNoFiles(dir) {
|
|
|
7203
7449
|
const current = pending.pop();
|
|
7204
7450
|
let entries;
|
|
7205
7451
|
try {
|
|
7206
|
-
entries =
|
|
7452
|
+
entries = fs12.readdirSync(current, { withFileTypes: true });
|
|
7207
7453
|
} catch {
|
|
7208
7454
|
return false;
|
|
7209
7455
|
}
|
|
7210
7456
|
for (const entry of entries) {
|
|
7211
7457
|
if (entry.isDirectory()) {
|
|
7212
|
-
pending.push(
|
|
7458
|
+
pending.push(path13.join(current, entry.name));
|
|
7213
7459
|
} else if (!IGNORABLE_ENTRIES.has(entry.name)) {
|
|
7214
7460
|
return false;
|
|
7215
7461
|
}
|
|
@@ -7218,13 +7464,13 @@ function containsNoFiles(dir) {
|
|
|
7218
7464
|
return true;
|
|
7219
7465
|
}
|
|
7220
7466
|
function assertReplaceable(target, label, secretRules) {
|
|
7221
|
-
if (!
|
|
7222
|
-
if (!
|
|
7467
|
+
if (!fs12.existsSync(target)) return;
|
|
7468
|
+
if (!fs12.statSync(target).isDirectory()) {
|
|
7223
7469
|
throw new Error(
|
|
7224
7470
|
`Refusing to write into ${label} ${target}: it exists but is not a directory.`
|
|
7225
7471
|
);
|
|
7226
7472
|
}
|
|
7227
|
-
const entries =
|
|
7473
|
+
const entries = fs12.readdirSync(target);
|
|
7228
7474
|
if (entries.length === 0) return;
|
|
7229
7475
|
if (entries.every((name) => IGNORABLE_ENTRIES.has(name))) return;
|
|
7230
7476
|
if (containsNoFiles(target)) return;
|
|
@@ -7244,18 +7490,18 @@ function assertReplaceable(target, label, secretRules) {
|
|
|
7244
7490
|
);
|
|
7245
7491
|
}
|
|
7246
7492
|
function assertStagingRootUsable(tmpDir, secretRules) {
|
|
7247
|
-
if (!
|
|
7248
|
-
if (!
|
|
7493
|
+
if (!fs12.existsSync(tmpDir)) return;
|
|
7494
|
+
if (!fs12.statSync(tmpDir).isDirectory()) {
|
|
7249
7495
|
throw new Error(`Refusing to write into tmpDir ${tmpDir}: it exists but is not a directory.`);
|
|
7250
7496
|
}
|
|
7251
|
-
const entries =
|
|
7497
|
+
const entries = fs12.readdirSync(tmpDir);
|
|
7252
7498
|
if (entries.length === 0) return;
|
|
7253
7499
|
const foreign = entries.filter((name) => {
|
|
7254
|
-
const full =
|
|
7500
|
+
const full = path13.join(tmpDir, name);
|
|
7255
7501
|
if (!name.startsWith(RUN_DIR_PREFIX)) return true;
|
|
7256
7502
|
let stats;
|
|
7257
7503
|
try {
|
|
7258
|
-
stats =
|
|
7504
|
+
stats = fs12.statSync(full);
|
|
7259
7505
|
} catch {
|
|
7260
7506
|
return true;
|
|
7261
7507
|
}
|
|
@@ -7263,7 +7509,7 @@ function assertStagingRootUsable(tmpDir, secretRules) {
|
|
|
7263
7509
|
const { marker: marker2 } = readOwnershipMarker(full);
|
|
7264
7510
|
if (marker2) return false;
|
|
7265
7511
|
try {
|
|
7266
|
-
return
|
|
7512
|
+
return fs12.readdirSync(full).length > 0;
|
|
7267
7513
|
} catch {
|
|
7268
7514
|
return true;
|
|
7269
7515
|
}
|
|
@@ -7278,13 +7524,13 @@ function assertStagingRootUsable(tmpDir, secretRules) {
|
|
|
7278
7524
|
function cleanStaleRunDirs(tmpDir) {
|
|
7279
7525
|
let entries;
|
|
7280
7526
|
try {
|
|
7281
|
-
entries =
|
|
7527
|
+
entries = fs12.readdirSync(tmpDir);
|
|
7282
7528
|
} catch {
|
|
7283
7529
|
return;
|
|
7284
7530
|
}
|
|
7285
7531
|
for (const name of entries) {
|
|
7286
7532
|
if (!name.startsWith(RUN_DIR_PREFIX)) continue;
|
|
7287
|
-
const full =
|
|
7533
|
+
const full = path13.join(tmpDir, name);
|
|
7288
7534
|
const { marker: marker2 } = readOwnershipMarker(full);
|
|
7289
7535
|
if (marker2) {
|
|
7290
7536
|
const created = Date.parse(marker2.createdAt);
|
|
@@ -7292,33 +7538,33 @@ function cleanStaleRunDirs(tmpDir) {
|
|
|
7292
7538
|
const abandoned = typeof marker2.pid === "number" && !isProcessAlive(marker2.pid);
|
|
7293
7539
|
if (aged || abandoned) {
|
|
7294
7540
|
try {
|
|
7295
|
-
|
|
7541
|
+
fs12.rmSync(full, { recursive: true, force: true });
|
|
7296
7542
|
} catch {
|
|
7297
7543
|
}
|
|
7298
7544
|
}
|
|
7299
7545
|
continue;
|
|
7300
7546
|
}
|
|
7301
7547
|
try {
|
|
7302
|
-
if (
|
|
7548
|
+
if (fs12.readdirSync(full).length === 0) fs12.rmSync(full, { recursive: true, force: true });
|
|
7303
7549
|
} catch {
|
|
7304
7550
|
}
|
|
7305
7551
|
}
|
|
7306
7552
|
}
|
|
7307
7553
|
function removeIfEmpty(dir) {
|
|
7308
7554
|
try {
|
|
7309
|
-
if (
|
|
7555
|
+
if (fs12.readdirSync(dir).length === 0) fs12.rmSync(dir, { recursive: true, force: true });
|
|
7310
7556
|
} catch {
|
|
7311
7557
|
}
|
|
7312
7558
|
}
|
|
7313
7559
|
function ensureParentDirectory(target, label) {
|
|
7314
|
-
const parent =
|
|
7315
|
-
if (
|
|
7560
|
+
const parent = path13.dirname(target);
|
|
7561
|
+
if (fs12.existsSync(parent) && !fs12.statSync(parent).isDirectory()) {
|
|
7316
7562
|
throw new Error(
|
|
7317
7563
|
`Refusing to create ${label} ${target}: ${parent} exists but is not a directory.`
|
|
7318
7564
|
);
|
|
7319
7565
|
}
|
|
7320
7566
|
try {
|
|
7321
|
-
|
|
7567
|
+
fs12.mkdirSync(parent, { recursive: true });
|
|
7322
7568
|
} catch (err) {
|
|
7323
7569
|
throw new Error(
|
|
7324
7570
|
`Refusing to create ${label} ${target}: its parent ${parent} could not be created (${err.message}).`
|
|
@@ -7327,7 +7573,7 @@ function ensureParentDirectory(target, label) {
|
|
|
7327
7573
|
}
|
|
7328
7574
|
function acquireRunLock(stagingRoot) {
|
|
7329
7575
|
const key = lockKeyFor(stagingRoot);
|
|
7330
|
-
const lockPath =
|
|
7576
|
+
const lockPath = path13.join(os.tmpdir(), `codebase-snapshot-${key}.lock`);
|
|
7331
7577
|
const payload = `${JSON.stringify({
|
|
7332
7578
|
pid: process.pid,
|
|
7333
7579
|
stagingRoot,
|
|
@@ -7336,22 +7582,22 @@ function acquireRunLock(stagingRoot) {
|
|
|
7336
7582
|
`;
|
|
7337
7583
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
7338
7584
|
try {
|
|
7339
|
-
const handle =
|
|
7585
|
+
const handle = fs12.openSync(lockPath, "wx");
|
|
7340
7586
|
try {
|
|
7341
|
-
|
|
7587
|
+
fs12.writeSync(handle, payload);
|
|
7342
7588
|
} finally {
|
|
7343
|
-
|
|
7589
|
+
fs12.closeSync(handle);
|
|
7344
7590
|
}
|
|
7345
7591
|
return () => {
|
|
7346
7592
|
try {
|
|
7347
|
-
|
|
7593
|
+
fs12.rmSync(lockPath, { force: true });
|
|
7348
7594
|
} catch {
|
|
7349
7595
|
}
|
|
7350
7596
|
};
|
|
7351
7597
|
} catch (err) {
|
|
7352
7598
|
if (err.code !== "EEXIST") throw err;
|
|
7353
7599
|
if (attempt === 0 && lockOwnerIsGone(lockPath)) {
|
|
7354
|
-
|
|
7600
|
+
fs12.rmSync(lockPath, { force: true });
|
|
7355
7601
|
continue;
|
|
7356
7602
|
}
|
|
7357
7603
|
throw new Error(
|
|
@@ -7364,7 +7610,7 @@ function acquireRunLock(stagingRoot) {
|
|
|
7364
7610
|
function lockKeyFor(stagingRoot) {
|
|
7365
7611
|
let key = stagingRoot;
|
|
7366
7612
|
try {
|
|
7367
|
-
key =
|
|
7613
|
+
key = fs12.realpathSync(stagingRoot);
|
|
7368
7614
|
} catch {
|
|
7369
7615
|
}
|
|
7370
7616
|
if (process.platform === "win32" || process.platform === "darwin") key = key.toLowerCase();
|
|
@@ -7373,7 +7619,7 @@ function lockKeyFor(stagingRoot) {
|
|
|
7373
7619
|
function lockOwnerIsGone(lockPath) {
|
|
7374
7620
|
let raw;
|
|
7375
7621
|
try {
|
|
7376
|
-
raw =
|
|
7622
|
+
raw = fs12.readFileSync(lockPath, "utf8");
|
|
7377
7623
|
} catch {
|
|
7378
7624
|
return false;
|
|
7379
7625
|
}
|
|
@@ -7393,12 +7639,12 @@ function lockOwnerIsGone(lockPath) {
|
|
|
7393
7639
|
}
|
|
7394
7640
|
function writeManifestAtomically(manifestPath, manifest) {
|
|
7395
7641
|
const tempPath = `${manifestPath}.${process.pid}.tmp`;
|
|
7396
|
-
|
|
7642
|
+
fs12.writeFileSync(tempPath, JSON.stringify(manifest, null, 2), "utf8");
|
|
7397
7643
|
try {
|
|
7398
|
-
|
|
7644
|
+
fs12.renameSync(tempPath, manifestPath);
|
|
7399
7645
|
} catch (err) {
|
|
7400
7646
|
try {
|
|
7401
|
-
|
|
7647
|
+
fs12.rmSync(tempPath, { force: true });
|
|
7402
7648
|
} catch {
|
|
7403
7649
|
}
|
|
7404
7650
|
throw err;
|
|
@@ -7421,31 +7667,31 @@ function swapIntoPlace(stagingDir, outDir) {
|
|
|
7421
7667
|
}
|
|
7422
7668
|
function swapOnce(stagingDir, outDir) {
|
|
7423
7669
|
const backupDir = `${outDir}.backup-${process.pid}-${Date.now()}`;
|
|
7424
|
-
const hadPrevious =
|
|
7425
|
-
if (hadPrevious)
|
|
7670
|
+
const hadPrevious = fs12.existsSync(outDir);
|
|
7671
|
+
if (hadPrevious) fs12.renameSync(outDir, backupDir);
|
|
7426
7672
|
try {
|
|
7427
7673
|
try {
|
|
7428
|
-
|
|
7674
|
+
fs12.renameSync(stagingDir, outDir);
|
|
7429
7675
|
} catch (err) {
|
|
7430
7676
|
if (err.code !== "EXDEV") throw err;
|
|
7431
7677
|
const partialDir = `${outDir}.partial-${process.pid}-${Date.now()}`;
|
|
7432
7678
|
try {
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
|
|
7679
|
+
fs12.cpSync(stagingDir, partialDir, { recursive: true });
|
|
7680
|
+
fs12.renameSync(partialDir, outDir);
|
|
7681
|
+
fs12.rmSync(stagingDir, { recursive: true, force: true });
|
|
7436
7682
|
} catch (copyErr) {
|
|
7437
7683
|
try {
|
|
7438
|
-
|
|
7684
|
+
fs12.rmSync(partialDir, { recursive: true, force: true });
|
|
7439
7685
|
} catch {
|
|
7440
7686
|
}
|
|
7441
7687
|
throw copyErr;
|
|
7442
7688
|
}
|
|
7443
7689
|
}
|
|
7444
|
-
if (hadPrevious)
|
|
7690
|
+
if (hadPrevious) fs12.rmSync(backupDir, { recursive: true, force: true });
|
|
7445
7691
|
} catch (err) {
|
|
7446
|
-
if (hadPrevious &&
|
|
7447
|
-
if (
|
|
7448
|
-
|
|
7692
|
+
if (hadPrevious && fs12.existsSync(backupDir)) {
|
|
7693
|
+
if (fs12.existsSync(outDir)) fs12.rmSync(outDir, { recursive: true, force: true });
|
|
7694
|
+
fs12.renameSync(backupDir, outDir);
|
|
7449
7695
|
}
|
|
7450
7696
|
throw err;
|
|
7451
7697
|
}
|
|
@@ -7540,7 +7786,7 @@ function generateSnapshot(configInput, options) {
|
|
|
7540
7786
|
// first run cannot have marked them yet, so the name alone keeps a run from recording its own
|
|
7541
7787
|
// output — but only at these exact paths, not at every directory that shares the name.
|
|
7542
7788
|
toolOwnedPaths: [config.outDir, config.tmpDir].map(
|
|
7543
|
-
(directory) =>
|
|
7789
|
+
(directory) => path13.relative(config.cwd, path13.resolve(config.cwd, directory)).replace(/\\/g, "/")
|
|
7544
7790
|
).filter((relative7) => relative7.length > 0 && !relative7.startsWith(".."))
|
|
7545
7791
|
});
|
|
7546
7792
|
const files = [];
|
|
@@ -7561,12 +7807,12 @@ function generateSnapshot(configInput, options) {
|
|
|
7561
7807
|
let totalSizeBytes = 0;
|
|
7562
7808
|
let largeFileCount = 0;
|
|
7563
7809
|
for (const relativePath of collection.files) {
|
|
7564
|
-
const absolutePath =
|
|
7810
|
+
const absolutePath = path13.join(config.cwd, relativePath);
|
|
7565
7811
|
let stats;
|
|
7566
7812
|
try {
|
|
7567
|
-
stats =
|
|
7813
|
+
stats = fs12.statSync(absolutePath);
|
|
7568
7814
|
if (!stats.isFile()) {
|
|
7569
|
-
const nestedRepository = stats.isDirectory() &&
|
|
7815
|
+
const nestedRepository = stats.isDirectory() && fs12.existsSync(path13.join(absolutePath, ".git"));
|
|
7570
7816
|
skipped.push(
|
|
7571
7817
|
nestedRepository ? {
|
|
7572
7818
|
path: relativePath,
|
|
@@ -7586,7 +7832,7 @@ function generateSnapshot(configInput, options) {
|
|
|
7586
7832
|
}
|
|
7587
7833
|
let buffer;
|
|
7588
7834
|
try {
|
|
7589
|
-
buffer =
|
|
7835
|
+
buffer = fs12.readFileSync(absolutePath);
|
|
7590
7836
|
} catch {
|
|
7591
7837
|
skipped.push({ path: relativePath, reason: "read-error" });
|
|
7592
7838
|
continue;
|
|
@@ -7916,12 +8162,12 @@ function generateSnapshot(configInput, options) {
|
|
|
7916
8162
|
let stagingDir = null;
|
|
7917
8163
|
try {
|
|
7918
8164
|
ensureParentDirectory(outDir, "outDir");
|
|
7919
|
-
|
|
8165
|
+
fs12.mkdirSync(tmpDir, { recursive: true });
|
|
7920
8166
|
cleanStaleRunDirs(tmpDir);
|
|
7921
8167
|
const snapshotId = crypto.randomUUID();
|
|
7922
8168
|
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7923
|
-
stagingDir =
|
|
7924
|
-
|
|
8169
|
+
stagingDir = path13.join(tmpDir, `${RUN_DIR_PREFIX}${process.pid}-${snapshotId.slice(0, 8)}`);
|
|
8170
|
+
fs12.mkdirSync(stagingDir);
|
|
7925
8171
|
writeOwnershipMarker(stagingDir, {
|
|
7926
8172
|
generator: GENERATOR_NAME,
|
|
7927
8173
|
version: GENERATOR_VERSION,
|
|
@@ -7931,41 +8177,41 @@ function generateSnapshot(configInput, options) {
|
|
|
7931
8177
|
id: snapshotId,
|
|
7932
8178
|
pid: process.pid
|
|
7933
8179
|
});
|
|
7934
|
-
const partsDir =
|
|
7935
|
-
const reportsDir =
|
|
7936
|
-
if (artifacts.parts)
|
|
8180
|
+
const partsDir = path13.join(stagingDir, "parts");
|
|
8181
|
+
const reportsDir = path13.join(stagingDir, "reports");
|
|
8182
|
+
if (artifacts.parts) fs12.mkdirSync(partsDir, { recursive: true });
|
|
7937
8183
|
if (artifacts.navigation || artifacts.projectTree || artifacts.audit) {
|
|
7938
|
-
|
|
8184
|
+
fs12.mkdirSync(reportsDir, { recursive: true });
|
|
7939
8185
|
}
|
|
7940
8186
|
if (artifacts.parts) {
|
|
7941
8187
|
for (const part of parts) {
|
|
7942
|
-
|
|
8188
|
+
fs12.writeFileSync(path13.join(partsDir, part.filename), part.markdown, "utf8");
|
|
7943
8189
|
}
|
|
7944
8190
|
}
|
|
7945
8191
|
if (projectTree !== null) {
|
|
7946
|
-
|
|
8192
|
+
fs12.writeFileSync(path13.join(reportsDir, "project-tree.md"), projectTree, "utf8");
|
|
7947
8193
|
}
|
|
7948
8194
|
if (artifacts.navigation) {
|
|
7949
|
-
|
|
8195
|
+
fs12.writeFileSync(path13.join(reportsDir, "navigation.md"), generateNavigation(manifest), "utf8");
|
|
7950
8196
|
}
|
|
7951
8197
|
if (artifacts.audit) {
|
|
7952
|
-
|
|
7953
|
-
|
|
8198
|
+
fs12.writeFileSync(
|
|
8199
|
+
path13.join(reportsDir, "audit.md"),
|
|
7954
8200
|
generateAuditReport(manifest, secretFindings, config.secretRules),
|
|
7955
8201
|
"utf8"
|
|
7956
8202
|
);
|
|
7957
8203
|
}
|
|
7958
8204
|
if (artifacts.readme) {
|
|
7959
|
-
|
|
8205
|
+
fs12.writeFileSync(path13.join(stagingDir, "README.md"), generateReadme(manifest, artifacts), "utf8");
|
|
7960
8206
|
}
|
|
7961
8207
|
if (artifacts.manifest) {
|
|
7962
|
-
|
|
8208
|
+
fs12.writeFileSync(path13.join(stagingDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf8");
|
|
7963
8209
|
}
|
|
7964
8210
|
if (monolithJson !== null) {
|
|
7965
|
-
|
|
8211
|
+
fs12.writeFileSync(path13.join(stagingDir, "full-codebase.json"), monolithJson, "utf8");
|
|
7966
8212
|
}
|
|
7967
8213
|
if (monolithMarkdown !== null) {
|
|
7968
|
-
|
|
8214
|
+
fs12.writeFileSync(path13.join(stagingDir, "full-codebase.md"), monolithMarkdown, "utf8");
|
|
7969
8215
|
}
|
|
7970
8216
|
writeOwnershipMarker(stagingDir, markerPayload(stagingDir, "complete", snapshotId, createdAt));
|
|
7971
8217
|
swapIntoPlace(stagingDir, outDir);
|
|
@@ -7974,7 +8220,7 @@ function generateSnapshot(configInput, options) {
|
|
|
7974
8220
|
const pendingHook = runAfterGenerate(config, manifest);
|
|
7975
8221
|
const shipHookState = () => {
|
|
7976
8222
|
if (artifacts.manifest && manifest.warnings.length !== warningsBeforeHook) {
|
|
7977
|
-
writeManifestAtomically(
|
|
8223
|
+
writeManifestAtomically(path13.join(outDir, "manifest.json"), manifest);
|
|
7978
8224
|
}
|
|
7979
8225
|
writeOwnershipMarker(outDir, markerPayload(outDir, "complete", snapshotId, createdAt));
|
|
7980
8226
|
};
|
|
@@ -7997,7 +8243,7 @@ function generateSnapshot(configInput, options) {
|
|
|
7997
8243
|
} catch (err) {
|
|
7998
8244
|
if (stagingDir !== null) {
|
|
7999
8245
|
try {
|
|
8000
|
-
|
|
8246
|
+
fs12.rmSync(stagingDir, { recursive: true, force: true });
|
|
8001
8247
|
} catch {
|
|
8002
8248
|
}
|
|
8003
8249
|
}
|
|
@@ -8011,6 +8257,6 @@ async function generateSnapshotAsync(configInput, options) {
|
|
|
8011
8257
|
return generateSnapshot(configInput, options);
|
|
8012
8258
|
}
|
|
8013
8259
|
|
|
8014
|
-
export { ARTIFACT_NAMES, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, GENERATOR_NAME, GENERATOR_VERSION, LANGUAGE_PROFILES, MIN_MAX_PART_BYTES, PRESETS, PromptCancelled, SCHEMA_VERSION, anchorForPath, appendGitignoreEntries, assertReplaceable, assertUsableConfigInput, collectFiles, compareManifests, countInvalidUtf8Bytes, countLines, decodeText, defaultIO, defineConfig, describeManifestShapeProblem, detectLanguage, detectPreset, escapeControls, explainPath, fenceForContent, fenceForText, findConfigFile, firstRunMessage, formatNumber, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, gitignorePath, globToRegExp, hasPriorSnapshot, isBinaryBuffer, isBinaryExtension, isBinaryFile, isDiscoveryMode, isEffectivelyEmpty, isInteractive, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, planFirstRun, profileForPath, renderConfig, renderDiffText, renderExplainText, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, unknownPresetMessage, validateSnapshot };
|
|
8015
|
-
//# sourceMappingURL=chunk-
|
|
8016
|
-
//# sourceMappingURL=chunk-
|
|
8260
|
+
export { ARTIFACT_NAMES, CHECK_INTERVAL_MS, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, FAILURE_INTERVAL_MS, GENERATOR_NAME, GENERATOR_VERSION, LANGUAGE_PROFILES, MIN_MAX_PART_BYTES, PACKAGE_LATEST_URL, PRESETS, PromptCancelled, REQUEST_TIMEOUT_MS, SCHEMA_VERSION, anchorForPath, appendGitignoreEntries, assertReplaceable, assertUsableConfigInput, cacheDirectory, cacheFilePath, checkForUpdate, collectFiles, compareManifests, countInvalidUtf8Bytes, countLines, decodeText, defaultIO, defineConfig, describeManifestShapeProblem, detectLanguage, detectPreset, escapeControls, explainPath, fenceForContent, fenceForText, fetchLatestVersion, findConfigFile, firstRunMessage, formatNumber, formatUpdateNotice, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, gitignorePath, globToRegExp, hasPriorSnapshot, isBinaryBuffer, isBinaryExtension, isBinaryFile, isDiscoveryMode, isEffectivelyEmpty, isInteractive, isNewer, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, planFirstRun, profileForPath, renderConfig, renderDiffText, renderExplainText, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, shouldCheck, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, unknownPresetMessage, validateSnapshot };
|
|
8261
|
+
//# sourceMappingURL=chunk-3KUL3QRH.js.map
|
|
8262
|
+
//# sourceMappingURL=chunk-3KUL3QRH.js.map
|