@ankurhalder/codebase-snapshot 4.0.2 → 4.0.4

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 CHANGED
@@ -4514,7 +4514,31 @@ function generateAuditReport(manifest, secretFindings, secretRules) {
4514
4514
  }
4515
4515
  lines.push("");
4516
4516
  }
4517
- lines.push("## 2. Large Files Analysis", "");
4517
+ const parseIssues = manifest.files.filter(
4518
+ (file) => file.summary !== void 0 && typeof file.summary === "object" && "parseErrors" in file.summary && typeof file.summary.parseErrors === "number" && file.summary.parseErrors > 0
4519
+ );
4520
+ lines.push("## 2. Parse & AST Diagnostics", "");
4521
+ if (parseIssues.length === 0) {
4522
+ lines.push("\u2705 Every parsed file produced a complete structural summary.", "");
4523
+ } else {
4524
+ lines.push(
4525
+ `${parseIssues.length} file(s) produced an incomplete summary:`,
4526
+ "",
4527
+ "| File | Parse Errors |",
4528
+ "| :--- | ---: |"
4529
+ );
4530
+ for (const file of parseIssues) {
4531
+ const errors = file.summary.parseErrors;
4532
+ lines.push(`| \`${mask(file.relativePath)}\` | ${errors} |`);
4533
+ }
4534
+ lines.push(
4535
+ "",
4536
+ "A parse error here means the summary is incomplete, not that the file is excluded \u2014",
4537
+ "the content is still in the parts.",
4538
+ ""
4539
+ );
4540
+ }
4541
+ lines.push("## 3. Large Files Analysis", "");
4518
4542
  const largeFiles = manifest.files.filter((file) => file.isLarge);
4519
4543
  if (largeFiles.length === 0) {
4520
4544
  lines.push("\u2705 No files exceeded the large file budget.", "");
@@ -4533,7 +4557,7 @@ function generateAuditReport(manifest, secretFindings, secretRules) {
4533
4557
  lines.push("");
4534
4558
  }
4535
4559
  lines.push(
4536
- "## 3. Architecture Layer Distribution",
4560
+ "## 4. Architecture Layer Distribution",
4537
4561
  "",
4538
4562
  "| Layer | File Count | Percentage |",
4539
4563
  "| :--- | :--- | :--- |"
@@ -4547,7 +4571,7 @@ function generateAuditReport(manifest, secretFindings, secretRules) {
4547
4571
  }
4548
4572
  lines.push("");
4549
4573
  lines.push(
4550
- "## 4. File Kind Distribution",
4574
+ "## 5. File Kind Distribution",
4551
4575
  "",
4552
4576
  "| Kind | File Count | Percentage |",
4553
4577
  "| :--- | :--- | :--- |"
@@ -4559,7 +4583,7 @@ function generateAuditReport(manifest, secretFindings, secretRules) {
4559
4583
  lines.push(`| \`${kind}\` | ${count} | ${pct}% |`);
4560
4584
  }
4561
4585
  lines.push("");
4562
- lines.push("## 5. Skipped / Non-Text Files", "");
4586
+ lines.push("## 6. Skipped / Non-Text Files", "");
4563
4587
  if (manifest.skipped.length === 0) {
4564
4588
  lines.push("No files were skipped.", "");
4565
4589
  } else {
@@ -5228,6 +5252,9 @@ function validateSnapshot(configInput) {
5228
5252
  });
5229
5253
  }
5230
5254
  }
5255
+ const maskValue = (value) => findSecretInPath(value, config.secretRules)?.masked ?? value;
5256
+ const currentExcludes = config.excludePatterns.map(maskValue);
5257
+ const currentInclude = config.include.map(maskValue);
5231
5258
  const recorded = manifest.config;
5232
5259
  if (recorded && typeof recorded === "object") {
5233
5260
  if (recorded.maxPartBytes !== config.maxPartBytes) {
@@ -5256,15 +5283,15 @@ function validateSnapshot(configInput) {
5256
5283
  );
5257
5284
  }
5258
5285
  const recordedExcludes = Array.isArray(recorded.excludePatterns) ? recorded.excludePatterns : [];
5259
- if (recordedExcludes.join("\0") !== config.excludePatterns.join("\0")) {
5286
+ if (recordedExcludes.join("\0") !== currentExcludes.join("\0")) {
5260
5287
  drift.configMismatches.push(
5261
- `excludePatterns: manifest [${recordedExcludes.join(", ")}] vs current [${config.excludePatterns.join(", ")}]`
5288
+ `excludePatterns: manifest [${recordedExcludes.join(", ")}] vs current [${currentExcludes.join(", ")}]`
5262
5289
  );
5263
5290
  }
5264
5291
  const recordedInclude = Array.isArray(recorded.include) ? recorded.include : [];
5265
- if (recordedInclude.join("\0") !== config.include.join("\0")) {
5292
+ if (recordedInclude.join("\0") !== currentInclude.join("\0")) {
5266
5293
  drift.configMismatches.push(
5267
- `include: manifest [${recordedInclude.join(", ")}] vs current [${config.include.join(", ")}]`
5294
+ `include: manifest [${recordedInclude.join(", ")}] vs current [${currentInclude.join(", ")}]`
5268
5295
  );
5269
5296
  }
5270
5297
  if (recorded?.artifacts && typeof recorded.artifacts === "object") {
@@ -5444,7 +5471,7 @@ function validateSnapshot(configInput) {
5444
5471
 
5445
5472
  // src/index.ts
5446
5473
  var GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
5447
- var GENERATOR_VERSION = "4.0.2";
5474
+ var GENERATOR_VERSION = "4.0.4";
5448
5475
  var SCHEMA_VERSION = "3.0.0";
5449
5476
  function sha256Hex2(input) {
5450
5477
  return crypto3.createHash("sha256").update(input).digest("hex");
@@ -5651,6 +5678,18 @@ function resolveSafeOutputDirs(config) {
5651
5678
  var PLACEHOLDER_ENTRIES = /* @__PURE__ */ new Set([".gitkeep", ".gitignore", ".DS_Store"]);
5652
5679
  var RUN_DIR_PREFIX = "run-";
5653
5680
  var STALE_RUN_MS = 60 * 60 * 1e3;
5681
+ function maskSummaryStrings(value, secretRules) {
5682
+ if (typeof value === "string") return maskPathText(value, secretRules);
5683
+ if (Array.isArray(value)) return value.map((item) => maskSummaryStrings(item, secretRules));
5684
+ if (value && typeof value === "object") {
5685
+ const out = {};
5686
+ for (const [key, item] of Object.entries(value)) {
5687
+ out[key] = maskSummaryStrings(item, secretRules);
5688
+ }
5689
+ return out;
5690
+ }
5691
+ return value;
5692
+ }
5654
5693
  function maskPathText(value, secretRules) {
5655
5694
  return findSecretInPath(value, secretRules)?.masked ?? value;
5656
5695
  }
@@ -6231,8 +6270,8 @@ function generateSnapshot(configInput, options) {
6231
6270
  let summary;
6232
6271
  let summaryQuality;
6233
6272
  try {
6234
- const outcome = summarizeFile(relativePath, redacted);
6235
- summary = outcome?.summary;
6273
+ const outcome = summarizeFile(relativePath, rawContent);
6274
+ summary = outcome?.summary ? maskSummaryStrings(outcome.summary, config.secretRules) : void 0;
6236
6275
  summaryQuality = outcome?.quality;
6237
6276
  if (isSourceSummary(summary) && summary.parseErrors) {
6238
6277
  warnings.push(
@@ -7779,7 +7818,7 @@ ${USAGE}
7779
7818
  info(` - Schema: ${manifest.schemaVersion}`);
7780
7819
  info(` - Fingerprint: ${manifest.fingerprint}`);
7781
7820
  info(` - Files included: ${manifest.counts.totalFiles}`);
7782
- info(` - Total lines: ${manifest.counts.totalLines.toLocaleString()}`);
7821
+ info(` - Total lines: ${manifest.counts.totalLines.toLocaleString("en-US")}`);
7783
7822
  info(
7784
7823
  ` - Total size: ${(manifest.counts.totalSizeBytes / (1024 * 1024)).toFixed(2)} MB`
7785
7824
  );
@@ -7831,14 +7870,14 @@ ${USAGE}
7831
7870
  info(`
7832
7871
  \u2705 Snapshot generated in ${elapsed}s:`);
7833
7872
  info(` - Tracked files: ${manifest.counts.totalFiles}`);
7834
- info(` - Total lines: ${manifest.counts.totalLines.toLocaleString()}`);
7873
+ info(` - Total lines: ${manifest.counts.totalLines.toLocaleString("en-US")}`);
7835
7874
  info(
7836
7875
  ` - Total size: ${(manifest.counts.totalSizeBytes / (1024 * 1024)).toFixed(2)} MB`
7837
7876
  );
7838
7877
  const { artifacts } = resolved;
7839
7878
  if (artifacts.parts) {
7840
7879
  info(
7841
- ` - Parts written: ${manifest.counts.partsCount} under ${displayOutPath(resolved.cwd, resolved.outDir, "parts")}/`
7880
+ ` - Parts written: ${manifest.counts.partsCount} under ${displayOutPath(resolved.cwd, resolved.outDir, "parts")}`
7842
7881
  );
7843
7882
  }
7844
7883
  const reports = [
@@ -7848,7 +7887,7 @@ ${USAGE}
7848
7887
  ].filter(Boolean);
7849
7888
  if (reports.length > 0) {
7850
7889
  info(
7851
- ` - Reports: ${displayOutPath(resolved.cwd, resolved.outDir, "reports")}/ (${reports.join(", ")})`
7890
+ ` - Reports: ${displayOutPath(resolved.cwd, resolved.outDir, "reports")} (${reports.join(", ")})`
7852
7891
  );
7853
7892
  }
7854
7893
  if (artifacts.manifest) {
@@ -7976,6 +8015,21 @@ async function runWatchLoop(invocation, resolved) {
7976
8015
  });
7977
8016
  return 0;
7978
8017
  }
8018
+ var entryFile = process.argv[1] ?? "";
8019
+ var entryName = path12.basename(entryFile).toLowerCase();
8020
+ var invokedDirectly = entryName === "cli.js" || entryName === "cli.cjs";
8021
+ if (invokedDirectly) {
8022
+ void main().then(
8023
+ (code) => {
8024
+ process.exitCode = code;
8025
+ },
8026
+ (err) => {
8027
+ process.stderr.write(`\u274C ${err.message}
8028
+ `);
8029
+ process.exitCode = 1;
8030
+ }
8031
+ );
8032
+ }
7979
8033
 
7980
8034
  // src/bin.ts
7981
8035
  main().then(
@@ -3399,7 +3399,31 @@ function generateAuditReport(manifest, secretFindings, secretRules) {
3399
3399
  }
3400
3400
  lines.push("");
3401
3401
  }
3402
- lines.push("## 2. Large Files Analysis", "");
3402
+ const parseIssues = manifest.files.filter(
3403
+ (file) => file.summary !== void 0 && typeof file.summary === "object" && "parseErrors" in file.summary && typeof file.summary.parseErrors === "number" && file.summary.parseErrors > 0
3404
+ );
3405
+ lines.push("## 2. Parse & AST Diagnostics", "");
3406
+ if (parseIssues.length === 0) {
3407
+ lines.push("\u2705 Every parsed file produced a complete structural summary.", "");
3408
+ } else {
3409
+ lines.push(
3410
+ `${parseIssues.length} file(s) produced an incomplete summary:`,
3411
+ "",
3412
+ "| File | Parse Errors |",
3413
+ "| :--- | ---: |"
3414
+ );
3415
+ for (const file of parseIssues) {
3416
+ const errors = file.summary.parseErrors;
3417
+ lines.push(`| \`${mask(file.relativePath)}\` | ${errors} |`);
3418
+ }
3419
+ lines.push(
3420
+ "",
3421
+ "A parse error here means the summary is incomplete, not that the file is excluded \u2014",
3422
+ "the content is still in the parts.",
3423
+ ""
3424
+ );
3425
+ }
3426
+ lines.push("## 3. Large Files Analysis", "");
3403
3427
  const largeFiles = manifest.files.filter((file) => file.isLarge);
3404
3428
  if (largeFiles.length === 0) {
3405
3429
  lines.push("\u2705 No files exceeded the large file budget.", "");
@@ -3418,7 +3442,7 @@ function generateAuditReport(manifest, secretFindings, secretRules) {
3418
3442
  lines.push("");
3419
3443
  }
3420
3444
  lines.push(
3421
- "## 3. Architecture Layer Distribution",
3445
+ "## 4. Architecture Layer Distribution",
3422
3446
  "",
3423
3447
  "| Layer | File Count | Percentage |",
3424
3448
  "| :--- | :--- | :--- |"
@@ -3432,7 +3456,7 @@ function generateAuditReport(manifest, secretFindings, secretRules) {
3432
3456
  }
3433
3457
  lines.push("");
3434
3458
  lines.push(
3435
- "## 4. File Kind Distribution",
3459
+ "## 5. File Kind Distribution",
3436
3460
  "",
3437
3461
  "| Kind | File Count | Percentage |",
3438
3462
  "| :--- | :--- | :--- |"
@@ -3444,7 +3468,7 @@ function generateAuditReport(manifest, secretFindings, secretRules) {
3444
3468
  lines.push(`| \`${kind}\` | ${count} | ${pct}% |`);
3445
3469
  }
3446
3470
  lines.push("");
3447
- lines.push("## 5. Skipped / Non-Text Files", "");
3471
+ lines.push("## 6. Skipped / Non-Text Files", "");
3448
3472
  if (manifest.skipped.length === 0) {
3449
3473
  lines.push("No files were skipped.", "");
3450
3474
  } else {
@@ -4276,6 +4300,9 @@ function validateSnapshot(configInput) {
4276
4300
  });
4277
4301
  }
4278
4302
  }
4303
+ const maskValue = (value) => findSecretInPath(value, config.secretRules)?.masked ?? value;
4304
+ const currentExcludes = config.excludePatterns.map(maskValue);
4305
+ const currentInclude = config.include.map(maskValue);
4279
4306
  const recorded = manifest.config;
4280
4307
  if (recorded && typeof recorded === "object") {
4281
4308
  if (recorded.maxPartBytes !== config.maxPartBytes) {
@@ -4304,15 +4331,15 @@ function validateSnapshot(configInput) {
4304
4331
  );
4305
4332
  }
4306
4333
  const recordedExcludes = Array.isArray(recorded.excludePatterns) ? recorded.excludePatterns : [];
4307
- if (recordedExcludes.join("\0") !== config.excludePatterns.join("\0")) {
4334
+ if (recordedExcludes.join("\0") !== currentExcludes.join("\0")) {
4308
4335
  drift.configMismatches.push(
4309
- `excludePatterns: manifest [${recordedExcludes.join(", ")}] vs current [${config.excludePatterns.join(", ")}]`
4336
+ `excludePatterns: manifest [${recordedExcludes.join(", ")}] vs current [${currentExcludes.join(", ")}]`
4310
4337
  );
4311
4338
  }
4312
4339
  const recordedInclude = Array.isArray(recorded.include) ? recorded.include : [];
4313
- if (recordedInclude.join("\0") !== config.include.join("\0")) {
4340
+ if (recordedInclude.join("\0") !== currentInclude.join("\0")) {
4314
4341
  drift.configMismatches.push(
4315
- `include: manifest [${recordedInclude.join(", ")}] vs current [${config.include.join(", ")}]`
4342
+ `include: manifest [${recordedInclude.join(", ")}] vs current [${currentInclude.join(", ")}]`
4316
4343
  );
4317
4344
  }
4318
4345
  if (recorded?.artifacts && typeof recorded.artifacts === "object") {
@@ -5407,7 +5434,7 @@ async function runInit(options) {
5407
5434
 
5408
5435
  // src/index.ts
5409
5436
  var GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
5410
- var GENERATOR_VERSION = "4.0.2";
5437
+ var GENERATOR_VERSION = "4.0.4";
5411
5438
  var SCHEMA_VERSION = "3.0.0";
5412
5439
  function sha256Hex2(input) {
5413
5440
  return crypto.createHash("sha256").update(input).digest("hex");
@@ -5614,6 +5641,18 @@ function resolveSafeOutputDirs(config) {
5614
5641
  var PLACEHOLDER_ENTRIES = /* @__PURE__ */ new Set([".gitkeep", ".gitignore", ".DS_Store"]);
5615
5642
  var RUN_DIR_PREFIX = "run-";
5616
5643
  var STALE_RUN_MS = 60 * 60 * 1e3;
5644
+ function maskSummaryStrings(value, secretRules) {
5645
+ if (typeof value === "string") return maskPathText(value, secretRules);
5646
+ if (Array.isArray(value)) return value.map((item) => maskSummaryStrings(item, secretRules));
5647
+ if (value && typeof value === "object") {
5648
+ const out = {};
5649
+ for (const [key, item] of Object.entries(value)) {
5650
+ out[key] = maskSummaryStrings(item, secretRules);
5651
+ }
5652
+ return out;
5653
+ }
5654
+ return value;
5655
+ }
5617
5656
  function maskPathText(value, secretRules) {
5618
5657
  return findSecretInPath(value, secretRules)?.masked ?? value;
5619
5658
  }
@@ -6194,8 +6233,8 @@ function generateSnapshot(configInput, options) {
6194
6233
  let summary;
6195
6234
  let summaryQuality;
6196
6235
  try {
6197
- const outcome = summarizeFile(relativePath, redacted);
6198
- summary = outcome?.summary;
6236
+ const outcome = summarizeFile(relativePath, rawContent);
6237
+ summary = outcome?.summary ? maskSummaryStrings(outcome.summary, config.secretRules) : void 0;
6199
6238
  summaryQuality = outcome?.quality;
6200
6239
  if (isSourceSummary(summary) && summary.parseErrors) {
6201
6240
  warnings.push(
@@ -6455,5 +6494,5 @@ async function generateSnapshotAsync(configInput, options) {
6455
6494
  }
6456
6495
 
6457
6496
  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, fenceForText, 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 };
6458
- //# sourceMappingURL=chunk-CY3XU5TS.js.map
6459
- //# sourceMappingURL=chunk-CY3XU5TS.js.map
6497
+ //# sourceMappingURL=chunk-CDZDVU74.js.map
6498
+ //# sourceMappingURL=chunk-CDZDVU74.js.map
package/dist/cli.cjs CHANGED
@@ -4502,7 +4502,31 @@ function generateAuditReport(manifest, secretFindings, secretRules) {
4502
4502
  }
4503
4503
  lines.push("");
4504
4504
  }
4505
- lines.push("## 2. Large Files Analysis", "");
4505
+ const parseIssues = manifest.files.filter(
4506
+ (file) => file.summary !== void 0 && typeof file.summary === "object" && "parseErrors" in file.summary && typeof file.summary.parseErrors === "number" && file.summary.parseErrors > 0
4507
+ );
4508
+ lines.push("## 2. Parse & AST Diagnostics", "");
4509
+ if (parseIssues.length === 0) {
4510
+ lines.push("\u2705 Every parsed file produced a complete structural summary.", "");
4511
+ } else {
4512
+ lines.push(
4513
+ `${parseIssues.length} file(s) produced an incomplete summary:`,
4514
+ "",
4515
+ "| File | Parse Errors |",
4516
+ "| :--- | ---: |"
4517
+ );
4518
+ for (const file of parseIssues) {
4519
+ const errors = file.summary.parseErrors;
4520
+ lines.push(`| \`${mask(file.relativePath)}\` | ${errors} |`);
4521
+ }
4522
+ lines.push(
4523
+ "",
4524
+ "A parse error here means the summary is incomplete, not that the file is excluded \u2014",
4525
+ "the content is still in the parts.",
4526
+ ""
4527
+ );
4528
+ }
4529
+ lines.push("## 3. Large Files Analysis", "");
4506
4530
  const largeFiles = manifest.files.filter((file) => file.isLarge);
4507
4531
  if (largeFiles.length === 0) {
4508
4532
  lines.push("\u2705 No files exceeded the large file budget.", "");
@@ -4521,7 +4545,7 @@ function generateAuditReport(manifest, secretFindings, secretRules) {
4521
4545
  lines.push("");
4522
4546
  }
4523
4547
  lines.push(
4524
- "## 3. Architecture Layer Distribution",
4548
+ "## 4. Architecture Layer Distribution",
4525
4549
  "",
4526
4550
  "| Layer | File Count | Percentage |",
4527
4551
  "| :--- | :--- | :--- |"
@@ -4535,7 +4559,7 @@ function generateAuditReport(manifest, secretFindings, secretRules) {
4535
4559
  }
4536
4560
  lines.push("");
4537
4561
  lines.push(
4538
- "## 4. File Kind Distribution",
4562
+ "## 5. File Kind Distribution",
4539
4563
  "",
4540
4564
  "| Kind | File Count | Percentage |",
4541
4565
  "| :--- | :--- | :--- |"
@@ -4547,7 +4571,7 @@ function generateAuditReport(manifest, secretFindings, secretRules) {
4547
4571
  lines.push(`| \`${kind}\` | ${count} | ${pct}% |`);
4548
4572
  }
4549
4573
  lines.push("");
4550
- lines.push("## 5. Skipped / Non-Text Files", "");
4574
+ lines.push("## 6. Skipped / Non-Text Files", "");
4551
4575
  if (manifest.skipped.length === 0) {
4552
4576
  lines.push("No files were skipped.", "");
4553
4577
  } else {
@@ -5208,6 +5232,9 @@ function validateSnapshot(configInput) {
5208
5232
  });
5209
5233
  }
5210
5234
  }
5235
+ const maskValue = (value) => findSecretInPath(value, config.secretRules)?.masked ?? value;
5236
+ const currentExcludes = config.excludePatterns.map(maskValue);
5237
+ const currentInclude = config.include.map(maskValue);
5211
5238
  const recorded = manifest.config;
5212
5239
  if (recorded && typeof recorded === "object") {
5213
5240
  if (recorded.maxPartBytes !== config.maxPartBytes) {
@@ -5236,15 +5263,15 @@ function validateSnapshot(configInput) {
5236
5263
  );
5237
5264
  }
5238
5265
  const recordedExcludes = Array.isArray(recorded.excludePatterns) ? recorded.excludePatterns : [];
5239
- if (recordedExcludes.join("\0") !== config.excludePatterns.join("\0")) {
5266
+ if (recordedExcludes.join("\0") !== currentExcludes.join("\0")) {
5240
5267
  drift.configMismatches.push(
5241
- `excludePatterns: manifest [${recordedExcludes.join(", ")}] vs current [${config.excludePatterns.join(", ")}]`
5268
+ `excludePatterns: manifest [${recordedExcludes.join(", ")}] vs current [${currentExcludes.join(", ")}]`
5242
5269
  );
5243
5270
  }
5244
5271
  const recordedInclude = Array.isArray(recorded.include) ? recorded.include : [];
5245
- if (recordedInclude.join("\0") !== config.include.join("\0")) {
5272
+ if (recordedInclude.join("\0") !== currentInclude.join("\0")) {
5246
5273
  drift.configMismatches.push(
5247
- `include: manifest [${recordedInclude.join(", ")}] vs current [${config.include.join(", ")}]`
5274
+ `include: manifest [${recordedInclude.join(", ")}] vs current [${currentInclude.join(", ")}]`
5248
5275
  );
5249
5276
  }
5250
5277
  if (recorded?.artifacts && typeof recorded.artifacts === "object") {
@@ -5424,7 +5451,7 @@ function validateSnapshot(configInput) {
5424
5451
 
5425
5452
  // src/index.ts
5426
5453
  var GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
5427
- var GENERATOR_VERSION = "4.0.2";
5454
+ var GENERATOR_VERSION = "4.0.4";
5428
5455
  var SCHEMA_VERSION = "3.0.0";
5429
5456
  function sha256Hex2(input) {
5430
5457
  return crypto__namespace.createHash("sha256").update(input).digest("hex");
@@ -5631,6 +5658,18 @@ function resolveSafeOutputDirs(config) {
5631
5658
  var PLACEHOLDER_ENTRIES = /* @__PURE__ */ new Set([".gitkeep", ".gitignore", ".DS_Store"]);
5632
5659
  var RUN_DIR_PREFIX = "run-";
5633
5660
  var STALE_RUN_MS = 60 * 60 * 1e3;
5661
+ function maskSummaryStrings(value, secretRules) {
5662
+ if (typeof value === "string") return maskPathText(value, secretRules);
5663
+ if (Array.isArray(value)) return value.map((item) => maskSummaryStrings(item, secretRules));
5664
+ if (value && typeof value === "object") {
5665
+ const out = {};
5666
+ for (const [key, item] of Object.entries(value)) {
5667
+ out[key] = maskSummaryStrings(item, secretRules);
5668
+ }
5669
+ return out;
5670
+ }
5671
+ return value;
5672
+ }
5634
5673
  function maskPathText(value, secretRules) {
5635
5674
  return findSecretInPath(value, secretRules)?.masked ?? value;
5636
5675
  }
@@ -6211,8 +6250,8 @@ function generateSnapshot(configInput, options) {
6211
6250
  let summary;
6212
6251
  let summaryQuality;
6213
6252
  try {
6214
- const outcome = summarizeFile(relativePath, redacted);
6215
- summary = outcome?.summary;
6253
+ const outcome = summarizeFile(relativePath, rawContent);
6254
+ summary = outcome?.summary ? maskSummaryStrings(outcome.summary, config.secretRules) : void 0;
6216
6255
  summaryQuality = outcome?.quality;
6217
6256
  if (isSourceSummary(summary) && summary.parseErrors) {
6218
6257
  warnings.push(
@@ -7767,7 +7806,7 @@ ${USAGE}
7767
7806
  info(` - Schema: ${manifest.schemaVersion}`);
7768
7807
  info(` - Fingerprint: ${manifest.fingerprint}`);
7769
7808
  info(` - Files included: ${manifest.counts.totalFiles}`);
7770
- info(` - Total lines: ${manifest.counts.totalLines.toLocaleString()}`);
7809
+ info(` - Total lines: ${manifest.counts.totalLines.toLocaleString("en-US")}`);
7771
7810
  info(
7772
7811
  ` - Total size: ${(manifest.counts.totalSizeBytes / (1024 * 1024)).toFixed(2)} MB`
7773
7812
  );
@@ -7819,14 +7858,14 @@ ${USAGE}
7819
7858
  info(`
7820
7859
  \u2705 Snapshot generated in ${elapsed}s:`);
7821
7860
  info(` - Tracked files: ${manifest.counts.totalFiles}`);
7822
- info(` - Total lines: ${manifest.counts.totalLines.toLocaleString()}`);
7861
+ info(` - Total lines: ${manifest.counts.totalLines.toLocaleString("en-US")}`);
7823
7862
  info(
7824
7863
  ` - Total size: ${(manifest.counts.totalSizeBytes / (1024 * 1024)).toFixed(2)} MB`
7825
7864
  );
7826
7865
  const { artifacts } = resolved;
7827
7866
  if (artifacts.parts) {
7828
7867
  info(
7829
- ` - Parts written: ${manifest.counts.partsCount} under ${displayOutPath(resolved.cwd, resolved.outDir, "parts")}/`
7868
+ ` - Parts written: ${manifest.counts.partsCount} under ${displayOutPath(resolved.cwd, resolved.outDir, "parts")}`
7830
7869
  );
7831
7870
  }
7832
7871
  const reports = [
@@ -7836,7 +7875,7 @@ ${USAGE}
7836
7875
  ].filter(Boolean);
7837
7876
  if (reports.length > 0) {
7838
7877
  info(
7839
- ` - Reports: ${displayOutPath(resolved.cwd, resolved.outDir, "reports")}/ (${reports.join(", ")})`
7878
+ ` - Reports: ${displayOutPath(resolved.cwd, resolved.outDir, "reports")} (${reports.join(", ")})`
7840
7879
  );
7841
7880
  }
7842
7881
  if (artifacts.manifest) {
@@ -7964,6 +8003,21 @@ async function runWatchLoop(invocation, resolved) {
7964
8003
  });
7965
8004
  return 0;
7966
8005
  }
8006
+ var entryFile = process.argv[1] ?? "";
8007
+ var entryName = path10__namespace.basename(entryFile).toLowerCase();
8008
+ var invokedDirectly = entryName === "cli.js" || entryName === "cli.cjs";
8009
+ if (invokedDirectly) {
8010
+ void main().then(
8011
+ (code) => {
8012
+ process.exitCode = code;
8013
+ },
8014
+ (err) => {
8015
+ process.stderr.write(`\u274C ${err.message}
8016
+ `);
8017
+ process.exitCode = 1;
8018
+ }
8019
+ );
8020
+ }
7967
8021
 
7968
8022
  exports.UsageError = UsageError;
7969
8023
  exports.main = main;
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, SCHEMA_VERSION, PRESETS, renderExplainText } from './chunk-CY3XU5TS.js';
1
+ import { loadConfigFileDetailed, resolveConfig, validateSnapshot, explainPath, compareManifests, loadManifest, renderDiffText, generateSnapshot, GENERATOR_VERSION, ARTIFACT_NAMES, getPreset, unknownPresetMessage, GENERATOR_NAME, runInit, PromptCancelled, MIN_MAX_PART_BYTES, SCHEMA_VERSION, PRESETS, parseByteSize, renderExplainText } from './chunk-CDZDVU74.js';
2
2
  import * as fs from 'fs';
3
3
  import * as path2 from 'path';
4
4
  import { parseArgs } from 'util';
@@ -1302,7 +1302,7 @@ ${USAGE}
1302
1302
  info(` - Schema: ${manifest.schemaVersion}`);
1303
1303
  info(` - Fingerprint: ${manifest.fingerprint}`);
1304
1304
  info(` - Files included: ${manifest.counts.totalFiles}`);
1305
- info(` - Total lines: ${manifest.counts.totalLines.toLocaleString()}`);
1305
+ info(` - Total lines: ${manifest.counts.totalLines.toLocaleString("en-US")}`);
1306
1306
  info(
1307
1307
  ` - Total size: ${(manifest.counts.totalSizeBytes / (1024 * 1024)).toFixed(2)} MB`
1308
1308
  );
@@ -1354,14 +1354,14 @@ ${USAGE}
1354
1354
  info(`
1355
1355
  \u2705 Snapshot generated in ${elapsed}s:`);
1356
1356
  info(` - Tracked files: ${manifest.counts.totalFiles}`);
1357
- info(` - Total lines: ${manifest.counts.totalLines.toLocaleString()}`);
1357
+ info(` - Total lines: ${manifest.counts.totalLines.toLocaleString("en-US")}`);
1358
1358
  info(
1359
1359
  ` - Total size: ${(manifest.counts.totalSizeBytes / (1024 * 1024)).toFixed(2)} MB`
1360
1360
  );
1361
1361
  const { artifacts } = resolved;
1362
1362
  if (artifacts.parts) {
1363
1363
  info(
1364
- ` - Parts written: ${manifest.counts.partsCount} under ${displayOutPath(resolved.cwd, resolved.outDir, "parts")}/`
1364
+ ` - Parts written: ${manifest.counts.partsCount} under ${displayOutPath(resolved.cwd, resolved.outDir, "parts")}`
1365
1365
  );
1366
1366
  }
1367
1367
  const reports = [
@@ -1371,7 +1371,7 @@ ${USAGE}
1371
1371
  ].filter(Boolean);
1372
1372
  if (reports.length > 0) {
1373
1373
  info(
1374
- ` - Reports: ${displayOutPath(resolved.cwd, resolved.outDir, "reports")}/ (${reports.join(", ")})`
1374
+ ` - Reports: ${displayOutPath(resolved.cwd, resolved.outDir, "reports")} (${reports.join(", ")})`
1375
1375
  );
1376
1376
  }
1377
1377
  if (artifacts.manifest) {
@@ -1499,6 +1499,21 @@ async function runWatchLoop(invocation, resolved) {
1499
1499
  });
1500
1500
  return 0;
1501
1501
  }
1502
+ var entryFile = process.argv[1] ?? "";
1503
+ var entryName = path2.basename(entryFile).toLowerCase();
1504
+ var invokedDirectly = entryName === "cli.js" || entryName === "cli.cjs";
1505
+ if (invokedDirectly) {
1506
+ void main().then(
1507
+ (code) => {
1508
+ process.exitCode = code;
1509
+ },
1510
+ (err) => {
1511
+ process.stderr.write(`\u274C ${err.message}
1512
+ `);
1513
+ process.exitCode = 1;
1514
+ }
1515
+ );
1516
+ }
1502
1517
 
1503
1518
  export { UsageError, main, parseByteOption, parseCliArgs, parsePositiveInteger };
1504
1519
  //# sourceMappingURL=cli.js.map
package/dist/index.cjs CHANGED
@@ -3429,7 +3429,31 @@ function generateAuditReport(manifest, secretFindings, secretRules) {
3429
3429
  }
3430
3430
  lines.push("");
3431
3431
  }
3432
- lines.push("## 2. Large Files Analysis", "");
3432
+ const parseIssues = manifest.files.filter(
3433
+ (file) => file.summary !== void 0 && typeof file.summary === "object" && "parseErrors" in file.summary && typeof file.summary.parseErrors === "number" && file.summary.parseErrors > 0
3434
+ );
3435
+ lines.push("## 2. Parse & AST Diagnostics", "");
3436
+ if (parseIssues.length === 0) {
3437
+ lines.push("\u2705 Every parsed file produced a complete structural summary.", "");
3438
+ } else {
3439
+ lines.push(
3440
+ `${parseIssues.length} file(s) produced an incomplete summary:`,
3441
+ "",
3442
+ "| File | Parse Errors |",
3443
+ "| :--- | ---: |"
3444
+ );
3445
+ for (const file of parseIssues) {
3446
+ const errors = file.summary.parseErrors;
3447
+ lines.push(`| \`${mask(file.relativePath)}\` | ${errors} |`);
3448
+ }
3449
+ lines.push(
3450
+ "",
3451
+ "A parse error here means the summary is incomplete, not that the file is excluded \u2014",
3452
+ "the content is still in the parts.",
3453
+ ""
3454
+ );
3455
+ }
3456
+ lines.push("## 3. Large Files Analysis", "");
3433
3457
  const largeFiles = manifest.files.filter((file) => file.isLarge);
3434
3458
  if (largeFiles.length === 0) {
3435
3459
  lines.push("\u2705 No files exceeded the large file budget.", "");
@@ -3448,7 +3472,7 @@ function generateAuditReport(manifest, secretFindings, secretRules) {
3448
3472
  lines.push("");
3449
3473
  }
3450
3474
  lines.push(
3451
- "## 3. Architecture Layer Distribution",
3475
+ "## 4. Architecture Layer Distribution",
3452
3476
  "",
3453
3477
  "| Layer | File Count | Percentage |",
3454
3478
  "| :--- | :--- | :--- |"
@@ -3462,7 +3486,7 @@ function generateAuditReport(manifest, secretFindings, secretRules) {
3462
3486
  }
3463
3487
  lines.push("");
3464
3488
  lines.push(
3465
- "## 4. File Kind Distribution",
3489
+ "## 5. File Kind Distribution",
3466
3490
  "",
3467
3491
  "| Kind | File Count | Percentage |",
3468
3492
  "| :--- | :--- | :--- |"
@@ -3474,7 +3498,7 @@ function generateAuditReport(manifest, secretFindings, secretRules) {
3474
3498
  lines.push(`| \`${kind}\` | ${count} | ${pct}% |`);
3475
3499
  }
3476
3500
  lines.push("");
3477
- lines.push("## 5. Skipped / Non-Text Files", "");
3501
+ lines.push("## 6. Skipped / Non-Text Files", "");
3478
3502
  if (manifest.skipped.length === 0) {
3479
3503
  lines.push("No files were skipped.", "");
3480
3504
  } else {
@@ -4306,6 +4330,9 @@ function validateSnapshot(configInput) {
4306
4330
  });
4307
4331
  }
4308
4332
  }
4333
+ const maskValue = (value) => findSecretInPath(value, config.secretRules)?.masked ?? value;
4334
+ const currentExcludes = config.excludePatterns.map(maskValue);
4335
+ const currentInclude = config.include.map(maskValue);
4309
4336
  const recorded = manifest.config;
4310
4337
  if (recorded && typeof recorded === "object") {
4311
4338
  if (recorded.maxPartBytes !== config.maxPartBytes) {
@@ -4334,15 +4361,15 @@ function validateSnapshot(configInput) {
4334
4361
  );
4335
4362
  }
4336
4363
  const recordedExcludes = Array.isArray(recorded.excludePatterns) ? recorded.excludePatterns : [];
4337
- if (recordedExcludes.join("\0") !== config.excludePatterns.join("\0")) {
4364
+ if (recordedExcludes.join("\0") !== currentExcludes.join("\0")) {
4338
4365
  drift.configMismatches.push(
4339
- `excludePatterns: manifest [${recordedExcludes.join(", ")}] vs current [${config.excludePatterns.join(", ")}]`
4366
+ `excludePatterns: manifest [${recordedExcludes.join(", ")}] vs current [${currentExcludes.join(", ")}]`
4340
4367
  );
4341
4368
  }
4342
4369
  const recordedInclude = Array.isArray(recorded.include) ? recorded.include : [];
4343
- if (recordedInclude.join("\0") !== config.include.join("\0")) {
4370
+ if (recordedInclude.join("\0") !== currentInclude.join("\0")) {
4344
4371
  drift.configMismatches.push(
4345
- `include: manifest [${recordedInclude.join(", ")}] vs current [${config.include.join(", ")}]`
4372
+ `include: manifest [${recordedInclude.join(", ")}] vs current [${currentInclude.join(", ")}]`
4346
4373
  );
4347
4374
  }
4348
4375
  if (recorded?.artifacts && typeof recorded.artifacts === "object") {
@@ -5437,7 +5464,7 @@ async function runInit(options) {
5437
5464
 
5438
5465
  // src/index.ts
5439
5466
  var GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
5440
- var GENERATOR_VERSION = "4.0.2";
5467
+ var GENERATOR_VERSION = "4.0.4";
5441
5468
  var SCHEMA_VERSION = "3.0.0";
5442
5469
  function sha256Hex2(input) {
5443
5470
  return crypto__namespace.createHash("sha256").update(input).digest("hex");
@@ -5644,6 +5671,18 @@ function resolveSafeOutputDirs(config) {
5644
5671
  var PLACEHOLDER_ENTRIES = /* @__PURE__ */ new Set([".gitkeep", ".gitignore", ".DS_Store"]);
5645
5672
  var RUN_DIR_PREFIX = "run-";
5646
5673
  var STALE_RUN_MS = 60 * 60 * 1e3;
5674
+ function maskSummaryStrings(value, secretRules) {
5675
+ if (typeof value === "string") return maskPathText(value, secretRules);
5676
+ if (Array.isArray(value)) return value.map((item) => maskSummaryStrings(item, secretRules));
5677
+ if (value && typeof value === "object") {
5678
+ const out = {};
5679
+ for (const [key, item] of Object.entries(value)) {
5680
+ out[key] = maskSummaryStrings(item, secretRules);
5681
+ }
5682
+ return out;
5683
+ }
5684
+ return value;
5685
+ }
5647
5686
  function maskPathText(value, secretRules) {
5648
5687
  return findSecretInPath(value, secretRules)?.masked ?? value;
5649
5688
  }
@@ -6224,8 +6263,8 @@ function generateSnapshot(configInput, options) {
6224
6263
  let summary;
6225
6264
  let summaryQuality;
6226
6265
  try {
6227
- const outcome = summarizeFile(relativePath, redacted);
6228
- summary = outcome?.summary;
6266
+ const outcome = summarizeFile(relativePath, rawContent);
6267
+ summary = outcome?.summary ? maskSummaryStrings(outcome.summary, config.secretRules) : void 0;
6229
6268
  summaryQuality = outcome?.quality;
6230
6269
  if (isSourceSummary(summary) && summary.parseErrors) {
6231
6270
  warnings.push(
package/dist/index.d.cts CHANGED
@@ -495,7 +495,7 @@ declare function matchesExclude(relativePath: string, pattern: string): boolean;
495
495
  declare function collectFiles(cwd: string, options?: CollectOptions): CollectResult;
496
496
 
497
497
  declare const GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
498
- declare const GENERATOR_VERSION = "4.0.2";
498
+ declare const GENERATOR_VERSION = "4.0.4";
499
499
  declare const SCHEMA_VERSION = "3.0.0";
500
500
  interface GenerateOptions {
501
501
  /** Compute the full manifest but write nothing to disk. */
package/dist/index.d.ts CHANGED
@@ -495,7 +495,7 @@ declare function matchesExclude(relativePath: string, pattern: string): boolean;
495
495
  declare function collectFiles(cwd: string, options?: CollectOptions): CollectResult;
496
496
 
497
497
  declare const GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
498
- declare const GENERATOR_VERSION = "4.0.2";
498
+ declare const GENERATOR_VERSION = "4.0.4";
499
499
  declare const SCHEMA_VERSION = "3.0.0";
500
500
  interface GenerateOptions {
501
501
  /** 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, fenceForText, 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-CY3XU5TS.js';
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, fenceForText, 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-CDZDVU74.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ankurhalder/codebase-snapshot",
3
- "version": "4.0.2",
3
+ "version": "4.0.4",
4
4
  "description": "Production-grade LLM codebase snapshot generator, auditor, and AST partitioner",
5
5
  "keywords": [
6
6
  "codebase",