@ankurhalder/codebase-snapshot 2.1.0 → 2.1.1
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/dist/bin.js +73 -9
- package/dist/{chunk-QEIOXPMU.js → chunk-SUOJL5EX.js} +23 -7
- package/dist/cli.cjs +73 -9
- package/dist/cli.js +53 -5
- package/dist/index.cjs +21 -5
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/docs/install.md +15 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -52,7 +52,13 @@ function compareManifests(before, after) {
|
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
54
|
function loadManifest(target) {
|
|
55
|
-
|
|
55
|
+
let isDirectory;
|
|
56
|
+
try {
|
|
57
|
+
isDirectory = fs.statSync(target).isDirectory();
|
|
58
|
+
} catch {
|
|
59
|
+
throw new Error(`No snapshot found at ${target}: the path does not exist.`);
|
|
60
|
+
}
|
|
61
|
+
const manifestPath = isDirectory ? path.join(target, "manifest.json") : target;
|
|
56
62
|
let raw;
|
|
57
63
|
try {
|
|
58
64
|
raw = fs.readFileSync(manifestPath, "utf8");
|
|
@@ -68,6 +74,9 @@ function loadManifest(target) {
|
|
|
68
74
|
if (!parsed || !Array.isArray(parsed.files)) {
|
|
69
75
|
throw new Error(`${manifestPath} is not a snapshot manifest (no "files" array).`);
|
|
70
76
|
}
|
|
77
|
+
if (!parsed.counts || typeof parsed.counts !== "object") {
|
|
78
|
+
throw new Error(`${manifestPath} is not a snapshot manifest (no "counts" object).`);
|
|
79
|
+
}
|
|
71
80
|
return parsed;
|
|
72
81
|
}
|
|
73
82
|
function renderDiffText(diff) {
|
|
@@ -948,11 +957,12 @@ import * as fs3 from "fs";
|
|
|
948
957
|
import * as path3 from "path";
|
|
949
958
|
function getGitInfo(cwd, fallbackBranch = "main") {
|
|
950
959
|
try {
|
|
951
|
-
const
|
|
960
|
+
const reported = childProcess.execSync("git rev-parse --abbrev-ref HEAD", {
|
|
952
961
|
cwd,
|
|
953
962
|
stdio: ["ignore", "pipe", "ignore"],
|
|
954
963
|
encoding: "utf8"
|
|
955
|
-
}).trim()
|
|
964
|
+
}).trim();
|
|
965
|
+
const branch = !reported || reported === "HEAD" ? fallbackBranch : reported;
|
|
956
966
|
const commit = childProcess.execSync("git rev-parse HEAD", {
|
|
957
967
|
cwd,
|
|
958
968
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -1573,6 +1583,9 @@ async function loadConfigFileDetailed(cwd) {
|
|
|
1573
1583
|
if (snapshotKey && typeof snapshotKey === "object") {
|
|
1574
1584
|
return { config: snapshotKey, file: pkgJsonPath, warnings, errors };
|
|
1575
1585
|
}
|
|
1586
|
+
if (snapshotKey !== void 0) {
|
|
1587
|
+
warnings.push(`${pkgJsonPath}: the "snapshot" key must be an object; it was ignored.`);
|
|
1588
|
+
}
|
|
1576
1589
|
} catch (err) {
|
|
1577
1590
|
const message = err.message;
|
|
1578
1591
|
warnings.push(message);
|
|
@@ -4295,6 +4308,7 @@ function validateSnapshot(configInput) {
|
|
|
4295
4308
|
drift.missingOnDisk.push(snapshotFile);
|
|
4296
4309
|
}
|
|
4297
4310
|
}
|
|
4311
|
+
drift.missingOnDisk = [...new Set(drift.missingOnDisk)];
|
|
4298
4312
|
const maxEffectiveBudget = Math.max(
|
|
4299
4313
|
config.maxPartBytes,
|
|
4300
4314
|
config.budgets.default,
|
|
@@ -4554,7 +4568,7 @@ function validateSnapshot(configInput) {
|
|
|
4554
4568
|
|
|
4555
4569
|
// src/index.ts
|
|
4556
4570
|
var GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
|
|
4557
|
-
var GENERATOR_VERSION = "2.1.
|
|
4571
|
+
var GENERATOR_VERSION = "2.1.1";
|
|
4558
4572
|
var SCHEMA_VERSION = "3.0.0";
|
|
4559
4573
|
function sha256Hex2(input) {
|
|
4560
4574
|
return crypto3.createHash("sha256").update(input).digest("hex");
|
|
@@ -4798,7 +4812,9 @@ function artifactWarnings(artifacts) {
|
|
|
4798
4812
|
);
|
|
4799
4813
|
}
|
|
4800
4814
|
if (ARTIFACT_NAMES.every((name) => artifacts[name] === false)) {
|
|
4801
|
-
messages.push(
|
|
4815
|
+
messages.push(
|
|
4816
|
+
"every artifact is disabled: only the .codebase-snapshot ownership marker will be written."
|
|
4817
|
+
);
|
|
4802
4818
|
}
|
|
4803
4819
|
return messages;
|
|
4804
4820
|
}
|
|
@@ -5253,9 +5269,32 @@ function parseCliArgs(argv) {
|
|
|
5253
5269
|
strict: true
|
|
5254
5270
|
});
|
|
5255
5271
|
} catch (err) {
|
|
5256
|
-
|
|
5272
|
+
const message = err.message;
|
|
5273
|
+
const ambiguous = /^Option '(--[^']+)' argument is ambiguous/i.exec(message);
|
|
5274
|
+
if (ambiguous) {
|
|
5275
|
+
throw new UsageError(
|
|
5276
|
+
`${ambiguous[1]} received a value that looks like another flag (for example a negative number). Use the "--option=value" form, and note that sizes must be positive.`
|
|
5277
|
+
);
|
|
5278
|
+
}
|
|
5279
|
+
throw new UsageError(message);
|
|
5257
5280
|
}
|
|
5258
5281
|
const values = parsed.values;
|
|
5282
|
+
for (const [name, spec] of Object.entries(CLI_OPTIONS)) {
|
|
5283
|
+
if (spec.type !== "string") continue;
|
|
5284
|
+
const raw = values[name];
|
|
5285
|
+
if (raw !== void 0 && String(raw).trim() === "") {
|
|
5286
|
+
throw new UsageError(`--${name} requires a value (received an empty string).`);
|
|
5287
|
+
}
|
|
5288
|
+
}
|
|
5289
|
+
if (values.cwd !== void 0) {
|
|
5290
|
+
const target = String(values.cwd);
|
|
5291
|
+
if (!fs10.existsSync(target)) {
|
|
5292
|
+
throw new UsageError(`--cwd directory does not exist: ${target}`);
|
|
5293
|
+
}
|
|
5294
|
+
if (!fs10.statSync(target).isDirectory()) {
|
|
5295
|
+
throw new UsageError(`--cwd is not a directory: ${target}`);
|
|
5296
|
+
}
|
|
5297
|
+
}
|
|
5259
5298
|
if (values.help) {
|
|
5260
5299
|
process.stdout.write(`${USAGE}
|
|
5261
5300
|
`);
|
|
@@ -5473,6 +5512,9 @@ function renderValidateText(result) {
|
|
|
5473
5512
|
for (const missing of result.drift.missingOnDisk.slice(0, 20)) {
|
|
5474
5513
|
warn(` - deleted: ${missing}`);
|
|
5475
5514
|
}
|
|
5515
|
+
for (const mismatch of result.drift.totalsMismatches.slice(0, 20)) {
|
|
5516
|
+
warn(` - counts: ${mismatch}`);
|
|
5517
|
+
}
|
|
5476
5518
|
}
|
|
5477
5519
|
for (const warning of result.warnings) warn(` \u26A0 ${warning}`);
|
|
5478
5520
|
}
|
|
@@ -5603,9 +5645,23 @@ ${USAGE}
|
|
|
5603
5645
|
info(
|
|
5604
5646
|
` - Total size: ${(manifest.counts.totalSizeBytes / (1024 * 1024)).toFixed(2)} MB`
|
|
5605
5647
|
);
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5648
|
+
const { artifacts } = resolved;
|
|
5649
|
+
if (artifacts.parts) {
|
|
5650
|
+
info(` - Parts written: ${manifest.counts.partsCount} under ${resolved.outDir}/parts/`);
|
|
5651
|
+
}
|
|
5652
|
+
const reports = [
|
|
5653
|
+
artifacts.projectTree && "project-tree",
|
|
5654
|
+
artifacts.navigation && "navigation",
|
|
5655
|
+
artifacts.audit && "audit"
|
|
5656
|
+
].filter(Boolean);
|
|
5657
|
+
if (reports.length > 0) {
|
|
5658
|
+
info(` - Reports: ${resolved.outDir}/reports/ (${reports.join(", ")})`);
|
|
5659
|
+
}
|
|
5660
|
+
if (artifacts.manifest) info(` - Manifest: ${resolved.outDir}/manifest.json`);
|
|
5661
|
+
if (artifacts.monolith) info(` - Monolith: ${resolved.outDir}/full-codebase.{json,md}`);
|
|
5662
|
+
if (reports.length === 0 && !artifacts.parts && !artifacts.manifest && !artifacts.monolith) {
|
|
5663
|
+
info(` - Artifacts: all disabled (only the ownership marker was written)`);
|
|
5664
|
+
}
|
|
5609
5665
|
info(` - Fingerprint: ${manifest.fingerprint}`);
|
|
5610
5666
|
info(` - Integrity: ${manifest.validation.status}`);
|
|
5611
5667
|
if (manifest.warnings.length > 0) {
|
|
@@ -5622,6 +5678,14 @@ ${USAGE}
|
|
|
5622
5678
|
}
|
|
5623
5679
|
return manifest.validation.status === "passed" ? 0 : 1;
|
|
5624
5680
|
} catch (err) {
|
|
5681
|
+
const code = err.code;
|
|
5682
|
+
if (code === "EPERM" || code === "EACCES") {
|
|
5683
|
+
warn(
|
|
5684
|
+
`\u274C Cannot write the snapshot: permission denied under ${resolved.outDir}. Check the directory's permissions or choose another --out-dir.`
|
|
5685
|
+
);
|
|
5686
|
+
warn(` (${err.message})`);
|
|
5687
|
+
return 1;
|
|
5688
|
+
}
|
|
5625
5689
|
warn(`\u274C Failed to generate snapshot: ${err.message}`);
|
|
5626
5690
|
return 1;
|
|
5627
5691
|
}
|
|
@@ -1678,11 +1678,12 @@ function detectPreset(cwd, forced) {
|
|
|
1678
1678
|
}
|
|
1679
1679
|
function getGitInfo(cwd, fallbackBranch = "main") {
|
|
1680
1680
|
try {
|
|
1681
|
-
const
|
|
1681
|
+
const reported = childProcess.execSync("git rev-parse --abbrev-ref HEAD", {
|
|
1682
1682
|
cwd,
|
|
1683
1683
|
stdio: ["ignore", "pipe", "ignore"],
|
|
1684
1684
|
encoding: "utf8"
|
|
1685
|
-
}).trim()
|
|
1685
|
+
}).trim();
|
|
1686
|
+
const branch = !reported || reported === "HEAD" ? fallbackBranch : reported;
|
|
1686
1687
|
const commit = childProcess.execSync("git rev-parse HEAD", {
|
|
1687
1688
|
cwd,
|
|
1688
1689
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -2303,6 +2304,9 @@ async function loadConfigFileDetailed(cwd) {
|
|
|
2303
2304
|
if (snapshotKey && typeof snapshotKey === "object") {
|
|
2304
2305
|
return { config: snapshotKey, file: pkgJsonPath, warnings, errors };
|
|
2305
2306
|
}
|
|
2307
|
+
if (snapshotKey !== void 0) {
|
|
2308
|
+
warnings.push(`${pkgJsonPath}: the "snapshot" key must be an object; it was ignored.`);
|
|
2309
|
+
}
|
|
2306
2310
|
} catch (err) {
|
|
2307
2311
|
const message = err.message;
|
|
2308
2312
|
warnings.push(message);
|
|
@@ -3417,6 +3421,7 @@ function validateSnapshot(configInput) {
|
|
|
3417
3421
|
drift.missingOnDisk.push(snapshotFile);
|
|
3418
3422
|
}
|
|
3419
3423
|
}
|
|
3424
|
+
drift.missingOnDisk = [...new Set(drift.missingOnDisk)];
|
|
3420
3425
|
const maxEffectiveBudget = Math.max(
|
|
3421
3426
|
config.maxPartBytes,
|
|
3422
3427
|
config.budgets.default,
|
|
@@ -3828,7 +3833,13 @@ function compareManifests(before, after) {
|
|
|
3828
3833
|
};
|
|
3829
3834
|
}
|
|
3830
3835
|
function loadManifest(target) {
|
|
3831
|
-
|
|
3836
|
+
let isDirectory;
|
|
3837
|
+
try {
|
|
3838
|
+
isDirectory = fs9.statSync(target).isDirectory();
|
|
3839
|
+
} catch {
|
|
3840
|
+
throw new Error(`No snapshot found at ${target}: the path does not exist.`);
|
|
3841
|
+
}
|
|
3842
|
+
const manifestPath = isDirectory ? path10.join(target, "manifest.json") : target;
|
|
3832
3843
|
let raw;
|
|
3833
3844
|
try {
|
|
3834
3845
|
raw = fs9.readFileSync(manifestPath, "utf8");
|
|
@@ -3844,6 +3855,9 @@ function loadManifest(target) {
|
|
|
3844
3855
|
if (!parsed || !Array.isArray(parsed.files)) {
|
|
3845
3856
|
throw new Error(`${manifestPath} is not a snapshot manifest (no "files" array).`);
|
|
3846
3857
|
}
|
|
3858
|
+
if (!parsed.counts || typeof parsed.counts !== "object") {
|
|
3859
|
+
throw new Error(`${manifestPath} is not a snapshot manifest (no "counts" object).`);
|
|
3860
|
+
}
|
|
3847
3861
|
return parsed;
|
|
3848
3862
|
}
|
|
3849
3863
|
function renderDiffText(diff) {
|
|
@@ -4514,7 +4528,7 @@ async function runInit(options) {
|
|
|
4514
4528
|
|
|
4515
4529
|
// src/index.ts
|
|
4516
4530
|
var GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
|
|
4517
|
-
var GENERATOR_VERSION = "2.1.
|
|
4531
|
+
var GENERATOR_VERSION = "2.1.1";
|
|
4518
4532
|
var SCHEMA_VERSION = "3.0.0";
|
|
4519
4533
|
function sha256Hex2(input) {
|
|
4520
4534
|
return crypto.createHash("sha256").update(input).digest("hex");
|
|
@@ -4758,7 +4772,9 @@ function artifactWarnings(artifacts) {
|
|
|
4758
4772
|
);
|
|
4759
4773
|
}
|
|
4760
4774
|
if (ARTIFACT_NAMES.every((name) => artifacts[name] === false)) {
|
|
4761
|
-
messages.push(
|
|
4775
|
+
messages.push(
|
|
4776
|
+
"every artifact is disabled: only the .codebase-snapshot ownership marker will be written."
|
|
4777
|
+
);
|
|
4762
4778
|
}
|
|
4763
4779
|
return messages;
|
|
4764
4780
|
}
|
|
@@ -5089,5 +5105,5 @@ async function generateSnapshotAsync(configInput, options) {
|
|
|
5089
5105
|
}
|
|
5090
5106
|
|
|
5091
5107
|
export { ARTIFACT_NAMES, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, GENERATOR_NAME, GENERATOR_VERSION, LANGUAGE_PROFILES, MIN_MAX_PART_BYTES, PRESETS, PromptCancelled, SCHEMA_VERSION, anchorForPath, assertReplaceable, assertUsableConfigInput, collectFiles, compareManifests, countLines, defineConfig, detectLanguage, detectPreset, explainPath, fenceForContent, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, isBinaryBuffer, isBinaryExtension, isBinaryFile, isInteractive, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, profileForPath, renderConfig, renderDiffText, renderExplainText, renderMinimalConfig, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, unknownPresetMessage, validateSnapshot };
|
|
5092
|
-
//# sourceMappingURL=chunk-
|
|
5093
|
-
//# sourceMappingURL=chunk-
|
|
5108
|
+
//# sourceMappingURL=chunk-SUOJL5EX.js.map
|
|
5109
|
+
//# sourceMappingURL=chunk-SUOJL5EX.js.map
|
package/dist/cli.cjs
CHANGED
|
@@ -81,7 +81,13 @@ function compareManifests(before, after) {
|
|
|
81
81
|
};
|
|
82
82
|
}
|
|
83
83
|
function loadManifest(target) {
|
|
84
|
-
|
|
84
|
+
let isDirectory;
|
|
85
|
+
try {
|
|
86
|
+
isDirectory = fs9__namespace.statSync(target).isDirectory();
|
|
87
|
+
} catch {
|
|
88
|
+
throw new Error(`No snapshot found at ${target}: the path does not exist.`);
|
|
89
|
+
}
|
|
90
|
+
const manifestPath = isDirectory ? path10__namespace.join(target, "manifest.json") : target;
|
|
85
91
|
let raw;
|
|
86
92
|
try {
|
|
87
93
|
raw = fs9__namespace.readFileSync(manifestPath, "utf8");
|
|
@@ -97,6 +103,9 @@ function loadManifest(target) {
|
|
|
97
103
|
if (!parsed || !Array.isArray(parsed.files)) {
|
|
98
104
|
throw new Error(`${manifestPath} is not a snapshot manifest (no "files" array).`);
|
|
99
105
|
}
|
|
106
|
+
if (!parsed.counts || typeof parsed.counts !== "object") {
|
|
107
|
+
throw new Error(`${manifestPath} is not a snapshot manifest (no "counts" object).`);
|
|
108
|
+
}
|
|
100
109
|
return parsed;
|
|
101
110
|
}
|
|
102
111
|
function renderDiffText(diff) {
|
|
@@ -959,11 +968,12 @@ function detectPreset(cwd, forced) {
|
|
|
959
968
|
}
|
|
960
969
|
function getGitInfo(cwd, fallbackBranch = "main") {
|
|
961
970
|
try {
|
|
962
|
-
const
|
|
971
|
+
const reported = childProcess__namespace.execSync("git rev-parse --abbrev-ref HEAD", {
|
|
963
972
|
cwd,
|
|
964
973
|
stdio: ["ignore", "pipe", "ignore"],
|
|
965
974
|
encoding: "utf8"
|
|
966
|
-
}).trim()
|
|
975
|
+
}).trim();
|
|
976
|
+
const branch = !reported || reported === "HEAD" ? fallbackBranch : reported;
|
|
967
977
|
const commit = childProcess__namespace.execSync("git rev-parse HEAD", {
|
|
968
978
|
cwd,
|
|
969
979
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -1584,6 +1594,9 @@ async function loadConfigFileDetailed(cwd) {
|
|
|
1584
1594
|
if (snapshotKey && typeof snapshotKey === "object") {
|
|
1585
1595
|
return { config: snapshotKey, file: pkgJsonPath, warnings, errors };
|
|
1586
1596
|
}
|
|
1597
|
+
if (snapshotKey !== void 0) {
|
|
1598
|
+
warnings.push(`${pkgJsonPath}: the "snapshot" key must be an object; it was ignored.`);
|
|
1599
|
+
}
|
|
1587
1600
|
} catch (err) {
|
|
1588
1601
|
const message = err.message;
|
|
1589
1602
|
warnings.push(message);
|
|
@@ -4274,6 +4287,7 @@ function validateSnapshot(configInput) {
|
|
|
4274
4287
|
drift.missingOnDisk.push(snapshotFile);
|
|
4275
4288
|
}
|
|
4276
4289
|
}
|
|
4290
|
+
drift.missingOnDisk = [...new Set(drift.missingOnDisk)];
|
|
4277
4291
|
const maxEffectiveBudget = Math.max(
|
|
4278
4292
|
config.maxPartBytes,
|
|
4279
4293
|
config.budgets.default,
|
|
@@ -4533,7 +4547,7 @@ function validateSnapshot(configInput) {
|
|
|
4533
4547
|
|
|
4534
4548
|
// src/index.ts
|
|
4535
4549
|
var GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
|
|
4536
|
-
var GENERATOR_VERSION = "2.1.
|
|
4550
|
+
var GENERATOR_VERSION = "2.1.1";
|
|
4537
4551
|
var SCHEMA_VERSION = "3.0.0";
|
|
4538
4552
|
function sha256Hex2(input) {
|
|
4539
4553
|
return crypto__namespace.createHash("sha256").update(input).digest("hex");
|
|
@@ -4777,7 +4791,9 @@ function artifactWarnings(artifacts) {
|
|
|
4777
4791
|
);
|
|
4778
4792
|
}
|
|
4779
4793
|
if (ARTIFACT_NAMES.every((name) => artifacts[name] === false)) {
|
|
4780
|
-
messages.push(
|
|
4794
|
+
messages.push(
|
|
4795
|
+
"every artifact is disabled: only the .codebase-snapshot ownership marker will be written."
|
|
4796
|
+
);
|
|
4781
4797
|
}
|
|
4782
4798
|
return messages;
|
|
4783
4799
|
}
|
|
@@ -5244,9 +5260,32 @@ function parseCliArgs(argv) {
|
|
|
5244
5260
|
strict: true
|
|
5245
5261
|
});
|
|
5246
5262
|
} catch (err) {
|
|
5247
|
-
|
|
5263
|
+
const message = err.message;
|
|
5264
|
+
const ambiguous = /^Option '(--[^']+)' argument is ambiguous/i.exec(message);
|
|
5265
|
+
if (ambiguous) {
|
|
5266
|
+
throw new UsageError(
|
|
5267
|
+
`${ambiguous[1]} received a value that looks like another flag (for example a negative number). Use the "--option=value" form, and note that sizes must be positive.`
|
|
5268
|
+
);
|
|
5269
|
+
}
|
|
5270
|
+
throw new UsageError(message);
|
|
5248
5271
|
}
|
|
5249
5272
|
const values = parsed.values;
|
|
5273
|
+
for (const [name, spec] of Object.entries(CLI_OPTIONS)) {
|
|
5274
|
+
if (spec.type !== "string") continue;
|
|
5275
|
+
const raw = values[name];
|
|
5276
|
+
if (raw !== void 0 && String(raw).trim() === "") {
|
|
5277
|
+
throw new UsageError(`--${name} requires a value (received an empty string).`);
|
|
5278
|
+
}
|
|
5279
|
+
}
|
|
5280
|
+
if (values.cwd !== void 0) {
|
|
5281
|
+
const target = String(values.cwd);
|
|
5282
|
+
if (!fs9__namespace.existsSync(target)) {
|
|
5283
|
+
throw new UsageError(`--cwd directory does not exist: ${target}`);
|
|
5284
|
+
}
|
|
5285
|
+
if (!fs9__namespace.statSync(target).isDirectory()) {
|
|
5286
|
+
throw new UsageError(`--cwd is not a directory: ${target}`);
|
|
5287
|
+
}
|
|
5288
|
+
}
|
|
5250
5289
|
if (values.help) {
|
|
5251
5290
|
process.stdout.write(`${USAGE}
|
|
5252
5291
|
`);
|
|
@@ -5464,6 +5503,9 @@ function renderValidateText(result) {
|
|
|
5464
5503
|
for (const missing of result.drift.missingOnDisk.slice(0, 20)) {
|
|
5465
5504
|
warn(` - deleted: ${missing}`);
|
|
5466
5505
|
}
|
|
5506
|
+
for (const mismatch of result.drift.totalsMismatches.slice(0, 20)) {
|
|
5507
|
+
warn(` - counts: ${mismatch}`);
|
|
5508
|
+
}
|
|
5467
5509
|
}
|
|
5468
5510
|
for (const warning of result.warnings) warn(` \u26A0 ${warning}`);
|
|
5469
5511
|
}
|
|
@@ -5594,9 +5636,23 @@ ${USAGE}
|
|
|
5594
5636
|
info(
|
|
5595
5637
|
` - Total size: ${(manifest.counts.totalSizeBytes / (1024 * 1024)).toFixed(2)} MB`
|
|
5596
5638
|
);
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5639
|
+
const { artifacts } = resolved;
|
|
5640
|
+
if (artifacts.parts) {
|
|
5641
|
+
info(` - Parts written: ${manifest.counts.partsCount} under ${resolved.outDir}/parts/`);
|
|
5642
|
+
}
|
|
5643
|
+
const reports = [
|
|
5644
|
+
artifacts.projectTree && "project-tree",
|
|
5645
|
+
artifacts.navigation && "navigation",
|
|
5646
|
+
artifacts.audit && "audit"
|
|
5647
|
+
].filter(Boolean);
|
|
5648
|
+
if (reports.length > 0) {
|
|
5649
|
+
info(` - Reports: ${resolved.outDir}/reports/ (${reports.join(", ")})`);
|
|
5650
|
+
}
|
|
5651
|
+
if (artifacts.manifest) info(` - Manifest: ${resolved.outDir}/manifest.json`);
|
|
5652
|
+
if (artifacts.monolith) info(` - Monolith: ${resolved.outDir}/full-codebase.{json,md}`);
|
|
5653
|
+
if (reports.length === 0 && !artifacts.parts && !artifacts.manifest && !artifacts.monolith) {
|
|
5654
|
+
info(` - Artifacts: all disabled (only the ownership marker was written)`);
|
|
5655
|
+
}
|
|
5600
5656
|
info(` - Fingerprint: ${manifest.fingerprint}`);
|
|
5601
5657
|
info(` - Integrity: ${manifest.validation.status}`);
|
|
5602
5658
|
if (manifest.warnings.length > 0) {
|
|
@@ -5613,6 +5669,14 @@ ${USAGE}
|
|
|
5613
5669
|
}
|
|
5614
5670
|
return manifest.validation.status === "passed" ? 0 : 1;
|
|
5615
5671
|
} catch (err) {
|
|
5672
|
+
const code = err.code;
|
|
5673
|
+
if (code === "EPERM" || code === "EACCES") {
|
|
5674
|
+
warn(
|
|
5675
|
+
`\u274C Cannot write the snapshot: permission denied under ${resolved.outDir}. Check the directory's permissions or choose another --out-dir.`
|
|
5676
|
+
);
|
|
5677
|
+
warn(` (${err.message})`);
|
|
5678
|
+
return 1;
|
|
5679
|
+
}
|
|
5616
5680
|
warn(`\u274C Failed to generate snapshot: ${err.message}`);
|
|
5617
5681
|
return 1;
|
|
5618
5682
|
}
|
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseByteSize, GENERATOR_VERSION, ARTIFACT_NAMES, getPreset, unknownPresetMessage, MIN_MAX_PART_BYTES, loadConfigFileDetailed, resolveConfig, validateSnapshot, explainPath, compareManifests, loadManifest, renderDiffText, generateSnapshot, GENERATOR_NAME, runInit, PromptCancelled, renderExplainText } from './chunk-
|
|
1
|
+
import { parseByteSize, GENERATOR_VERSION, ARTIFACT_NAMES, getPreset, unknownPresetMessage, MIN_MAX_PART_BYTES, loadConfigFileDetailed, resolveConfig, validateSnapshot, explainPath, compareManifests, loadManifest, renderDiffText, generateSnapshot, GENERATOR_NAME, runInit, PromptCancelled, renderExplainText } from './chunk-SUOJL5EX.js';
|
|
2
2
|
import * as fs from 'fs';
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { parseArgs } from 'util';
|
|
@@ -142,9 +142,32 @@ function parseCliArgs(argv) {
|
|
|
142
142
|
strict: true
|
|
143
143
|
});
|
|
144
144
|
} catch (err) {
|
|
145
|
-
|
|
145
|
+
const message = err.message;
|
|
146
|
+
const ambiguous = /^Option '(--[^']+)' argument is ambiguous/i.exec(message);
|
|
147
|
+
if (ambiguous) {
|
|
148
|
+
throw new UsageError(
|
|
149
|
+
`${ambiguous[1]} received a value that looks like another flag (for example a negative number). Use the "--option=value" form, and note that sizes must be positive.`
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
throw new UsageError(message);
|
|
146
153
|
}
|
|
147
154
|
const values = parsed.values;
|
|
155
|
+
for (const [name, spec] of Object.entries(CLI_OPTIONS)) {
|
|
156
|
+
if (spec.type !== "string") continue;
|
|
157
|
+
const raw = values[name];
|
|
158
|
+
if (raw !== void 0 && String(raw).trim() === "") {
|
|
159
|
+
throw new UsageError(`--${name} requires a value (received an empty string).`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (values.cwd !== void 0) {
|
|
163
|
+
const target = String(values.cwd);
|
|
164
|
+
if (!fs.existsSync(target)) {
|
|
165
|
+
throw new UsageError(`--cwd directory does not exist: ${target}`);
|
|
166
|
+
}
|
|
167
|
+
if (!fs.statSync(target).isDirectory()) {
|
|
168
|
+
throw new UsageError(`--cwd is not a directory: ${target}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
148
171
|
if (values.help) {
|
|
149
172
|
process.stdout.write(`${USAGE}
|
|
150
173
|
`);
|
|
@@ -362,6 +385,9 @@ function renderValidateText(result) {
|
|
|
362
385
|
for (const missing of result.drift.missingOnDisk.slice(0, 20)) {
|
|
363
386
|
warn(` - deleted: ${missing}`);
|
|
364
387
|
}
|
|
388
|
+
for (const mismatch of result.drift.totalsMismatches.slice(0, 20)) {
|
|
389
|
+
warn(` - counts: ${mismatch}`);
|
|
390
|
+
}
|
|
365
391
|
}
|
|
366
392
|
for (const warning of result.warnings) warn(` \u26A0 ${warning}`);
|
|
367
393
|
}
|
|
@@ -492,9 +518,23 @@ ${USAGE}
|
|
|
492
518
|
info(
|
|
493
519
|
` - Total size: ${(manifest.counts.totalSizeBytes / (1024 * 1024)).toFixed(2)} MB`
|
|
494
520
|
);
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
521
|
+
const { artifacts } = resolved;
|
|
522
|
+
if (artifacts.parts) {
|
|
523
|
+
info(` - Parts written: ${manifest.counts.partsCount} under ${resolved.outDir}/parts/`);
|
|
524
|
+
}
|
|
525
|
+
const reports = [
|
|
526
|
+
artifacts.projectTree && "project-tree",
|
|
527
|
+
artifacts.navigation && "navigation",
|
|
528
|
+
artifacts.audit && "audit"
|
|
529
|
+
].filter(Boolean);
|
|
530
|
+
if (reports.length > 0) {
|
|
531
|
+
info(` - Reports: ${resolved.outDir}/reports/ (${reports.join(", ")})`);
|
|
532
|
+
}
|
|
533
|
+
if (artifacts.manifest) info(` - Manifest: ${resolved.outDir}/manifest.json`);
|
|
534
|
+
if (artifacts.monolith) info(` - Monolith: ${resolved.outDir}/full-codebase.{json,md}`);
|
|
535
|
+
if (reports.length === 0 && !artifacts.parts && !artifacts.manifest && !artifacts.monolith) {
|
|
536
|
+
info(` - Artifacts: all disabled (only the ownership marker was written)`);
|
|
537
|
+
}
|
|
498
538
|
info(` - Fingerprint: ${manifest.fingerprint}`);
|
|
499
539
|
info(` - Integrity: ${manifest.validation.status}`);
|
|
500
540
|
if (manifest.warnings.length > 0) {
|
|
@@ -511,6 +551,14 @@ ${USAGE}
|
|
|
511
551
|
}
|
|
512
552
|
return manifest.validation.status === "passed" ? 0 : 1;
|
|
513
553
|
} catch (err) {
|
|
554
|
+
const code = err.code;
|
|
555
|
+
if (code === "EPERM" || code === "EACCES") {
|
|
556
|
+
warn(
|
|
557
|
+
`\u274C Cannot write the snapshot: permission denied under ${resolved.outDir}. Check the directory's permissions or choose another --out-dir.`
|
|
558
|
+
);
|
|
559
|
+
warn(` (${err.message})`);
|
|
560
|
+
return 1;
|
|
561
|
+
}
|
|
514
562
|
warn(`\u274C Failed to generate snapshot: ${err.message}`);
|
|
515
563
|
return 1;
|
|
516
564
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -1707,11 +1707,12 @@ function detectPreset(cwd, forced) {
|
|
|
1707
1707
|
}
|
|
1708
1708
|
function getGitInfo(cwd, fallbackBranch = "main") {
|
|
1709
1709
|
try {
|
|
1710
|
-
const
|
|
1710
|
+
const reported = childProcess__namespace.execSync("git rev-parse --abbrev-ref HEAD", {
|
|
1711
1711
|
cwd,
|
|
1712
1712
|
stdio: ["ignore", "pipe", "ignore"],
|
|
1713
1713
|
encoding: "utf8"
|
|
1714
|
-
}).trim()
|
|
1714
|
+
}).trim();
|
|
1715
|
+
const branch = !reported || reported === "HEAD" ? fallbackBranch : reported;
|
|
1715
1716
|
const commit = childProcess__namespace.execSync("git rev-parse HEAD", {
|
|
1716
1717
|
cwd,
|
|
1717
1718
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -2332,6 +2333,9 @@ async function loadConfigFileDetailed(cwd) {
|
|
|
2332
2333
|
if (snapshotKey && typeof snapshotKey === "object") {
|
|
2333
2334
|
return { config: snapshotKey, file: pkgJsonPath, warnings, errors };
|
|
2334
2335
|
}
|
|
2336
|
+
if (snapshotKey !== void 0) {
|
|
2337
|
+
warnings.push(`${pkgJsonPath}: the "snapshot" key must be an object; it was ignored.`);
|
|
2338
|
+
}
|
|
2335
2339
|
} catch (err) {
|
|
2336
2340
|
const message = err.message;
|
|
2337
2341
|
warnings.push(message);
|
|
@@ -3446,6 +3450,7 @@ function validateSnapshot(configInput) {
|
|
|
3446
3450
|
drift.missingOnDisk.push(snapshotFile);
|
|
3447
3451
|
}
|
|
3448
3452
|
}
|
|
3453
|
+
drift.missingOnDisk = [...new Set(drift.missingOnDisk)];
|
|
3449
3454
|
const maxEffectiveBudget = Math.max(
|
|
3450
3455
|
config.maxPartBytes,
|
|
3451
3456
|
config.budgets.default,
|
|
@@ -3857,7 +3862,13 @@ function compareManifests(before, after) {
|
|
|
3857
3862
|
};
|
|
3858
3863
|
}
|
|
3859
3864
|
function loadManifest(target) {
|
|
3860
|
-
|
|
3865
|
+
let isDirectory;
|
|
3866
|
+
try {
|
|
3867
|
+
isDirectory = fs9__namespace.statSync(target).isDirectory();
|
|
3868
|
+
} catch {
|
|
3869
|
+
throw new Error(`No snapshot found at ${target}: the path does not exist.`);
|
|
3870
|
+
}
|
|
3871
|
+
const manifestPath = isDirectory ? path10__namespace.join(target, "manifest.json") : target;
|
|
3861
3872
|
let raw;
|
|
3862
3873
|
try {
|
|
3863
3874
|
raw = fs9__namespace.readFileSync(manifestPath, "utf8");
|
|
@@ -3873,6 +3884,9 @@ function loadManifest(target) {
|
|
|
3873
3884
|
if (!parsed || !Array.isArray(parsed.files)) {
|
|
3874
3885
|
throw new Error(`${manifestPath} is not a snapshot manifest (no "files" array).`);
|
|
3875
3886
|
}
|
|
3887
|
+
if (!parsed.counts || typeof parsed.counts !== "object") {
|
|
3888
|
+
throw new Error(`${manifestPath} is not a snapshot manifest (no "counts" object).`);
|
|
3889
|
+
}
|
|
3876
3890
|
return parsed;
|
|
3877
3891
|
}
|
|
3878
3892
|
function renderDiffText(diff) {
|
|
@@ -4543,7 +4557,7 @@ async function runInit(options) {
|
|
|
4543
4557
|
|
|
4544
4558
|
// src/index.ts
|
|
4545
4559
|
var GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
|
|
4546
|
-
var GENERATOR_VERSION = "2.1.
|
|
4560
|
+
var GENERATOR_VERSION = "2.1.1";
|
|
4547
4561
|
var SCHEMA_VERSION = "3.0.0";
|
|
4548
4562
|
function sha256Hex2(input) {
|
|
4549
4563
|
return crypto__namespace.createHash("sha256").update(input).digest("hex");
|
|
@@ -4787,7 +4801,9 @@ function artifactWarnings(artifacts) {
|
|
|
4787
4801
|
);
|
|
4788
4802
|
}
|
|
4789
4803
|
if (ARTIFACT_NAMES.every((name) => artifacts[name] === false)) {
|
|
4790
|
-
messages.push(
|
|
4804
|
+
messages.push(
|
|
4805
|
+
"every artifact is disabled: only the .codebase-snapshot ownership marker will be written."
|
|
4806
|
+
);
|
|
4791
4807
|
}
|
|
4792
4808
|
return messages;
|
|
4793
4809
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -497,7 +497,7 @@ declare function matchesExclude(relativePath: string, pattern: string): boolean;
|
|
|
497
497
|
declare function collectFiles(cwd: string, options?: CollectOptions): CollectResult;
|
|
498
498
|
|
|
499
499
|
declare const GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
|
|
500
|
-
declare const GENERATOR_VERSION = "2.1.
|
|
500
|
+
declare const GENERATOR_VERSION = "2.1.1";
|
|
501
501
|
declare const SCHEMA_VERSION = "3.0.0";
|
|
502
502
|
interface GenerateOptions {
|
|
503
503
|
/** Compute the full manifest but write nothing to disk. */
|
package/dist/index.d.ts
CHANGED
|
@@ -497,7 +497,7 @@ declare function matchesExclude(relativePath: string, pattern: string): boolean;
|
|
|
497
497
|
declare function collectFiles(cwd: string, options?: CollectOptions): CollectResult;
|
|
498
498
|
|
|
499
499
|
declare const GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
|
|
500
|
-
declare const GENERATOR_VERSION = "2.1.
|
|
500
|
+
declare const GENERATOR_VERSION = "2.1.1";
|
|
501
501
|
declare const SCHEMA_VERSION = "3.0.0";
|
|
502
502
|
interface GenerateOptions {
|
|
503
503
|
/** Compute the full manifest but write nothing to disk. */
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { ARTIFACT_NAMES, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, GENERATOR_NAME, GENERATOR_VERSION, LANGUAGE_PROFILES, MIN_MAX_PART_BYTES, PRESETS, PromptCancelled, SCHEMA_VERSION, anchorForPath, assertReplaceable, assertUsableConfigInput, collectFiles, compareManifests, countLines, defineConfig, detectLanguage, detectPreset, explainPath, fenceForContent, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, isBinaryBuffer, isBinaryExtension, isBinaryFile, isInteractive, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, profileForPath, renderConfig, renderDiffText, renderExplainText, renderMinimalConfig, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, validateSnapshot } from './chunk-
|
|
1
|
+
export { ARTIFACT_NAMES, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, GENERATOR_NAME, GENERATOR_VERSION, LANGUAGE_PROFILES, MIN_MAX_PART_BYTES, PRESETS, PromptCancelled, SCHEMA_VERSION, anchorForPath, assertReplaceable, assertUsableConfigInput, collectFiles, compareManifests, countLines, defineConfig, detectLanguage, detectPreset, explainPath, fenceForContent, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, isBinaryBuffer, isBinaryExtension, isBinaryFile, isInteractive, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, profileForPath, renderConfig, renderDiffText, renderExplainText, renderMinimalConfig, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, validateSnapshot } from './chunk-SUOJL5EX.js';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/docs/install.md
CHANGED
|
@@ -12,6 +12,20 @@ Requires **Node.js 18 or newer**.
|
|
|
12
12
|
npx @ankurhalder/codebase-snapshot generate
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
If that exits with **no output and no error** instead of generating, your npm has
|
|
16
|
+
resolved the bare spec to a placeholder manifest that carries no executable — npm creates
|
|
17
|
+
a `0.0.0-stage` placeholder version during staged publishing, and some npm builds pick it
|
|
18
|
+
when no version is given. Pin the version or the tag and it works:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx @ankurhalder/codebase-snapshot@latest generate
|
|
22
|
+
npx @ankurhalder/codebase-snapshot@2 generate
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`npx -p @ankurhalder/codebase-snapshot codebase-snapshot generate`, `pnpm dlx`,
|
|
26
|
+
`yarn dlx` and `bunx` are unaffected. A normal `npm install -D` followed by `npx snap`
|
|
27
|
+
is unaffected too, and is the more reproducible choice for a project.
|
|
28
|
+
|
|
15
29
|
Equivalent one-liners for other clients:
|
|
16
30
|
|
|
17
31
|
```bash
|
|
@@ -68,7 +82,7 @@ if the generator version is reproducible.
|
|
|
68
82
|
|
|
69
83
|
```bash
|
|
70
84
|
npx @ankurhalder/codebase-snapshot@2 generate
|
|
71
|
-
pnpm dlx @ankurhalder/codebase-snapshot@2.1.
|
|
85
|
+
pnpm dlx @ankurhalder/codebase-snapshot@2.1.1 generate
|
|
72
86
|
```
|
|
73
87
|
|
|
74
88
|
## Verified clients
|