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
package/dist/index.cjs
CHANGED
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
var crypto = require('crypto');
|
|
4
4
|
var async_hooks = require('async_hooks');
|
|
5
|
-
var
|
|
5
|
+
var fs12 = require('fs');
|
|
6
6
|
var os = require('os');
|
|
7
|
-
var
|
|
7
|
+
var path13 = require('path');
|
|
8
8
|
var ts = require('typescript');
|
|
9
9
|
var module$1 = require('module');
|
|
10
10
|
var url = require('url');
|
|
11
11
|
var childProcess = require('child_process');
|
|
12
|
+
var https = require('https');
|
|
12
13
|
var readline = require('readline');
|
|
13
14
|
|
|
14
15
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -32,11 +33,12 @@ function _interopNamespace(e) {
|
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto);
|
|
35
|
-
var
|
|
36
|
+
var fs12__namespace = /*#__PURE__*/_interopNamespace(fs12);
|
|
36
37
|
var os__namespace = /*#__PURE__*/_interopNamespace(os);
|
|
37
|
-
var
|
|
38
|
+
var path13__namespace = /*#__PURE__*/_interopNamespace(path13);
|
|
38
39
|
var ts__default = /*#__PURE__*/_interopDefault(ts);
|
|
39
40
|
var childProcess__namespace = /*#__PURE__*/_interopNamespace(childProcess);
|
|
41
|
+
var https__namespace = /*#__PURE__*/_interopNamespace(https);
|
|
40
42
|
var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
|
|
41
43
|
|
|
42
44
|
// src/index.ts
|
|
@@ -263,9 +265,9 @@ var JAVA_METHOD = /^\s+(?:public|private|protected)\s+(?:static\s+)?(?:final\s+)
|
|
|
263
265
|
var jvmProfile = {
|
|
264
266
|
id: "jvm",
|
|
265
267
|
extensions: [".java", ".kt", ".kts", ".scala"],
|
|
266
|
-
summarize(
|
|
268
|
+
summarize(path14, content) {
|
|
267
269
|
const summary = emptySummary();
|
|
268
|
-
const lower =
|
|
270
|
+
const lower = path14.toLowerCase();
|
|
269
271
|
const isJava = lower.endsWith(".java");
|
|
270
272
|
const isKotlin = lower.endsWith(".kt") || lower.endsWith(".kts");
|
|
271
273
|
eachLine(content, (line) => {
|
|
@@ -718,16 +720,16 @@ function summarizeTypeScriptSource(relativePath, content) {
|
|
|
718
720
|
// src/ast/profiles/sfc.ts
|
|
719
721
|
var SCRIPT_BLOCK = /<script[^>]*>([\s\S]*?)<\/script>/gi;
|
|
720
722
|
var ASTRO_FRONTMATTER = /^\uFEFF?---[ \t]*\r?\n([\s\S]*?)\r?\n---[ \t]*(?=\r?\n|$)/;
|
|
721
|
-
function componentName(
|
|
722
|
-
const base =
|
|
723
|
+
function componentName(path14) {
|
|
724
|
+
const base = path14.split("/").pop() ?? path14;
|
|
723
725
|
return base.replace(/\.[^.]+$/, "");
|
|
724
726
|
}
|
|
725
727
|
var sfcProfile = {
|
|
726
728
|
id: "sfc",
|
|
727
729
|
extensions: [".vue", ".svelte", ".astro"],
|
|
728
|
-
summarize(
|
|
730
|
+
summarize(path14, content) {
|
|
729
731
|
let script = "";
|
|
730
|
-
if (
|
|
732
|
+
if (path14.toLowerCase().endsWith(".astro")) {
|
|
731
733
|
const frontmatter = ASTRO_FRONTMATTER.exec(content);
|
|
732
734
|
if (frontmatter) script += `${frontmatter[1]}
|
|
733
735
|
`;
|
|
@@ -736,7 +738,7 @@ var sfcProfile = {
|
|
|
736
738
|
script += `${match[1]}
|
|
737
739
|
`;
|
|
738
740
|
}
|
|
739
|
-
const name = componentName(
|
|
741
|
+
const name = componentName(path14);
|
|
740
742
|
if (!script.trim()) {
|
|
741
743
|
const summary2 = emptySummary();
|
|
742
744
|
if (name) {
|
|
@@ -770,15 +772,15 @@ for (const profile of LANGUAGE_PROFILES) {
|
|
|
770
772
|
BY_EXTENSION.set(extension.toLowerCase(), profile);
|
|
771
773
|
}
|
|
772
774
|
}
|
|
773
|
-
function profileForPath(
|
|
774
|
-
const lower =
|
|
775
|
+
function profileForPath(path14) {
|
|
776
|
+
const lower = path14.toLowerCase();
|
|
775
777
|
const dot = lower.lastIndexOf(".");
|
|
776
778
|
if (dot === -1) return null;
|
|
777
779
|
return BY_EXTENSION.get(lower.slice(dot)) ?? null;
|
|
778
780
|
}
|
|
779
|
-
function summarizeWithProfile(
|
|
780
|
-
const profile = profileForPath(
|
|
781
|
-
return profile ? profile.summarize(
|
|
781
|
+
function summarizeWithProfile(path14, content) {
|
|
782
|
+
const profile = profileForPath(path14);
|
|
783
|
+
return profile ? profile.summarize(path14, content) : null;
|
|
782
784
|
}
|
|
783
785
|
|
|
784
786
|
// src/ast/structured.ts
|
|
@@ -949,15 +951,15 @@ var SKIPPED_WALK_DIRS = /* @__PURE__ */ new Set([
|
|
|
949
951
|
]);
|
|
950
952
|
function readSmallFile(fullPath) {
|
|
951
953
|
try {
|
|
952
|
-
const stats =
|
|
954
|
+
const stats = fs12__namespace.statSync(fullPath);
|
|
953
955
|
if (!stats.isFile() || stats.size > MANIFEST_MAX_BYTES) return null;
|
|
954
|
-
return
|
|
956
|
+
return fs12__namespace.readFileSync(fullPath, "utf8");
|
|
955
957
|
} catch {
|
|
956
958
|
return null;
|
|
957
959
|
}
|
|
958
960
|
}
|
|
959
961
|
function readManifest(cwd, name) {
|
|
960
|
-
return readSmallFile(
|
|
962
|
+
return readSmallFile(path13__namespace.join(cwd, name));
|
|
961
963
|
}
|
|
962
964
|
function dependenciesFromPackageJson(raw) {
|
|
963
965
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -1017,7 +1019,7 @@ function pnpmWorkspacePatterns(raw) {
|
|
|
1017
1019
|
function childDirectories(cwd, parent) {
|
|
1018
1020
|
let entries;
|
|
1019
1021
|
try {
|
|
1020
|
-
entries =
|
|
1022
|
+
entries = fs12__namespace.readdirSync(path13__namespace.join(cwd, parent), { withFileTypes: true });
|
|
1021
1023
|
} catch {
|
|
1022
1024
|
return [];
|
|
1023
1025
|
}
|
|
@@ -1053,12 +1055,12 @@ function scanWorkspacePackages(cwd, patterns) {
|
|
|
1053
1055
|
const files = /* @__PURE__ */ new Set();
|
|
1054
1056
|
const dependencies = /* @__PURE__ */ new Set();
|
|
1055
1057
|
for (const relative7 of workspacePackageDirs(cwd, patterns)) {
|
|
1056
|
-
const full =
|
|
1058
|
+
const full = path13__namespace.join(cwd, relative7);
|
|
1057
1059
|
try {
|
|
1058
|
-
for (const entry of
|
|
1060
|
+
for (const entry of fs12__namespace.readdirSync(full, { withFileTypes: true })) files.add(entry.name);
|
|
1059
1061
|
} catch {
|
|
1060
1062
|
}
|
|
1061
|
-
const raw = readSmallFile(
|
|
1063
|
+
const raw = readSmallFile(path13__namespace.join(full, "package.json"));
|
|
1062
1064
|
if (raw !== null) {
|
|
1063
1065
|
for (const name of dependenciesFromPackageJson(raw)) dependencies.add(name);
|
|
1064
1066
|
}
|
|
@@ -1075,7 +1077,7 @@ function countMarkdownFiles(cwd) {
|
|
|
1075
1077
|
directoriesSeen += 1;
|
|
1076
1078
|
let entries;
|
|
1077
1079
|
try {
|
|
1078
|
-
entries =
|
|
1080
|
+
entries = fs12__namespace.readdirSync(current.dir, { withFileTypes: true });
|
|
1079
1081
|
} catch {
|
|
1080
1082
|
continue;
|
|
1081
1083
|
}
|
|
@@ -1086,7 +1088,7 @@ function countMarkdownFiles(cwd) {
|
|
|
1086
1088
|
}
|
|
1087
1089
|
if (!entry.isDirectory() || current.depth >= 2) continue;
|
|
1088
1090
|
if (entry.name.startsWith(".") || SKIPPED_WALK_DIRS.has(entry.name)) continue;
|
|
1089
|
-
queue.push({ dir:
|
|
1091
|
+
queue.push({ dir: path13__namespace.join(current.dir, entry.name), depth: current.depth + 1 });
|
|
1090
1092
|
}
|
|
1091
1093
|
}
|
|
1092
1094
|
return count;
|
|
@@ -1095,7 +1097,7 @@ function buildPresetContext(cwd) {
|
|
|
1095
1097
|
const files = /* @__PURE__ */ new Set();
|
|
1096
1098
|
const dirs = /* @__PURE__ */ new Set();
|
|
1097
1099
|
try {
|
|
1098
|
-
for (const entry of
|
|
1100
|
+
for (const entry of fs12__namespace.readdirSync(cwd, { withFileTypes: true })) {
|
|
1099
1101
|
if (entry.isDirectory()) dirs.add(entry.name);
|
|
1100
1102
|
else if (entry.isFile()) files.add(entry.name);
|
|
1101
1103
|
}
|
|
@@ -1112,7 +1114,7 @@ function buildPresetContext(cwd) {
|
|
|
1112
1114
|
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;
|
|
1113
1115
|
let workspace = { files: /* @__PURE__ */ new Set(), dependencies: /* @__PURE__ */ new Set() };
|
|
1114
1116
|
if (isWorkspace) {
|
|
1115
|
-
const pnpmRaw = files.has("pnpm-workspace.yaml") ? readSmallFile(
|
|
1117
|
+
const pnpmRaw = files.has("pnpm-workspace.yaml") ? readSmallFile(path13__namespace.join(cwd, "pnpm-workspace.yaml")) : null;
|
|
1116
1118
|
const declared = pnpmRaw === null ? [] : pnpmWorkspacePatterns(pnpmRaw);
|
|
1117
1119
|
const patterns = declared.length > 0 ? declared : declaredWorkspaces.length > 0 ? declaredWorkspaces : DEFAULT_WORKSPACE_PATTERNS;
|
|
1118
1120
|
workspace = scanWorkspacePackages(cwd, patterns);
|
|
@@ -2387,14 +2389,14 @@ var PRESET_IGNORES = new Set(
|
|
|
2387
2389
|
);
|
|
2388
2390
|
function readLinkTarget(linkPath, fallback) {
|
|
2389
2391
|
try {
|
|
2390
|
-
return
|
|
2392
|
+
return fs12__namespace.readlinkSync(linkPath);
|
|
2391
2393
|
} catch {
|
|
2392
2394
|
return fallback;
|
|
2393
2395
|
}
|
|
2394
2396
|
}
|
|
2395
2397
|
function isInside(root, candidate) {
|
|
2396
|
-
const relative7 =
|
|
2397
|
-
return relative7 === "" || !relative7.startsWith(`..${
|
|
2398
|
+
const relative7 = path13__namespace.relative(root, candidate);
|
|
2399
|
+
return relative7 === "" || !relative7.startsWith(`..${path13__namespace.sep}`) && relative7 !== ".." && !path13__namespace.isAbsolute(relative7);
|
|
2398
2400
|
}
|
|
2399
2401
|
function getGitInfo(cwd, fallbackBranch = "main") {
|
|
2400
2402
|
try {
|
|
@@ -2599,10 +2601,10 @@ function trimUnescapedTrailingSpaces(line) {
|
|
|
2599
2601
|
return line.slice(0, end);
|
|
2600
2602
|
}
|
|
2601
2603
|
function readGitignoreRules(dir) {
|
|
2602
|
-
const gitignorePath =
|
|
2604
|
+
const gitignorePath = path13__namespace.join(dir, ".gitignore");
|
|
2603
2605
|
let raw;
|
|
2604
2606
|
try {
|
|
2605
|
-
raw =
|
|
2607
|
+
raw = fs12__namespace.readFileSync(gitignorePath, "utf8");
|
|
2606
2608
|
} catch {
|
|
2607
2609
|
return [];
|
|
2608
2610
|
}
|
|
@@ -2729,7 +2731,7 @@ function isToolOwnedDirName(name) {
|
|
|
2729
2731
|
}
|
|
2730
2732
|
function hasSnapshotMarker(target) {
|
|
2731
2733
|
try {
|
|
2732
|
-
return
|
|
2734
|
+
return fs12__namespace.statSync(target).isDirectory() && fs12__namespace.existsSync(path13__namespace.join(target, ".codebase-snapshot"));
|
|
2733
2735
|
} catch {
|
|
2734
2736
|
return false;
|
|
2735
2737
|
}
|
|
@@ -2743,7 +2745,7 @@ function makeToolOwnedDecider(cwd, toolOwnedPaths) {
|
|
|
2743
2745
|
const prefix = parts.slice(0, depth).join("/");
|
|
2744
2746
|
let hasMarker = markers.get(prefix);
|
|
2745
2747
|
if (hasMarker === void 0) {
|
|
2746
|
-
hasMarker =
|
|
2748
|
+
hasMarker = fs12__namespace.existsSync(path13__namespace.join(cwd, prefix, ".codebase-snapshot"));
|
|
2747
2749
|
markers.set(prefix, hasMarker);
|
|
2748
2750
|
}
|
|
2749
2751
|
if (hasMarker) return true;
|
|
@@ -2758,7 +2760,7 @@ function makeLinkProbe() {
|
|
|
2758
2760
|
let known = cache.get(absolutePath);
|
|
2759
2761
|
if (known === void 0) {
|
|
2760
2762
|
try {
|
|
2761
|
-
known =
|
|
2763
|
+
known = fs12__namespace.lstatSync(absolutePath).isSymbolicLink();
|
|
2762
2764
|
} catch {
|
|
2763
2765
|
known = false;
|
|
2764
2766
|
}
|
|
@@ -2771,7 +2773,7 @@ function dropLinkedDirectories(cwd, candidates, skipped) {
|
|
|
2771
2773
|
const isLink = makeLinkProbe();
|
|
2772
2774
|
let rootReal = cwd;
|
|
2773
2775
|
try {
|
|
2774
|
-
rootReal =
|
|
2776
|
+
rootReal = fs12__namespace.realpathSync(cwd);
|
|
2775
2777
|
} catch {
|
|
2776
2778
|
}
|
|
2777
2779
|
const reported = /* @__PURE__ */ new Set();
|
|
@@ -2781,7 +2783,7 @@ function dropLinkedDirectories(cwd, candidates, skipped) {
|
|
|
2781
2783
|
let linkedDir = null;
|
|
2782
2784
|
for (let depth = 1; depth <= parts.length; depth += 1) {
|
|
2783
2785
|
const prefix = parts.slice(0, depth).join("/");
|
|
2784
|
-
if (isLink(
|
|
2786
|
+
if (isLink(path13__namespace.join(cwd, prefix))) {
|
|
2785
2787
|
linkedDir = prefix;
|
|
2786
2788
|
break;
|
|
2787
2789
|
}
|
|
@@ -2792,10 +2794,10 @@ function dropLinkedDirectories(cwd, candidates, skipped) {
|
|
|
2792
2794
|
}
|
|
2793
2795
|
if (reported.has(linkedDir)) continue;
|
|
2794
2796
|
reported.add(linkedDir);
|
|
2795
|
-
const absolute =
|
|
2797
|
+
const absolute = path13__namespace.join(cwd, linkedDir);
|
|
2796
2798
|
let targetReal = absolute;
|
|
2797
2799
|
try {
|
|
2798
|
-
targetReal =
|
|
2800
|
+
targetReal = fs12__namespace.realpathSync(absolute);
|
|
2799
2801
|
} catch {
|
|
2800
2802
|
}
|
|
2801
2803
|
const target = readLinkTarget(absolute, targetReal);
|
|
@@ -2872,7 +2874,7 @@ function collectFiles(cwd, options = {}) {
|
|
|
2872
2874
|
"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."
|
|
2873
2875
|
);
|
|
2874
2876
|
}
|
|
2875
|
-
if (
|
|
2877
|
+
if (fs12__namespace.existsSync(path13__namespace.join(cwd, ".git"))) {
|
|
2876
2878
|
throw new Error(
|
|
2877
2879
|
"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."
|
|
2878
2880
|
);
|
|
@@ -2931,7 +2933,7 @@ function collectFiles(cwd, options = {}) {
|
|
|
2931
2933
|
}
|
|
2932
2934
|
function rootRealFor(root) {
|
|
2933
2935
|
try {
|
|
2934
|
-
return
|
|
2936
|
+
return fs12__namespace.realpathSync(root);
|
|
2935
2937
|
} catch {
|
|
2936
2938
|
return root;
|
|
2937
2939
|
}
|
|
@@ -2939,18 +2941,18 @@ function rootRealFor(root) {
|
|
|
2939
2941
|
function walkDirectory(dir, baseDir, rootReal, visited, reservedPaths = /* @__PURE__ */ new Set(), parentGitignoreLayers = []) {
|
|
2940
2942
|
const results = { files: [], skipped: [] };
|
|
2941
2943
|
const stack = [];
|
|
2942
|
-
const relativeToBase = (target) =>
|
|
2944
|
+
const relativeToBase = (target) => path13__namespace.relative(baseDir, target).replace(/\\/g, "/") || ".";
|
|
2943
2945
|
const enter = (current, layers) => {
|
|
2944
2946
|
if (visited.has(current)) return false;
|
|
2945
2947
|
visited.add(current);
|
|
2946
2948
|
const localRules = readGitignoreRules(current);
|
|
2947
2949
|
const gitignoreLayers = localRules.length === 0 ? layers : [
|
|
2948
2950
|
...layers,
|
|
2949
|
-
{ prefix:
|
|
2951
|
+
{ prefix: path13__namespace.relative(baseDir, current).replace(/\\/g, "/"), rules: localRules }
|
|
2950
2952
|
];
|
|
2951
2953
|
let entries;
|
|
2952
2954
|
try {
|
|
2953
|
-
entries =
|
|
2955
|
+
entries = fs12__namespace.readdirSync(current, { withFileTypes: true });
|
|
2954
2956
|
} catch {
|
|
2955
2957
|
results.skipped.push({
|
|
2956
2958
|
path: relativeToBase(current),
|
|
@@ -2972,8 +2974,8 @@ function walkDirectory(dir, baseDir, rootReal, visited, reservedPaths = /* @__PU
|
|
|
2972
2974
|
}
|
|
2973
2975
|
const entry = frame.entries[frame.index];
|
|
2974
2976
|
frame.index += 1;
|
|
2975
|
-
const fullPath =
|
|
2976
|
-
const relPath =
|
|
2977
|
+
const fullPath = path13__namespace.join(frame.dir, entry.name);
|
|
2978
|
+
const relPath = path13__namespace.relative(baseDir, fullPath).replace(/\\/g, "/");
|
|
2977
2979
|
if (isToolOwnedDirName(entry.name) && reservedPaths.has(relPath)) continue;
|
|
2978
2980
|
if (DEFAULT_IGNORED_DIRS.includes(entry.name)) {
|
|
2979
2981
|
results.skipped.push({
|
|
@@ -3006,14 +3008,14 @@ function walkDirectory(dir, baseDir, rootReal, visited, reservedPaths = /* @__PU
|
|
|
3006
3008
|
if (entry.isSymbolicLink()) {
|
|
3007
3009
|
let targetReal;
|
|
3008
3010
|
try {
|
|
3009
|
-
targetReal =
|
|
3011
|
+
targetReal = fs12__namespace.realpathSync(fullPath);
|
|
3010
3012
|
} catch {
|
|
3011
3013
|
results.skipped.push({ path: relPath, reason: "read-error", detail: "broken symlink" });
|
|
3012
3014
|
continue;
|
|
3013
3015
|
}
|
|
3014
3016
|
let stats;
|
|
3015
3017
|
try {
|
|
3016
|
-
stats =
|
|
3018
|
+
stats = fs12__namespace.statSync(fullPath);
|
|
3017
3019
|
} catch {
|
|
3018
3020
|
results.skipped.push({ path: relPath, reason: "read-error", detail: "unreadable symlink" });
|
|
3019
3021
|
continue;
|
|
@@ -3311,11 +3313,11 @@ async function loadConfigFileDetailed(cwd) {
|
|
|
3311
3313
|
const warnings = [];
|
|
3312
3314
|
const errors = [];
|
|
3313
3315
|
for (const filename of CONFIG_FILENAMES) {
|
|
3314
|
-
const fullPath =
|
|
3315
|
-
if (!
|
|
3316
|
+
const fullPath = path13__namespace.join(cwd, filename);
|
|
3317
|
+
if (!fs12__namespace.existsSync(fullPath)) continue;
|
|
3316
3318
|
if (filename.endsWith(".json") || filename === ".snapshotrc") {
|
|
3317
3319
|
try {
|
|
3318
|
-
const config = parseJsonish(
|
|
3320
|
+
const config = parseJsonish(fs12__namespace.readFileSync(fullPath, "utf8"), fullPath);
|
|
3319
3321
|
if (config === null || typeof config !== "object" || Array.isArray(config)) {
|
|
3320
3322
|
throw new Error(
|
|
3321
3323
|
`${fullPath} does not hold a configuration object (received ${describeValue2(config)}).`
|
|
@@ -3349,10 +3351,10 @@ async function loadConfigFileDetailed(cwd) {
|
|
|
3349
3351
|
continue;
|
|
3350
3352
|
}
|
|
3351
3353
|
}
|
|
3352
|
-
const pkgJsonPath =
|
|
3353
|
-
if (
|
|
3354
|
+
const pkgJsonPath = path13__namespace.join(cwd, "package.json");
|
|
3355
|
+
if (fs12__namespace.existsSync(pkgJsonPath)) {
|
|
3354
3356
|
try {
|
|
3355
|
-
const parsed = parseJsonish(
|
|
3357
|
+
const parsed = parseJsonish(fs12__namespace.readFileSync(pkgJsonPath, "utf8"), pkgJsonPath);
|
|
3356
3358
|
const snapshotKey = parsed.snapshot;
|
|
3357
3359
|
if (snapshotKey && typeof snapshotKey === "object" && !Array.isArray(snapshotKey)) {
|
|
3358
3360
|
return { config: snapshotKey, file: pkgJsonPath, warnings, errors };
|
|
@@ -3375,7 +3377,7 @@ async function loadConfigFile(cwd) {
|
|
|
3375
3377
|
const loaded = await loadConfigFileDetailed(cwd);
|
|
3376
3378
|
if (loaded.config && loaded.file && typeof loaded.config === "object") {
|
|
3377
3379
|
Object.defineProperty(loaded.config, CONFIG_DIR_SYMBOL, {
|
|
3378
|
-
value:
|
|
3380
|
+
value: path13__namespace.dirname(loaded.file),
|
|
3379
3381
|
enumerable: false,
|
|
3380
3382
|
configurable: true
|
|
3381
3383
|
});
|
|
@@ -3534,9 +3536,9 @@ function resolveKindRules(value) {
|
|
|
3534
3536
|
function outputExcludePatterns(cwd, outDir, tmpDir) {
|
|
3535
3537
|
const patterns = [];
|
|
3536
3538
|
for (const dir of [outDir, tmpDir]) {
|
|
3537
|
-
const absolute =
|
|
3538
|
-
const relative7 =
|
|
3539
|
-
if (!relative7 || relative7 === ".." || relative7.startsWith(`..${
|
|
3539
|
+
const absolute = path13__namespace.resolve(cwd, dir);
|
|
3540
|
+
const relative7 = path13__namespace.relative(cwd, absolute);
|
|
3541
|
+
if (!relative7 || relative7 === ".." || relative7.startsWith(`..${path13__namespace.sep}`) || path13__namespace.isAbsolute(relative7)) {
|
|
3540
3542
|
continue;
|
|
3541
3543
|
}
|
|
3542
3544
|
patterns.push(`${relative7.replace(/\\/g, "/")}/**`);
|
|
@@ -3655,11 +3657,11 @@ function resolveCandidateCwd(userConfig, cliOptions, baseDir) {
|
|
|
3655
3657
|
);
|
|
3656
3658
|
}
|
|
3657
3659
|
const candidate = cliOptions?.cwd || userConfig?.cwd || baseDir || process.cwd();
|
|
3658
|
-
const resolved =
|
|
3659
|
-
if (!
|
|
3660
|
+
const resolved = path13__namespace.resolve(candidate);
|
|
3661
|
+
if (!fs12__namespace.existsSync(resolved)) {
|
|
3660
3662
|
throw new Error(`Working directory does not exist: ${resolved}`);
|
|
3661
3663
|
}
|
|
3662
|
-
if (!
|
|
3664
|
+
if (!fs12__namespace.statSync(resolved).isDirectory()) {
|
|
3663
3665
|
throw new Error(`Working directory is not a directory: ${resolved}`);
|
|
3664
3666
|
}
|
|
3665
3667
|
return resolved;
|
|
@@ -4683,7 +4685,7 @@ var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
4683
4685
|
".so"
|
|
4684
4686
|
]);
|
|
4685
4687
|
function isBinaryExtension(filePath) {
|
|
4686
|
-
const ext =
|
|
4688
|
+
const ext = path13__namespace.extname(filePath).toLowerCase();
|
|
4687
4689
|
return BINARY_EXTENSIONS.has(ext);
|
|
4688
4690
|
}
|
|
4689
4691
|
function isBinaryBuffer(buffer) {
|
|
@@ -4853,13 +4855,13 @@ function isBinaryFile(absolutePath) {
|
|
|
4853
4855
|
if (isBinaryExtension(absolutePath)) return true;
|
|
4854
4856
|
let fd;
|
|
4855
4857
|
try {
|
|
4856
|
-
fd =
|
|
4858
|
+
fd = fs12__namespace.openSync(absolutePath, "r");
|
|
4857
4859
|
const buffer = Buffer.alloc(CHUNK);
|
|
4858
4860
|
let sample;
|
|
4859
4861
|
let position = 0;
|
|
4860
4862
|
while (position < BINARY_SCAN_BYTES) {
|
|
4861
4863
|
const wanted = Math.min(CHUNK, BINARY_SCAN_BYTES - position);
|
|
4862
|
-
const bytesRead =
|
|
4864
|
+
const bytesRead = fs12__namespace.readSync(fd, buffer, 0, wanted, position);
|
|
4863
4865
|
if (bytesRead === 0) return false;
|
|
4864
4866
|
const chunk = buffer.subarray(0, bytesRead);
|
|
4865
4867
|
if (sample === void 0) {
|
|
@@ -4877,7 +4879,7 @@ function isBinaryFile(absolutePath) {
|
|
|
4877
4879
|
} finally {
|
|
4878
4880
|
if (fd !== void 0) {
|
|
4879
4881
|
try {
|
|
4880
|
-
|
|
4882
|
+
fs12__namespace.closeSync(fd);
|
|
4881
4883
|
} catch {
|
|
4882
4884
|
}
|
|
4883
4885
|
}
|
|
@@ -4937,10 +4939,10 @@ var LANGUAGE_BY_BASENAME = {
|
|
|
4937
4939
|
};
|
|
4938
4940
|
function detectLanguage(filePath) {
|
|
4939
4941
|
const normalized = filePath.replace(/\\/g, "/");
|
|
4940
|
-
const base =
|
|
4942
|
+
const base = path13__namespace.posix.basename(normalized);
|
|
4941
4943
|
if (LANGUAGE_BY_BASENAME[base]) return LANGUAGE_BY_BASENAME[base];
|
|
4942
4944
|
if (base === ".env" || base.startsWith(".env.")) return "dotenv";
|
|
4943
|
-
const ext =
|
|
4945
|
+
const ext = path13__namespace.posix.extname(base).toLowerCase();
|
|
4944
4946
|
return LANGUAGE_BY_EXTENSION[ext] ?? "text";
|
|
4945
4947
|
}
|
|
4946
4948
|
function maskedPath(value, secretRules) {
|
|
@@ -4948,33 +4950,33 @@ function maskedPath(value, secretRules) {
|
|
|
4948
4950
|
}
|
|
4949
4951
|
function confineToDirectory(directory, filename) {
|
|
4950
4952
|
if (filename.includes("\0")) return null;
|
|
4951
|
-
if (
|
|
4952
|
-
const base =
|
|
4953
|
-
const resolved =
|
|
4953
|
+
if (path13__namespace.isAbsolute(filename)) return null;
|
|
4954
|
+
const base = path13__namespace.resolve(directory);
|
|
4955
|
+
const resolved = path13__namespace.resolve(base, filename);
|
|
4954
4956
|
const caseInsensitive = process.platform === "win32" || process.platform === "darwin";
|
|
4955
|
-
const prefix = caseInsensitive ? `${base}${
|
|
4957
|
+
const prefix = caseInsensitive ? `${base}${path13__namespace.sep}`.toLowerCase() : `${base}${path13__namespace.sep}`;
|
|
4956
4958
|
const candidate = caseInsensitive ? resolved.toLowerCase() : resolved;
|
|
4957
4959
|
return candidate.startsWith(prefix) ? resolved : null;
|
|
4958
4960
|
}
|
|
4959
4961
|
function findStagingDirectory(config) {
|
|
4960
|
-
const tmpDir =
|
|
4962
|
+
const tmpDir = path13__namespace.resolve(config.cwd, config.tmpDir);
|
|
4961
4963
|
let entries;
|
|
4962
4964
|
try {
|
|
4963
|
-
entries =
|
|
4965
|
+
entries = fs12__namespace.readdirSync(tmpDir);
|
|
4964
4966
|
} catch {
|
|
4965
4967
|
return null;
|
|
4966
4968
|
}
|
|
4967
4969
|
const runs = entries.filter((name) => name.startsWith("run-")).sort();
|
|
4968
4970
|
const newest = runs[runs.length - 1];
|
|
4969
|
-
return newest ?
|
|
4971
|
+
return newest ? path13__namespace.join(tmpDir, newest) : null;
|
|
4970
4972
|
}
|
|
4971
4973
|
function describeMissingManifest(config, manifestPath) {
|
|
4972
|
-
const outDir =
|
|
4973
|
-
const markerPath =
|
|
4974
|
+
const outDir = path13__namespace.resolve(config.cwd, config.outDir);
|
|
4975
|
+
const markerPath = path13__namespace.join(outDir, ".codebase-snapshot");
|
|
4974
4976
|
let marker2 = null;
|
|
4975
4977
|
try {
|
|
4976
|
-
if (
|
|
4977
|
-
const parsed = JSON.parse(
|
|
4978
|
+
if (fs12__namespace.existsSync(markerPath)) {
|
|
4979
|
+
const parsed = JSON.parse(fs12__namespace.readFileSync(markerPath, "utf8"));
|
|
4978
4980
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
4979
4981
|
marker2 = parsed;
|
|
4980
4982
|
}
|
|
@@ -5010,14 +5012,14 @@ function sha256Hex(buffer) {
|
|
|
5010
5012
|
}
|
|
5011
5013
|
var VERIFY_SNIFF_MAX_BYTES = 8 * 1024 * 1024;
|
|
5012
5014
|
function wouldNowBeIncluded(cwd, relativePath, reason) {
|
|
5013
|
-
const absolutePath =
|
|
5015
|
+
const absolutePath = path13__namespace.join(cwd, relativePath);
|
|
5014
5016
|
try {
|
|
5015
|
-
const stats =
|
|
5017
|
+
const stats = fs12__namespace.statSync(absolutePath);
|
|
5016
5018
|
if (!stats.isFile()) return false;
|
|
5017
5019
|
if (isBinaryFile(absolutePath)) return false;
|
|
5018
5020
|
if (reason !== "binary") return true;
|
|
5019
5021
|
if (stats.size > VERIFY_SNIFF_MAX_BYTES) return false;
|
|
5020
|
-
return !decodeText(
|
|
5022
|
+
return !decodeText(fs12__namespace.readFileSync(absolutePath)).binary;
|
|
5021
5023
|
} catch {
|
|
5022
5024
|
return false;
|
|
5023
5025
|
}
|
|
@@ -5075,8 +5077,8 @@ function describeManifestShapeProblem(value) {
|
|
|
5075
5077
|
function validateSnapshot(configInput) {
|
|
5076
5078
|
assertUsableConfigInput(configInput);
|
|
5077
5079
|
const config = isResolvedConfig(configInput) ? normalizeResolvedConfig(configInput) : resolveConfig(configInput);
|
|
5078
|
-
const manifestPath =
|
|
5079
|
-
if (!
|
|
5080
|
+
const manifestPath = path13__namespace.resolve(config.cwd, config.outDir, "manifest.json");
|
|
5081
|
+
if (!fs12__namespace.existsSync(manifestPath)) {
|
|
5080
5082
|
return {
|
|
5081
5083
|
valid: false,
|
|
5082
5084
|
manifestPresent: false,
|
|
@@ -5087,7 +5089,7 @@ function validateSnapshot(configInput) {
|
|
|
5087
5089
|
}
|
|
5088
5090
|
let manifest;
|
|
5089
5091
|
try {
|
|
5090
|
-
manifest = JSON.parse(
|
|
5092
|
+
manifest = JSON.parse(fs12__namespace.readFileSync(manifestPath, "utf8"));
|
|
5091
5093
|
} catch (err) {
|
|
5092
5094
|
return {
|
|
5093
5095
|
valid: false,
|
|
@@ -5109,7 +5111,7 @@ function validateSnapshot(configInput) {
|
|
|
5109
5111
|
}
|
|
5110
5112
|
const drift = emptyDrift();
|
|
5111
5113
|
const warnings = [];
|
|
5112
|
-
const snapshotDir =
|
|
5114
|
+
const snapshotDir = path13__namespace.resolve(config.cwd, config.outDir);
|
|
5113
5115
|
const manifestFileMap = /* @__PURE__ */ new Map();
|
|
5114
5116
|
for (const file of manifest.files) {
|
|
5115
5117
|
if (file && typeof file.relativePath === "string") {
|
|
@@ -5143,7 +5145,7 @@ function validateSnapshot(configInput) {
|
|
|
5143
5145
|
}
|
|
5144
5146
|
let diskHash;
|
|
5145
5147
|
try {
|
|
5146
|
-
diskHash = sha256Hex(
|
|
5148
|
+
diskHash = sha256Hex(fs12__namespace.readFileSync(path13__namespace.join(config.cwd, diskFile)));
|
|
5147
5149
|
} catch (err) {
|
|
5148
5150
|
if (err.code === "ENOENT") {
|
|
5149
5151
|
drift.missingOnDisk.push(diskFile);
|
|
@@ -5167,7 +5169,7 @@ function validateSnapshot(configInput) {
|
|
|
5167
5169
|
}
|
|
5168
5170
|
let statFailure = null;
|
|
5169
5171
|
try {
|
|
5170
|
-
|
|
5172
|
+
fs12__namespace.statSync(confined);
|
|
5171
5173
|
} catch (err) {
|
|
5172
5174
|
statFailure = err;
|
|
5173
5175
|
}
|
|
@@ -5187,7 +5189,7 @@ function validateSnapshot(configInput) {
|
|
|
5187
5189
|
...Object.values(config.budgets.byLayer)
|
|
5188
5190
|
);
|
|
5189
5191
|
const partNames = /* @__PURE__ */ new Set();
|
|
5190
|
-
const partsDir =
|
|
5192
|
+
const partsDir = path13__namespace.join(snapshotDir, "parts");
|
|
5191
5193
|
for (const part of manifest.parts) {
|
|
5192
5194
|
if (!part || typeof part.filename !== "string") continue;
|
|
5193
5195
|
partNames.add(part.filename);
|
|
@@ -5202,7 +5204,7 @@ function validateSnapshot(configInput) {
|
|
|
5202
5204
|
}
|
|
5203
5205
|
let buffer;
|
|
5204
5206
|
try {
|
|
5205
|
-
buffer =
|
|
5207
|
+
buffer = fs12__namespace.readFileSync(partPath);
|
|
5206
5208
|
} catch {
|
|
5207
5209
|
drift.partIssues.push({ part: part.filename, issue: "missing from snapshot/parts" });
|
|
5208
5210
|
continue;
|
|
@@ -5416,9 +5418,9 @@ function validateSnapshot(configInput) {
|
|
|
5416
5418
|
["full-codebase.md", manifest.artifacts?.fullMarkdown]
|
|
5417
5419
|
]) {
|
|
5418
5420
|
if (!artifact) continue;
|
|
5419
|
-
const artifactPath =
|
|
5421
|
+
const artifactPath = path13__namespace.join(snapshotDir, key);
|
|
5420
5422
|
try {
|
|
5421
|
-
const buffer =
|
|
5423
|
+
const buffer = fs12__namespace.readFileSync(artifactPath);
|
|
5422
5424
|
if (sha256Hex(buffer) !== artifact.sha256 || buffer.length !== artifact.byteSize) {
|
|
5423
5425
|
drift.partIssues.push({ part: key, issue: "artifact does not match its recorded digest" });
|
|
5424
5426
|
}
|
|
@@ -5488,12 +5490,168 @@ function validateSnapshot(configInput) {
|
|
|
5488
5490
|
|
|
5489
5491
|
// src/version.ts
|
|
5490
5492
|
var GENERATOR_NAME = "codebase-snapshot";
|
|
5491
|
-
var GENERATOR_VERSION = "0.9.
|
|
5493
|
+
var GENERATOR_VERSION = "0.9.6";
|
|
5492
5494
|
var LEGACY_GENERATOR_NAMES = ["@ankurhalder/codebase-snapshot"];
|
|
5493
5495
|
function isOurGeneratorName(name) {
|
|
5494
5496
|
if (typeof name !== "string") return false;
|
|
5495
5497
|
return name === GENERATOR_NAME || LEGACY_GENERATOR_NAMES.includes(name);
|
|
5496
5498
|
}
|
|
5499
|
+
var PACKAGE_LATEST_URL = "https://registry.npmjs.org/codebase-snapshot/latest";
|
|
5500
|
+
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
5501
|
+
var FAILURE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
5502
|
+
var REQUEST_TIMEOUT_MS = 1200;
|
|
5503
|
+
function versionParts(value) {
|
|
5504
|
+
const core = value.trim().replace(/^v/i, "").split("-")[0];
|
|
5505
|
+
return core.split(".").map((part) => {
|
|
5506
|
+
const parsed = Number(part);
|
|
5507
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
5508
|
+
});
|
|
5509
|
+
}
|
|
5510
|
+
function isNewer(candidate, current) {
|
|
5511
|
+
const left = versionParts(candidate);
|
|
5512
|
+
const right = versionParts(current);
|
|
5513
|
+
const length = Math.max(left.length, right.length);
|
|
5514
|
+
for (let index = 0; index < length; index += 1) {
|
|
5515
|
+
const a = left[index] ?? 0;
|
|
5516
|
+
const b = right[index] ?? 0;
|
|
5517
|
+
if (a !== b) return a > b;
|
|
5518
|
+
}
|
|
5519
|
+
return false;
|
|
5520
|
+
}
|
|
5521
|
+
function cacheDirectory(env = process.env, platform = process.platform) {
|
|
5522
|
+
if (platform === "win32") {
|
|
5523
|
+
const base2 = env.LOCALAPPDATA ?? path13__namespace.join(os__namespace.homedir(), "AppData", "Local");
|
|
5524
|
+
return path13__namespace.join(base2, "codebase-snapshot");
|
|
5525
|
+
}
|
|
5526
|
+
if (platform === "darwin") {
|
|
5527
|
+
return path13__namespace.join(os__namespace.homedir(), "Library", "Caches", "codebase-snapshot");
|
|
5528
|
+
}
|
|
5529
|
+
const base = env.XDG_CACHE_HOME ?? path13__namespace.join(os__namespace.homedir(), ".cache");
|
|
5530
|
+
return path13__namespace.join(base, "codebase-snapshot");
|
|
5531
|
+
}
|
|
5532
|
+
function cacheFilePath(env = process.env) {
|
|
5533
|
+
return path13__namespace.join(cacheDirectory(env), "update-check.json");
|
|
5534
|
+
}
|
|
5535
|
+
function shouldCheck(argv, env) {
|
|
5536
|
+
const disabled = ["1", "true", "yes"].includes(
|
|
5537
|
+
String(env.CODEBASE_SNAPSHOT_NO_UPDATE_CHECK ?? "").toLowerCase()
|
|
5538
|
+
);
|
|
5539
|
+
if (disabled) return false;
|
|
5540
|
+
if (env.CI !== void 0 && env.CI !== "" && env.CI !== "false" && env.CI !== "0") return false;
|
|
5541
|
+
const args = argv.map((argument) => argument.toLowerCase());
|
|
5542
|
+
if (args.includes("--no-update-check")) return false;
|
|
5543
|
+
for (const skip of ["mcp", "describe", "skill", "--version", "-v", "--help", "-h"]) {
|
|
5544
|
+
if (args.includes(skip)) return false;
|
|
5545
|
+
}
|
|
5546
|
+
if (args.some((argument) => argument.includes("json"))) return false;
|
|
5547
|
+
return true;
|
|
5548
|
+
}
|
|
5549
|
+
function readCache(file) {
|
|
5550
|
+
let raw;
|
|
5551
|
+
try {
|
|
5552
|
+
raw = fs12__namespace.readFileSync(file, "utf8");
|
|
5553
|
+
} catch {
|
|
5554
|
+
return null;
|
|
5555
|
+
}
|
|
5556
|
+
try {
|
|
5557
|
+
const parsed = JSON.parse(raw);
|
|
5558
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
5559
|
+
const candidate = parsed;
|
|
5560
|
+
if (typeof candidate.checkedAt !== "number") return null;
|
|
5561
|
+
const latest = typeof candidate.latest === "string" ? candidate.latest : null;
|
|
5562
|
+
return { checkedAt: candidate.checkedAt, latest };
|
|
5563
|
+
} catch {
|
|
5564
|
+
return null;
|
|
5565
|
+
}
|
|
5566
|
+
}
|
|
5567
|
+
function writeCache(file, entry) {
|
|
5568
|
+
try {
|
|
5569
|
+
fs12__namespace.mkdirSync(path13__namespace.dirname(file), { recursive: true });
|
|
5570
|
+
fs12__namespace.writeFileSync(file, `${JSON.stringify(entry)}
|
|
5571
|
+
`, "utf8");
|
|
5572
|
+
} catch {
|
|
5573
|
+
}
|
|
5574
|
+
}
|
|
5575
|
+
function fetchLatestVersion(url = PACKAGE_LATEST_URL, timeoutMs = REQUEST_TIMEOUT_MS) {
|
|
5576
|
+
return new Promise((resolve5) => {
|
|
5577
|
+
let settled = false;
|
|
5578
|
+
const finish = (value) => {
|
|
5579
|
+
if (settled) return;
|
|
5580
|
+
settled = true;
|
|
5581
|
+
resolve5(value);
|
|
5582
|
+
};
|
|
5583
|
+
const request = https__namespace.get(
|
|
5584
|
+
url,
|
|
5585
|
+
{
|
|
5586
|
+
headers: {
|
|
5587
|
+
accept: "application/json",
|
|
5588
|
+
"user-agent": "codebase-snapshot (update check)"
|
|
5589
|
+
}
|
|
5590
|
+
},
|
|
5591
|
+
(response) => {
|
|
5592
|
+
if (response.statusCode !== 200) {
|
|
5593
|
+
response.resume();
|
|
5594
|
+
finish(null);
|
|
5595
|
+
return;
|
|
5596
|
+
}
|
|
5597
|
+
let body = "";
|
|
5598
|
+
response.setEncoding("utf8");
|
|
5599
|
+
response.on("data", (chunk) => {
|
|
5600
|
+
body += chunk;
|
|
5601
|
+
if (body.length > 64 * 1024) {
|
|
5602
|
+
request.destroy();
|
|
5603
|
+
finish(null);
|
|
5604
|
+
}
|
|
5605
|
+
});
|
|
5606
|
+
response.on("end", () => {
|
|
5607
|
+
try {
|
|
5608
|
+
const parsed = JSON.parse(body);
|
|
5609
|
+
finish(typeof parsed.version === "string" ? parsed.version : null);
|
|
5610
|
+
} catch {
|
|
5611
|
+
finish(null);
|
|
5612
|
+
}
|
|
5613
|
+
});
|
|
5614
|
+
}
|
|
5615
|
+
);
|
|
5616
|
+
request.on("error", () => finish(null));
|
|
5617
|
+
request.setTimeout(timeoutMs, () => {
|
|
5618
|
+
request.destroy();
|
|
5619
|
+
finish(null);
|
|
5620
|
+
});
|
|
5621
|
+
});
|
|
5622
|
+
}
|
|
5623
|
+
async function checkForUpdate(options) {
|
|
5624
|
+
if (options.enabled === false) return null;
|
|
5625
|
+
const now = options.now ?? (() => Date.now());
|
|
5626
|
+
const fetchLatest = options.fetchLatest ?? fetchLatestVersion;
|
|
5627
|
+
let latest = null;
|
|
5628
|
+
try {
|
|
5629
|
+
const cached = readCache(options.cacheFile);
|
|
5630
|
+
let needsFetch = cached === null;
|
|
5631
|
+
if (cached) {
|
|
5632
|
+
const age = now() - cached.checkedAt;
|
|
5633
|
+
if (cached.latest === null) {
|
|
5634
|
+
needsFetch = age >= FAILURE_INTERVAL_MS;
|
|
5635
|
+
} else {
|
|
5636
|
+
latest = cached.latest;
|
|
5637
|
+
needsFetch = age >= CHECK_INTERVAL_MS;
|
|
5638
|
+
}
|
|
5639
|
+
}
|
|
5640
|
+
if (needsFetch) {
|
|
5641
|
+
const fetched = await fetchLatest(PACKAGE_LATEST_URL, REQUEST_TIMEOUT_MS);
|
|
5642
|
+
writeCache(options.cacheFile, { checkedAt: now(), latest: fetched });
|
|
5643
|
+
latest = fetched;
|
|
5644
|
+
}
|
|
5645
|
+
} catch {
|
|
5646
|
+
return null;
|
|
5647
|
+
}
|
|
5648
|
+
if (!latest) return null;
|
|
5649
|
+
return isNewer(latest, options.current) ? { current: options.current, latest } : null;
|
|
5650
|
+
}
|
|
5651
|
+
function formatUpdateNotice(notice) {
|
|
5652
|
+
return `\u2191 codebase-snapshot ${notice.latest} is available \u2014 you have ${notice.current}.
|
|
5653
|
+
npm install -g codebase-snapshot`;
|
|
5654
|
+
}
|
|
5497
5655
|
function describeMatcher(matcher) {
|
|
5498
5656
|
if (typeof matcher === "string") return matcher;
|
|
5499
5657
|
if (matcher instanceof RegExp) return String(matcher);
|
|
@@ -5503,10 +5661,10 @@ function describeMatcher(matcher) {
|
|
|
5503
5661
|
return String(matcher);
|
|
5504
5662
|
}
|
|
5505
5663
|
function normalizeTarget(cwd, target) {
|
|
5506
|
-
const absolute =
|
|
5507
|
-
const relative7 =
|
|
5508
|
-
if (relative7.startsWith("..") ||
|
|
5509
|
-
return relative7.split(
|
|
5664
|
+
const absolute = path13__namespace.resolve(cwd, target);
|
|
5665
|
+
const relative7 = path13__namespace.relative(cwd, absolute);
|
|
5666
|
+
if (relative7.startsWith("..") || path13__namespace.isAbsolute(relative7)) return target;
|
|
5667
|
+
return relative7.split(path13__namespace.sep).join("/");
|
|
5510
5668
|
}
|
|
5511
5669
|
function findRuleMatch(rules, relativePath) {
|
|
5512
5670
|
return rules.find(
|
|
@@ -5525,20 +5683,20 @@ function findRecordedAncestor(skipped, relative7, maskedPath2) {
|
|
|
5525
5683
|
return nearest;
|
|
5526
5684
|
}
|
|
5527
5685
|
function readManifest2(config) {
|
|
5528
|
-
const manifestPath =
|
|
5686
|
+
const manifestPath = path13__namespace.resolve(config.cwd, config.outDir, "manifest.json");
|
|
5529
5687
|
try {
|
|
5530
|
-
return JSON.parse(
|
|
5688
|
+
return JSON.parse(fs12__namespace.readFileSync(manifestPath, "utf8"));
|
|
5531
5689
|
} catch {
|
|
5532
5690
|
return null;
|
|
5533
5691
|
}
|
|
5534
5692
|
}
|
|
5535
5693
|
function explainPath(config, target) {
|
|
5536
5694
|
const relative7 = normalizeTarget(config.cwd, target);
|
|
5537
|
-
const absolute =
|
|
5695
|
+
const absolute = path13__namespace.join(config.cwd, relative7);
|
|
5538
5696
|
const maskedPath2 = findSecretInPath(relative7, config.secretRules)?.masked ?? relative7;
|
|
5539
5697
|
const result = {
|
|
5540
5698
|
path: maskedPath2,
|
|
5541
|
-
exists:
|
|
5699
|
+
exists: fs12__namespace.existsSync(absolute),
|
|
5542
5700
|
included: false
|
|
5543
5701
|
};
|
|
5544
5702
|
const collection = collectFiles(config.cwd, {
|
|
@@ -5549,7 +5707,7 @@ function explainPath(config, target) {
|
|
|
5549
5707
|
// Same exclusion `generate` applies, so `explain` never says "not-discovered" about a file
|
|
5550
5708
|
// that is only missing because the walker dropped the tool's own output directory.
|
|
5551
5709
|
toolOwnedPaths: [config.outDir, config.tmpDir].map(
|
|
5552
|
-
(directory) =>
|
|
5710
|
+
(directory) => path13__namespace.relative(config.cwd, path13__namespace.resolve(config.cwd, directory)).replace(/\\/g, "/")
|
|
5553
5711
|
).filter((relative8) => relative8.length > 0 && !relative8.startsWith(".."))
|
|
5554
5712
|
});
|
|
5555
5713
|
if (!collection.files.includes(relative7)) {
|
|
@@ -5588,8 +5746,8 @@ function explainPath(config, target) {
|
|
|
5588
5746
|
if (layerRule) result.layerMatch = describeMatcher(layerRule.match);
|
|
5589
5747
|
const kindRule = findRuleMatch(config.kinds, relative7);
|
|
5590
5748
|
if (kindRule) result.kindMatch = describeMatcher(kindRule.match);
|
|
5591
|
-
if (
|
|
5592
|
-
const buffer =
|
|
5749
|
+
if (fs12__namespace.existsSync(absolute) && fs12__namespace.statSync(absolute).isFile()) {
|
|
5750
|
+
const buffer = fs12__namespace.readFileSync(absolute);
|
|
5593
5751
|
const decoded = decodeText(buffer);
|
|
5594
5752
|
if (decoded.binary) {
|
|
5595
5753
|
result.included = false;
|
|
@@ -5837,14 +5995,14 @@ function compareManifests(before, after) {
|
|
|
5837
5995
|
function loadManifest(target) {
|
|
5838
5996
|
let isDirectory;
|
|
5839
5997
|
try {
|
|
5840
|
-
isDirectory =
|
|
5998
|
+
isDirectory = fs12__namespace.statSync(target).isDirectory();
|
|
5841
5999
|
} catch {
|
|
5842
6000
|
throw new Error(`No snapshot found at ${target}: the path does not exist.`);
|
|
5843
6001
|
}
|
|
5844
|
-
const manifestPath = isDirectory ?
|
|
6002
|
+
const manifestPath = isDirectory ? path13__namespace.join(target, "manifest.json") : target;
|
|
5845
6003
|
let raw;
|
|
5846
6004
|
try {
|
|
5847
|
-
raw =
|
|
6005
|
+
raw = fs12__namespace.readFileSync(manifestPath, "utf8");
|
|
5848
6006
|
} catch {
|
|
5849
6007
|
throw new Error(`Could not read a manifest at ${manifestPath}.`);
|
|
5850
6008
|
}
|
|
@@ -5901,15 +6059,15 @@ function renderDiffText(diff) {
|
|
|
5901
6059
|
function appendGitignoreEntries(cwd, entries) {
|
|
5902
6060
|
const wanted = [...new Set(entries)].filter((entry) => entry.trim().length > 0);
|
|
5903
6061
|
if (wanted.length === 0) return { added: [], note: null };
|
|
5904
|
-
const ignorePath =
|
|
6062
|
+
const ignorePath = path13__namespace.join(cwd, ".gitignore");
|
|
5905
6063
|
const manual = `Add ${wanted.map((entry) => `"${entry}"`).join(" and ")} to your .gitignore yourself.`;
|
|
5906
6064
|
let existing = "";
|
|
5907
6065
|
try {
|
|
5908
|
-
if (
|
|
5909
|
-
if (
|
|
6066
|
+
if (fs12__namespace.existsSync(ignorePath)) {
|
|
6067
|
+
if (fs12__namespace.statSync(ignorePath).isDirectory()) {
|
|
5910
6068
|
return { added: [], note: `${ignorePath} is a directory, so it was not updated. ${manual}` };
|
|
5911
6069
|
}
|
|
5912
|
-
existing =
|
|
6070
|
+
existing = fs12__namespace.readFileSync(ignorePath, "utf8");
|
|
5913
6071
|
}
|
|
5914
6072
|
} catch (err) {
|
|
5915
6073
|
return {
|
|
@@ -5922,7 +6080,7 @@ function appendGitignoreEntries(cwd, entries) {
|
|
|
5922
6080
|
if (added.length === 0) return { added: [], note: null };
|
|
5923
6081
|
const prefix = existing.length === 0 || existing.endsWith("\n") ? "" : "\n";
|
|
5924
6082
|
try {
|
|
5925
|
-
|
|
6083
|
+
fs12__namespace.writeFileSync(ignorePath, `${existing}${prefix}${added.join("\n")}
|
|
5926
6084
|
`, "utf8");
|
|
5927
6085
|
} catch (err) {
|
|
5928
6086
|
return { added: [], note: `${err.message}. ${manual}` };
|
|
@@ -6061,6 +6219,12 @@ var PromptCancelled = class extends Error {
|
|
|
6061
6219
|
this.name = "PromptCancelled";
|
|
6062
6220
|
}
|
|
6063
6221
|
};
|
|
6222
|
+
var PromptBack = class extends Error {
|
|
6223
|
+
constructor() {
|
|
6224
|
+
super("Prompt back");
|
|
6225
|
+
this.name = "PromptBack";
|
|
6226
|
+
}
|
|
6227
|
+
};
|
|
6064
6228
|
function defaultIO() {
|
|
6065
6229
|
return { input: process.stdin, output: process.stdout };
|
|
6066
6230
|
}
|
|
@@ -6084,35 +6248,40 @@ function choiceLine(choice, active) {
|
|
|
6084
6248
|
const hint = choice.hint ? ` ${choice.hint}` : "";
|
|
6085
6249
|
return ` ${marker(active)} ${choice.label}${hint}`;
|
|
6086
6250
|
}
|
|
6087
|
-
function
|
|
6251
|
+
function listFooter(base, allowBack) {
|
|
6252
|
+
return allowBack ? `${base} \xB7 \u2190 back` : base;
|
|
6253
|
+
}
|
|
6254
|
+
function renderSelect(message, choices, index, allowBack = false) {
|
|
6088
6255
|
const lines = [`\u25C6 ${message}`, ""];
|
|
6089
6256
|
choices.forEach((choice, position) => lines.push(choiceLine(choice, position === index)));
|
|
6090
|
-
lines.push("", "
|
|
6257
|
+
lines.push("", ` ${listFooter("\u2191\u2193 move \xB7 enter select", allowBack)}`);
|
|
6091
6258
|
return lines.join("\n");
|
|
6092
6259
|
}
|
|
6093
|
-
function renderMultiSelect(message, choices, index, selected) {
|
|
6260
|
+
function renderMultiSelect(message, choices, index, selected, allowBack = false) {
|
|
6094
6261
|
const lines = [`\u25C6 ${message}`, ""];
|
|
6095
6262
|
choices.forEach((choice, position) => {
|
|
6096
6263
|
const box = selected.has(position) ? "\u25FC" : "\u25FB";
|
|
6097
6264
|
const hint = choice.hint ? ` ${choice.hint}` : "";
|
|
6098
6265
|
lines.push(` ${marker(position === index)} ${box} ${choice.label}${hint}`);
|
|
6099
6266
|
});
|
|
6100
|
-
lines.push("", "
|
|
6267
|
+
lines.push("", ` ${listFooter("\u2191\u2193 move \xB7 space toggle \xB7 enter confirm", allowBack)}`);
|
|
6101
6268
|
return lines.join("\n");
|
|
6102
6269
|
}
|
|
6103
|
-
function renderConfirm(message, value) {
|
|
6270
|
+
function renderConfirm(message, value, allowBack = false) {
|
|
6271
|
+
const footer = allowBack ? "\u2190\u2192 or y/n \xB7 enter confirm \xB7 b back" : "\u2190\u2192 or y/n \xB7 enter confirm";
|
|
6104
6272
|
return [
|
|
6105
6273
|
`\u25C6 ${message}`,
|
|
6106
6274
|
"",
|
|
6107
6275
|
` ${marker(value)} Yes`,
|
|
6108
6276
|
` ${marker(!value)} No`,
|
|
6109
6277
|
"",
|
|
6110
|
-
|
|
6278
|
+
` ${footer}`
|
|
6111
6279
|
].join("\n");
|
|
6112
6280
|
}
|
|
6113
|
-
function renderText(message, value, error) {
|
|
6281
|
+
function renderText(message, value, error, allowBack = false) {
|
|
6114
6282
|
const lines = [`\u25C6 ${message}`, "", ` ${value || "\u258F"}`];
|
|
6115
6283
|
if (error) lines.push("", ` \u2716 ${error}`);
|
|
6284
|
+
if (allowBack) lines.push("", " enter confirm \xB7 \u2190 back");
|
|
6116
6285
|
return lines.join("\n");
|
|
6117
6286
|
}
|
|
6118
6287
|
function keyReader(input) {
|
|
@@ -6161,14 +6330,18 @@ var Frame = class {
|
|
|
6161
6330
|
function isCancel(key) {
|
|
6162
6331
|
return key.ctrl === true && key.name === "c" || key.ctrl === true && key.name === "d";
|
|
6163
6332
|
}
|
|
6333
|
+
function isListBack(key, allowBack) {
|
|
6334
|
+
return allowBack && (key.name === "left" || key.name === "b");
|
|
6335
|
+
}
|
|
6164
6336
|
async function select(io, message, choices, options = {}) {
|
|
6165
6337
|
if (choices.length === 0) throw new Error("select() requires at least one choice.");
|
|
6338
|
+
const allowBack = options.allowBack === true;
|
|
6166
6339
|
const fallbackIndex = Math.max(
|
|
6167
6340
|
0,
|
|
6168
6341
|
choices.findIndex((choice) => choice.value === options.defaultValue)
|
|
6169
6342
|
);
|
|
6170
6343
|
if (!isInteractive(io)) {
|
|
6171
|
-
io.output.write(`${renderSelect(message, choices, fallbackIndex)}
|
|
6344
|
+
io.output.write(`${renderSelect(message, choices, fallbackIndex, allowBack)}
|
|
6172
6345
|
`);
|
|
6173
6346
|
return choices[fallbackIndex].value;
|
|
6174
6347
|
}
|
|
@@ -6177,9 +6350,10 @@ async function select(io, message, choices, options = {}) {
|
|
|
6177
6350
|
let index = fallbackIndex;
|
|
6178
6351
|
try {
|
|
6179
6352
|
for (; ; ) {
|
|
6180
|
-
frame.draw(renderSelect(message, choices, index));
|
|
6353
|
+
frame.draw(renderSelect(message, choices, index, allowBack));
|
|
6181
6354
|
const key = await reader.next();
|
|
6182
6355
|
if (isCancel(key)) throw new PromptCancelled();
|
|
6356
|
+
if (isListBack(key, allowBack)) throw new PromptBack();
|
|
6183
6357
|
if (key.name === "up") index = moveSelection(index, -1, choices.length);
|
|
6184
6358
|
else if (key.name === "down") index = moveSelection(index, 1, choices.length);
|
|
6185
6359
|
else if (key.name === "return" || key.name === "enter") {
|
|
@@ -6188,18 +6362,22 @@ async function select(io, message, choices, options = {}) {
|
|
|
6188
6362
|
} else if (key.name === "j") index = moveSelection(index, 1, choices.length);
|
|
6189
6363
|
else if (key.name === "k") index = moveSelection(index, -1, choices.length);
|
|
6190
6364
|
}
|
|
6365
|
+
} catch (error) {
|
|
6366
|
+
frame.erase();
|
|
6367
|
+
throw error;
|
|
6191
6368
|
} finally {
|
|
6192
6369
|
reader.close();
|
|
6193
6370
|
}
|
|
6194
6371
|
}
|
|
6195
6372
|
async function multiSelect(io, message, choices, options = {}) {
|
|
6373
|
+
const allowBack = options.allowBack === true;
|
|
6196
6374
|
const selected = /* @__PURE__ */ new Set();
|
|
6197
6375
|
choices.forEach((choice, position) => {
|
|
6198
6376
|
if (options.defaults?.includes(choice.value)) selected.add(position);
|
|
6199
6377
|
});
|
|
6200
6378
|
const result = () => choices.filter((_, position) => selected.has(position)).map((choice) => choice.value);
|
|
6201
6379
|
if (!isInteractive(io)) {
|
|
6202
|
-
io.output.write(`${renderMultiSelect(message, choices, 0, selected)}
|
|
6380
|
+
io.output.write(`${renderMultiSelect(message, choices, 0, selected, allowBack)}
|
|
6203
6381
|
`);
|
|
6204
6382
|
return result();
|
|
6205
6383
|
}
|
|
@@ -6208,9 +6386,10 @@ async function multiSelect(io, message, choices, options = {}) {
|
|
|
6208
6386
|
let index = 0;
|
|
6209
6387
|
try {
|
|
6210
6388
|
for (; ; ) {
|
|
6211
|
-
frame.draw(renderMultiSelect(message, choices, index, selected));
|
|
6389
|
+
frame.draw(renderMultiSelect(message, choices, index, selected, allowBack));
|
|
6212
6390
|
const key = await reader.next();
|
|
6213
6391
|
if (isCancel(key)) throw new PromptCancelled();
|
|
6392
|
+
if (isListBack(key, allowBack)) throw new PromptBack();
|
|
6214
6393
|
if (key.name === "up") index = moveSelection(index, -1, choices.length);
|
|
6215
6394
|
else if (key.name === "down") index = moveSelection(index, 1, choices.length);
|
|
6216
6395
|
else if (key.name === "space") {
|
|
@@ -6225,14 +6404,18 @@ async function multiSelect(io, message, choices, options = {}) {
|
|
|
6225
6404
|
return result();
|
|
6226
6405
|
}
|
|
6227
6406
|
}
|
|
6407
|
+
} catch (error) {
|
|
6408
|
+
frame.erase();
|
|
6409
|
+
throw error;
|
|
6228
6410
|
} finally {
|
|
6229
6411
|
reader.close();
|
|
6230
6412
|
}
|
|
6231
6413
|
}
|
|
6232
6414
|
async function confirm(io, message, options = {}) {
|
|
6415
|
+
const allowBack = options.allowBack === true;
|
|
6233
6416
|
let value = options.defaultValue ?? true;
|
|
6234
6417
|
if (!isInteractive(io)) {
|
|
6235
|
-
io.output.write(`${renderConfirm(message, value)}
|
|
6418
|
+
io.output.write(`${renderConfirm(message, value, allowBack)}
|
|
6236
6419
|
`);
|
|
6237
6420
|
return value;
|
|
6238
6421
|
}
|
|
@@ -6240,9 +6423,10 @@ async function confirm(io, message, options = {}) {
|
|
|
6240
6423
|
const reader = keyReader(io.input);
|
|
6241
6424
|
try {
|
|
6242
6425
|
for (; ; ) {
|
|
6243
|
-
frame.draw(renderConfirm(message, value));
|
|
6426
|
+
frame.draw(renderConfirm(message, value, allowBack));
|
|
6244
6427
|
const key = await reader.next();
|
|
6245
6428
|
if (isCancel(key)) throw new PromptCancelled();
|
|
6429
|
+
if (allowBack && key.name === "b") throw new PromptBack();
|
|
6246
6430
|
if (key.name === "up" || key.name === "left") value = true;
|
|
6247
6431
|
else if (key.name === "down" || key.name === "right") value = false;
|
|
6248
6432
|
else if (key.name === "y") value = true;
|
|
@@ -6252,14 +6436,18 @@ async function confirm(io, message, options = {}) {
|
|
|
6252
6436
|
return value;
|
|
6253
6437
|
}
|
|
6254
6438
|
}
|
|
6439
|
+
} catch (error) {
|
|
6440
|
+
frame.erase();
|
|
6441
|
+
throw error;
|
|
6255
6442
|
} finally {
|
|
6256
6443
|
reader.close();
|
|
6257
6444
|
}
|
|
6258
6445
|
}
|
|
6259
6446
|
async function text(io, message, options = {}) {
|
|
6447
|
+
const allowBack = options.allowBack === true;
|
|
6260
6448
|
const fallback = options.defaultValue ?? "";
|
|
6261
6449
|
if (!isInteractive(io)) {
|
|
6262
|
-
io.output.write(`${renderText(message, fallback)}
|
|
6450
|
+
io.output.write(`${renderText(message, fallback, void 0, allowBack)}
|
|
6263
6451
|
`);
|
|
6264
6452
|
return fallback;
|
|
6265
6453
|
}
|
|
@@ -6269,9 +6457,10 @@ async function text(io, message, options = {}) {
|
|
|
6269
6457
|
let error;
|
|
6270
6458
|
try {
|
|
6271
6459
|
for (; ; ) {
|
|
6272
|
-
frame.draw(renderText(message, value, error));
|
|
6460
|
+
frame.draw(renderText(message, value, error, allowBack));
|
|
6273
6461
|
const key = await reader.next();
|
|
6274
6462
|
if (isCancel(key)) throw new PromptCancelled();
|
|
6463
|
+
if (allowBack && key.name === "left") throw new PromptBack();
|
|
6275
6464
|
error = void 0;
|
|
6276
6465
|
if (key.name === "return" || key.name === "enter") {
|
|
6277
6466
|
const problem = options.validate ? options.validate(value) : null;
|
|
@@ -6292,6 +6481,9 @@ async function text(io, message, options = {}) {
|
|
|
6292
6481
|
}
|
|
6293
6482
|
if (_isPrintable(key)) value += _keyText(key);
|
|
6294
6483
|
}
|
|
6484
|
+
} catch (error_) {
|
|
6485
|
+
frame.erase();
|
|
6486
|
+
throw error_;
|
|
6295
6487
|
} finally {
|
|
6296
6488
|
reader.close();
|
|
6297
6489
|
}
|
|
@@ -6315,10 +6507,10 @@ var CONFIG_CANDIDATES = [
|
|
|
6315
6507
|
];
|
|
6316
6508
|
function chooseConfigFileName(cwd) {
|
|
6317
6509
|
if (!supportsTypeScriptImports()) return "snapshot.config.mjs";
|
|
6318
|
-
const pkgPath =
|
|
6319
|
-
if (!
|
|
6510
|
+
const pkgPath = path13__namespace.join(cwd, "package.json");
|
|
6511
|
+
if (!fs12__namespace.existsSync(pkgPath)) return "snapshot.config.mjs";
|
|
6320
6512
|
try {
|
|
6321
|
-
const parsed = JSON.parse(
|
|
6513
|
+
const parsed = JSON.parse(fs12__namespace.readFileSync(pkgPath, "utf8"));
|
|
6322
6514
|
return parsed.type === "module" ? "snapshot.config.ts" : "snapshot.config.mjs";
|
|
6323
6515
|
} catch {
|
|
6324
6516
|
return "snapshot.config.mjs";
|
|
@@ -6332,7 +6524,7 @@ var SIZE_CHOICES = [
|
|
|
6332
6524
|
];
|
|
6333
6525
|
function packageJsonHasConfig(cwd) {
|
|
6334
6526
|
try {
|
|
6335
|
-
const parsed = JSON.parse(
|
|
6527
|
+
const parsed = JSON.parse(fs12__namespace.readFileSync(path13__namespace.join(cwd, "package.json"), "utf8"));
|
|
6336
6528
|
return typeof parsed.snapshot === "object" && parsed.snapshot !== null && !Array.isArray(parsed.snapshot);
|
|
6337
6529
|
} catch {
|
|
6338
6530
|
return false;
|
|
@@ -6353,7 +6545,7 @@ function artifactAnswers(options) {
|
|
|
6353
6545
|
}
|
|
6354
6546
|
function topLevelDirs(cwd) {
|
|
6355
6547
|
try {
|
|
6356
|
-
return
|
|
6548
|
+
return fs12__namespace.readdirSync(cwd, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules").map((entry) => entry.name).sort();
|
|
6357
6549
|
} catch {
|
|
6358
6550
|
return [];
|
|
6359
6551
|
}
|
|
@@ -6366,7 +6558,7 @@ function describeJsonValue(value) {
|
|
|
6366
6558
|
}
|
|
6367
6559
|
function writeFileOrExplain(target, content) {
|
|
6368
6560
|
try {
|
|
6369
|
-
|
|
6561
|
+
fs12__namespace.writeFileSync(target, content, "utf8");
|
|
6370
6562
|
} catch (err) {
|
|
6371
6563
|
const code = err.code;
|
|
6372
6564
|
const reason = code === "EACCES" || code === "EPERM" || code === "EROFS" ? `permission denied (${code})` : code === "EISDIR" ? "it is a directory" : `${err.message}`;
|
|
@@ -6377,7 +6569,7 @@ function canWriteModuleConfig(name, cwd) {
|
|
|
6377
6569
|
if (name.endsWith(".mjs") || name.endsWith(".ts")) return true;
|
|
6378
6570
|
if (!name.endsWith(".js")) return false;
|
|
6379
6571
|
try {
|
|
6380
|
-
const parsed = JSON.parse(
|
|
6572
|
+
const parsed = JSON.parse(fs12__namespace.readFileSync(path13__namespace.join(cwd, "package.json"), "utf8"));
|
|
6381
6573
|
return parsed.type === "module";
|
|
6382
6574
|
} catch {
|
|
6383
6575
|
return false;
|
|
@@ -6412,19 +6604,19 @@ function serializePackageJson(raw, value) {
|
|
|
6412
6604
|
return `${text2}${raw.endsWith("\n") ? crlf ? "\r\n" : "\n" : ""}`;
|
|
6413
6605
|
}
|
|
6414
6606
|
function updatePackageJson(cwd, notes) {
|
|
6415
|
-
const packagePath =
|
|
6607
|
+
const packagePath = path13__namespace.join(cwd, "package.json");
|
|
6416
6608
|
const unchanged = {
|
|
6417
6609
|
scripts: [],
|
|
6418
6610
|
dependency: { name: GENERATOR_NAME, range: null, added: false }
|
|
6419
6611
|
};
|
|
6420
|
-
if (!
|
|
6612
|
+
if (!fs12__namespace.existsSync(packagePath)) {
|
|
6421
6613
|
notes.push("No package.json found, so npm scripts and the devDependency were not added.");
|
|
6422
6614
|
return unchanged;
|
|
6423
6615
|
}
|
|
6424
6616
|
let raw;
|
|
6425
6617
|
let parsed;
|
|
6426
6618
|
try {
|
|
6427
|
-
raw =
|
|
6619
|
+
raw = fs12__namespace.readFileSync(packagePath, "utf8");
|
|
6428
6620
|
parsed = JSON.parse(raw);
|
|
6429
6621
|
} catch {
|
|
6430
6622
|
notes.push("Could not parse package.json; npm scripts and the devDependency were not added.");
|
|
@@ -6548,98 +6740,108 @@ async function runInit(options) {
|
|
|
6548
6740
|
{ value: "walk", label: "Go through each setting", hint: "every question starts on its default" },
|
|
6549
6741
|
{ value: "choose", label: "Pick a different preset", hint: "everything else stays at the defaults" }
|
|
6550
6742
|
];
|
|
6551
|
-
const
|
|
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
|
-
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
|
|
6583
|
-
|
|
6584
|
-
|
|
6585
|
-
|
|
6586
|
-
|
|
6587
|
-
|
|
6588
|
-
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6743
|
+
const baseInclude = [...answers.include];
|
|
6744
|
+
const baseExclude = [...answers.excludePatterns];
|
|
6745
|
+
let lastScope = "all";
|
|
6746
|
+
const artifactChoices = [
|
|
6747
|
+
{ value: "readme", label: "README.md", hint: "orientation page" },
|
|
6748
|
+
{ value: "manifest", label: "manifest.json", hint: "required by validate and report" },
|
|
6749
|
+
{ value: "parts", label: "parts/", hint: "the code payload" },
|
|
6750
|
+
{ value: "navigation", label: "reports/navigation.md", hint: "file \u2192 part index" },
|
|
6751
|
+
{ value: "projectTree", label: "reports/project-tree.md", hint: "ASCII tree" },
|
|
6752
|
+
{ value: "audit", label: "reports/audit.md", hint: "security and health findings" },
|
|
6753
|
+
{ value: "monolith", label: "full-codebase.json + .md", hint: "roughly doubles output" }
|
|
6754
|
+
];
|
|
6755
|
+
const scopeStep = async () => {
|
|
6756
|
+
for (; ; ) {
|
|
6757
|
+
const scope = await select(
|
|
6758
|
+
io,
|
|
6759
|
+
"What should go into the snapshot?",
|
|
6760
|
+
[
|
|
6761
|
+
{ value: "all", label: "Everything the scanner finds", hint: "recommended \xB7 respects .gitignore" },
|
|
6762
|
+
{ value: "folders", label: "Only specific folders\u2026" },
|
|
6763
|
+
{ value: "no-tests", label: "Everything, but skip tests" },
|
|
6764
|
+
{ value: "custom", label: "Let me write glob patterns" }
|
|
6765
|
+
],
|
|
6766
|
+
{ defaultValue: lastScope, allowBack: true }
|
|
6767
|
+
);
|
|
6768
|
+
lastScope = scope;
|
|
6769
|
+
answers.include = [...baseInclude];
|
|
6770
|
+
answers.excludePatterns = [...baseExclude];
|
|
6771
|
+
try {
|
|
6772
|
+
if (scope === "folders") {
|
|
6773
|
+
const dirs = topLevelDirs(options.cwd).slice(0, 40);
|
|
6774
|
+
if (dirs.length === 0) {
|
|
6775
|
+
notes.push("No top-level directories found; the snapshot will include everything.");
|
|
6776
|
+
} else {
|
|
6777
|
+
const chosen = await multiSelect(
|
|
6778
|
+
io,
|
|
6779
|
+
"Select folders",
|
|
6780
|
+
dirs.map((name) => ({ value: name, label: `${name}/` })),
|
|
6781
|
+
{ defaults: dirs, allowBack: true }
|
|
6782
|
+
);
|
|
6783
|
+
answers.include = chosen.map((name) => `${name}/**`);
|
|
6784
|
+
}
|
|
6785
|
+
} else if (scope === "no-tests") {
|
|
6786
|
+
answers.excludePatterns = [...baseExclude, "**/*.test.*", "**/*.spec.*", "tests", "test"];
|
|
6787
|
+
} else if (scope === "custom") {
|
|
6788
|
+
const raw = await text(io, "Glob patterns to include (comma separated)", {
|
|
6789
|
+
defaultValue: baseInclude.join(", "),
|
|
6790
|
+
allowBack: true
|
|
6791
|
+
});
|
|
6792
|
+
answers.include = raw.split(",").map((value) => value.trim()).filter(Boolean);
|
|
6793
|
+
}
|
|
6794
|
+
return;
|
|
6795
|
+
} catch (error) {
|
|
6796
|
+
if (error instanceof PromptBack) continue;
|
|
6797
|
+
throw error;
|
|
6592
6798
|
}
|
|
6593
|
-
} else if (scope === "no-tests") {
|
|
6594
|
-
answers.excludePatterns = [
|
|
6595
|
-
...answers.excludePatterns,
|
|
6596
|
-
"**/*.test.*",
|
|
6597
|
-
"**/*.spec.*",
|
|
6598
|
-
"tests",
|
|
6599
|
-
"test"
|
|
6600
|
-
];
|
|
6601
|
-
} else if (scope === "custom") {
|
|
6602
|
-
const raw = await text(io, "Glob patterns to include (comma separated)", {
|
|
6603
|
-
defaultValue: ""
|
|
6604
|
-
});
|
|
6605
|
-
answers.include = raw.split(",").map((value) => value.trim()).filter(Boolean);
|
|
6606
6799
|
}
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
validate: (value) => parseByteSize(value) === void 0 ? "Not a valid size." : null
|
|
6800
|
+
};
|
|
6801
|
+
const sizeStep = async () => {
|
|
6802
|
+
for (; ; ) {
|
|
6803
|
+
const currentBudget = String(answers.maxPartBytes);
|
|
6804
|
+
const sizeChoice = await select(io, "How large should each part be?", SIZE_CHOICES, {
|
|
6805
|
+
defaultValue: SIZE_CHOICES.some((choice) => choice.value === currentBudget) ? currentBudget : "custom",
|
|
6806
|
+
allowBack: true
|
|
6615
6807
|
});
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6808
|
+
if (sizeChoice !== "custom") {
|
|
6809
|
+
answers.maxPartBytes = sizeChoice;
|
|
6810
|
+
return;
|
|
6811
|
+
}
|
|
6812
|
+
try {
|
|
6813
|
+
const raw = await text(io, "Part size (e.g. 150k, 1.5mb, 900000)", {
|
|
6814
|
+
defaultValue: currentBudget,
|
|
6815
|
+
validate: (value) => parseByteSize(value) === void 0 ? "Not a valid size." : null,
|
|
6816
|
+
allowBack: true
|
|
6817
|
+
});
|
|
6818
|
+
answers.maxPartBytes = parseByteSize(raw) ?? answers.maxPartBytes;
|
|
6819
|
+
return;
|
|
6820
|
+
} catch (error) {
|
|
6821
|
+
if (error instanceof PromptBack) continue;
|
|
6822
|
+
throw error;
|
|
6823
|
+
}
|
|
6824
|
+
}
|
|
6825
|
+
};
|
|
6826
|
+
const artifactsStep = async () => {
|
|
6827
|
+
const enabled = ARTIFACT_NAMES.filter((name) => answers.artifacts[name]);
|
|
6630
6828
|
const selectedArtifacts = await multiSelect(
|
|
6631
6829
|
io,
|
|
6632
6830
|
"Which artifacts should be generated?",
|
|
6633
6831
|
artifactChoices,
|
|
6634
|
-
{ defaults:
|
|
6832
|
+
{ defaults: enabled, allowBack: true }
|
|
6635
6833
|
);
|
|
6636
6834
|
for (const name of ARTIFACT_NAMES) answers.artifacts[name] = selectedArtifacts.includes(name);
|
|
6637
|
-
|
|
6835
|
+
};
|
|
6836
|
+
const credentialsStep = async () => {
|
|
6638
6837
|
answers.includeSensitiveFiles = await confirm(
|
|
6639
6838
|
io,
|
|
6640
|
-
"Include credential files (.env, *.pem,
|
|
6641
|
-
{ defaultValue:
|
|
6839
|
+
"Include credential files (.env, *.pem, *.npmrc, *.ssh/)?",
|
|
6840
|
+
{ defaultValue: answers.includeSensitiveFiles, allowBack: true }
|
|
6642
6841
|
);
|
|
6842
|
+
};
|
|
6843
|
+
const reviewStep = async () => {
|
|
6844
|
+
const enabledCount = ARTIFACT_NAMES.filter((name) => answers.artifacts[name]).length;
|
|
6643
6845
|
io.output.write("\n Review\n\n");
|
|
6644
6846
|
io.output.write(` project ${answers.preset}
|
|
6645
6847
|
`);
|
|
@@ -6654,14 +6856,59 @@ async function runInit(options) {
|
|
|
6654
6856
|
`);
|
|
6655
6857
|
io.output.write(" Will write snapshot.config with your answers, plus every other setting\n");
|
|
6656
6858
|
io.output.write(" at its default \u2014 so nothing is hidden behind the docs.\n\n");
|
|
6657
|
-
const proceed = await confirm(io, "Write this and continue?", {
|
|
6658
|
-
|
|
6859
|
+
const proceed = await confirm(io, "Write this and continue?", {
|
|
6860
|
+
defaultValue: true,
|
|
6861
|
+
allowBack: true
|
|
6862
|
+
});
|
|
6863
|
+
if (!proceed) throw new PromptBack();
|
|
6864
|
+
};
|
|
6865
|
+
const walk = async () => {
|
|
6866
|
+
const steps = [scopeStep, sizeStep, artifactsStep, credentialsStep, reviewStep];
|
|
6867
|
+
let index = 0;
|
|
6868
|
+
while (index < steps.length) {
|
|
6869
|
+
try {
|
|
6870
|
+
await steps[index]();
|
|
6871
|
+
index += 1;
|
|
6872
|
+
} catch (error) {
|
|
6873
|
+
if (!(error instanceof PromptBack)) throw error;
|
|
6874
|
+
if (index === 0) return false;
|
|
6875
|
+
index -= 1;
|
|
6876
|
+
io.output.write("\n");
|
|
6877
|
+
}
|
|
6878
|
+
}
|
|
6879
|
+
return true;
|
|
6880
|
+
};
|
|
6881
|
+
for (; ; ) {
|
|
6882
|
+
const pace = await select(io, "How should I set this up?", paceChoices, {
|
|
6883
|
+
defaultValue: fallback ? "choose" : "recommended"
|
|
6884
|
+
});
|
|
6885
|
+
if (pace === "choose") {
|
|
6886
|
+
try {
|
|
6887
|
+
answers.preset = await select(
|
|
6888
|
+
io,
|
|
6889
|
+
"What kind of project is this?",
|
|
6890
|
+
listPresetNames().map(
|
|
6891
|
+
(name) => resolvePresetChoice(fallback ? null : detected.presetName, name)
|
|
6892
|
+
),
|
|
6893
|
+
{ defaultValue: answers.preset, allowBack: true }
|
|
6894
|
+
);
|
|
6895
|
+
} catch (error) {
|
|
6896
|
+
if (error instanceof PromptBack) continue;
|
|
6897
|
+
throw error;
|
|
6898
|
+
}
|
|
6899
|
+
const chosen = detectPreset(options.cwd, answers.preset);
|
|
6900
|
+
answers.preset = chosen.presetName;
|
|
6901
|
+
reason = null;
|
|
6902
|
+
fallback = false;
|
|
6903
|
+
}
|
|
6904
|
+
if (pace === "walk" && !await walk()) continue;
|
|
6905
|
+
break;
|
|
6659
6906
|
}
|
|
6660
6907
|
}
|
|
6661
6908
|
const configText = renderConfig(answers);
|
|
6662
6909
|
const preferredName = chooseConfigFileName(options.cwd);
|
|
6663
6910
|
const presentConfigs = CONFIG_CANDIDATES.filter(
|
|
6664
|
-
(name) =>
|
|
6911
|
+
(name) => fs12__namespace.existsSync(path13__namespace.join(options.cwd, name))
|
|
6665
6912
|
);
|
|
6666
6913
|
const present = presentConfigs[0] ?? null;
|
|
6667
6914
|
if (presentConfigs.length > 1) {
|
|
@@ -6670,7 +6917,7 @@ async function runInit(options) {
|
|
|
6670
6917
|
);
|
|
6671
6918
|
}
|
|
6672
6919
|
const configName = present !== null && options.force ? present : preferredName;
|
|
6673
|
-
const configPath =
|
|
6920
|
+
const configPath = path13__namespace.join(options.cwd, configName);
|
|
6674
6921
|
const reused = present !== null && options.force !== true && options.reuseConfig === true;
|
|
6675
6922
|
if (reused) notes.push(`Kept the existing ${present} instead of writing a new one.`);
|
|
6676
6923
|
if (options.dryRun) {
|
|
@@ -6703,7 +6950,7 @@ async function runInit(options) {
|
|
|
6703
6950
|
'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.'
|
|
6704
6951
|
);
|
|
6705
6952
|
}
|
|
6706
|
-
if (
|
|
6953
|
+
if (fs12__namespace.existsSync(configPath) && !options.force && !reused) {
|
|
6707
6954
|
throw new Error(`${configName} already exists. Re-run with --force to replace it.`);
|
|
6708
6955
|
}
|
|
6709
6956
|
if (!reused) writeFileOrExplain(configPath, configText);
|
|
@@ -6725,9 +6972,9 @@ async function runInit(options) {
|
|
|
6725
6972
|
};
|
|
6726
6973
|
}
|
|
6727
6974
|
function describeTarget(cwd) {
|
|
6728
|
-
const relative7 =
|
|
6975
|
+
const relative7 = path13__namespace.relative(process.cwd(), cwd);
|
|
6729
6976
|
if (relative7 === "") return "this directory";
|
|
6730
|
-
if (relative7.startsWith("..") ||
|
|
6977
|
+
if (relative7.startsWith("..") || path13__namespace.isAbsolute(relative7)) return cwd;
|
|
6731
6978
|
return relative7;
|
|
6732
6979
|
}
|
|
6733
6980
|
function firstRunMessage(reason, cwd) {
|
|
@@ -6751,7 +6998,7 @@ function planFirstRun(facts) {
|
|
|
6751
6998
|
var NOT_CONTENT = /* @__PURE__ */ new Set([".git", ".hg", ".svn", ".bzr", ".DS_Store", "Thumbs.db"]);
|
|
6752
6999
|
function isEffectivelyEmpty(cwd) {
|
|
6753
7000
|
try {
|
|
6754
|
-
return
|
|
7001
|
+
return fs12__namespace.readdirSync(cwd).every((entry) => NOT_CONTENT.has(entry));
|
|
6755
7002
|
} catch {
|
|
6756
7003
|
return false;
|
|
6757
7004
|
}
|
|
@@ -6759,7 +7006,7 @@ function isEffectivelyEmpty(cwd) {
|
|
|
6759
7006
|
function hasPriorSnapshot(cwd, outDir) {
|
|
6760
7007
|
let parsed;
|
|
6761
7008
|
try {
|
|
6762
|
-
parsed = JSON.parse(
|
|
7009
|
+
parsed = JSON.parse(fs12__namespace.readFileSync(path13__namespace.join(cwd, outDir, ".codebase-snapshot"), "utf8"));
|
|
6763
7010
|
} catch {
|
|
6764
7011
|
return false;
|
|
6765
7012
|
}
|
|
@@ -6847,13 +7094,13 @@ function buildImportResolver(files) {
|
|
|
6847
7094
|
const relativePath = file.relativePath;
|
|
6848
7095
|
remember(byPath, relativePath, relativePath);
|
|
6849
7096
|
remember(byPathFolded, relativePath.toLowerCase(), relativePath);
|
|
6850
|
-
const extension =
|
|
7097
|
+
const extension = path13__namespace.posix.extname(relativePath);
|
|
6851
7098
|
if (!SOURCE_EXTENSIONS.has(extension)) continue;
|
|
6852
7099
|
const stem = relativePath.slice(0, -extension.length);
|
|
6853
7100
|
remember(byStem, stem, relativePath);
|
|
6854
7101
|
remember(byStemFolded, stem.toLowerCase(), relativePath);
|
|
6855
|
-
if (
|
|
6856
|
-
const directory =
|
|
7102
|
+
if (path13__namespace.posix.basename(stem) === "index") {
|
|
7103
|
+
const directory = path13__namespace.posix.dirname(stem);
|
|
6857
7104
|
remember(byStem, directory, relativePath);
|
|
6858
7105
|
remember(byStemFolded, directory.toLowerCase(), relativePath);
|
|
6859
7106
|
}
|
|
@@ -6862,8 +7109,8 @@ function buildImportResolver(files) {
|
|
|
6862
7109
|
}
|
|
6863
7110
|
function resolveSpecifier(fromFile, specifier, resolver) {
|
|
6864
7111
|
if (!RELATIVE_SPECIFIER.test(specifier)) return null;
|
|
6865
|
-
const joined =
|
|
6866
|
-
|
|
7112
|
+
const joined = path13__namespace.posix.normalize(
|
|
7113
|
+
path13__namespace.posix.join(path13__namespace.posix.dirname(fromFile), specifier)
|
|
6867
7114
|
);
|
|
6868
7115
|
const exact = (key) => resolver.byPath.get(key) ?? resolver.byPathFolded.get(key.toLowerCase()) ?? null;
|
|
6869
7116
|
const direct = exact(joined);
|
|
@@ -6956,11 +7203,11 @@ function verifyInMemory(files, parts, maxPartBytes) {
|
|
|
6956
7203
|
return errors;
|
|
6957
7204
|
}
|
|
6958
7205
|
function resolveSafeOutputDirs(config) {
|
|
6959
|
-
const cwd =
|
|
6960
|
-
const outDir =
|
|
6961
|
-
const tmpDir =
|
|
6962
|
-
const root =
|
|
6963
|
-
const contains = (parent, child) => child === parent || child.startsWith(`${parent}${
|
|
7206
|
+
const cwd = path13__namespace.resolve(config.cwd);
|
|
7207
|
+
const outDir = path13__namespace.resolve(cwd, config.outDir);
|
|
7208
|
+
const tmpDir = path13__namespace.resolve(cwd, config.tmpDir);
|
|
7209
|
+
const root = path13__namespace.parse(cwd).root;
|
|
7210
|
+
const contains = (parent, child) => child === parent || child.startsWith(`${parent}${path13__namespace.sep}`);
|
|
6964
7211
|
const reject = (reason) => {
|
|
6965
7212
|
throw new Error(
|
|
6966
7213
|
`Refusing to generate: ${reason}. outDir=${outDir} tmpDir=${tmpDir} cwd=${cwd}`
|
|
@@ -7016,14 +7263,14 @@ function listEntries(dir) {
|
|
|
7016
7263
|
const walk = (absolute, prefix) => {
|
|
7017
7264
|
let children;
|
|
7018
7265
|
try {
|
|
7019
|
-
children =
|
|
7266
|
+
children = fs12__namespace.readdirSync(absolute, { withFileTypes: true });
|
|
7020
7267
|
} catch {
|
|
7021
7268
|
return;
|
|
7022
7269
|
}
|
|
7023
7270
|
for (const child of children) {
|
|
7024
7271
|
const relative7 = prefix === "" ? child.name : `${prefix}/${child.name}`;
|
|
7025
7272
|
entries.push(relative7);
|
|
7026
|
-
if (child.isDirectory()) walk(
|
|
7273
|
+
if (child.isDirectory()) walk(path13__namespace.join(absolute, child.name), relative7);
|
|
7027
7274
|
}
|
|
7028
7275
|
};
|
|
7029
7276
|
walk(dir, "");
|
|
@@ -7040,28 +7287,28 @@ function markerPayload(dir, state, id, createdAt) {
|
|
|
7040
7287
|
pid: process.pid,
|
|
7041
7288
|
entries: listEntries(dir)
|
|
7042
7289
|
};
|
|
7043
|
-
const manifestPath =
|
|
7044
|
-
if (
|
|
7045
|
-
marker2.manifestSha256 = sha256Hex2(
|
|
7290
|
+
const manifestPath = path13__namespace.join(dir, "manifest.json");
|
|
7291
|
+
if (fs12__namespace.existsSync(manifestPath)) {
|
|
7292
|
+
marker2.manifestSha256 = sha256Hex2(fs12__namespace.readFileSync(manifestPath));
|
|
7046
7293
|
}
|
|
7047
7294
|
return marker2;
|
|
7048
7295
|
}
|
|
7049
7296
|
function writeOwnershipMarker(dir, marker2) {
|
|
7050
|
-
|
|
7051
|
-
|
|
7297
|
+
fs12__namespace.writeFileSync(
|
|
7298
|
+
path13__namespace.join(dir, OWNERSHIP_MARKER),
|
|
7052
7299
|
`${JSON.stringify(marker2, null, 2)}
|
|
7053
7300
|
`,
|
|
7054
7301
|
"utf8"
|
|
7055
7302
|
);
|
|
7056
7303
|
}
|
|
7057
7304
|
function readOwnershipMarker(dir) {
|
|
7058
|
-
const markerPath =
|
|
7059
|
-
if (!
|
|
7305
|
+
const markerPath = path13__namespace.join(dir, OWNERSHIP_MARKER);
|
|
7306
|
+
if (!fs12__namespace.existsSync(markerPath)) {
|
|
7060
7307
|
return { marker: null, problem: "it holds no .codebase-snapshot marker" };
|
|
7061
7308
|
}
|
|
7062
7309
|
let raw;
|
|
7063
7310
|
try {
|
|
7064
|
-
raw =
|
|
7311
|
+
raw = fs12__namespace.readFileSync(markerPath, "utf8");
|
|
7065
7312
|
} catch {
|
|
7066
7313
|
return { marker: null, problem: "its .codebase-snapshot marker could not be read" };
|
|
7067
7314
|
}
|
|
@@ -7129,11 +7376,11 @@ function assessSnapshotDirectory(dir) {
|
|
|
7129
7376
|
marker: marker2
|
|
7130
7377
|
};
|
|
7131
7378
|
}
|
|
7132
|
-
const manifestPath =
|
|
7133
|
-
if (
|
|
7379
|
+
const manifestPath = path13__namespace.join(dir, "manifest.json");
|
|
7380
|
+
if (fs12__namespace.existsSync(manifestPath)) {
|
|
7134
7381
|
let raw;
|
|
7135
7382
|
try {
|
|
7136
|
-
raw =
|
|
7383
|
+
raw = fs12__namespace.readFileSync(manifestPath, "utf8");
|
|
7137
7384
|
} catch {
|
|
7138
7385
|
return {
|
|
7139
7386
|
owned: false,
|
|
@@ -7215,13 +7462,13 @@ function containsNoFiles(dir) {
|
|
|
7215
7462
|
const current = pending.pop();
|
|
7216
7463
|
let entries;
|
|
7217
7464
|
try {
|
|
7218
|
-
entries =
|
|
7465
|
+
entries = fs12__namespace.readdirSync(current, { withFileTypes: true });
|
|
7219
7466
|
} catch {
|
|
7220
7467
|
return false;
|
|
7221
7468
|
}
|
|
7222
7469
|
for (const entry of entries) {
|
|
7223
7470
|
if (entry.isDirectory()) {
|
|
7224
|
-
pending.push(
|
|
7471
|
+
pending.push(path13__namespace.join(current, entry.name));
|
|
7225
7472
|
} else if (!IGNORABLE_ENTRIES.has(entry.name)) {
|
|
7226
7473
|
return false;
|
|
7227
7474
|
}
|
|
@@ -7230,13 +7477,13 @@ function containsNoFiles(dir) {
|
|
|
7230
7477
|
return true;
|
|
7231
7478
|
}
|
|
7232
7479
|
function assertReplaceable(target, label, secretRules) {
|
|
7233
|
-
if (!
|
|
7234
|
-
if (!
|
|
7480
|
+
if (!fs12__namespace.existsSync(target)) return;
|
|
7481
|
+
if (!fs12__namespace.statSync(target).isDirectory()) {
|
|
7235
7482
|
throw new Error(
|
|
7236
7483
|
`Refusing to write into ${label} ${target}: it exists but is not a directory.`
|
|
7237
7484
|
);
|
|
7238
7485
|
}
|
|
7239
|
-
const entries =
|
|
7486
|
+
const entries = fs12__namespace.readdirSync(target);
|
|
7240
7487
|
if (entries.length === 0) return;
|
|
7241
7488
|
if (entries.every((name) => IGNORABLE_ENTRIES.has(name))) return;
|
|
7242
7489
|
if (containsNoFiles(target)) return;
|
|
@@ -7256,18 +7503,18 @@ function assertReplaceable(target, label, secretRules) {
|
|
|
7256
7503
|
);
|
|
7257
7504
|
}
|
|
7258
7505
|
function assertStagingRootUsable(tmpDir, secretRules) {
|
|
7259
|
-
if (!
|
|
7260
|
-
if (!
|
|
7506
|
+
if (!fs12__namespace.existsSync(tmpDir)) return;
|
|
7507
|
+
if (!fs12__namespace.statSync(tmpDir).isDirectory()) {
|
|
7261
7508
|
throw new Error(`Refusing to write into tmpDir ${tmpDir}: it exists but is not a directory.`);
|
|
7262
7509
|
}
|
|
7263
|
-
const entries =
|
|
7510
|
+
const entries = fs12__namespace.readdirSync(tmpDir);
|
|
7264
7511
|
if (entries.length === 0) return;
|
|
7265
7512
|
const foreign = entries.filter((name) => {
|
|
7266
|
-
const full =
|
|
7513
|
+
const full = path13__namespace.join(tmpDir, name);
|
|
7267
7514
|
if (!name.startsWith(RUN_DIR_PREFIX)) return true;
|
|
7268
7515
|
let stats;
|
|
7269
7516
|
try {
|
|
7270
|
-
stats =
|
|
7517
|
+
stats = fs12__namespace.statSync(full);
|
|
7271
7518
|
} catch {
|
|
7272
7519
|
return true;
|
|
7273
7520
|
}
|
|
@@ -7275,7 +7522,7 @@ function assertStagingRootUsable(tmpDir, secretRules) {
|
|
|
7275
7522
|
const { marker: marker2 } = readOwnershipMarker(full);
|
|
7276
7523
|
if (marker2) return false;
|
|
7277
7524
|
try {
|
|
7278
|
-
return
|
|
7525
|
+
return fs12__namespace.readdirSync(full).length > 0;
|
|
7279
7526
|
} catch {
|
|
7280
7527
|
return true;
|
|
7281
7528
|
}
|
|
@@ -7290,13 +7537,13 @@ function assertStagingRootUsable(tmpDir, secretRules) {
|
|
|
7290
7537
|
function cleanStaleRunDirs(tmpDir) {
|
|
7291
7538
|
let entries;
|
|
7292
7539
|
try {
|
|
7293
|
-
entries =
|
|
7540
|
+
entries = fs12__namespace.readdirSync(tmpDir);
|
|
7294
7541
|
} catch {
|
|
7295
7542
|
return;
|
|
7296
7543
|
}
|
|
7297
7544
|
for (const name of entries) {
|
|
7298
7545
|
if (!name.startsWith(RUN_DIR_PREFIX)) continue;
|
|
7299
|
-
const full =
|
|
7546
|
+
const full = path13__namespace.join(tmpDir, name);
|
|
7300
7547
|
const { marker: marker2 } = readOwnershipMarker(full);
|
|
7301
7548
|
if (marker2) {
|
|
7302
7549
|
const created = Date.parse(marker2.createdAt);
|
|
@@ -7304,33 +7551,33 @@ function cleanStaleRunDirs(tmpDir) {
|
|
|
7304
7551
|
const abandoned = typeof marker2.pid === "number" && !isProcessAlive(marker2.pid);
|
|
7305
7552
|
if (aged || abandoned) {
|
|
7306
7553
|
try {
|
|
7307
|
-
|
|
7554
|
+
fs12__namespace.rmSync(full, { recursive: true, force: true });
|
|
7308
7555
|
} catch {
|
|
7309
7556
|
}
|
|
7310
7557
|
}
|
|
7311
7558
|
continue;
|
|
7312
7559
|
}
|
|
7313
7560
|
try {
|
|
7314
|
-
if (
|
|
7561
|
+
if (fs12__namespace.readdirSync(full).length === 0) fs12__namespace.rmSync(full, { recursive: true, force: true });
|
|
7315
7562
|
} catch {
|
|
7316
7563
|
}
|
|
7317
7564
|
}
|
|
7318
7565
|
}
|
|
7319
7566
|
function removeIfEmpty(dir) {
|
|
7320
7567
|
try {
|
|
7321
|
-
if (
|
|
7568
|
+
if (fs12__namespace.readdirSync(dir).length === 0) fs12__namespace.rmSync(dir, { recursive: true, force: true });
|
|
7322
7569
|
} catch {
|
|
7323
7570
|
}
|
|
7324
7571
|
}
|
|
7325
7572
|
function ensureParentDirectory(target, label) {
|
|
7326
|
-
const parent =
|
|
7327
|
-
if (
|
|
7573
|
+
const parent = path13__namespace.dirname(target);
|
|
7574
|
+
if (fs12__namespace.existsSync(parent) && !fs12__namespace.statSync(parent).isDirectory()) {
|
|
7328
7575
|
throw new Error(
|
|
7329
7576
|
`Refusing to create ${label} ${target}: ${parent} exists but is not a directory.`
|
|
7330
7577
|
);
|
|
7331
7578
|
}
|
|
7332
7579
|
try {
|
|
7333
|
-
|
|
7580
|
+
fs12__namespace.mkdirSync(parent, { recursive: true });
|
|
7334
7581
|
} catch (err) {
|
|
7335
7582
|
throw new Error(
|
|
7336
7583
|
`Refusing to create ${label} ${target}: its parent ${parent} could not be created (${err.message}).`
|
|
@@ -7339,7 +7586,7 @@ function ensureParentDirectory(target, label) {
|
|
|
7339
7586
|
}
|
|
7340
7587
|
function acquireRunLock(stagingRoot) {
|
|
7341
7588
|
const key = lockKeyFor(stagingRoot);
|
|
7342
|
-
const lockPath =
|
|
7589
|
+
const lockPath = path13__namespace.join(os__namespace.tmpdir(), `codebase-snapshot-${key}.lock`);
|
|
7343
7590
|
const payload = `${JSON.stringify({
|
|
7344
7591
|
pid: process.pid,
|
|
7345
7592
|
stagingRoot,
|
|
@@ -7348,22 +7595,22 @@ function acquireRunLock(stagingRoot) {
|
|
|
7348
7595
|
`;
|
|
7349
7596
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
7350
7597
|
try {
|
|
7351
|
-
const handle =
|
|
7598
|
+
const handle = fs12__namespace.openSync(lockPath, "wx");
|
|
7352
7599
|
try {
|
|
7353
|
-
|
|
7600
|
+
fs12__namespace.writeSync(handle, payload);
|
|
7354
7601
|
} finally {
|
|
7355
|
-
|
|
7602
|
+
fs12__namespace.closeSync(handle);
|
|
7356
7603
|
}
|
|
7357
7604
|
return () => {
|
|
7358
7605
|
try {
|
|
7359
|
-
|
|
7606
|
+
fs12__namespace.rmSync(lockPath, { force: true });
|
|
7360
7607
|
} catch {
|
|
7361
7608
|
}
|
|
7362
7609
|
};
|
|
7363
7610
|
} catch (err) {
|
|
7364
7611
|
if (err.code !== "EEXIST") throw err;
|
|
7365
7612
|
if (attempt === 0 && lockOwnerIsGone(lockPath)) {
|
|
7366
|
-
|
|
7613
|
+
fs12__namespace.rmSync(lockPath, { force: true });
|
|
7367
7614
|
continue;
|
|
7368
7615
|
}
|
|
7369
7616
|
throw new Error(
|
|
@@ -7376,7 +7623,7 @@ function acquireRunLock(stagingRoot) {
|
|
|
7376
7623
|
function lockKeyFor(stagingRoot) {
|
|
7377
7624
|
let key = stagingRoot;
|
|
7378
7625
|
try {
|
|
7379
|
-
key =
|
|
7626
|
+
key = fs12__namespace.realpathSync(stagingRoot);
|
|
7380
7627
|
} catch {
|
|
7381
7628
|
}
|
|
7382
7629
|
if (process.platform === "win32" || process.platform === "darwin") key = key.toLowerCase();
|
|
@@ -7385,7 +7632,7 @@ function lockKeyFor(stagingRoot) {
|
|
|
7385
7632
|
function lockOwnerIsGone(lockPath) {
|
|
7386
7633
|
let raw;
|
|
7387
7634
|
try {
|
|
7388
|
-
raw =
|
|
7635
|
+
raw = fs12__namespace.readFileSync(lockPath, "utf8");
|
|
7389
7636
|
} catch {
|
|
7390
7637
|
return false;
|
|
7391
7638
|
}
|
|
@@ -7405,12 +7652,12 @@ function lockOwnerIsGone(lockPath) {
|
|
|
7405
7652
|
}
|
|
7406
7653
|
function writeManifestAtomically(manifestPath, manifest) {
|
|
7407
7654
|
const tempPath = `${manifestPath}.${process.pid}.tmp`;
|
|
7408
|
-
|
|
7655
|
+
fs12__namespace.writeFileSync(tempPath, JSON.stringify(manifest, null, 2), "utf8");
|
|
7409
7656
|
try {
|
|
7410
|
-
|
|
7657
|
+
fs12__namespace.renameSync(tempPath, manifestPath);
|
|
7411
7658
|
} catch (err) {
|
|
7412
7659
|
try {
|
|
7413
|
-
|
|
7660
|
+
fs12__namespace.rmSync(tempPath, { force: true });
|
|
7414
7661
|
} catch {
|
|
7415
7662
|
}
|
|
7416
7663
|
throw err;
|
|
@@ -7433,31 +7680,31 @@ function swapIntoPlace(stagingDir, outDir) {
|
|
|
7433
7680
|
}
|
|
7434
7681
|
function swapOnce(stagingDir, outDir) {
|
|
7435
7682
|
const backupDir = `${outDir}.backup-${process.pid}-${Date.now()}`;
|
|
7436
|
-
const hadPrevious =
|
|
7437
|
-
if (hadPrevious)
|
|
7683
|
+
const hadPrevious = fs12__namespace.existsSync(outDir);
|
|
7684
|
+
if (hadPrevious) fs12__namespace.renameSync(outDir, backupDir);
|
|
7438
7685
|
try {
|
|
7439
7686
|
try {
|
|
7440
|
-
|
|
7687
|
+
fs12__namespace.renameSync(stagingDir, outDir);
|
|
7441
7688
|
} catch (err) {
|
|
7442
7689
|
if (err.code !== "EXDEV") throw err;
|
|
7443
7690
|
const partialDir = `${outDir}.partial-${process.pid}-${Date.now()}`;
|
|
7444
7691
|
try {
|
|
7445
|
-
|
|
7446
|
-
|
|
7447
|
-
|
|
7692
|
+
fs12__namespace.cpSync(stagingDir, partialDir, { recursive: true });
|
|
7693
|
+
fs12__namespace.renameSync(partialDir, outDir);
|
|
7694
|
+
fs12__namespace.rmSync(stagingDir, { recursive: true, force: true });
|
|
7448
7695
|
} catch (copyErr) {
|
|
7449
7696
|
try {
|
|
7450
|
-
|
|
7697
|
+
fs12__namespace.rmSync(partialDir, { recursive: true, force: true });
|
|
7451
7698
|
} catch {
|
|
7452
7699
|
}
|
|
7453
7700
|
throw copyErr;
|
|
7454
7701
|
}
|
|
7455
7702
|
}
|
|
7456
|
-
if (hadPrevious)
|
|
7703
|
+
if (hadPrevious) fs12__namespace.rmSync(backupDir, { recursive: true, force: true });
|
|
7457
7704
|
} catch (err) {
|
|
7458
|
-
if (hadPrevious &&
|
|
7459
|
-
if (
|
|
7460
|
-
|
|
7705
|
+
if (hadPrevious && fs12__namespace.existsSync(backupDir)) {
|
|
7706
|
+
if (fs12__namespace.existsSync(outDir)) fs12__namespace.rmSync(outDir, { recursive: true, force: true });
|
|
7707
|
+
fs12__namespace.renameSync(backupDir, outDir);
|
|
7461
7708
|
}
|
|
7462
7709
|
throw err;
|
|
7463
7710
|
}
|
|
@@ -7552,7 +7799,7 @@ function generateSnapshot(configInput, options) {
|
|
|
7552
7799
|
// first run cannot have marked them yet, so the name alone keeps a run from recording its own
|
|
7553
7800
|
// output — but only at these exact paths, not at every directory that shares the name.
|
|
7554
7801
|
toolOwnedPaths: [config.outDir, config.tmpDir].map(
|
|
7555
|
-
(directory) =>
|
|
7802
|
+
(directory) => path13__namespace.relative(config.cwd, path13__namespace.resolve(config.cwd, directory)).replace(/\\/g, "/")
|
|
7556
7803
|
).filter((relative7) => relative7.length > 0 && !relative7.startsWith(".."))
|
|
7557
7804
|
});
|
|
7558
7805
|
const files = [];
|
|
@@ -7573,12 +7820,12 @@ function generateSnapshot(configInput, options) {
|
|
|
7573
7820
|
let totalSizeBytes = 0;
|
|
7574
7821
|
let largeFileCount = 0;
|
|
7575
7822
|
for (const relativePath of collection.files) {
|
|
7576
|
-
const absolutePath =
|
|
7823
|
+
const absolutePath = path13__namespace.join(config.cwd, relativePath);
|
|
7577
7824
|
let stats;
|
|
7578
7825
|
try {
|
|
7579
|
-
stats =
|
|
7826
|
+
stats = fs12__namespace.statSync(absolutePath);
|
|
7580
7827
|
if (!stats.isFile()) {
|
|
7581
|
-
const nestedRepository = stats.isDirectory() &&
|
|
7828
|
+
const nestedRepository = stats.isDirectory() && fs12__namespace.existsSync(path13__namespace.join(absolutePath, ".git"));
|
|
7582
7829
|
skipped.push(
|
|
7583
7830
|
nestedRepository ? {
|
|
7584
7831
|
path: relativePath,
|
|
@@ -7598,7 +7845,7 @@ function generateSnapshot(configInput, options) {
|
|
|
7598
7845
|
}
|
|
7599
7846
|
let buffer;
|
|
7600
7847
|
try {
|
|
7601
|
-
buffer =
|
|
7848
|
+
buffer = fs12__namespace.readFileSync(absolutePath);
|
|
7602
7849
|
} catch {
|
|
7603
7850
|
skipped.push({ path: relativePath, reason: "read-error" });
|
|
7604
7851
|
continue;
|
|
@@ -7928,12 +8175,12 @@ function generateSnapshot(configInput, options) {
|
|
|
7928
8175
|
let stagingDir = null;
|
|
7929
8176
|
try {
|
|
7930
8177
|
ensureParentDirectory(outDir, "outDir");
|
|
7931
|
-
|
|
8178
|
+
fs12__namespace.mkdirSync(tmpDir, { recursive: true });
|
|
7932
8179
|
cleanStaleRunDirs(tmpDir);
|
|
7933
8180
|
const snapshotId = crypto__namespace.randomUUID();
|
|
7934
8181
|
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7935
|
-
stagingDir =
|
|
7936
|
-
|
|
8182
|
+
stagingDir = path13__namespace.join(tmpDir, `${RUN_DIR_PREFIX}${process.pid}-${snapshotId.slice(0, 8)}`);
|
|
8183
|
+
fs12__namespace.mkdirSync(stagingDir);
|
|
7937
8184
|
writeOwnershipMarker(stagingDir, {
|
|
7938
8185
|
generator: GENERATOR_NAME,
|
|
7939
8186
|
version: GENERATOR_VERSION,
|
|
@@ -7943,41 +8190,41 @@ function generateSnapshot(configInput, options) {
|
|
|
7943
8190
|
id: snapshotId,
|
|
7944
8191
|
pid: process.pid
|
|
7945
8192
|
});
|
|
7946
|
-
const partsDir =
|
|
7947
|
-
const reportsDir =
|
|
7948
|
-
if (artifacts.parts)
|
|
8193
|
+
const partsDir = path13__namespace.join(stagingDir, "parts");
|
|
8194
|
+
const reportsDir = path13__namespace.join(stagingDir, "reports");
|
|
8195
|
+
if (artifacts.parts) fs12__namespace.mkdirSync(partsDir, { recursive: true });
|
|
7949
8196
|
if (artifacts.navigation || artifacts.projectTree || artifacts.audit) {
|
|
7950
|
-
|
|
8197
|
+
fs12__namespace.mkdirSync(reportsDir, { recursive: true });
|
|
7951
8198
|
}
|
|
7952
8199
|
if (artifacts.parts) {
|
|
7953
8200
|
for (const part of parts) {
|
|
7954
|
-
|
|
8201
|
+
fs12__namespace.writeFileSync(path13__namespace.join(partsDir, part.filename), part.markdown, "utf8");
|
|
7955
8202
|
}
|
|
7956
8203
|
}
|
|
7957
8204
|
if (projectTree !== null) {
|
|
7958
|
-
|
|
8205
|
+
fs12__namespace.writeFileSync(path13__namespace.join(reportsDir, "project-tree.md"), projectTree, "utf8");
|
|
7959
8206
|
}
|
|
7960
8207
|
if (artifacts.navigation) {
|
|
7961
|
-
|
|
8208
|
+
fs12__namespace.writeFileSync(path13__namespace.join(reportsDir, "navigation.md"), generateNavigation(manifest), "utf8");
|
|
7962
8209
|
}
|
|
7963
8210
|
if (artifacts.audit) {
|
|
7964
|
-
|
|
7965
|
-
|
|
8211
|
+
fs12__namespace.writeFileSync(
|
|
8212
|
+
path13__namespace.join(reportsDir, "audit.md"),
|
|
7966
8213
|
generateAuditReport(manifest, secretFindings, config.secretRules),
|
|
7967
8214
|
"utf8"
|
|
7968
8215
|
);
|
|
7969
8216
|
}
|
|
7970
8217
|
if (artifacts.readme) {
|
|
7971
|
-
|
|
8218
|
+
fs12__namespace.writeFileSync(path13__namespace.join(stagingDir, "README.md"), generateReadme(manifest, artifacts), "utf8");
|
|
7972
8219
|
}
|
|
7973
8220
|
if (artifacts.manifest) {
|
|
7974
|
-
|
|
8221
|
+
fs12__namespace.writeFileSync(path13__namespace.join(stagingDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf8");
|
|
7975
8222
|
}
|
|
7976
8223
|
if (monolithJson !== null) {
|
|
7977
|
-
|
|
8224
|
+
fs12__namespace.writeFileSync(path13__namespace.join(stagingDir, "full-codebase.json"), monolithJson, "utf8");
|
|
7978
8225
|
}
|
|
7979
8226
|
if (monolithMarkdown !== null) {
|
|
7980
|
-
|
|
8227
|
+
fs12__namespace.writeFileSync(path13__namespace.join(stagingDir, "full-codebase.md"), monolithMarkdown, "utf8");
|
|
7981
8228
|
}
|
|
7982
8229
|
writeOwnershipMarker(stagingDir, markerPayload(stagingDir, "complete", snapshotId, createdAt));
|
|
7983
8230
|
swapIntoPlace(stagingDir, outDir);
|
|
@@ -7986,7 +8233,7 @@ function generateSnapshot(configInput, options) {
|
|
|
7986
8233
|
const pendingHook = runAfterGenerate(config, manifest);
|
|
7987
8234
|
const shipHookState = () => {
|
|
7988
8235
|
if (artifacts.manifest && manifest.warnings.length !== warningsBeforeHook) {
|
|
7989
|
-
writeManifestAtomically(
|
|
8236
|
+
writeManifestAtomically(path13__namespace.join(outDir, "manifest.json"), manifest);
|
|
7990
8237
|
}
|
|
7991
8238
|
writeOwnershipMarker(outDir, markerPayload(outDir, "complete", snapshotId, createdAt));
|
|
7992
8239
|
};
|
|
@@ -8009,7 +8256,7 @@ function generateSnapshot(configInput, options) {
|
|
|
8009
8256
|
} catch (err) {
|
|
8010
8257
|
if (stagingDir !== null) {
|
|
8011
8258
|
try {
|
|
8012
|
-
|
|
8259
|
+
fs12__namespace.rmSync(stagingDir, { recursive: true, force: true });
|
|
8013
8260
|
} catch {
|
|
8014
8261
|
}
|
|
8015
8262
|
}
|
|
@@ -8024,18 +8271,25 @@ async function generateSnapshotAsync(configInput, options) {
|
|
|
8024
8271
|
}
|
|
8025
8272
|
|
|
8026
8273
|
exports.ARTIFACT_NAMES = ARTIFACT_NAMES;
|
|
8274
|
+
exports.CHECK_INTERVAL_MS = CHECK_INTERVAL_MS;
|
|
8027
8275
|
exports.DEFAULT_ANSWERS = DEFAULT_ANSWERS;
|
|
8028
8276
|
exports.DEFAULT_SECRET_PATTERNS = DEFAULT_SECRET_PATTERNS;
|
|
8277
|
+
exports.FAILURE_INTERVAL_MS = FAILURE_INTERVAL_MS;
|
|
8029
8278
|
exports.GENERATOR_NAME = GENERATOR_NAME;
|
|
8030
8279
|
exports.GENERATOR_VERSION = GENERATOR_VERSION;
|
|
8031
8280
|
exports.LANGUAGE_PROFILES = LANGUAGE_PROFILES;
|
|
8032
8281
|
exports.MIN_MAX_PART_BYTES = MIN_MAX_PART_BYTES;
|
|
8282
|
+
exports.PACKAGE_LATEST_URL = PACKAGE_LATEST_URL;
|
|
8033
8283
|
exports.PRESETS = PRESETS;
|
|
8034
8284
|
exports.PromptCancelled = PromptCancelled;
|
|
8285
|
+
exports.REQUEST_TIMEOUT_MS = REQUEST_TIMEOUT_MS;
|
|
8035
8286
|
exports.SCHEMA_VERSION = SCHEMA_VERSION;
|
|
8036
8287
|
exports.anchorForPath = anchorForPath;
|
|
8037
8288
|
exports.assertReplaceable = assertReplaceable;
|
|
8038
8289
|
exports.assertUsableConfigInput = assertUsableConfigInput;
|
|
8290
|
+
exports.cacheDirectory = cacheDirectory;
|
|
8291
|
+
exports.cacheFilePath = cacheFilePath;
|
|
8292
|
+
exports.checkForUpdate = checkForUpdate;
|
|
8039
8293
|
exports.collectFiles = collectFiles;
|
|
8040
8294
|
exports.compareManifests = compareManifests;
|
|
8041
8295
|
exports.countInvalidUtf8Bytes = countInvalidUtf8Bytes;
|
|
@@ -8047,7 +8301,9 @@ exports.detectPreset = detectPreset;
|
|
|
8047
8301
|
exports.explainPath = explainPath;
|
|
8048
8302
|
exports.fenceForContent = fenceForContent;
|
|
8049
8303
|
exports.fenceForText = fenceForText;
|
|
8304
|
+
exports.fetchLatestVersion = fetchLatestVersion;
|
|
8050
8305
|
exports.firstRunMessage = firstRunMessage;
|
|
8306
|
+
exports.formatUpdateNotice = formatUpdateNotice;
|
|
8051
8307
|
exports.generateProjectTree = generateProjectTree;
|
|
8052
8308
|
exports.generateSnapshot = generateSnapshot;
|
|
8053
8309
|
exports.generateSnapshotAsync = generateSnapshotAsync;
|
|
@@ -8059,6 +8315,7 @@ exports.isBinaryExtension = isBinaryExtension;
|
|
|
8059
8315
|
exports.isBinaryFile = isBinaryFile;
|
|
8060
8316
|
exports.isEffectivelyEmpty = isEffectivelyEmpty;
|
|
8061
8317
|
exports.isInteractive = isInteractive;
|
|
8318
|
+
exports.isNewer = isNewer;
|
|
8062
8319
|
exports.isResolvedConfig = isResolvedConfig;
|
|
8063
8320
|
exports.isSensitivePath = isSensitivePath;
|
|
8064
8321
|
exports.listPresetNames = listPresetNames;
|
|
@@ -8081,6 +8338,7 @@ exports.resolveConfig = resolveConfig;
|
|
|
8081
8338
|
exports.resolveSafeOutputDirs = resolveSafeOutputDirs;
|
|
8082
8339
|
exports.runInit = runInit;
|
|
8083
8340
|
exports.scanAndRedactSecrets = scanAndRedactSecrets;
|
|
8341
|
+
exports.shouldCheck = shouldCheck;
|
|
8084
8342
|
exports.stripJsonComments = stripJsonComments;
|
|
8085
8343
|
exports.summarizeJson = summarizeJson;
|
|
8086
8344
|
exports.summarizeMarkdown = summarizeMarkdown;
|