@ankurhalder/codebase-snapshot 4.0.6 → 4.0.7

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
@@ -874,7 +874,7 @@ var DEFAULT_SECRET_PATTERNS = [
874
874
  },
875
875
  {
876
876
  rule: "aws-access-key-id",
877
- pattern: /(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA)[0-9A-Z]{16}/
877
+ pattern: /(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA|ABIA)[0-9A-Z]{16}/
878
878
  },
879
879
  {
880
880
  // The name is no longer limited to the three snake_case spellings: an
@@ -913,7 +913,7 @@ var DEFAULT_SECRET_PATTERNS = [
913
913
  // and batch tokens), `whsec_` (Stripe webhook secret), `dckr_pat_` (Docker
914
914
  // Hub), `hf_` (HuggingFace), `ya29.` (Google OAuth access token).
915
915
  rule: "known-vendor-token-prefix",
916
- pattern: /\b(?:glpat-[A-Za-z0-9_-]{20,64}|hvs\.[A-Za-z0-9_-]{20,128}|s\.[A-Za-z0-9]{20,64}|whsec_[A-Za-z0-9]{20,64}|dckr_pat_[A-Za-z0-9_-]{20,64}|hf_[A-Za-z0-9]{30,64}|ya29\.[A-Za-z0-9_-]{20,128})/
916
+ pattern: /\b(?:glpat-[A-Za-z0-9_-]{20,64}|glrt-[A-Za-z0-9_-]{20,64}|hvs\.[A-Za-z0-9_-]{20,128}|hvb\.[A-Za-z0-9_-]{20,128}|s\.[A-Za-z0-9]{20,64}|whsec_[A-Za-z0-9]{20,64}|dckr_pat_[A-Za-z0-9_-]{20,64}|hf_[A-Za-z0-9]{30,64}|ya29\.[A-Za-z0-9_-]{20,128}|sk_test_[A-Za-z0-9]{16,64}|1\/\/0[A-Za-z0-9_-]{20,64})/
917
917
  },
918
918
  {
919
919
  rule: "slack-webhook-url",
@@ -1945,6 +1945,7 @@ import * as fs4 from "fs";
1945
1945
  import { createHash } from "crypto";
1946
1946
  import * as path4 from "path";
1947
1947
  import { pathToFileURL } from "url";
1948
+ var CONFIG_DIR_SYMBOL = /* @__PURE__ */ Symbol.for("codebase-snapshot.configDir");
1948
1949
  var CONFIG_FILENAMES = [
1949
1950
  "snapshot.config.ts",
1950
1951
  "snapshot.config.js",
@@ -2483,7 +2484,8 @@ function resolveCandidateCwd(userConfig, cliOptions, baseDir) {
2483
2484
  return resolved;
2484
2485
  }
2485
2486
  function resolveConfig(userConfig, cliOptions, baseDir) {
2486
- const cwd = resolveCandidateCwd(userConfig ?? null, cliOptions, baseDir);
2487
+ const configDir = userConfig?.[CONFIG_DIR_SYMBOL];
2488
+ const cwd = resolveCandidateCwd(userConfig ?? null, cliOptions, baseDir ?? configDir);
2487
2489
  const forcedPreset = resolvePresetName(userConfig?.preset);
2488
2490
  if (forcedPreset !== void 0 && !getPreset(forcedPreset)) {
2489
2491
  throw new Error(unknownPresetMessage(forcedPreset));
@@ -2583,7 +2585,11 @@ function resolveConfig(userConfig, cliOptions, baseDir) {
2583
2585
  hooks: resolveHooks(userConfig?.hooks),
2584
2586
  layers,
2585
2587
  kinds,
2586
- excludePatterns: resolveExcludePatterns(userConfig?.excludePatterns),
2588
+ // `exclude` is the flag spelling of the same setting; writing it in a config used to
2589
+ // be ignored without a word.
2590
+ excludePatterns: resolveExcludePatterns(
2591
+ userConfig?.excludePatterns ?? userConfig?.exclude
2592
+ ),
2587
2593
  secretRules
2588
2594
  });
2589
2595
  }
@@ -3428,11 +3434,11 @@ function addScripts(cwd, notes) {
3428
3434
  const scripts = parsed.scripts && typeof parsed.scripts === "object" ? parsed.scripts : {};
3429
3435
  const added = [];
3430
3436
  if (!scripts.snapshot) {
3431
- scripts.snapshot = "codebase-snapshot generate";
3437
+ scripts.snapshot = "npx @ankurhalder/codebase-snapshot generate";
3432
3438
  added.push("snapshot");
3433
3439
  }
3434
3440
  if (!scripts["snapshot:validate"]) {
3435
- scripts["snapshot:validate"] = "codebase-snapshot validate";
3441
+ scripts["snapshot:validate"] = "npx @ankurhalder/codebase-snapshot validate";
3436
3442
  added.push("snapshot:validate");
3437
3443
  }
3438
3444
  if (added.length === 0) return [];
@@ -5505,7 +5511,7 @@ function validateSnapshot(configInput) {
5505
5511
 
5506
5512
  // src/index.ts
5507
5513
  var GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
5508
- var GENERATOR_VERSION = "4.0.6";
5514
+ var GENERATOR_VERSION = "4.0.7";
5509
5515
  var SCHEMA_VERSION = "3.0.0";
5510
5516
  function sha256Hex2(input) {
5511
5517
  return crypto3.createHash("sha256").update(input).digest("hex");
@@ -6366,7 +6372,9 @@ function generateSnapshot(configInput, options) {
6366
6372
  name: GENERATOR_NAME,
6367
6373
  version: GENERATOR_VERSION
6368
6374
  },
6369
- git: gitInfo,
6375
+ // A branch name is user input and can carry a token: it reaches the manifest,
6376
+ // the README and the audit report.
6377
+ git: { ...gitInfo, branch: maskPathText(gitInfo.branch, config.secretRules) },
6370
6378
  budgets: {
6371
6379
  maxPartBytes: config.maxPartBytes,
6372
6380
  largeFileBytes: config.largeFileBytes
@@ -7526,6 +7534,19 @@ function parseCliArgs(argv) {
7526
7534
  }
7527
7535
  command = resolved;
7528
7536
  }
7537
+ if (explicitMode !== void 0) {
7538
+ const resolvedMode = COMMAND_ALIASES.get(explicitMode);
7539
+ if (!resolvedMode) {
7540
+ throw new UsageError(
7541
+ `Unknown --mode "${explicitMode}". Expected one of: ${Array.from(COMMAND_ALIASES.keys()).join(", ")}.`
7542
+ );
7543
+ }
7544
+ if (firstPositional !== void 0 && resolvedMode !== command) {
7545
+ throw new UsageError(
7546
+ `--mode ${explicitMode} contradicts the command "${firstPositional}". Pass one or the other.`
7547
+ );
7548
+ }
7549
+ }
7529
7550
  const expectedArgs = COMMAND_ARITY[command];
7530
7551
  if (args.length !== expectedArgs) {
7531
7552
  if (command === "explain") {
@@ -7544,6 +7565,7 @@ function parseCliArgs(argv) {
7544
7565
  if (rawFormat !== "text" && rawFormat !== "json") {
7545
7566
  throw new UsageError(`--format must be "text" or "json", received "${rawFormat}".`);
7546
7567
  }
7568
+ let onlyNamesMonolith = false;
7547
7569
  const rawSkip = values["skip-artifacts"];
7548
7570
  const rawOnly = values["only-artifacts"];
7549
7571
  if (rawSkip !== void 0 && rawOnly !== void 0) {
@@ -7552,6 +7574,7 @@ function parseCliArgs(argv) {
7552
7574
  let skipArtifacts;
7553
7575
  if (rawOnly !== void 0) {
7554
7576
  const keep = parseArtifactList(String(rawOnly), "--only-artifacts");
7577
+ onlyNamesMonolith = keep.includes("monolith");
7555
7578
  skipArtifacts = ARTIFACT_NAMES.filter(
7556
7579
  (name) => !keep.includes(name)
7557
7580
  );
@@ -7606,7 +7629,7 @@ function parseCliArgs(argv) {
7606
7629
  target: values.target === void 0 ? void 0 : String(values.target),
7607
7630
  cwd: values.cwd === void 0 ? process.cwd() : path12.resolve(String(values.cwd)),
7608
7631
  outDir: values["out-dir"] === void 0 ? void 0 : String(values["out-dir"]),
7609
- includeMonolith: values["include-monolith"] === true ? true : void 0,
7632
+ includeMonolith: values["include-monolith"] === true || onlyNamesMonolith === true ? true : void 0,
7610
7633
  includeSensitiveFiles: values["include-sensitive-files"] === true ? true : void 0,
7611
7634
  maxPartBytes: parseByteOption(
7612
7635
  values["max-part-bytes"],
@@ -1729,7 +1729,7 @@ var DEFAULT_SECRET_PATTERNS = [
1729
1729
  },
1730
1730
  {
1731
1731
  rule: "aws-access-key-id",
1732
- pattern: /(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA)[0-9A-Z]{16}/
1732
+ pattern: /(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA|ABIA)[0-9A-Z]{16}/
1733
1733
  },
1734
1734
  {
1735
1735
  // The name is no longer limited to the three snake_case spellings: an
@@ -1768,7 +1768,7 @@ var DEFAULT_SECRET_PATTERNS = [
1768
1768
  // and batch tokens), `whsec_` (Stripe webhook secret), `dckr_pat_` (Docker
1769
1769
  // Hub), `hf_` (HuggingFace), `ya29.` (Google OAuth access token).
1770
1770
  rule: "known-vendor-token-prefix",
1771
- pattern: /\b(?:glpat-[A-Za-z0-9_-]{20,64}|hvs\.[A-Za-z0-9_-]{20,128}|s\.[A-Za-z0-9]{20,64}|whsec_[A-Za-z0-9]{20,64}|dckr_pat_[A-Za-z0-9_-]{20,64}|hf_[A-Za-z0-9]{30,64}|ya29\.[A-Za-z0-9_-]{20,128})/
1771
+ pattern: /\b(?:glpat-[A-Za-z0-9_-]{20,64}|glrt-[A-Za-z0-9_-]{20,64}|hvs\.[A-Za-z0-9_-]{20,128}|hvb\.[A-Za-z0-9_-]{20,128}|s\.[A-Za-z0-9]{20,64}|whsec_[A-Za-z0-9]{20,64}|dckr_pat_[A-Za-z0-9_-]{20,64}|hf_[A-Za-z0-9]{30,64}|ya29\.[A-Za-z0-9_-]{20,128}|sk_test_[A-Za-z0-9]{16,64}|1\/\/0[A-Za-z0-9_-]{20,64})/
1772
1772
  },
1773
1773
  {
1774
1774
  rule: "slack-webhook-url",
@@ -2665,6 +2665,7 @@ function walkDirectory(dir, baseDir, rootReal, visited, isRoot = false) {
2665
2665
  }
2666
2666
 
2667
2667
  // src/config.ts
2668
+ var CONFIG_DIR_SYMBOL = /* @__PURE__ */ Symbol.for("codebase-snapshot.configDir");
2668
2669
  var CONFIG_FILENAMES = [
2669
2670
  "snapshot.config.ts",
2670
2671
  "snapshot.config.js",
@@ -2925,6 +2926,13 @@ async function loadConfigFileDetailed(cwd) {
2925
2926
  }
2926
2927
  async function loadConfigFile(cwd) {
2927
2928
  const loaded = await loadConfigFileDetailed(cwd);
2929
+ if (loaded.config && loaded.file && typeof loaded.config === "object") {
2930
+ Object.defineProperty(loaded.config, CONFIG_DIR_SYMBOL, {
2931
+ value: path10.dirname(loaded.file),
2932
+ enumerable: false,
2933
+ configurable: true
2934
+ });
2935
+ }
2928
2936
  if (loaded.errors.length > 0) {
2929
2937
  throw new Error(`The config file could not be read: ${loaded.errors.join("; ")}`);
2930
2938
  }
@@ -3210,7 +3218,8 @@ function resolveCandidateCwd(userConfig, cliOptions, baseDir) {
3210
3218
  return resolved;
3211
3219
  }
3212
3220
  function resolveConfig(userConfig, cliOptions, baseDir) {
3213
- const cwd = resolveCandidateCwd(userConfig ?? null, cliOptions, baseDir);
3221
+ const configDir = userConfig?.[CONFIG_DIR_SYMBOL];
3222
+ const cwd = resolveCandidateCwd(userConfig ?? null, cliOptions, baseDir ?? configDir);
3214
3223
  const forcedPreset = resolvePresetName(userConfig?.preset);
3215
3224
  if (forcedPreset !== void 0 && !getPreset(forcedPreset)) {
3216
3225
  throw new Error(unknownPresetMessage(forcedPreset));
@@ -3310,7 +3319,11 @@ function resolveConfig(userConfig, cliOptions, baseDir) {
3310
3319
  hooks: resolveHooks(userConfig?.hooks),
3311
3320
  layers,
3312
3321
  kinds,
3313
- excludePatterns: resolveExcludePatterns(userConfig?.excludePatterns),
3322
+ // `exclude` is the flag spelling of the same setting; writing it in a config used to
3323
+ // be ignored without a word.
3324
+ excludePatterns: resolveExcludePatterns(
3325
+ userConfig?.excludePatterns ?? userConfig?.exclude
3326
+ ),
3314
3327
  secretRules
3315
3328
  });
3316
3329
  }
@@ -5268,11 +5281,11 @@ function addScripts(cwd, notes) {
5268
5281
  const scripts = parsed.scripts && typeof parsed.scripts === "object" ? parsed.scripts : {};
5269
5282
  const added = [];
5270
5283
  if (!scripts.snapshot) {
5271
- scripts.snapshot = "codebase-snapshot generate";
5284
+ scripts.snapshot = "npx @ankurhalder/codebase-snapshot generate";
5272
5285
  added.push("snapshot");
5273
5286
  }
5274
5287
  if (!scripts["snapshot:validate"]) {
5275
- scripts["snapshot:validate"] = "codebase-snapshot validate";
5288
+ scripts["snapshot:validate"] = "npx @ankurhalder/codebase-snapshot validate";
5276
5289
  added.push("snapshot:validate");
5277
5290
  }
5278
5291
  if (added.length === 0) return [];
@@ -5468,7 +5481,7 @@ async function runInit(options) {
5468
5481
 
5469
5482
  // src/index.ts
5470
5483
  var GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
5471
- var GENERATOR_VERSION = "4.0.6";
5484
+ var GENERATOR_VERSION = "4.0.7";
5472
5485
  var SCHEMA_VERSION = "3.0.0";
5473
5486
  function sha256Hex2(input) {
5474
5487
  return crypto.createHash("sha256").update(input).digest("hex");
@@ -6329,7 +6342,9 @@ function generateSnapshot(configInput, options) {
6329
6342
  name: GENERATOR_NAME,
6330
6343
  version: GENERATOR_VERSION
6331
6344
  },
6332
- git: gitInfo,
6345
+ // A branch name is user input and can carry a token: it reaches the manifest,
6346
+ // the README and the audit report.
6347
+ git: { ...gitInfo, branch: maskPathText(gitInfo.branch, config.secretRules) },
6333
6348
  budgets: {
6334
6349
  maxPartBytes: config.maxPartBytes,
6335
6350
  largeFileBytes: config.largeFileBytes
@@ -6534,5 +6549,5 @@ async function generateSnapshotAsync(configInput, options) {
6534
6549
  }
6535
6550
 
6536
6551
  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 };
6537
- //# sourceMappingURL=chunk-GAY7W5MK.js.map
6538
- //# sourceMappingURL=chunk-GAY7W5MK.js.map
6552
+ //# sourceMappingURL=chunk-VRJTXNJV.js.map
6553
+ //# sourceMappingURL=chunk-VRJTXNJV.js.map
package/dist/cli.cjs CHANGED
@@ -896,7 +896,7 @@ var DEFAULT_SECRET_PATTERNS = [
896
896
  },
897
897
  {
898
898
  rule: "aws-access-key-id",
899
- pattern: /(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA)[0-9A-Z]{16}/
899
+ pattern: /(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA|ABIA)[0-9A-Z]{16}/
900
900
  },
901
901
  {
902
902
  // The name is no longer limited to the three snake_case spellings: an
@@ -935,7 +935,7 @@ var DEFAULT_SECRET_PATTERNS = [
935
935
  // and batch tokens), `whsec_` (Stripe webhook secret), `dckr_pat_` (Docker
936
936
  // Hub), `hf_` (HuggingFace), `ya29.` (Google OAuth access token).
937
937
  rule: "known-vendor-token-prefix",
938
- pattern: /\b(?:glpat-[A-Za-z0-9_-]{20,64}|hvs\.[A-Za-z0-9_-]{20,128}|s\.[A-Za-z0-9]{20,64}|whsec_[A-Za-z0-9]{20,64}|dckr_pat_[A-Za-z0-9_-]{20,64}|hf_[A-Za-z0-9]{30,64}|ya29\.[A-Za-z0-9_-]{20,128})/
938
+ pattern: /\b(?:glpat-[A-Za-z0-9_-]{20,64}|glrt-[A-Za-z0-9_-]{20,64}|hvs\.[A-Za-z0-9_-]{20,128}|hvb\.[A-Za-z0-9_-]{20,128}|s\.[A-Za-z0-9]{20,64}|whsec_[A-Za-z0-9]{20,64}|dckr_pat_[A-Za-z0-9_-]{20,64}|hf_[A-Za-z0-9]{30,64}|ya29\.[A-Za-z0-9_-]{20,128}|sk_test_[A-Za-z0-9]{16,64}|1\/\/0[A-Za-z0-9_-]{20,64})/
939
939
  },
940
940
  {
941
941
  rule: "slack-webhook-url",
@@ -1957,6 +1957,7 @@ function renderDiffText(diff) {
1957
1957
  section("changed:", diff.changed);
1958
1958
  return lines.join("\n");
1959
1959
  }
1960
+ var CONFIG_DIR_SYMBOL = /* @__PURE__ */ Symbol.for("codebase-snapshot.configDir");
1960
1961
  var CONFIG_FILENAMES = [
1961
1962
  "snapshot.config.ts",
1962
1963
  "snapshot.config.js",
@@ -2495,7 +2496,8 @@ function resolveCandidateCwd(userConfig, cliOptions, baseDir) {
2495
2496
  return resolved;
2496
2497
  }
2497
2498
  function resolveConfig(userConfig, cliOptions, baseDir) {
2498
- const cwd = resolveCandidateCwd(userConfig ?? null, cliOptions, baseDir);
2499
+ const configDir = userConfig?.[CONFIG_DIR_SYMBOL];
2500
+ const cwd = resolveCandidateCwd(userConfig ?? null, cliOptions, baseDir ?? configDir);
2499
2501
  const forcedPreset = resolvePresetName(userConfig?.preset);
2500
2502
  if (forcedPreset !== void 0 && !getPreset(forcedPreset)) {
2501
2503
  throw new Error(unknownPresetMessage(forcedPreset));
@@ -2595,7 +2597,11 @@ function resolveConfig(userConfig, cliOptions, baseDir) {
2595
2597
  hooks: resolveHooks(userConfig?.hooks),
2596
2598
  layers,
2597
2599
  kinds,
2598
- excludePatterns: resolveExcludePatterns(userConfig?.excludePatterns),
2600
+ // `exclude` is the flag spelling of the same setting; writing it in a config used to
2601
+ // be ignored without a word.
2602
+ excludePatterns: resolveExcludePatterns(
2603
+ userConfig?.excludePatterns ?? userConfig?.exclude
2604
+ ),
2599
2605
  secretRules
2600
2606
  });
2601
2607
  }
@@ -3424,11 +3430,11 @@ function addScripts(cwd, notes) {
3424
3430
  const scripts = parsed.scripts && typeof parsed.scripts === "object" ? parsed.scripts : {};
3425
3431
  const added = [];
3426
3432
  if (!scripts.snapshot) {
3427
- scripts.snapshot = "codebase-snapshot generate";
3433
+ scripts.snapshot = "npx @ankurhalder/codebase-snapshot generate";
3428
3434
  added.push("snapshot");
3429
3435
  }
3430
3436
  if (!scripts["snapshot:validate"]) {
3431
- scripts["snapshot:validate"] = "codebase-snapshot validate";
3437
+ scripts["snapshot:validate"] = "npx @ankurhalder/codebase-snapshot validate";
3432
3438
  added.push("snapshot:validate");
3433
3439
  }
3434
3440
  if (added.length === 0) return [];
@@ -5484,7 +5490,7 @@ function validateSnapshot(configInput) {
5484
5490
 
5485
5491
  // src/index.ts
5486
5492
  var GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
5487
- var GENERATOR_VERSION = "4.0.6";
5493
+ var GENERATOR_VERSION = "4.0.7";
5488
5494
  var SCHEMA_VERSION = "3.0.0";
5489
5495
  function sha256Hex2(input) {
5490
5496
  return crypto__namespace.createHash("sha256").update(input).digest("hex");
@@ -6345,7 +6351,9 @@ function generateSnapshot(configInput, options) {
6345
6351
  name: GENERATOR_NAME,
6346
6352
  version: GENERATOR_VERSION
6347
6353
  },
6348
- git: gitInfo,
6354
+ // A branch name is user input and can carry a token: it reaches the manifest,
6355
+ // the README and the audit report.
6356
+ git: { ...gitInfo, branch: maskPathText(gitInfo.branch, config.secretRules) },
6349
6357
  budgets: {
6350
6358
  maxPartBytes: config.maxPartBytes,
6351
6359
  largeFileBytes: config.largeFileBytes
@@ -7513,6 +7521,19 @@ function parseCliArgs(argv) {
7513
7521
  }
7514
7522
  command = resolved;
7515
7523
  }
7524
+ if (explicitMode !== void 0) {
7525
+ const resolvedMode = COMMAND_ALIASES.get(explicitMode);
7526
+ if (!resolvedMode) {
7527
+ throw new UsageError(
7528
+ `Unknown --mode "${explicitMode}". Expected one of: ${Array.from(COMMAND_ALIASES.keys()).join(", ")}.`
7529
+ );
7530
+ }
7531
+ if (firstPositional !== void 0 && resolvedMode !== command) {
7532
+ throw new UsageError(
7533
+ `--mode ${explicitMode} contradicts the command "${firstPositional}". Pass one or the other.`
7534
+ );
7535
+ }
7536
+ }
7516
7537
  const expectedArgs = COMMAND_ARITY[command];
7517
7538
  if (args.length !== expectedArgs) {
7518
7539
  if (command === "explain") {
@@ -7531,6 +7552,7 @@ function parseCliArgs(argv) {
7531
7552
  if (rawFormat !== "text" && rawFormat !== "json") {
7532
7553
  throw new UsageError(`--format must be "text" or "json", received "${rawFormat}".`);
7533
7554
  }
7555
+ let onlyNamesMonolith = false;
7534
7556
  const rawSkip = values["skip-artifacts"];
7535
7557
  const rawOnly = values["only-artifacts"];
7536
7558
  if (rawSkip !== void 0 && rawOnly !== void 0) {
@@ -7539,6 +7561,7 @@ function parseCliArgs(argv) {
7539
7561
  let skipArtifacts;
7540
7562
  if (rawOnly !== void 0) {
7541
7563
  const keep = parseArtifactList(String(rawOnly), "--only-artifacts");
7564
+ onlyNamesMonolith = keep.includes("monolith");
7542
7565
  skipArtifacts = ARTIFACT_NAMES.filter(
7543
7566
  (name) => !keep.includes(name)
7544
7567
  );
@@ -7593,7 +7616,7 @@ function parseCliArgs(argv) {
7593
7616
  target: values.target === void 0 ? void 0 : String(values.target),
7594
7617
  cwd: values.cwd === void 0 ? process.cwd() : path10__namespace.resolve(String(values.cwd)),
7595
7618
  outDir: values["out-dir"] === void 0 ? void 0 : String(values["out-dir"]),
7596
- includeMonolith: values["include-monolith"] === true ? true : void 0,
7619
+ includeMonolith: values["include-monolith"] === true || onlyNamesMonolith === true ? true : void 0,
7597
7620
  includeSensitiveFiles: values["include-sensitive-files"] === true ? true : void 0,
7598
7621
  maxPartBytes: parseByteOption(
7599
7622
  values["max-part-bytes"],
package/dist/cli.js CHANGED
@@ -1,4 +1,4 @@
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-GAY7W5MK.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-VRJTXNJV.js';
2
2
  import * as fs from 'fs';
3
3
  import * as path2 from 'path';
4
4
  import { parseArgs } from 'util';
@@ -970,6 +970,19 @@ function parseCliArgs(argv) {
970
970
  }
971
971
  command = resolved;
972
972
  }
973
+ if (explicitMode !== void 0) {
974
+ const resolvedMode = COMMAND_ALIASES.get(explicitMode);
975
+ if (!resolvedMode) {
976
+ throw new UsageError(
977
+ `Unknown --mode "${explicitMode}". Expected one of: ${Array.from(COMMAND_ALIASES.keys()).join(", ")}.`
978
+ );
979
+ }
980
+ if (firstPositional !== void 0 && resolvedMode !== command) {
981
+ throw new UsageError(
982
+ `--mode ${explicitMode} contradicts the command "${firstPositional}". Pass one or the other.`
983
+ );
984
+ }
985
+ }
973
986
  const expectedArgs = COMMAND_ARITY[command];
974
987
  if (args.length !== expectedArgs) {
975
988
  if (command === "explain") {
@@ -988,6 +1001,7 @@ function parseCliArgs(argv) {
988
1001
  if (rawFormat !== "text" && rawFormat !== "json") {
989
1002
  throw new UsageError(`--format must be "text" or "json", received "${rawFormat}".`);
990
1003
  }
1004
+ let onlyNamesMonolith = false;
991
1005
  const rawSkip = values["skip-artifacts"];
992
1006
  const rawOnly = values["only-artifacts"];
993
1007
  if (rawSkip !== void 0 && rawOnly !== void 0) {
@@ -996,6 +1010,7 @@ function parseCliArgs(argv) {
996
1010
  let skipArtifacts;
997
1011
  if (rawOnly !== void 0) {
998
1012
  const keep = parseArtifactList(String(rawOnly), "--only-artifacts");
1013
+ onlyNamesMonolith = keep.includes("monolith");
999
1014
  skipArtifacts = ARTIFACT_NAMES.filter(
1000
1015
  (name) => !keep.includes(name)
1001
1016
  );
@@ -1050,7 +1065,7 @@ function parseCliArgs(argv) {
1050
1065
  target: values.target === void 0 ? void 0 : String(values.target),
1051
1066
  cwd: values.cwd === void 0 ? process.cwd() : path2.resolve(String(values.cwd)),
1052
1067
  outDir: values["out-dir"] === void 0 ? void 0 : String(values["out-dir"]),
1053
- includeMonolith: values["include-monolith"] === true ? true : void 0,
1068
+ includeMonolith: values["include-monolith"] === true || onlyNamesMonolith === true ? true : void 0,
1054
1069
  includeSensitiveFiles: values["include-sensitive-files"] === true ? true : void 0,
1055
1070
  maxPartBytes: parseByteOption(
1056
1071
  values["max-part-bytes"],
package/dist/index.cjs CHANGED
@@ -1758,7 +1758,7 @@ var DEFAULT_SECRET_PATTERNS = [
1758
1758
  },
1759
1759
  {
1760
1760
  rule: "aws-access-key-id",
1761
- pattern: /(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA)[0-9A-Z]{16}/
1761
+ pattern: /(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA|ABIA)[0-9A-Z]{16}/
1762
1762
  },
1763
1763
  {
1764
1764
  // The name is no longer limited to the three snake_case spellings: an
@@ -1797,7 +1797,7 @@ var DEFAULT_SECRET_PATTERNS = [
1797
1797
  // and batch tokens), `whsec_` (Stripe webhook secret), `dckr_pat_` (Docker
1798
1798
  // Hub), `hf_` (HuggingFace), `ya29.` (Google OAuth access token).
1799
1799
  rule: "known-vendor-token-prefix",
1800
- pattern: /\b(?:glpat-[A-Za-z0-9_-]{20,64}|hvs\.[A-Za-z0-9_-]{20,128}|s\.[A-Za-z0-9]{20,64}|whsec_[A-Za-z0-9]{20,64}|dckr_pat_[A-Za-z0-9_-]{20,64}|hf_[A-Za-z0-9]{30,64}|ya29\.[A-Za-z0-9_-]{20,128})/
1800
+ pattern: /\b(?:glpat-[A-Za-z0-9_-]{20,64}|glrt-[A-Za-z0-9_-]{20,64}|hvs\.[A-Za-z0-9_-]{20,128}|hvb\.[A-Za-z0-9_-]{20,128}|s\.[A-Za-z0-9]{20,64}|whsec_[A-Za-z0-9]{20,64}|dckr_pat_[A-Za-z0-9_-]{20,64}|hf_[A-Za-z0-9]{30,64}|ya29\.[A-Za-z0-9_-]{20,128}|sk_test_[A-Za-z0-9]{16,64}|1\/\/0[A-Za-z0-9_-]{20,64})/
1801
1801
  },
1802
1802
  {
1803
1803
  rule: "slack-webhook-url",
@@ -2694,6 +2694,7 @@ function walkDirectory(dir, baseDir, rootReal, visited, isRoot = false) {
2694
2694
  }
2695
2695
 
2696
2696
  // src/config.ts
2697
+ var CONFIG_DIR_SYMBOL = /* @__PURE__ */ Symbol.for("codebase-snapshot.configDir");
2697
2698
  var CONFIG_FILENAMES = [
2698
2699
  "snapshot.config.ts",
2699
2700
  "snapshot.config.js",
@@ -2954,6 +2955,13 @@ async function loadConfigFileDetailed(cwd) {
2954
2955
  }
2955
2956
  async function loadConfigFile(cwd) {
2956
2957
  const loaded = await loadConfigFileDetailed(cwd);
2958
+ if (loaded.config && loaded.file && typeof loaded.config === "object") {
2959
+ Object.defineProperty(loaded.config, CONFIG_DIR_SYMBOL, {
2960
+ value: path10__namespace.dirname(loaded.file),
2961
+ enumerable: false,
2962
+ configurable: true
2963
+ });
2964
+ }
2957
2965
  if (loaded.errors.length > 0) {
2958
2966
  throw new Error(`The config file could not be read: ${loaded.errors.join("; ")}`);
2959
2967
  }
@@ -3239,7 +3247,8 @@ function resolveCandidateCwd(userConfig, cliOptions, baseDir) {
3239
3247
  return resolved;
3240
3248
  }
3241
3249
  function resolveConfig(userConfig, cliOptions, baseDir) {
3242
- const cwd = resolveCandidateCwd(userConfig ?? null, cliOptions, baseDir);
3250
+ const configDir = userConfig?.[CONFIG_DIR_SYMBOL];
3251
+ const cwd = resolveCandidateCwd(userConfig ?? null, cliOptions, baseDir ?? configDir);
3243
3252
  const forcedPreset = resolvePresetName(userConfig?.preset);
3244
3253
  if (forcedPreset !== void 0 && !getPreset(forcedPreset)) {
3245
3254
  throw new Error(unknownPresetMessage(forcedPreset));
@@ -3339,7 +3348,11 @@ function resolveConfig(userConfig, cliOptions, baseDir) {
3339
3348
  hooks: resolveHooks(userConfig?.hooks),
3340
3349
  layers,
3341
3350
  kinds,
3342
- excludePatterns: resolveExcludePatterns(userConfig?.excludePatterns),
3351
+ // `exclude` is the flag spelling of the same setting; writing it in a config used to
3352
+ // be ignored without a word.
3353
+ excludePatterns: resolveExcludePatterns(
3354
+ userConfig?.excludePatterns ?? userConfig?.exclude
3355
+ ),
3343
3356
  secretRules
3344
3357
  });
3345
3358
  }
@@ -5297,11 +5310,11 @@ function addScripts(cwd, notes) {
5297
5310
  const scripts = parsed.scripts && typeof parsed.scripts === "object" ? parsed.scripts : {};
5298
5311
  const added = [];
5299
5312
  if (!scripts.snapshot) {
5300
- scripts.snapshot = "codebase-snapshot generate";
5313
+ scripts.snapshot = "npx @ankurhalder/codebase-snapshot generate";
5301
5314
  added.push("snapshot");
5302
5315
  }
5303
5316
  if (!scripts["snapshot:validate"]) {
5304
- scripts["snapshot:validate"] = "codebase-snapshot validate";
5317
+ scripts["snapshot:validate"] = "npx @ankurhalder/codebase-snapshot validate";
5305
5318
  added.push("snapshot:validate");
5306
5319
  }
5307
5320
  if (added.length === 0) return [];
@@ -5497,7 +5510,7 @@ async function runInit(options) {
5497
5510
 
5498
5511
  // src/index.ts
5499
5512
  var GENERATOR_NAME = "@ankurhalder/codebase-snapshot";
5500
- var GENERATOR_VERSION = "4.0.6";
5513
+ var GENERATOR_VERSION = "4.0.7";
5501
5514
  var SCHEMA_VERSION = "3.0.0";
5502
5515
  function sha256Hex2(input) {
5503
5516
  return crypto__namespace.createHash("sha256").update(input).digest("hex");
@@ -6358,7 +6371,9 @@ function generateSnapshot(configInput, options) {
6358
6371
  name: GENERATOR_NAME,
6359
6372
  version: GENERATOR_VERSION
6360
6373
  },
6361
- git: gitInfo,
6374
+ // A branch name is user input and can carry a token: it reaches the manifest,
6375
+ // the README and the audit report.
6376
+ git: { ...gitInfo, branch: maskPathText(gitInfo.branch, config.secretRules) },
6362
6377
  budgets: {
6363
6378
  maxPartBytes: config.maxPartBytes,
6364
6379
  largeFileBytes: config.largeFileBytes
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.6";
498
+ declare const GENERATOR_VERSION = "4.0.7";
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.6";
498
+ declare const GENERATOR_VERSION = "4.0.7";
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-GAY7W5MK.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-VRJTXNJV.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.6",
3
+ "version": "4.0.7",
4
4
  "description": "Production-grade LLM codebase snapshot generator, auditor, and AST partitioner",
5
5
  "keywords": [
6
6
  "codebase",