codebase-snapshot 0.9.5 → 0.9.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/cli.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var childProcess = require('child_process');
4
- var fs11 = require('fs');
5
- var path12 = require('path');
4
+ var fs12 = require('fs');
5
+ var path13 = require('path');
6
6
  var util = require('util');
7
7
  var crypto2 = require('crypto');
8
8
  var module$1 = require('module');
@@ -11,6 +11,7 @@ var readline = require('readline');
11
11
  var async_hooks = require('async_hooks');
12
12
  var os = require('os');
13
13
  var ts = require('typescript');
14
+ var https = require('https');
14
15
 
15
16
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
16
17
 
@@ -33,12 +34,13 @@ function _interopNamespace(e) {
33
34
  }
34
35
 
35
36
  var childProcess__namespace = /*#__PURE__*/_interopNamespace(childProcess);
36
- var fs11__namespace = /*#__PURE__*/_interopNamespace(fs11);
37
- var path12__namespace = /*#__PURE__*/_interopNamespace(path12);
37
+ var fs12__namespace = /*#__PURE__*/_interopNamespace(fs12);
38
+ var path13__namespace = /*#__PURE__*/_interopNamespace(path13);
38
39
  var crypto2__namespace = /*#__PURE__*/_interopNamespace(crypto2);
39
40
  var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
40
41
  var os__namespace = /*#__PURE__*/_interopNamespace(os);
41
42
  var ts__default = /*#__PURE__*/_interopDefault(ts);
43
+ var https__namespace = /*#__PURE__*/_interopNamespace(https);
42
44
 
43
45
  // src/cli.ts
44
46
  var MANIFEST_FILES = [
@@ -87,15 +89,15 @@ var SKIPPED_WALK_DIRS = /* @__PURE__ */ new Set([
87
89
  ]);
88
90
  function readSmallFile(fullPath) {
89
91
  try {
90
- const stats = fs11__namespace.statSync(fullPath);
92
+ const stats = fs12__namespace.statSync(fullPath);
91
93
  if (!stats.isFile() || stats.size > MANIFEST_MAX_BYTES) return null;
92
- return fs11__namespace.readFileSync(fullPath, "utf8");
94
+ return fs12__namespace.readFileSync(fullPath, "utf8");
93
95
  } catch {
94
96
  return null;
95
97
  }
96
98
  }
97
99
  function readManifest(cwd, name) {
98
- return readSmallFile(path12__namespace.join(cwd, name));
100
+ return readSmallFile(path13__namespace.join(cwd, name));
99
101
  }
100
102
  function dependenciesFromPackageJson(raw) {
101
103
  const names = /* @__PURE__ */ new Set();
@@ -155,7 +157,7 @@ function pnpmWorkspacePatterns(raw) {
155
157
  function childDirectories(cwd, parent) {
156
158
  let entries;
157
159
  try {
158
- entries = fs11__namespace.readdirSync(path12__namespace.join(cwd, parent), { withFileTypes: true });
160
+ entries = fs12__namespace.readdirSync(path13__namespace.join(cwd, parent), { withFileTypes: true });
159
161
  } catch {
160
162
  return [];
161
163
  }
@@ -191,12 +193,12 @@ function scanWorkspacePackages(cwd, patterns) {
191
193
  const files = /* @__PURE__ */ new Set();
192
194
  const dependencies = /* @__PURE__ */ new Set();
193
195
  for (const relative11 of workspacePackageDirs(cwd, patterns)) {
194
- const full = path12__namespace.join(cwd, relative11);
196
+ const full = path13__namespace.join(cwd, relative11);
195
197
  try {
196
- for (const entry of fs11__namespace.readdirSync(full, { withFileTypes: true })) files.add(entry.name);
198
+ for (const entry of fs12__namespace.readdirSync(full, { withFileTypes: true })) files.add(entry.name);
197
199
  } catch {
198
200
  }
199
- const raw = readSmallFile(path12__namespace.join(full, "package.json"));
201
+ const raw = readSmallFile(path13__namespace.join(full, "package.json"));
200
202
  if (raw !== null) {
201
203
  for (const name of dependenciesFromPackageJson(raw)) dependencies.add(name);
202
204
  }
@@ -213,7 +215,7 @@ function countMarkdownFiles(cwd) {
213
215
  directoriesSeen += 1;
214
216
  let entries;
215
217
  try {
216
- entries = fs11__namespace.readdirSync(current.dir, { withFileTypes: true });
218
+ entries = fs12__namespace.readdirSync(current.dir, { withFileTypes: true });
217
219
  } catch {
218
220
  continue;
219
221
  }
@@ -224,7 +226,7 @@ function countMarkdownFiles(cwd) {
224
226
  }
225
227
  if (!entry.isDirectory() || current.depth >= 2) continue;
226
228
  if (entry.name.startsWith(".") || SKIPPED_WALK_DIRS.has(entry.name)) continue;
227
- queue.push({ dir: path12__namespace.join(current.dir, entry.name), depth: current.depth + 1 });
229
+ queue.push({ dir: path13__namespace.join(current.dir, entry.name), depth: current.depth + 1 });
228
230
  }
229
231
  }
230
232
  return count;
@@ -233,7 +235,7 @@ function buildPresetContext(cwd) {
233
235
  const files = /* @__PURE__ */ new Set();
234
236
  const dirs = /* @__PURE__ */ new Set();
235
237
  try {
236
- for (const entry of fs11__namespace.readdirSync(cwd, { withFileTypes: true })) {
238
+ for (const entry of fs12__namespace.readdirSync(cwd, { withFileTypes: true })) {
237
239
  if (entry.isDirectory()) dirs.add(entry.name);
238
240
  else if (entry.isFile()) files.add(entry.name);
239
241
  }
@@ -250,7 +252,7 @@ function buildPresetContext(cwd) {
250
252
  const isWorkspace = files.has("pnpm-workspace.yaml") || files.has("nx.json") || files.has("turbo.json") || files.has("lerna.json") || packageJson !== void 0 && packageJson.includes('"workspaces"') || declaredWorkspaces.length > 0;
251
253
  let workspace = { files: /* @__PURE__ */ new Set(), dependencies: /* @__PURE__ */ new Set() };
252
254
  if (isWorkspace) {
253
- const pnpmRaw = files.has("pnpm-workspace.yaml") ? readSmallFile(path12__namespace.join(cwd, "pnpm-workspace.yaml")) : null;
255
+ const pnpmRaw = files.has("pnpm-workspace.yaml") ? readSmallFile(path13__namespace.join(cwd, "pnpm-workspace.yaml")) : null;
254
256
  const declared = pnpmRaw === null ? [] : pnpmWorkspacePatterns(pnpmRaw);
255
257
  const patterns = declared.length > 0 ? declared : declaredWorkspaces.length > 0 ? declaredWorkspaces : DEFAULT_WORKSPACE_PATTERNS;
256
258
  workspace = scanWorkspacePackages(cwd, patterns);
@@ -1525,14 +1527,14 @@ var PRESET_IGNORES = new Set(
1525
1527
  );
1526
1528
  function readLinkTarget(linkPath, fallback) {
1527
1529
  try {
1528
- return fs11__namespace.readlinkSync(linkPath);
1530
+ return fs12__namespace.readlinkSync(linkPath);
1529
1531
  } catch {
1530
1532
  return fallback;
1531
1533
  }
1532
1534
  }
1533
1535
  function isInside(root, candidate) {
1534
- const relative11 = path12__namespace.relative(root, candidate);
1535
- return relative11 === "" || !relative11.startsWith(`..${path12__namespace.sep}`) && relative11 !== ".." && !path12__namespace.isAbsolute(relative11);
1536
+ const relative11 = path13__namespace.relative(root, candidate);
1537
+ return relative11 === "" || !relative11.startsWith(`..${path13__namespace.sep}`) && relative11 !== ".." && !path13__namespace.isAbsolute(relative11);
1536
1538
  }
1537
1539
  function getGitInfo(cwd, fallbackBranch = "main") {
1538
1540
  try {
@@ -1737,10 +1739,10 @@ function trimUnescapedTrailingSpaces(line) {
1737
1739
  return line.slice(0, end);
1738
1740
  }
1739
1741
  function readGitignoreRules(dir) {
1740
- const gitignorePath2 = path12__namespace.join(dir, ".gitignore");
1742
+ const gitignorePath2 = path13__namespace.join(dir, ".gitignore");
1741
1743
  let raw;
1742
1744
  try {
1743
- raw = fs11__namespace.readFileSync(gitignorePath2, "utf8");
1745
+ raw = fs12__namespace.readFileSync(gitignorePath2, "utf8");
1744
1746
  } catch {
1745
1747
  return [];
1746
1748
  }
@@ -1867,7 +1869,7 @@ function isToolOwnedDirName(name) {
1867
1869
  }
1868
1870
  function hasSnapshotMarker(target) {
1869
1871
  try {
1870
- return fs11__namespace.statSync(target).isDirectory() && fs11__namespace.existsSync(path12__namespace.join(target, ".codebase-snapshot"));
1872
+ return fs12__namespace.statSync(target).isDirectory() && fs12__namespace.existsSync(path13__namespace.join(target, ".codebase-snapshot"));
1871
1873
  } catch {
1872
1874
  return false;
1873
1875
  }
@@ -1881,7 +1883,7 @@ function makeToolOwnedDecider(cwd, toolOwnedPaths) {
1881
1883
  const prefix = parts.slice(0, depth).join("/");
1882
1884
  let hasMarker = markers.get(prefix);
1883
1885
  if (hasMarker === void 0) {
1884
- hasMarker = fs11__namespace.existsSync(path12__namespace.join(cwd, prefix, ".codebase-snapshot"));
1886
+ hasMarker = fs12__namespace.existsSync(path13__namespace.join(cwd, prefix, ".codebase-snapshot"));
1885
1887
  markers.set(prefix, hasMarker);
1886
1888
  }
1887
1889
  if (hasMarker) return true;
@@ -1896,7 +1898,7 @@ function makeLinkProbe() {
1896
1898
  let known = cache.get(absolutePath);
1897
1899
  if (known === void 0) {
1898
1900
  try {
1899
- known = fs11__namespace.lstatSync(absolutePath).isSymbolicLink();
1901
+ known = fs12__namespace.lstatSync(absolutePath).isSymbolicLink();
1900
1902
  } catch {
1901
1903
  known = false;
1902
1904
  }
@@ -1909,7 +1911,7 @@ function dropLinkedDirectories(cwd, candidates, skipped) {
1909
1911
  const isLink = makeLinkProbe();
1910
1912
  let rootReal = cwd;
1911
1913
  try {
1912
- rootReal = fs11__namespace.realpathSync(cwd);
1914
+ rootReal = fs12__namespace.realpathSync(cwd);
1913
1915
  } catch {
1914
1916
  }
1915
1917
  const reported = /* @__PURE__ */ new Set();
@@ -1919,7 +1921,7 @@ function dropLinkedDirectories(cwd, candidates, skipped) {
1919
1921
  let linkedDir = null;
1920
1922
  for (let depth = 1; depth <= parts.length; depth += 1) {
1921
1923
  const prefix = parts.slice(0, depth).join("/");
1922
- if (isLink(path12__namespace.join(cwd, prefix))) {
1924
+ if (isLink(path13__namespace.join(cwd, prefix))) {
1923
1925
  linkedDir = prefix;
1924
1926
  break;
1925
1927
  }
@@ -1930,10 +1932,10 @@ function dropLinkedDirectories(cwd, candidates, skipped) {
1930
1932
  }
1931
1933
  if (reported.has(linkedDir)) continue;
1932
1934
  reported.add(linkedDir);
1933
- const absolute = path12__namespace.join(cwd, linkedDir);
1935
+ const absolute = path13__namespace.join(cwd, linkedDir);
1934
1936
  let targetReal = absolute;
1935
1937
  try {
1936
- targetReal = fs11__namespace.realpathSync(absolute);
1938
+ targetReal = fs12__namespace.realpathSync(absolute);
1937
1939
  } catch {
1938
1940
  }
1939
1941
  const target = readLinkTarget(absolute, targetReal);
@@ -2010,7 +2012,7 @@ function collectFiles(cwd, options = {}) {
2010
2012
  "Discovery mode is `git`, but git could not list this directory's files. Run inside a working repository, or pass --discovery walk (or auto) to scan the tree directly."
2011
2013
  );
2012
2014
  }
2013
- if (fs11__namespace.existsSync(path12__namespace.join(cwd, ".git"))) {
2015
+ if (fs12__namespace.existsSync(path13__namespace.join(cwd, ".git"))) {
2014
2016
  throw new Error(
2015
2017
  "This directory is a git repository, but git could not list its files. A plain walk honours .gitignore files, but git also applies .git/info/exclude and your global excludes file, includes files that are tracked although a .gitignore now matches them, and treats a submodule as a single entry. Fix the repository (git status should work), run outside git, or pass --discovery walk to accept those differences."
2016
2018
  );
@@ -2069,7 +2071,7 @@ function collectFiles(cwd, options = {}) {
2069
2071
  }
2070
2072
  function rootRealFor(root) {
2071
2073
  try {
2072
- return fs11__namespace.realpathSync(root);
2074
+ return fs12__namespace.realpathSync(root);
2073
2075
  } catch {
2074
2076
  return root;
2075
2077
  }
@@ -2077,18 +2079,18 @@ function rootRealFor(root) {
2077
2079
  function walkDirectory(dir, baseDir, rootReal, visited, reservedPaths = /* @__PURE__ */ new Set(), parentGitignoreLayers = []) {
2078
2080
  const results = { files: [], skipped: [] };
2079
2081
  const stack = [];
2080
- const relativeToBase = (target) => path12__namespace.relative(baseDir, target).replace(/\\/g, "/") || ".";
2082
+ const relativeToBase = (target) => path13__namespace.relative(baseDir, target).replace(/\\/g, "/") || ".";
2081
2083
  const enter = (current, layers) => {
2082
2084
  if (visited.has(current)) return false;
2083
2085
  visited.add(current);
2084
2086
  const localRules = readGitignoreRules(current);
2085
2087
  const gitignoreLayers = localRules.length === 0 ? layers : [
2086
2088
  ...layers,
2087
- { prefix: path12__namespace.relative(baseDir, current).replace(/\\/g, "/"), rules: localRules }
2089
+ { prefix: path13__namespace.relative(baseDir, current).replace(/\\/g, "/"), rules: localRules }
2088
2090
  ];
2089
2091
  let entries;
2090
2092
  try {
2091
- entries = fs11__namespace.readdirSync(current, { withFileTypes: true });
2093
+ entries = fs12__namespace.readdirSync(current, { withFileTypes: true });
2092
2094
  } catch {
2093
2095
  results.skipped.push({
2094
2096
  path: relativeToBase(current),
@@ -2110,8 +2112,8 @@ function walkDirectory(dir, baseDir, rootReal, visited, reservedPaths = /* @__PU
2110
2112
  }
2111
2113
  const entry = frame.entries[frame.index];
2112
2114
  frame.index += 1;
2113
- const fullPath = path12__namespace.join(frame.dir, entry.name);
2114
- const relPath = path12__namespace.relative(baseDir, fullPath).replace(/\\/g, "/");
2115
+ const fullPath = path13__namespace.join(frame.dir, entry.name);
2116
+ const relPath = path13__namespace.relative(baseDir, fullPath).replace(/\\/g, "/");
2115
2117
  if (isToolOwnedDirName(entry.name) && reservedPaths.has(relPath)) continue;
2116
2118
  if (DEFAULT_IGNORED_DIRS.includes(entry.name)) {
2117
2119
  results.skipped.push({
@@ -2144,14 +2146,14 @@ function walkDirectory(dir, baseDir, rootReal, visited, reservedPaths = /* @__PU
2144
2146
  if (entry.isSymbolicLink()) {
2145
2147
  let targetReal;
2146
2148
  try {
2147
- targetReal = fs11__namespace.realpathSync(fullPath);
2149
+ targetReal = fs12__namespace.realpathSync(fullPath);
2148
2150
  } catch {
2149
2151
  results.skipped.push({ path: relPath, reason: "read-error", detail: "broken symlink" });
2150
2152
  continue;
2151
2153
  }
2152
2154
  let stats;
2153
2155
  try {
2154
- stats = fs11__namespace.statSync(fullPath);
2156
+ stats = fs12__namespace.statSync(fullPath);
2155
2157
  } catch {
2156
2158
  results.skipped.push({ path: relPath, reason: "read-error", detail: "unreadable symlink" });
2157
2159
  continue;
@@ -2204,13 +2206,13 @@ var CONFIG_FILENAMES = [
2204
2206
  ];
2205
2207
  function findConfigFile(cwd) {
2206
2208
  for (const filename of CONFIG_FILENAMES) {
2207
- const fullPath = path12__namespace.join(cwd, filename);
2208
- if (fs11__namespace.existsSync(fullPath)) return fullPath;
2209
+ const fullPath = path13__namespace.join(cwd, filename);
2210
+ if (fs12__namespace.existsSync(fullPath)) return fullPath;
2209
2211
  }
2210
- const pkgJsonPath = path12__namespace.join(cwd, "package.json");
2211
- if (!fs11__namespace.existsSync(pkgJsonPath)) return null;
2212
+ const pkgJsonPath = path13__namespace.join(cwd, "package.json");
2213
+ if (!fs12__namespace.existsSync(pkgJsonPath)) return null;
2212
2214
  try {
2213
- const parsed = JSON.parse(fs11__namespace.readFileSync(pkgJsonPath, "utf8"));
2215
+ const parsed = JSON.parse(fs12__namespace.readFileSync(pkgJsonPath, "utf8"));
2214
2216
  return parsed.snapshot === void 0 ? null : pkgJsonPath;
2215
2217
  } catch {
2216
2218
  return null;
@@ -2461,11 +2463,11 @@ async function loadConfigFileDetailed(cwd) {
2461
2463
  const warnings = [];
2462
2464
  const errors = [];
2463
2465
  for (const filename of CONFIG_FILENAMES) {
2464
- const fullPath = path12__namespace.join(cwd, filename);
2465
- if (!fs11__namespace.existsSync(fullPath)) continue;
2466
+ const fullPath = path13__namespace.join(cwd, filename);
2467
+ if (!fs12__namespace.existsSync(fullPath)) continue;
2466
2468
  if (filename.endsWith(".json") || filename === ".snapshotrc") {
2467
2469
  try {
2468
- const config = parseJsonish(fs11__namespace.readFileSync(fullPath, "utf8"), fullPath);
2470
+ const config = parseJsonish(fs12__namespace.readFileSync(fullPath, "utf8"), fullPath);
2469
2471
  if (config === null || typeof config !== "object" || Array.isArray(config)) {
2470
2472
  throw new Error(
2471
2473
  `${fullPath} does not hold a configuration object (received ${describeValue2(config)}).`
@@ -2499,10 +2501,10 @@ async function loadConfigFileDetailed(cwd) {
2499
2501
  continue;
2500
2502
  }
2501
2503
  }
2502
- const pkgJsonPath = path12__namespace.join(cwd, "package.json");
2503
- if (fs11__namespace.existsSync(pkgJsonPath)) {
2504
+ const pkgJsonPath = path13__namespace.join(cwd, "package.json");
2505
+ if (fs12__namespace.existsSync(pkgJsonPath)) {
2504
2506
  try {
2505
- const parsed = parseJsonish(fs11__namespace.readFileSync(pkgJsonPath, "utf8"), pkgJsonPath);
2507
+ const parsed = parseJsonish(fs12__namespace.readFileSync(pkgJsonPath, "utf8"), pkgJsonPath);
2506
2508
  const snapshotKey = parsed.snapshot;
2507
2509
  if (snapshotKey && typeof snapshotKey === "object" && !Array.isArray(snapshotKey)) {
2508
2510
  return { config: snapshotKey, file: pkgJsonPath, warnings, errors };
@@ -2670,9 +2672,9 @@ function resolveKindRules(value) {
2670
2672
  function outputExcludePatterns(cwd, outDir, tmpDir) {
2671
2673
  const patterns = [];
2672
2674
  for (const dir of [outDir, tmpDir]) {
2673
- const absolute = path12__namespace.resolve(cwd, dir);
2674
- const relative11 = path12__namespace.relative(cwd, absolute);
2675
- if (!relative11 || relative11 === ".." || relative11.startsWith(`..${path12__namespace.sep}`) || path12__namespace.isAbsolute(relative11)) {
2675
+ const absolute = path13__namespace.resolve(cwd, dir);
2676
+ const relative11 = path13__namespace.relative(cwd, absolute);
2677
+ if (!relative11 || relative11 === ".." || relative11.startsWith(`..${path13__namespace.sep}`) || path13__namespace.isAbsolute(relative11)) {
2676
2678
  continue;
2677
2679
  }
2678
2680
  patterns.push(`${relative11.replace(/\\/g, "/")}/**`);
@@ -2791,11 +2793,11 @@ function resolveCandidateCwd(userConfig, cliOptions, baseDir) {
2791
2793
  );
2792
2794
  }
2793
2795
  const candidate = cliOptions?.cwd || userConfig?.cwd || baseDir || process.cwd();
2794
- const resolved = path12__namespace.resolve(candidate);
2795
- if (!fs11__namespace.existsSync(resolved)) {
2796
+ const resolved = path13__namespace.resolve(candidate);
2797
+ if (!fs12__namespace.existsSync(resolved)) {
2796
2798
  throw new Error(`Working directory does not exist: ${resolved}`);
2797
2799
  }
2798
- if (!fs11__namespace.statSync(resolved).isDirectory()) {
2800
+ if (!fs12__namespace.statSync(resolved).isDirectory()) {
2799
2801
  throw new Error(`Working directory is not a directory: ${resolved}`);
2800
2802
  }
2801
2803
  return resolved;
@@ -3021,7 +3023,7 @@ var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
3021
3023
  ".so"
3022
3024
  ]);
3023
3025
  function isBinaryExtension(filePath) {
3024
- const ext = path12__namespace.extname(filePath).toLowerCase();
3026
+ const ext = path13__namespace.extname(filePath).toLowerCase();
3025
3027
  return BINARY_EXTENSIONS.has(ext);
3026
3028
  }
3027
3029
  function countControlBytes(buffer) {
@@ -3188,13 +3190,13 @@ function isBinaryFile(absolutePath) {
3188
3190
  if (isBinaryExtension(absolutePath)) return true;
3189
3191
  let fd;
3190
3192
  try {
3191
- fd = fs11__namespace.openSync(absolutePath, "r");
3193
+ fd = fs12__namespace.openSync(absolutePath, "r");
3192
3194
  const buffer = Buffer.alloc(CHUNK);
3193
3195
  let sample;
3194
3196
  let position = 0;
3195
3197
  while (position < BINARY_SCAN_BYTES) {
3196
3198
  const wanted = Math.min(CHUNK, BINARY_SCAN_BYTES - position);
3197
- const bytesRead = fs11__namespace.readSync(fd, buffer, 0, wanted, position);
3199
+ const bytesRead = fs12__namespace.readSync(fd, buffer, 0, wanted, position);
3198
3200
  if (bytesRead === 0) return false;
3199
3201
  const chunk = buffer.subarray(0, bytesRead);
3200
3202
  if (sample === void 0) {
@@ -3212,7 +3214,7 @@ function isBinaryFile(absolutePath) {
3212
3214
  } finally {
3213
3215
  if (fd !== void 0) {
3214
3216
  try {
3215
- fs11__namespace.closeSync(fd);
3217
+ fs12__namespace.closeSync(fd);
3216
3218
  } catch {
3217
3219
  }
3218
3220
  }
@@ -3225,33 +3227,33 @@ function maskedPath(value, secretRules) {
3225
3227
  }
3226
3228
  function confineToDirectory(directory, filename) {
3227
3229
  if (filename.includes("\0")) return null;
3228
- if (path12__namespace.isAbsolute(filename)) return null;
3229
- const base = path12__namespace.resolve(directory);
3230
- const resolved = path12__namespace.resolve(base, filename);
3230
+ if (path13__namespace.isAbsolute(filename)) return null;
3231
+ const base = path13__namespace.resolve(directory);
3232
+ const resolved = path13__namespace.resolve(base, filename);
3231
3233
  const caseInsensitive = process.platform === "win32" || process.platform === "darwin";
3232
- const prefix = caseInsensitive ? `${base}${path12__namespace.sep}`.toLowerCase() : `${base}${path12__namespace.sep}`;
3234
+ const prefix = caseInsensitive ? `${base}${path13__namespace.sep}`.toLowerCase() : `${base}${path13__namespace.sep}`;
3233
3235
  const candidate = caseInsensitive ? resolved.toLowerCase() : resolved;
3234
3236
  return candidate.startsWith(prefix) ? resolved : null;
3235
3237
  }
3236
3238
  function findStagingDirectory(config) {
3237
- const tmpDir = path12__namespace.resolve(config.cwd, config.tmpDir);
3239
+ const tmpDir = path13__namespace.resolve(config.cwd, config.tmpDir);
3238
3240
  let entries;
3239
3241
  try {
3240
- entries = fs11__namespace.readdirSync(tmpDir);
3242
+ entries = fs12__namespace.readdirSync(tmpDir);
3241
3243
  } catch {
3242
3244
  return null;
3243
3245
  }
3244
3246
  const runs = entries.filter((name) => name.startsWith("run-")).sort();
3245
3247
  const newest = runs[runs.length - 1];
3246
- return newest ? path12__namespace.join(tmpDir, newest) : null;
3248
+ return newest ? path13__namespace.join(tmpDir, newest) : null;
3247
3249
  }
3248
3250
  function describeMissingManifest(config, manifestPath) {
3249
- const outDir = path12__namespace.resolve(config.cwd, config.outDir);
3250
- const markerPath = path12__namespace.join(outDir, ".codebase-snapshot");
3251
+ const outDir = path13__namespace.resolve(config.cwd, config.outDir);
3252
+ const markerPath = path13__namespace.join(outDir, ".codebase-snapshot");
3251
3253
  let marker2 = null;
3252
3254
  try {
3253
- if (fs11__namespace.existsSync(markerPath)) {
3254
- const parsed = JSON.parse(fs11__namespace.readFileSync(markerPath, "utf8"));
3255
+ if (fs12__namespace.existsSync(markerPath)) {
3256
+ const parsed = JSON.parse(fs12__namespace.readFileSync(markerPath, "utf8"));
3255
3257
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
3256
3258
  marker2 = parsed;
3257
3259
  }
@@ -3287,14 +3289,14 @@ function sha256Hex(buffer) {
3287
3289
  }
3288
3290
  var VERIFY_SNIFF_MAX_BYTES = 8 * 1024 * 1024;
3289
3291
  function wouldNowBeIncluded(cwd, relativePath, reason) {
3290
- const absolutePath = path12__namespace.join(cwd, relativePath);
3292
+ const absolutePath = path13__namespace.join(cwd, relativePath);
3291
3293
  try {
3292
- const stats = fs11__namespace.statSync(absolutePath);
3294
+ const stats = fs12__namespace.statSync(absolutePath);
3293
3295
  if (!stats.isFile()) return false;
3294
3296
  if (isBinaryFile(absolutePath)) return false;
3295
3297
  if (reason !== "binary") return true;
3296
3298
  if (stats.size > VERIFY_SNIFF_MAX_BYTES) return false;
3297
- return !decodeText(fs11__namespace.readFileSync(absolutePath)).binary;
3299
+ return !decodeText(fs12__namespace.readFileSync(absolutePath)).binary;
3298
3300
  } catch {
3299
3301
  return false;
3300
3302
  }
@@ -3352,8 +3354,8 @@ function describeManifestShapeProblem(value) {
3352
3354
  function validateSnapshot(configInput) {
3353
3355
  assertUsableConfigInput(configInput);
3354
3356
  const config = isResolvedConfig(configInput) ? normalizeResolvedConfig(configInput) : resolveConfig(configInput);
3355
- const manifestPath = path12__namespace.resolve(config.cwd, config.outDir, "manifest.json");
3356
- if (!fs11__namespace.existsSync(manifestPath)) {
3357
+ const manifestPath = path13__namespace.resolve(config.cwd, config.outDir, "manifest.json");
3358
+ if (!fs12__namespace.existsSync(manifestPath)) {
3357
3359
  return {
3358
3360
  valid: false,
3359
3361
  manifestPresent: false,
@@ -3364,7 +3366,7 @@ function validateSnapshot(configInput) {
3364
3366
  }
3365
3367
  let manifest;
3366
3368
  try {
3367
- manifest = JSON.parse(fs11__namespace.readFileSync(manifestPath, "utf8"));
3369
+ manifest = JSON.parse(fs12__namespace.readFileSync(manifestPath, "utf8"));
3368
3370
  } catch (err) {
3369
3371
  return {
3370
3372
  valid: false,
@@ -3386,7 +3388,7 @@ function validateSnapshot(configInput) {
3386
3388
  }
3387
3389
  const drift = emptyDrift();
3388
3390
  const warnings = [];
3389
- const snapshotDir = path12__namespace.resolve(config.cwd, config.outDir);
3391
+ const snapshotDir = path13__namespace.resolve(config.cwd, config.outDir);
3390
3392
  const manifestFileMap = /* @__PURE__ */ new Map();
3391
3393
  for (const file of manifest.files) {
3392
3394
  if (file && typeof file.relativePath === "string") {
@@ -3420,7 +3422,7 @@ function validateSnapshot(configInput) {
3420
3422
  }
3421
3423
  let diskHash;
3422
3424
  try {
3423
- diskHash = sha256Hex(fs11__namespace.readFileSync(path12__namespace.join(config.cwd, diskFile)));
3425
+ diskHash = sha256Hex(fs12__namespace.readFileSync(path13__namespace.join(config.cwd, diskFile)));
3424
3426
  } catch (err) {
3425
3427
  if (err.code === "ENOENT") {
3426
3428
  drift.missingOnDisk.push(diskFile);
@@ -3444,7 +3446,7 @@ function validateSnapshot(configInput) {
3444
3446
  }
3445
3447
  let statFailure = null;
3446
3448
  try {
3447
- fs11__namespace.statSync(confined);
3449
+ fs12__namespace.statSync(confined);
3448
3450
  } catch (err) {
3449
3451
  statFailure = err;
3450
3452
  }
@@ -3464,7 +3466,7 @@ function validateSnapshot(configInput) {
3464
3466
  ...Object.values(config.budgets.byLayer)
3465
3467
  );
3466
3468
  const partNames = /* @__PURE__ */ new Set();
3467
- const partsDir = path12__namespace.join(snapshotDir, "parts");
3469
+ const partsDir = path13__namespace.join(snapshotDir, "parts");
3468
3470
  for (const part of manifest.parts) {
3469
3471
  if (!part || typeof part.filename !== "string") continue;
3470
3472
  partNames.add(part.filename);
@@ -3479,7 +3481,7 @@ function validateSnapshot(configInput) {
3479
3481
  }
3480
3482
  let buffer;
3481
3483
  try {
3482
- buffer = fs11__namespace.readFileSync(partPath);
3484
+ buffer = fs12__namespace.readFileSync(partPath);
3483
3485
  } catch {
3484
3486
  drift.partIssues.push({ part: part.filename, issue: "missing from snapshot/parts" });
3485
3487
  continue;
@@ -3693,9 +3695,9 @@ function validateSnapshot(configInput) {
3693
3695
  ["full-codebase.md", manifest.artifacts?.fullMarkdown]
3694
3696
  ]) {
3695
3697
  if (!artifact) continue;
3696
- const artifactPath = path12__namespace.join(snapshotDir, key);
3698
+ const artifactPath = path13__namespace.join(snapshotDir, key);
3697
3699
  try {
3698
- const buffer = fs11__namespace.readFileSync(artifactPath);
3700
+ const buffer = fs12__namespace.readFileSync(artifactPath);
3699
3701
  if (sha256Hex(buffer) !== artifact.sha256 || buffer.length !== artifact.byteSize) {
3700
3702
  drift.partIssues.push({ part: key, issue: "artifact does not match its recorded digest" });
3701
3703
  }
@@ -3956,14 +3958,14 @@ function compareManifests(before, after) {
3956
3958
  function loadManifest(target) {
3957
3959
  let isDirectory;
3958
3960
  try {
3959
- isDirectory = fs11__namespace.statSync(target).isDirectory();
3961
+ isDirectory = fs12__namespace.statSync(target).isDirectory();
3960
3962
  } catch {
3961
3963
  throw new Error(`No snapshot found at ${target}: the path does not exist.`);
3962
3964
  }
3963
- const manifestPath = isDirectory ? path12__namespace.join(target, "manifest.json") : target;
3965
+ const manifestPath = isDirectory ? path13__namespace.join(target, "manifest.json") : target;
3964
3966
  let raw;
3965
3967
  try {
3966
- raw = fs11__namespace.readFileSync(manifestPath, "utf8");
3968
+ raw = fs12__namespace.readFileSync(manifestPath, "utf8");
3967
3969
  } catch {
3968
3970
  throw new Error(`Could not read a manifest at ${manifestPath}.`);
3969
3971
  }
@@ -4114,10 +4116,10 @@ var LANGUAGE_BY_BASENAME = {
4114
4116
  };
4115
4117
  function detectLanguage(filePath) {
4116
4118
  const normalized = filePath.replace(/\\/g, "/");
4117
- const base = path12__namespace.posix.basename(normalized);
4119
+ const base = path13__namespace.posix.basename(normalized);
4118
4120
  if (LANGUAGE_BY_BASENAME[base]) return LANGUAGE_BY_BASENAME[base];
4119
4121
  if (base === ".env" || base.startsWith(".env.")) return "dotenv";
4120
- const ext = path12__namespace.posix.extname(base).toLowerCase();
4122
+ const ext = path13__namespace.posix.extname(base).toLowerCase();
4121
4123
  return LANGUAGE_BY_EXTENSION[ext] ?? "text";
4122
4124
  }
4123
4125
 
@@ -4159,10 +4161,10 @@ function describeMatcher(matcher) {
4159
4161
  return String(matcher);
4160
4162
  }
4161
4163
  function normalizeTarget(cwd, target) {
4162
- const absolute = path12__namespace.resolve(cwd, target);
4163
- const relative11 = path12__namespace.relative(cwd, absolute);
4164
- if (relative11.startsWith("..") || path12__namespace.isAbsolute(relative11)) return target;
4165
- return relative11.split(path12__namespace.sep).join("/");
4164
+ const absolute = path13__namespace.resolve(cwd, target);
4165
+ const relative11 = path13__namespace.relative(cwd, absolute);
4166
+ if (relative11.startsWith("..") || path13__namespace.isAbsolute(relative11)) return target;
4167
+ return relative11.split(path13__namespace.sep).join("/");
4166
4168
  }
4167
4169
  function findRuleMatch(rules, relativePath) {
4168
4170
  return rules.find(
@@ -4181,20 +4183,20 @@ function findRecordedAncestor(skipped, relative11, maskedPath2) {
4181
4183
  return nearest;
4182
4184
  }
4183
4185
  function readManifest2(config) {
4184
- const manifestPath = path12__namespace.resolve(config.cwd, config.outDir, "manifest.json");
4186
+ const manifestPath = path13__namespace.resolve(config.cwd, config.outDir, "manifest.json");
4185
4187
  try {
4186
- return JSON.parse(fs11__namespace.readFileSync(manifestPath, "utf8"));
4188
+ return JSON.parse(fs12__namespace.readFileSync(manifestPath, "utf8"));
4187
4189
  } catch {
4188
4190
  return null;
4189
4191
  }
4190
4192
  }
4191
4193
  function explainPath(config, target) {
4192
4194
  const relative11 = normalizeTarget(config.cwd, target);
4193
- const absolute = path12__namespace.join(config.cwd, relative11);
4195
+ const absolute = path13__namespace.join(config.cwd, relative11);
4194
4196
  const maskedPath2 = findSecretInPath(relative11, config.secretRules)?.masked ?? relative11;
4195
4197
  const result = {
4196
4198
  path: maskedPath2,
4197
- exists: fs11__namespace.existsSync(absolute),
4199
+ exists: fs12__namespace.existsSync(absolute),
4198
4200
  included: false
4199
4201
  };
4200
4202
  const collection = collectFiles(config.cwd, {
@@ -4205,7 +4207,7 @@ function explainPath(config, target) {
4205
4207
  // Same exclusion `generate` applies, so `explain` never says "not-discovered" about a file
4206
4208
  // that is only missing because the walker dropped the tool's own output directory.
4207
4209
  toolOwnedPaths: [config.outDir, config.tmpDir].map(
4208
- (directory) => path12__namespace.relative(config.cwd, path12__namespace.resolve(config.cwd, directory)).replace(/\\/g, "/")
4210
+ (directory) => path13__namespace.relative(config.cwd, path13__namespace.resolve(config.cwd, directory)).replace(/\\/g, "/")
4209
4211
  ).filter((relative12) => relative12.length > 0 && !relative12.startsWith(".."))
4210
4212
  });
4211
4213
  if (!collection.files.includes(relative11)) {
@@ -4244,8 +4246,8 @@ function explainPath(config, target) {
4244
4246
  if (layerRule) result.layerMatch = describeMatcher(layerRule.match);
4245
4247
  const kindRule = findRuleMatch(config.kinds, relative11);
4246
4248
  if (kindRule) result.kindMatch = describeMatcher(kindRule.match);
4247
- if (fs11__namespace.existsSync(absolute) && fs11__namespace.statSync(absolute).isFile()) {
4248
- const buffer = fs11__namespace.readFileSync(absolute);
4249
+ if (fs12__namespace.existsSync(absolute) && fs12__namespace.statSync(absolute).isFile()) {
4250
+ const buffer = fs12__namespace.readFileSync(absolute);
4249
4251
  const decoded = decodeText(buffer);
4250
4252
  if (decoded.binary) {
4251
4253
  result.included = false;
@@ -4304,15 +4306,15 @@ function renderExplainText(result) {
4304
4306
  function appendGitignoreEntries(cwd, entries) {
4305
4307
  const wanted = [...new Set(entries)].filter((entry) => entry.trim().length > 0);
4306
4308
  if (wanted.length === 0) return { added: [], note: null };
4307
- const ignorePath = path12__namespace.join(cwd, ".gitignore");
4309
+ const ignorePath = path13__namespace.join(cwd, ".gitignore");
4308
4310
  const manual = `Add ${wanted.map((entry) => `"${entry}"`).join(" and ")} to your .gitignore yourself.`;
4309
4311
  let existing = "";
4310
4312
  try {
4311
- if (fs11__namespace.existsSync(ignorePath)) {
4312
- if (fs11__namespace.statSync(ignorePath).isDirectory()) {
4313
+ if (fs12__namespace.existsSync(ignorePath)) {
4314
+ if (fs12__namespace.statSync(ignorePath).isDirectory()) {
4313
4315
  return { added: [], note: `${ignorePath} is a directory, so it was not updated. ${manual}` };
4314
4316
  }
4315
- existing = fs11__namespace.readFileSync(ignorePath, "utf8");
4317
+ existing = fs12__namespace.readFileSync(ignorePath, "utf8");
4316
4318
  }
4317
4319
  } catch (err) {
4318
4320
  return {
@@ -4325,7 +4327,7 @@ function appendGitignoreEntries(cwd, entries) {
4325
4327
  if (added.length === 0) return { added: [], note: null };
4326
4328
  const prefix = existing.length === 0 || existing.endsWith("\n") ? "" : "\n";
4327
4329
  try {
4328
- fs11__namespace.writeFileSync(ignorePath, `${existing}${prefix}${added.join("\n")}
4330
+ fs12__namespace.writeFileSync(ignorePath, `${existing}${prefix}${added.join("\n")}
4329
4331
  `, "utf8");
4330
4332
  } catch (err) {
4331
4333
  return { added: [], note: `${err.message}. ${manual}` };
@@ -4333,12 +4335,12 @@ function appendGitignoreEntries(cwd, entries) {
4333
4335
  return { added, note: null };
4334
4336
  }
4335
4337
  function gitignorePath(cwd, filePath) {
4336
- return path12__namespace.relative(cwd, filePath).split(path12__namespace.sep).join("/");
4338
+ return path13__namespace.relative(cwd, filePath).split(path13__namespace.sep).join("/");
4337
4339
  }
4338
4340
 
4339
4341
  // src/version.ts
4340
4342
  var GENERATOR_NAME = "codebase-snapshot";
4341
- var GENERATOR_VERSION = "0.9.5";
4343
+ var GENERATOR_VERSION = "0.9.7";
4342
4344
  var LEGACY_GENERATOR_NAMES = ["@ankurhalder/codebase-snapshot"];
4343
4345
  function isOurGeneratorName(name) {
4344
4346
  if (typeof name !== "string") return false;
@@ -4494,6 +4496,57 @@ function toggleIndex(selected, index) {
4494
4496
  else next.add(index);
4495
4497
  return next;
4496
4498
  }
4499
+ function isWideCodePoint(code) {
4500
+ return code >= 4352 && code <= 4447 || // Hangul Jamo
4501
+ code >= 11904 && code <= 12350 || // CJK radicals, Kangxi, CJK symbols
4502
+ code >= 12353 && code <= 13311 || // kana through CJK compatibility
4503
+ code >= 13312 && code <= 19903 || // CJK extension A
4504
+ code >= 19968 && code <= 40959 || // CJK unified ideographs
4505
+ code >= 40960 && code <= 42191 || // Yi
4506
+ code >= 44032 && code <= 55203 || // Hangul syllables
4507
+ code >= 63744 && code <= 64255 || // CJK compatibility ideographs
4508
+ code >= 65072 && code <= 65135 || // CJK compatibility forms
4509
+ code >= 65280 && code <= 65376 || // fullwidth forms
4510
+ code >= 65504 && code <= 65510 || code >= 127744 && code <= 129535 || // emoji and pictographs
4511
+ code >= 131072 && code <= 262141;
4512
+ }
4513
+ var ANSI_PATTERN = /\u001b\[[0-9;?]*[A-Za-z]/g;
4514
+ function displayWidth(line) {
4515
+ let width = 0;
4516
+ for (const character of line.replace(ANSI_PATTERN, "")) {
4517
+ width += isWideCodePoint(character.codePointAt(0) ?? 0) ? 2 : 1;
4518
+ }
4519
+ return width;
4520
+ }
4521
+ function wrapOneLine(line, limit) {
4522
+ if (displayWidth(line) <= limit) return [line];
4523
+ const indent = /^[ \t]*/.exec(line)?.[0] ?? "";
4524
+ const continuation = `${indent} `;
4525
+ const rows = [];
4526
+ let prefix = indent;
4527
+ let rest = line.slice(indent.length).trimEnd();
4528
+ while (rest.length > 0) {
4529
+ const room = limit - displayWidth(prefix);
4530
+ if (room <= 0 || displayWidth(rest) <= room) {
4531
+ rows.push(prefix + rest);
4532
+ break;
4533
+ }
4534
+ let cut = room;
4535
+ const space = rest.slice(0, room).lastIndexOf(" ");
4536
+ if (space > 0) cut = space;
4537
+ const taken = rest.slice(0, cut).trimEnd();
4538
+ rows.push(`${prefix}${taken.length > 0 ? taken : rest.slice(0, cut)}`);
4539
+ rest = rest.slice(cut).trimStart();
4540
+ prefix = continuation;
4541
+ }
4542
+ return rows;
4543
+ }
4544
+ function wrapLines(text2, limit) {
4545
+ const width = Math.max(8, Math.floor(limit));
4546
+ const rows = [];
4547
+ for (const line of text2.split("\n")) rows.push(...wrapOneLine(line, width));
4548
+ return rows;
4549
+ }
4497
4550
  function marker(active) {
4498
4551
  return active ? "\u276F" : " ";
4499
4552
  }
@@ -4571,14 +4624,27 @@ var Frame = class {
4571
4624
  drawn = 0;
4572
4625
  draw(text2) {
4573
4626
  this.erase();
4574
- this.output.write(`${text2}
4627
+ const rows = wrapLines(text2, this.width());
4628
+ this.output.write(`${rows.join("\n")}
4575
4629
  `);
4576
- this.drawn = text2.split("\n").length;
4630
+ this.drawn = rows.length;
4577
4631
  }
4578
4632
  erase() {
4579
4633
  if (this.drawn > 0) this.output.write(`\x1B[${this.drawn}A\x1B[0J`);
4580
4634
  this.drawn = 0;
4581
4635
  }
4636
+ /**
4637
+ * The usable width, in cells.
4638
+ *
4639
+ * Two cells of slack: an ambiguous-width glyph (`◆`, `❯`, `←`) renders two cells in some fonts
4640
+ * and one in others, and a row that lands exactly on the last column is the one case a terminal
4641
+ * may or may not wrap. Below that, a line cannot reach the edge to begin with.
4642
+ */
4643
+ width() {
4644
+ const columns = this.output.columns;
4645
+ if (typeof columns !== "number" || !Number.isFinite(columns) || columns <= 0) return 80;
4646
+ return Math.max(8, Math.floor(columns) - 2);
4647
+ }
4582
4648
  };
4583
4649
  function isCancel(key) {
4584
4650
  return key.ctrl === true && key.name === "c" || key.ctrl === true && key.name === "d";
@@ -4760,10 +4826,10 @@ var CONFIG_CANDIDATES = [
4760
4826
  ];
4761
4827
  function chooseConfigFileName(cwd) {
4762
4828
  if (!supportsTypeScriptImports()) return "snapshot.config.mjs";
4763
- const pkgPath = path12__namespace.join(cwd, "package.json");
4764
- if (!fs11__namespace.existsSync(pkgPath)) return "snapshot.config.mjs";
4829
+ const pkgPath = path13__namespace.join(cwd, "package.json");
4830
+ if (!fs12__namespace.existsSync(pkgPath)) return "snapshot.config.mjs";
4765
4831
  try {
4766
- const parsed = JSON.parse(fs11__namespace.readFileSync(pkgPath, "utf8"));
4832
+ const parsed = JSON.parse(fs12__namespace.readFileSync(pkgPath, "utf8"));
4767
4833
  return parsed.type === "module" ? "snapshot.config.ts" : "snapshot.config.mjs";
4768
4834
  } catch {
4769
4835
  return "snapshot.config.mjs";
@@ -4777,7 +4843,7 @@ var SIZE_CHOICES = [
4777
4843
  ];
4778
4844
  function packageJsonHasConfig(cwd) {
4779
4845
  try {
4780
- const parsed = JSON.parse(fs11__namespace.readFileSync(path12__namespace.join(cwd, "package.json"), "utf8"));
4846
+ const parsed = JSON.parse(fs12__namespace.readFileSync(path13__namespace.join(cwd, "package.json"), "utf8"));
4781
4847
  return typeof parsed.snapshot === "object" && parsed.snapshot !== null && !Array.isArray(parsed.snapshot);
4782
4848
  } catch {
4783
4849
  return false;
@@ -4798,7 +4864,7 @@ function artifactAnswers(options) {
4798
4864
  }
4799
4865
  function topLevelDirs(cwd) {
4800
4866
  try {
4801
- return fs11__namespace.readdirSync(cwd, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules").map((entry) => entry.name).sort();
4867
+ return fs12__namespace.readdirSync(cwd, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules").map((entry) => entry.name).sort();
4802
4868
  } catch {
4803
4869
  return [];
4804
4870
  }
@@ -4811,7 +4877,7 @@ function describeJsonValue(value) {
4811
4877
  }
4812
4878
  function writeFileOrExplain(target, content) {
4813
4879
  try {
4814
- fs11__namespace.writeFileSync(target, content, "utf8");
4880
+ fs12__namespace.writeFileSync(target, content, "utf8");
4815
4881
  } catch (err) {
4816
4882
  const code = err.code;
4817
4883
  const reason = code === "EACCES" || code === "EPERM" || code === "EROFS" ? `permission denied (${code})` : code === "EISDIR" ? "it is a directory" : `${err.message}`;
@@ -4822,7 +4888,7 @@ function canWriteModuleConfig(name, cwd) {
4822
4888
  if (name.endsWith(".mjs") || name.endsWith(".ts")) return true;
4823
4889
  if (!name.endsWith(".js")) return false;
4824
4890
  try {
4825
- const parsed = JSON.parse(fs11__namespace.readFileSync(path12__namespace.join(cwd, "package.json"), "utf8"));
4891
+ const parsed = JSON.parse(fs12__namespace.readFileSync(path13__namespace.join(cwd, "package.json"), "utf8"));
4826
4892
  return parsed.type === "module";
4827
4893
  } catch {
4828
4894
  return false;
@@ -4857,19 +4923,19 @@ function serializePackageJson(raw, value) {
4857
4923
  return `${text2}${raw.endsWith("\n") ? crlf ? "\r\n" : "\n" : ""}`;
4858
4924
  }
4859
4925
  function updatePackageJson(cwd, notes) {
4860
- const packagePath = path12__namespace.join(cwd, "package.json");
4926
+ const packagePath = path13__namespace.join(cwd, "package.json");
4861
4927
  const unchanged = {
4862
4928
  scripts: [],
4863
4929
  dependency: { name: GENERATOR_NAME, range: null, added: false }
4864
4930
  };
4865
- if (!fs11__namespace.existsSync(packagePath)) {
4931
+ if (!fs12__namespace.existsSync(packagePath)) {
4866
4932
  notes.push("No package.json found, so npm scripts and the devDependency were not added.");
4867
4933
  return unchanged;
4868
4934
  }
4869
4935
  let raw;
4870
4936
  let parsed;
4871
4937
  try {
4872
- raw = fs11__namespace.readFileSync(packagePath, "utf8");
4938
+ raw = fs12__namespace.readFileSync(packagePath, "utf8");
4873
4939
  parsed = JSON.parse(raw);
4874
4940
  } catch {
4875
4941
  notes.push("Could not parse package.json; npm scripts and the devDependency were not added.");
@@ -5161,7 +5227,7 @@ async function runInit(options) {
5161
5227
  const configText = renderConfig(answers);
5162
5228
  const preferredName = chooseConfigFileName(options.cwd);
5163
5229
  const presentConfigs = CONFIG_CANDIDATES.filter(
5164
- (name) => fs11__namespace.existsSync(path12__namespace.join(options.cwd, name))
5230
+ (name) => fs12__namespace.existsSync(path13__namespace.join(options.cwd, name))
5165
5231
  );
5166
5232
  const present = presentConfigs[0] ?? null;
5167
5233
  if (presentConfigs.length > 1) {
@@ -5170,7 +5236,7 @@ async function runInit(options) {
5170
5236
  );
5171
5237
  }
5172
5238
  const configName = present !== null && options.force ? present : preferredName;
5173
- const configPath = path12__namespace.join(options.cwd, configName);
5239
+ const configPath = path13__namespace.join(options.cwd, configName);
5174
5240
  const reused = present !== null && options.force !== true && options.reuseConfig === true;
5175
5241
  if (reused) notes.push(`Kept the existing ${present} instead of writing a new one.`);
5176
5242
  if (options.dryRun) {
@@ -5203,7 +5269,7 @@ async function runInit(options) {
5203
5269
  'package.json already defines a "snapshot" config. Remove that key, or re-run with --force to write a config file that takes precedence over it.'
5204
5270
  );
5205
5271
  }
5206
- if (fs11__namespace.existsSync(configPath) && !options.force && !reused) {
5272
+ if (fs12__namespace.existsSync(configPath) && !options.force && !reused) {
5207
5273
  throw new Error(`${configName} already exists. Re-run with --force to replace it.`);
5208
5274
  }
5209
5275
  if (!reused) writeFileOrExplain(configPath, configText);
@@ -5225,9 +5291,9 @@ async function runInit(options) {
5225
5291
  };
5226
5292
  }
5227
5293
  function describeTarget(cwd) {
5228
- const relative11 = path12__namespace.relative(process.cwd(), cwd);
5294
+ const relative11 = path13__namespace.relative(process.cwd(), cwd);
5229
5295
  if (relative11 === "") return "this directory";
5230
- if (relative11.startsWith("..") || path12__namespace.isAbsolute(relative11)) return cwd;
5296
+ if (relative11.startsWith("..") || path13__namespace.isAbsolute(relative11)) return cwd;
5231
5297
  return relative11;
5232
5298
  }
5233
5299
  function firstRunMessage(reason, cwd) {
@@ -5251,7 +5317,7 @@ function planFirstRun(facts) {
5251
5317
  var NOT_CONTENT = /* @__PURE__ */ new Set([".git", ".hg", ".svn", ".bzr", ".DS_Store", "Thumbs.db"]);
5252
5318
  function isEffectivelyEmpty(cwd) {
5253
5319
  try {
5254
- return fs11__namespace.readdirSync(cwd).every((entry) => NOT_CONTENT.has(entry));
5320
+ return fs12__namespace.readdirSync(cwd).every((entry) => NOT_CONTENT.has(entry));
5255
5321
  } catch {
5256
5322
  return false;
5257
5323
  }
@@ -5259,7 +5325,7 @@ function isEffectivelyEmpty(cwd) {
5259
5325
  function hasPriorSnapshot(cwd, outDir) {
5260
5326
  let parsed;
5261
5327
  try {
5262
- parsed = JSON.parse(fs11__namespace.readFileSync(path12__namespace.join(cwd, outDir, ".codebase-snapshot"), "utf8"));
5328
+ parsed = JSON.parse(fs12__namespace.readFileSync(path13__namespace.join(cwd, outDir, ".codebase-snapshot"), "utf8"));
5263
5329
  } catch {
5264
5330
  return false;
5265
5331
  }
@@ -5489,9 +5555,9 @@ var JAVA_METHOD = /^\s+(?:public|private|protected)\s+(?:static\s+)?(?:final\s+)
5489
5555
  var jvmProfile = {
5490
5556
  id: "jvm",
5491
5557
  extensions: [".java", ".kt", ".kts", ".scala"],
5492
- summarize(path18, content) {
5558
+ summarize(path19, content) {
5493
5559
  const summary = emptySummary();
5494
- const lower = path18.toLowerCase();
5560
+ const lower = path19.toLowerCase();
5495
5561
  const isJava = lower.endsWith(".java");
5496
5562
  const isKotlin = lower.endsWith(".kt") || lower.endsWith(".kts");
5497
5563
  eachLine(content, (line) => {
@@ -5944,16 +6010,16 @@ function summarizeTypeScriptSource(relativePath, content) {
5944
6010
  // src/ast/profiles/sfc.ts
5945
6011
  var SCRIPT_BLOCK = /<script[^>]*>([\s\S]*?)<\/script>/gi;
5946
6012
  var ASTRO_FRONTMATTER = /^\uFEFF?---[ \t]*\r?\n([\s\S]*?)\r?\n---[ \t]*(?=\r?\n|$)/;
5947
- function componentName(path18) {
5948
- const base = path18.split("/").pop() ?? path18;
6013
+ function componentName(path19) {
6014
+ const base = path19.split("/").pop() ?? path19;
5949
6015
  return base.replace(/\.[^.]+$/, "");
5950
6016
  }
5951
6017
  var sfcProfile = {
5952
6018
  id: "sfc",
5953
6019
  extensions: [".vue", ".svelte", ".astro"],
5954
- summarize(path18, content) {
6020
+ summarize(path19, content) {
5955
6021
  let script = "";
5956
- if (path18.toLowerCase().endsWith(".astro")) {
6022
+ if (path19.toLowerCase().endsWith(".astro")) {
5957
6023
  const frontmatter = ASTRO_FRONTMATTER.exec(content);
5958
6024
  if (frontmatter) script += `${frontmatter[1]}
5959
6025
  `;
@@ -5962,7 +6028,7 @@ var sfcProfile = {
5962
6028
  script += `${match[1]}
5963
6029
  `;
5964
6030
  }
5965
- const name = componentName(path18);
6031
+ const name = componentName(path19);
5966
6032
  if (!script.trim()) {
5967
6033
  const summary2 = emptySummary();
5968
6034
  if (name) {
@@ -5996,15 +6062,15 @@ for (const profile of LANGUAGE_PROFILES) {
5996
6062
  BY_EXTENSION.set(extension.toLowerCase(), profile);
5997
6063
  }
5998
6064
  }
5999
- function profileForPath(path18) {
6000
- const lower = path18.toLowerCase();
6065
+ function profileForPath(path19) {
6066
+ const lower = path19.toLowerCase();
6001
6067
  const dot = lower.lastIndexOf(".");
6002
6068
  if (dot === -1) return null;
6003
6069
  return BY_EXTENSION.get(lower.slice(dot)) ?? null;
6004
6070
  }
6005
- function summarizeWithProfile(path18, content) {
6006
- const profile = profileForPath(path18);
6007
- return profile ? profile.summarize(path18, content) : null;
6071
+ function summarizeWithProfile(path19, content) {
6072
+ const profile = profileForPath(path19);
6073
+ return profile ? profile.summarize(path19, content) : null;
6008
6074
  }
6009
6075
 
6010
6076
  // src/ast/structured.ts
@@ -6849,6 +6915,162 @@ function generateProjectTree(filePaths) {
6849
6915
  const fence = fenceForText(lines.join("\n"), 3);
6850
6916
  return ["# Project Tree", "", `${fence}text`, ...lines, fence, ""].join("\n");
6851
6917
  }
6918
+ var PACKAGE_LATEST_URL = "https://registry.npmjs.org/codebase-snapshot/latest";
6919
+ var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
6920
+ var FAILURE_INTERVAL_MS = 60 * 60 * 1e3;
6921
+ var REQUEST_TIMEOUT_MS = 1200;
6922
+ function versionParts(value) {
6923
+ const core = value.trim().replace(/^v/i, "").split("-")[0];
6924
+ return core.split(".").map((part) => {
6925
+ const parsed = Number(part);
6926
+ return Number.isFinite(parsed) ? parsed : 0;
6927
+ });
6928
+ }
6929
+ function isNewer(candidate, current) {
6930
+ const left = versionParts(candidate);
6931
+ const right = versionParts(current);
6932
+ const length = Math.max(left.length, right.length);
6933
+ for (let index = 0; index < length; index += 1) {
6934
+ const a = left[index] ?? 0;
6935
+ const b = right[index] ?? 0;
6936
+ if (a !== b) return a > b;
6937
+ }
6938
+ return false;
6939
+ }
6940
+ function cacheDirectory(env = process.env, platform = process.platform) {
6941
+ if (platform === "win32") {
6942
+ const base2 = env.LOCALAPPDATA ?? path13__namespace.join(os__namespace.homedir(), "AppData", "Local");
6943
+ return path13__namespace.join(base2, "codebase-snapshot");
6944
+ }
6945
+ if (platform === "darwin") {
6946
+ return path13__namespace.join(os__namespace.homedir(), "Library", "Caches", "codebase-snapshot");
6947
+ }
6948
+ const base = env.XDG_CACHE_HOME ?? path13__namespace.join(os__namespace.homedir(), ".cache");
6949
+ return path13__namespace.join(base, "codebase-snapshot");
6950
+ }
6951
+ function cacheFilePath(env = process.env) {
6952
+ return path13__namespace.join(cacheDirectory(env), "update-check.json");
6953
+ }
6954
+ function shouldCheck(argv, env) {
6955
+ const disabled = ["1", "true", "yes"].includes(
6956
+ String(env.CODEBASE_SNAPSHOT_NO_UPDATE_CHECK ?? "").toLowerCase()
6957
+ );
6958
+ if (disabled) return false;
6959
+ if (env.CI !== void 0 && env.CI !== "" && env.CI !== "false" && env.CI !== "0") return false;
6960
+ const args = argv.map((argument) => argument.toLowerCase());
6961
+ if (args.includes("--no-update-check")) return false;
6962
+ for (const skip of ["mcp", "describe", "skill", "--version", "-v", "--help", "-h"]) {
6963
+ if (args.includes(skip)) return false;
6964
+ }
6965
+ if (args.some((argument) => argument.includes("json"))) return false;
6966
+ return true;
6967
+ }
6968
+ function readCache(file) {
6969
+ let raw;
6970
+ try {
6971
+ raw = fs12__namespace.readFileSync(file, "utf8");
6972
+ } catch {
6973
+ return null;
6974
+ }
6975
+ try {
6976
+ const parsed = JSON.parse(raw);
6977
+ if (typeof parsed !== "object" || parsed === null) return null;
6978
+ const candidate = parsed;
6979
+ if (typeof candidate.checkedAt !== "number") return null;
6980
+ const latest = typeof candidate.latest === "string" ? candidate.latest : null;
6981
+ return { checkedAt: candidate.checkedAt, latest };
6982
+ } catch {
6983
+ return null;
6984
+ }
6985
+ }
6986
+ function writeCache(file, entry) {
6987
+ try {
6988
+ fs12__namespace.mkdirSync(path13__namespace.dirname(file), { recursive: true });
6989
+ fs12__namespace.writeFileSync(file, `${JSON.stringify(entry)}
6990
+ `, "utf8");
6991
+ } catch {
6992
+ }
6993
+ }
6994
+ function fetchLatestVersion(url = PACKAGE_LATEST_URL, timeoutMs = REQUEST_TIMEOUT_MS) {
6995
+ return new Promise((resolve9) => {
6996
+ let settled = false;
6997
+ const finish = (value) => {
6998
+ if (settled) return;
6999
+ settled = true;
7000
+ resolve9(value);
7001
+ };
7002
+ const request = https__namespace.get(
7003
+ url,
7004
+ {
7005
+ headers: {
7006
+ accept: "application/json",
7007
+ "user-agent": "codebase-snapshot (update check)"
7008
+ }
7009
+ },
7010
+ (response) => {
7011
+ if (response.statusCode !== 200) {
7012
+ response.resume();
7013
+ finish(null);
7014
+ return;
7015
+ }
7016
+ let body = "";
7017
+ response.setEncoding("utf8");
7018
+ response.on("data", (chunk) => {
7019
+ body += chunk;
7020
+ if (body.length > 64 * 1024) {
7021
+ request.destroy();
7022
+ finish(null);
7023
+ }
7024
+ });
7025
+ response.on("end", () => {
7026
+ try {
7027
+ const parsed = JSON.parse(body);
7028
+ finish(typeof parsed.version === "string" ? parsed.version : null);
7029
+ } catch {
7030
+ finish(null);
7031
+ }
7032
+ });
7033
+ }
7034
+ );
7035
+ request.on("error", () => finish(null));
7036
+ request.setTimeout(timeoutMs, () => {
7037
+ request.destroy();
7038
+ finish(null);
7039
+ });
7040
+ });
7041
+ }
7042
+ async function checkForUpdate(options) {
7043
+ if (options.enabled === false) return null;
7044
+ const now = options.now ?? (() => Date.now());
7045
+ const fetchLatest = options.fetchLatest ?? fetchLatestVersion;
7046
+ let latest = null;
7047
+ try {
7048
+ const cached = readCache(options.cacheFile);
7049
+ let needsFetch = cached === null;
7050
+ if (cached) {
7051
+ const age = now() - cached.checkedAt;
7052
+ if (cached.latest === null) {
7053
+ needsFetch = age >= FAILURE_INTERVAL_MS;
7054
+ } else {
7055
+ latest = cached.latest;
7056
+ needsFetch = age >= CHECK_INTERVAL_MS;
7057
+ }
7058
+ }
7059
+ if (needsFetch) {
7060
+ const fetched = await fetchLatest(PACKAGE_LATEST_URL, REQUEST_TIMEOUT_MS);
7061
+ writeCache(options.cacheFile, { checkedAt: now(), latest: fetched });
7062
+ latest = fetched;
7063
+ }
7064
+ } catch {
7065
+ return null;
7066
+ }
7067
+ if (!latest) return null;
7068
+ return isNewer(latest, options.current) ? { current: options.current, latest } : null;
7069
+ }
7070
+ function formatUpdateNotice(notice) {
7071
+ return `\u2191 codebase-snapshot ${notice.latest} is available \u2014 you have ${notice.current}.
7072
+ npm install -g codebase-snapshot`;
7073
+ }
6852
7074
 
6853
7075
  // src/index.ts
6854
7076
  var SCHEMA_VERSION = "3.0.0";
@@ -6930,13 +7152,13 @@ function buildImportResolver(files) {
6930
7152
  const relativePath = file.relativePath;
6931
7153
  remember(byPath, relativePath, relativePath);
6932
7154
  remember(byPathFolded, relativePath.toLowerCase(), relativePath);
6933
- const extension = path12__namespace.posix.extname(relativePath);
7155
+ const extension = path13__namespace.posix.extname(relativePath);
6934
7156
  if (!SOURCE_EXTENSIONS.has(extension)) continue;
6935
7157
  const stem = relativePath.slice(0, -extension.length);
6936
7158
  remember(byStem, stem, relativePath);
6937
7159
  remember(byStemFolded, stem.toLowerCase(), relativePath);
6938
- if (path12__namespace.posix.basename(stem) === "index") {
6939
- const directory = path12__namespace.posix.dirname(stem);
7160
+ if (path13__namespace.posix.basename(stem) === "index") {
7161
+ const directory = path13__namespace.posix.dirname(stem);
6940
7162
  remember(byStem, directory, relativePath);
6941
7163
  remember(byStemFolded, directory.toLowerCase(), relativePath);
6942
7164
  }
@@ -6945,8 +7167,8 @@ function buildImportResolver(files) {
6945
7167
  }
6946
7168
  function resolveSpecifier(fromFile, specifier, resolver) {
6947
7169
  if (!RELATIVE_SPECIFIER.test(specifier)) return null;
6948
- const joined = path12__namespace.posix.normalize(
6949
- path12__namespace.posix.join(path12__namespace.posix.dirname(fromFile), specifier)
7170
+ const joined = path13__namespace.posix.normalize(
7171
+ path13__namespace.posix.join(path13__namespace.posix.dirname(fromFile), specifier)
6950
7172
  );
6951
7173
  const exact = (key) => resolver.byPath.get(key) ?? resolver.byPathFolded.get(key.toLowerCase()) ?? null;
6952
7174
  const direct = exact(joined);
@@ -7039,11 +7261,11 @@ function verifyInMemory(files, parts, maxPartBytes) {
7039
7261
  return errors;
7040
7262
  }
7041
7263
  function resolveSafeOutputDirs(config) {
7042
- const cwd = path12__namespace.resolve(config.cwd);
7043
- const outDir = path12__namespace.resolve(cwd, config.outDir);
7044
- const tmpDir = path12__namespace.resolve(cwd, config.tmpDir);
7045
- const root = path12__namespace.parse(cwd).root;
7046
- const contains = (parent, child) => child === parent || child.startsWith(`${parent}${path12__namespace.sep}`);
7264
+ const cwd = path13__namespace.resolve(config.cwd);
7265
+ const outDir = path13__namespace.resolve(cwd, config.outDir);
7266
+ const tmpDir = path13__namespace.resolve(cwd, config.tmpDir);
7267
+ const root = path13__namespace.parse(cwd).root;
7268
+ const contains = (parent, child) => child === parent || child.startsWith(`${parent}${path13__namespace.sep}`);
7047
7269
  const reject = (reason) => {
7048
7270
  throw new Error(
7049
7271
  `Refusing to generate: ${reason}. outDir=${outDir} tmpDir=${tmpDir} cwd=${cwd}`
@@ -7099,14 +7321,14 @@ function listEntries(dir) {
7099
7321
  const walk = (absolute, prefix) => {
7100
7322
  let children;
7101
7323
  try {
7102
- children = fs11__namespace.readdirSync(absolute, { withFileTypes: true });
7324
+ children = fs12__namespace.readdirSync(absolute, { withFileTypes: true });
7103
7325
  } catch {
7104
7326
  return;
7105
7327
  }
7106
7328
  for (const child of children) {
7107
7329
  const relative11 = prefix === "" ? child.name : `${prefix}/${child.name}`;
7108
7330
  entries.push(relative11);
7109
- if (child.isDirectory()) walk(path12__namespace.join(absolute, child.name), relative11);
7331
+ if (child.isDirectory()) walk(path13__namespace.join(absolute, child.name), relative11);
7110
7332
  }
7111
7333
  };
7112
7334
  walk(dir, "");
@@ -7123,28 +7345,28 @@ function markerPayload(dir, state, id, createdAt) {
7123
7345
  pid: process.pid,
7124
7346
  entries: listEntries(dir)
7125
7347
  };
7126
- const manifestPath = path12__namespace.join(dir, "manifest.json");
7127
- if (fs11__namespace.existsSync(manifestPath)) {
7128
- marker2.manifestSha256 = sha256Hex2(fs11__namespace.readFileSync(manifestPath));
7348
+ const manifestPath = path13__namespace.join(dir, "manifest.json");
7349
+ if (fs12__namespace.existsSync(manifestPath)) {
7350
+ marker2.manifestSha256 = sha256Hex2(fs12__namespace.readFileSync(manifestPath));
7129
7351
  }
7130
7352
  return marker2;
7131
7353
  }
7132
7354
  function writeOwnershipMarker(dir, marker2) {
7133
- fs11__namespace.writeFileSync(
7134
- path12__namespace.join(dir, OWNERSHIP_MARKER),
7355
+ fs12__namespace.writeFileSync(
7356
+ path13__namespace.join(dir, OWNERSHIP_MARKER),
7135
7357
  `${JSON.stringify(marker2, null, 2)}
7136
7358
  `,
7137
7359
  "utf8"
7138
7360
  );
7139
7361
  }
7140
7362
  function readOwnershipMarker(dir) {
7141
- const markerPath = path12__namespace.join(dir, OWNERSHIP_MARKER);
7142
- if (!fs11__namespace.existsSync(markerPath)) {
7363
+ const markerPath = path13__namespace.join(dir, OWNERSHIP_MARKER);
7364
+ if (!fs12__namespace.existsSync(markerPath)) {
7143
7365
  return { marker: null, problem: "it holds no .codebase-snapshot marker" };
7144
7366
  }
7145
7367
  let raw;
7146
7368
  try {
7147
- raw = fs11__namespace.readFileSync(markerPath, "utf8");
7369
+ raw = fs12__namespace.readFileSync(markerPath, "utf8");
7148
7370
  } catch {
7149
7371
  return { marker: null, problem: "its .codebase-snapshot marker could not be read" };
7150
7372
  }
@@ -7212,11 +7434,11 @@ function assessSnapshotDirectory(dir) {
7212
7434
  marker: marker2
7213
7435
  };
7214
7436
  }
7215
- const manifestPath = path12__namespace.join(dir, "manifest.json");
7216
- if (fs11__namespace.existsSync(manifestPath)) {
7437
+ const manifestPath = path13__namespace.join(dir, "manifest.json");
7438
+ if (fs12__namespace.existsSync(manifestPath)) {
7217
7439
  let raw;
7218
7440
  try {
7219
- raw = fs11__namespace.readFileSync(manifestPath, "utf8");
7441
+ raw = fs12__namespace.readFileSync(manifestPath, "utf8");
7220
7442
  } catch {
7221
7443
  return {
7222
7444
  owned: false,
@@ -7298,13 +7520,13 @@ function containsNoFiles(dir) {
7298
7520
  const current = pending.pop();
7299
7521
  let entries;
7300
7522
  try {
7301
- entries = fs11__namespace.readdirSync(current, { withFileTypes: true });
7523
+ entries = fs12__namespace.readdirSync(current, { withFileTypes: true });
7302
7524
  } catch {
7303
7525
  return false;
7304
7526
  }
7305
7527
  for (const entry of entries) {
7306
7528
  if (entry.isDirectory()) {
7307
- pending.push(path12__namespace.join(current, entry.name));
7529
+ pending.push(path13__namespace.join(current, entry.name));
7308
7530
  } else if (!IGNORABLE_ENTRIES.has(entry.name)) {
7309
7531
  return false;
7310
7532
  }
@@ -7313,13 +7535,13 @@ function containsNoFiles(dir) {
7313
7535
  return true;
7314
7536
  }
7315
7537
  function assertReplaceable(target, label, secretRules) {
7316
- if (!fs11__namespace.existsSync(target)) return;
7317
- if (!fs11__namespace.statSync(target).isDirectory()) {
7538
+ if (!fs12__namespace.existsSync(target)) return;
7539
+ if (!fs12__namespace.statSync(target).isDirectory()) {
7318
7540
  throw new Error(
7319
7541
  `Refusing to write into ${label} ${target}: it exists but is not a directory.`
7320
7542
  );
7321
7543
  }
7322
- const entries = fs11__namespace.readdirSync(target);
7544
+ const entries = fs12__namespace.readdirSync(target);
7323
7545
  if (entries.length === 0) return;
7324
7546
  if (entries.every((name) => IGNORABLE_ENTRIES.has(name))) return;
7325
7547
  if (containsNoFiles(target)) return;
@@ -7339,18 +7561,18 @@ function assertReplaceable(target, label, secretRules) {
7339
7561
  );
7340
7562
  }
7341
7563
  function assertStagingRootUsable(tmpDir, secretRules) {
7342
- if (!fs11__namespace.existsSync(tmpDir)) return;
7343
- if (!fs11__namespace.statSync(tmpDir).isDirectory()) {
7564
+ if (!fs12__namespace.existsSync(tmpDir)) return;
7565
+ if (!fs12__namespace.statSync(tmpDir).isDirectory()) {
7344
7566
  throw new Error(`Refusing to write into tmpDir ${tmpDir}: it exists but is not a directory.`);
7345
7567
  }
7346
- const entries = fs11__namespace.readdirSync(tmpDir);
7568
+ const entries = fs12__namespace.readdirSync(tmpDir);
7347
7569
  if (entries.length === 0) return;
7348
7570
  const foreign = entries.filter((name) => {
7349
- const full = path12__namespace.join(tmpDir, name);
7571
+ const full = path13__namespace.join(tmpDir, name);
7350
7572
  if (!name.startsWith(RUN_DIR_PREFIX)) return true;
7351
7573
  let stats;
7352
7574
  try {
7353
- stats = fs11__namespace.statSync(full);
7575
+ stats = fs12__namespace.statSync(full);
7354
7576
  } catch {
7355
7577
  return true;
7356
7578
  }
@@ -7358,7 +7580,7 @@ function assertStagingRootUsable(tmpDir, secretRules) {
7358
7580
  const { marker: marker2 } = readOwnershipMarker(full);
7359
7581
  if (marker2) return false;
7360
7582
  try {
7361
- return fs11__namespace.readdirSync(full).length > 0;
7583
+ return fs12__namespace.readdirSync(full).length > 0;
7362
7584
  } catch {
7363
7585
  return true;
7364
7586
  }
@@ -7373,13 +7595,13 @@ function assertStagingRootUsable(tmpDir, secretRules) {
7373
7595
  function cleanStaleRunDirs(tmpDir) {
7374
7596
  let entries;
7375
7597
  try {
7376
- entries = fs11__namespace.readdirSync(tmpDir);
7598
+ entries = fs12__namespace.readdirSync(tmpDir);
7377
7599
  } catch {
7378
7600
  return;
7379
7601
  }
7380
7602
  for (const name of entries) {
7381
7603
  if (!name.startsWith(RUN_DIR_PREFIX)) continue;
7382
- const full = path12__namespace.join(tmpDir, name);
7604
+ const full = path13__namespace.join(tmpDir, name);
7383
7605
  const { marker: marker2 } = readOwnershipMarker(full);
7384
7606
  if (marker2) {
7385
7607
  const created = Date.parse(marker2.createdAt);
@@ -7387,33 +7609,33 @@ function cleanStaleRunDirs(tmpDir) {
7387
7609
  const abandoned = typeof marker2.pid === "number" && !isProcessAlive(marker2.pid);
7388
7610
  if (aged || abandoned) {
7389
7611
  try {
7390
- fs11__namespace.rmSync(full, { recursive: true, force: true });
7612
+ fs12__namespace.rmSync(full, { recursive: true, force: true });
7391
7613
  } catch {
7392
7614
  }
7393
7615
  }
7394
7616
  continue;
7395
7617
  }
7396
7618
  try {
7397
- if (fs11__namespace.readdirSync(full).length === 0) fs11__namespace.rmSync(full, { recursive: true, force: true });
7619
+ if (fs12__namespace.readdirSync(full).length === 0) fs12__namespace.rmSync(full, { recursive: true, force: true });
7398
7620
  } catch {
7399
7621
  }
7400
7622
  }
7401
7623
  }
7402
7624
  function removeIfEmpty(dir) {
7403
7625
  try {
7404
- if (fs11__namespace.readdirSync(dir).length === 0) fs11__namespace.rmSync(dir, { recursive: true, force: true });
7626
+ if (fs12__namespace.readdirSync(dir).length === 0) fs12__namespace.rmSync(dir, { recursive: true, force: true });
7405
7627
  } catch {
7406
7628
  }
7407
7629
  }
7408
7630
  function ensureParentDirectory(target, label) {
7409
- const parent = path12__namespace.dirname(target);
7410
- if (fs11__namespace.existsSync(parent) && !fs11__namespace.statSync(parent).isDirectory()) {
7631
+ const parent = path13__namespace.dirname(target);
7632
+ if (fs12__namespace.existsSync(parent) && !fs12__namespace.statSync(parent).isDirectory()) {
7411
7633
  throw new Error(
7412
7634
  `Refusing to create ${label} ${target}: ${parent} exists but is not a directory.`
7413
7635
  );
7414
7636
  }
7415
7637
  try {
7416
- fs11__namespace.mkdirSync(parent, { recursive: true });
7638
+ fs12__namespace.mkdirSync(parent, { recursive: true });
7417
7639
  } catch (err) {
7418
7640
  throw new Error(
7419
7641
  `Refusing to create ${label} ${target}: its parent ${parent} could not be created (${err.message}).`
@@ -7422,7 +7644,7 @@ function ensureParentDirectory(target, label) {
7422
7644
  }
7423
7645
  function acquireRunLock(stagingRoot) {
7424
7646
  const key = lockKeyFor(stagingRoot);
7425
- const lockPath = path12__namespace.join(os__namespace.tmpdir(), `codebase-snapshot-${key}.lock`);
7647
+ const lockPath = path13__namespace.join(os__namespace.tmpdir(), `codebase-snapshot-${key}.lock`);
7426
7648
  const payload = `${JSON.stringify({
7427
7649
  pid: process.pid,
7428
7650
  stagingRoot,
@@ -7431,22 +7653,22 @@ function acquireRunLock(stagingRoot) {
7431
7653
  `;
7432
7654
  for (let attempt = 0; attempt < 2; attempt += 1) {
7433
7655
  try {
7434
- const handle = fs11__namespace.openSync(lockPath, "wx");
7656
+ const handle = fs12__namespace.openSync(lockPath, "wx");
7435
7657
  try {
7436
- fs11__namespace.writeSync(handle, payload);
7658
+ fs12__namespace.writeSync(handle, payload);
7437
7659
  } finally {
7438
- fs11__namespace.closeSync(handle);
7660
+ fs12__namespace.closeSync(handle);
7439
7661
  }
7440
7662
  return () => {
7441
7663
  try {
7442
- fs11__namespace.rmSync(lockPath, { force: true });
7664
+ fs12__namespace.rmSync(lockPath, { force: true });
7443
7665
  } catch {
7444
7666
  }
7445
7667
  };
7446
7668
  } catch (err) {
7447
7669
  if (err.code !== "EEXIST") throw err;
7448
7670
  if (attempt === 0 && lockOwnerIsGone(lockPath)) {
7449
- fs11__namespace.rmSync(lockPath, { force: true });
7671
+ fs12__namespace.rmSync(lockPath, { force: true });
7450
7672
  continue;
7451
7673
  }
7452
7674
  throw new Error(
@@ -7459,7 +7681,7 @@ function acquireRunLock(stagingRoot) {
7459
7681
  function lockKeyFor(stagingRoot) {
7460
7682
  let key = stagingRoot;
7461
7683
  try {
7462
- key = fs11__namespace.realpathSync(stagingRoot);
7684
+ key = fs12__namespace.realpathSync(stagingRoot);
7463
7685
  } catch {
7464
7686
  }
7465
7687
  if (process.platform === "win32" || process.platform === "darwin") key = key.toLowerCase();
@@ -7468,7 +7690,7 @@ function lockKeyFor(stagingRoot) {
7468
7690
  function lockOwnerIsGone(lockPath) {
7469
7691
  let raw;
7470
7692
  try {
7471
- raw = fs11__namespace.readFileSync(lockPath, "utf8");
7693
+ raw = fs12__namespace.readFileSync(lockPath, "utf8");
7472
7694
  } catch {
7473
7695
  return false;
7474
7696
  }
@@ -7488,12 +7710,12 @@ function lockOwnerIsGone(lockPath) {
7488
7710
  }
7489
7711
  function writeManifestAtomically(manifestPath, manifest) {
7490
7712
  const tempPath = `${manifestPath}.${process.pid}.tmp`;
7491
- fs11__namespace.writeFileSync(tempPath, JSON.stringify(manifest, null, 2), "utf8");
7713
+ fs12__namespace.writeFileSync(tempPath, JSON.stringify(manifest, null, 2), "utf8");
7492
7714
  try {
7493
- fs11__namespace.renameSync(tempPath, manifestPath);
7715
+ fs12__namespace.renameSync(tempPath, manifestPath);
7494
7716
  } catch (err) {
7495
7717
  try {
7496
- fs11__namespace.rmSync(tempPath, { force: true });
7718
+ fs12__namespace.rmSync(tempPath, { force: true });
7497
7719
  } catch {
7498
7720
  }
7499
7721
  throw err;
@@ -7516,31 +7738,31 @@ function swapIntoPlace(stagingDir, outDir) {
7516
7738
  }
7517
7739
  function swapOnce(stagingDir, outDir) {
7518
7740
  const backupDir = `${outDir}.backup-${process.pid}-${Date.now()}`;
7519
- const hadPrevious = fs11__namespace.existsSync(outDir);
7520
- if (hadPrevious) fs11__namespace.renameSync(outDir, backupDir);
7741
+ const hadPrevious = fs12__namespace.existsSync(outDir);
7742
+ if (hadPrevious) fs12__namespace.renameSync(outDir, backupDir);
7521
7743
  try {
7522
7744
  try {
7523
- fs11__namespace.renameSync(stagingDir, outDir);
7745
+ fs12__namespace.renameSync(stagingDir, outDir);
7524
7746
  } catch (err) {
7525
7747
  if (err.code !== "EXDEV") throw err;
7526
7748
  const partialDir = `${outDir}.partial-${process.pid}-${Date.now()}`;
7527
7749
  try {
7528
- fs11__namespace.cpSync(stagingDir, partialDir, { recursive: true });
7529
- fs11__namespace.renameSync(partialDir, outDir);
7530
- fs11__namespace.rmSync(stagingDir, { recursive: true, force: true });
7750
+ fs12__namespace.cpSync(stagingDir, partialDir, { recursive: true });
7751
+ fs12__namespace.renameSync(partialDir, outDir);
7752
+ fs12__namespace.rmSync(stagingDir, { recursive: true, force: true });
7531
7753
  } catch (copyErr) {
7532
7754
  try {
7533
- fs11__namespace.rmSync(partialDir, { recursive: true, force: true });
7755
+ fs12__namespace.rmSync(partialDir, { recursive: true, force: true });
7534
7756
  } catch {
7535
7757
  }
7536
7758
  throw copyErr;
7537
7759
  }
7538
7760
  }
7539
- if (hadPrevious) fs11__namespace.rmSync(backupDir, { recursive: true, force: true });
7761
+ if (hadPrevious) fs12__namespace.rmSync(backupDir, { recursive: true, force: true });
7540
7762
  } catch (err) {
7541
- if (hadPrevious && fs11__namespace.existsSync(backupDir)) {
7542
- if (fs11__namespace.existsSync(outDir)) fs11__namespace.rmSync(outDir, { recursive: true, force: true });
7543
- fs11__namespace.renameSync(backupDir, outDir);
7763
+ if (hadPrevious && fs12__namespace.existsSync(backupDir)) {
7764
+ if (fs12__namespace.existsSync(outDir)) fs12__namespace.rmSync(outDir, { recursive: true, force: true });
7765
+ fs12__namespace.renameSync(backupDir, outDir);
7544
7766
  }
7545
7767
  throw err;
7546
7768
  }
@@ -7635,7 +7857,7 @@ function generateSnapshot(configInput, options) {
7635
7857
  // first run cannot have marked them yet, so the name alone keeps a run from recording its own
7636
7858
  // output — but only at these exact paths, not at every directory that shares the name.
7637
7859
  toolOwnedPaths: [config.outDir, config.tmpDir].map(
7638
- (directory) => path12__namespace.relative(config.cwd, path12__namespace.resolve(config.cwd, directory)).replace(/\\/g, "/")
7860
+ (directory) => path13__namespace.relative(config.cwd, path13__namespace.resolve(config.cwd, directory)).replace(/\\/g, "/")
7639
7861
  ).filter((relative11) => relative11.length > 0 && !relative11.startsWith(".."))
7640
7862
  });
7641
7863
  const files = [];
@@ -7656,12 +7878,12 @@ function generateSnapshot(configInput, options) {
7656
7878
  let totalSizeBytes = 0;
7657
7879
  let largeFileCount = 0;
7658
7880
  for (const relativePath of collection.files) {
7659
- const absolutePath = path12__namespace.join(config.cwd, relativePath);
7881
+ const absolutePath = path13__namespace.join(config.cwd, relativePath);
7660
7882
  let stats;
7661
7883
  try {
7662
- stats = fs11__namespace.statSync(absolutePath);
7884
+ stats = fs12__namespace.statSync(absolutePath);
7663
7885
  if (!stats.isFile()) {
7664
- const nestedRepository = stats.isDirectory() && fs11__namespace.existsSync(path12__namespace.join(absolutePath, ".git"));
7886
+ const nestedRepository = stats.isDirectory() && fs12__namespace.existsSync(path13__namespace.join(absolutePath, ".git"));
7665
7887
  skipped.push(
7666
7888
  nestedRepository ? {
7667
7889
  path: relativePath,
@@ -7681,7 +7903,7 @@ function generateSnapshot(configInput, options) {
7681
7903
  }
7682
7904
  let buffer;
7683
7905
  try {
7684
- buffer = fs11__namespace.readFileSync(absolutePath);
7906
+ buffer = fs12__namespace.readFileSync(absolutePath);
7685
7907
  } catch {
7686
7908
  skipped.push({ path: relativePath, reason: "read-error" });
7687
7909
  continue;
@@ -8011,12 +8233,12 @@ function generateSnapshot(configInput, options) {
8011
8233
  let stagingDir = null;
8012
8234
  try {
8013
8235
  ensureParentDirectory(outDir, "outDir");
8014
- fs11__namespace.mkdirSync(tmpDir, { recursive: true });
8236
+ fs12__namespace.mkdirSync(tmpDir, { recursive: true });
8015
8237
  cleanStaleRunDirs(tmpDir);
8016
8238
  const snapshotId = crypto2__namespace.randomUUID();
8017
8239
  const createdAt = (/* @__PURE__ */ new Date()).toISOString();
8018
- stagingDir = path12__namespace.join(tmpDir, `${RUN_DIR_PREFIX}${process.pid}-${snapshotId.slice(0, 8)}`);
8019
- fs11__namespace.mkdirSync(stagingDir);
8240
+ stagingDir = path13__namespace.join(tmpDir, `${RUN_DIR_PREFIX}${process.pid}-${snapshotId.slice(0, 8)}`);
8241
+ fs12__namespace.mkdirSync(stagingDir);
8020
8242
  writeOwnershipMarker(stagingDir, {
8021
8243
  generator: GENERATOR_NAME,
8022
8244
  version: GENERATOR_VERSION,
@@ -8026,41 +8248,41 @@ function generateSnapshot(configInput, options) {
8026
8248
  id: snapshotId,
8027
8249
  pid: process.pid
8028
8250
  });
8029
- const partsDir = path12__namespace.join(stagingDir, "parts");
8030
- const reportsDir = path12__namespace.join(stagingDir, "reports");
8031
- if (artifacts.parts) fs11__namespace.mkdirSync(partsDir, { recursive: true });
8251
+ const partsDir = path13__namespace.join(stagingDir, "parts");
8252
+ const reportsDir = path13__namespace.join(stagingDir, "reports");
8253
+ if (artifacts.parts) fs12__namespace.mkdirSync(partsDir, { recursive: true });
8032
8254
  if (artifacts.navigation || artifacts.projectTree || artifacts.audit) {
8033
- fs11__namespace.mkdirSync(reportsDir, { recursive: true });
8255
+ fs12__namespace.mkdirSync(reportsDir, { recursive: true });
8034
8256
  }
8035
8257
  if (artifacts.parts) {
8036
8258
  for (const part of parts) {
8037
- fs11__namespace.writeFileSync(path12__namespace.join(partsDir, part.filename), part.markdown, "utf8");
8259
+ fs12__namespace.writeFileSync(path13__namespace.join(partsDir, part.filename), part.markdown, "utf8");
8038
8260
  }
8039
8261
  }
8040
8262
  if (projectTree !== null) {
8041
- fs11__namespace.writeFileSync(path12__namespace.join(reportsDir, "project-tree.md"), projectTree, "utf8");
8263
+ fs12__namespace.writeFileSync(path13__namespace.join(reportsDir, "project-tree.md"), projectTree, "utf8");
8042
8264
  }
8043
8265
  if (artifacts.navigation) {
8044
- fs11__namespace.writeFileSync(path12__namespace.join(reportsDir, "navigation.md"), generateNavigation(manifest), "utf8");
8266
+ fs12__namespace.writeFileSync(path13__namespace.join(reportsDir, "navigation.md"), generateNavigation(manifest), "utf8");
8045
8267
  }
8046
8268
  if (artifacts.audit) {
8047
- fs11__namespace.writeFileSync(
8048
- path12__namespace.join(reportsDir, "audit.md"),
8269
+ fs12__namespace.writeFileSync(
8270
+ path13__namespace.join(reportsDir, "audit.md"),
8049
8271
  generateAuditReport(manifest, secretFindings, config.secretRules),
8050
8272
  "utf8"
8051
8273
  );
8052
8274
  }
8053
8275
  if (artifacts.readme) {
8054
- fs11__namespace.writeFileSync(path12__namespace.join(stagingDir, "README.md"), generateReadme(manifest, artifacts), "utf8");
8276
+ fs12__namespace.writeFileSync(path13__namespace.join(stagingDir, "README.md"), generateReadme(manifest, artifacts), "utf8");
8055
8277
  }
8056
8278
  if (artifacts.manifest) {
8057
- fs11__namespace.writeFileSync(path12__namespace.join(stagingDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf8");
8279
+ fs12__namespace.writeFileSync(path13__namespace.join(stagingDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf8");
8058
8280
  }
8059
8281
  if (monolithJson !== null) {
8060
- fs11__namespace.writeFileSync(path12__namespace.join(stagingDir, "full-codebase.json"), monolithJson, "utf8");
8282
+ fs12__namespace.writeFileSync(path13__namespace.join(stagingDir, "full-codebase.json"), monolithJson, "utf8");
8061
8283
  }
8062
8284
  if (monolithMarkdown !== null) {
8063
- fs11__namespace.writeFileSync(path12__namespace.join(stagingDir, "full-codebase.md"), monolithMarkdown, "utf8");
8285
+ fs12__namespace.writeFileSync(path13__namespace.join(stagingDir, "full-codebase.md"), monolithMarkdown, "utf8");
8064
8286
  }
8065
8287
  writeOwnershipMarker(stagingDir, markerPayload(stagingDir, "complete", snapshotId, createdAt));
8066
8288
  swapIntoPlace(stagingDir, outDir);
@@ -8069,7 +8291,7 @@ function generateSnapshot(configInput, options) {
8069
8291
  const pendingHook = runAfterGenerate(config, manifest);
8070
8292
  const shipHookState = () => {
8071
8293
  if (artifacts.manifest && manifest.warnings.length !== warningsBeforeHook) {
8072
- writeManifestAtomically(path12__namespace.join(outDir, "manifest.json"), manifest);
8294
+ writeManifestAtomically(path13__namespace.join(outDir, "manifest.json"), manifest);
8073
8295
  }
8074
8296
  writeOwnershipMarker(outDir, markerPayload(outDir, "complete", snapshotId, createdAt));
8075
8297
  };
@@ -8092,7 +8314,7 @@ function generateSnapshot(configInput, options) {
8092
8314
  } catch (err) {
8093
8315
  if (stagingDir !== null) {
8094
8316
  try {
8095
- fs11__namespace.rmSync(stagingDir, { recursive: true, force: true });
8317
+ fs12__namespace.rmSync(stagingDir, { recursive: true, force: true });
8096
8318
  } catch {
8097
8319
  }
8098
8320
  }
@@ -8189,9 +8411,9 @@ function foldForComparison(value) {
8189
8411
  return process.platform === "win32" || process.platform === "darwin" ? value.toLowerCase() : value;
8190
8412
  }
8191
8413
  function canonicalPath(value) {
8192
- const absolute = path12__namespace.resolve(value);
8414
+ const absolute = path13__namespace.resolve(value);
8193
8415
  try {
8194
- return fs11__namespace.realpathSync(absolute);
8416
+ return fs12__namespace.realpathSync(absolute);
8195
8417
  } catch {
8196
8418
  return absolute;
8197
8419
  }
@@ -8199,17 +8421,17 @@ function canonicalPath(value) {
8199
8421
  function isInside2(parent, child) {
8200
8422
  const foldedParent = foldForComparison(parent);
8201
8423
  const foldedChild = foldForComparison(child);
8202
- return foldedChild === foldedParent || foldedChild.startsWith(`${foldedParent}${path12__namespace.sep}`);
8424
+ return foldedChild === foldedParent || foldedChild.startsWith(`${foldedParent}${path13__namespace.sep}`);
8203
8425
  }
8204
8426
  function resolveRoot(requested, context) {
8205
8427
  if (requested !== void 0 && (typeof requested !== "string" || requested.trim().length === 0)) {
8206
8428
  return { ok: false, message: '"root" must be a non-empty string when provided.' };
8207
8429
  }
8208
8430
  const wanted = typeof requested === "string" ? requested.trim() : context.cwd;
8209
- const absolute = path12__namespace.resolve(context.cwd, wanted);
8431
+ const absolute = path13__namespace.resolve(context.cwd, wanted);
8210
8432
  let stats;
8211
8433
  try {
8212
- stats = fs11__namespace.statSync(absolute);
8434
+ stats = fs12__namespace.statSync(absolute);
8213
8435
  } catch {
8214
8436
  return { ok: false, message: `"${wanted}" does not exist, so it cannot be a repository root.` };
8215
8437
  }
@@ -8260,14 +8482,14 @@ async function openWorkspace(root, overrides = {}) {
8260
8482
  }
8261
8483
  var manifestCache = /* @__PURE__ */ new Map();
8262
8484
  function manifestPathFor(workspace) {
8263
- return path12__namespace.resolve(workspace.root, workspace.config.outDir, "manifest.json");
8485
+ return path13__namespace.resolve(workspace.root, workspace.config.outDir, "manifest.json");
8264
8486
  }
8265
8487
  function readManifest3(workspace) {
8266
8488
  const file = manifestPathFor(workspace);
8267
- const shown = path12__namespace.relative(workspace.root, file).split(path12__namespace.sep).join("/") || file;
8489
+ const shown = path13__namespace.relative(workspace.root, file).split(path13__namespace.sep).join("/") || file;
8268
8490
  let stats;
8269
8491
  try {
8270
- stats = fs11__namespace.statSync(file);
8492
+ stats = fs12__namespace.statSync(file);
8271
8493
  } catch {
8272
8494
  return {
8273
8495
  ok: false,
@@ -8281,7 +8503,7 @@ function readManifest3(workspace) {
8281
8503
  }
8282
8504
  let raw;
8283
8505
  try {
8284
- raw = fs11__namespace.readFileSync(file, "utf8");
8506
+ raw = fs12__namespace.readFileSync(file, "utf8");
8285
8507
  } catch (error) {
8286
8508
  return {
8287
8509
  ok: false,
@@ -8339,7 +8561,7 @@ function formatBytes(bytes) {
8339
8561
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
8340
8562
  }
8341
8563
  function relativeFor(workspace, absolute) {
8342
- return path12__namespace.relative(workspace.root, absolute).split(path12__namespace.sep).join("/");
8564
+ return path13__namespace.relative(workspace.root, absolute).split(path13__namespace.sep).join("/");
8343
8565
  }
8344
8566
  function capped(values, limit = 20) {
8345
8567
  return { count: values.length, sample: values.slice(0, limit) };
@@ -8358,12 +8580,12 @@ function summarizeDrift(drift) {
8358
8580
  function toRelativePath(root, value) {
8359
8581
  const cleaned = value.trim();
8360
8582
  if (cleaned.length === 0) return null;
8361
- if (!path12__namespace.isAbsolute(cleaned)) {
8583
+ if (!path13__namespace.isAbsolute(cleaned)) {
8362
8584
  return cleaned.replace(/\\/g, "/").replace(/^\.\//, "");
8363
8585
  }
8364
- const relative11 = path12__namespace.relative(root, cleaned);
8365
- if (relative11.startsWith("..") || path12__namespace.isAbsolute(relative11)) return null;
8366
- return relative11.split(path12__namespace.sep).join("/");
8586
+ const relative11 = path13__namespace.relative(root, cleaned);
8587
+ if (relative11.startsWith("..") || path13__namespace.isAbsolute(relative11)) return null;
8588
+ return relative11.split(path13__namespace.sep).join("/");
8367
8589
  }
8368
8590
  function symbolsOf(entry) {
8369
8591
  const summary = entry.summary;
@@ -8574,7 +8796,7 @@ var generateTool = {
8574
8796
  return failure(error instanceof Error ? error.message : String(error));
8575
8797
  }
8576
8798
  forgetManifest(manifestPathFor(workspace));
8577
- const written = relativeFor(workspace, path12__namespace.resolve(workspace.root, workspace.config.outDir));
8799
+ const written = relativeFor(workspace, path13__namespace.resolve(workspace.root, workspace.config.outDir));
8578
8800
  const lines = [
8579
8801
  `Wrote ${written}/`,
8580
8802
  `Files: ${manifest.counts.totalFiles} included, ${manifest.counts.skippedCount} skipped, ${plural(manifest.counts.partsCount, "part")}`,
@@ -8839,10 +9061,10 @@ var readTool = {
8839
9061
  `${relativePath} is not in the snapshot. Call snapshot_locate to find the path, or snapshot_explain to learn why it was excluded.`
8840
9062
  );
8841
9063
  }
8842
- const partPath = path12__namespace.resolve(workspace.root, workspace.config.outDir, "parts", entry.part);
9064
+ const partPath = path13__namespace.resolve(workspace.root, workspace.config.outDir, "parts", entry.part);
8843
9065
  let partText;
8844
9066
  try {
8845
- partText = fs11__namespace.readFileSync(partPath, "utf8");
9067
+ partText = fs12__namespace.readFileSync(partPath, "utf8");
8846
9068
  } catch {
8847
9069
  return failure(
8848
9070
  `${entry.part} could not be read, so the snapshot is damaged. Run snapshot_generate to rebuild it.`
@@ -9100,6 +9322,7 @@ var VALIDATE_OPTIONS = [
9100
9322
  "no-config",
9101
9323
  "discovery",
9102
9324
  "format",
9325
+ "no-update-check",
9103
9326
  "mode",
9104
9327
  "help",
9105
9328
  "version"
@@ -9123,6 +9346,7 @@ var COMMAND_OPTION_SCOPE = {
9123
9346
  "watch",
9124
9347
  "autopilot",
9125
9348
  "no-install",
9349
+ "no-update-check",
9126
9350
  "help",
9127
9351
  "version"
9128
9352
  ],
@@ -9138,6 +9362,7 @@ var COMMAND_OPTION_SCOPE = {
9138
9362
  "skip-artifacts",
9139
9363
  "only-artifacts",
9140
9364
  "no-config",
9365
+ "no-update-check",
9141
9366
  "format",
9142
9367
  "mode",
9143
9368
  "help",
@@ -9155,12 +9380,13 @@ var COMMAND_OPTION_SCOPE = {
9155
9380
  "only-artifacts",
9156
9381
  "no-config",
9157
9382
  "discovery",
9383
+ "no-update-check",
9158
9384
  "format",
9159
9385
  "mode",
9160
9386
  "help",
9161
9387
  "version"
9162
9388
  ],
9163
- diff: ["format", "mode", "no-config", "help", "version"],
9389
+ diff: ["format", "mode", "no-config", "no-update-check", "help", "version"],
9164
9390
  describe: ["format", "mode", "help", "version"],
9165
9391
  init: [
9166
9392
  "cwd",
@@ -9175,6 +9401,7 @@ var COMMAND_OPTION_SCOPE = {
9175
9401
  "yes",
9176
9402
  "force",
9177
9403
  "dry-run",
9404
+ "no-update-check",
9178
9405
  "format",
9179
9406
  "mode",
9180
9407
  "help",
@@ -9198,6 +9425,7 @@ var COMMAND_OPTION_SCOPE = {
9198
9425
  "force",
9199
9426
  "no-install",
9200
9427
  "dry-run",
9428
+ "no-update-check",
9201
9429
  "format",
9202
9430
  "mode",
9203
9431
  "help",
@@ -9630,6 +9858,13 @@ function buildAgentContract() {
9630
9858
  default: false,
9631
9859
  appliesTo: optionAppliesTo("no-install"),
9632
9860
  summary: "Skip installing the dependency before generating: `setup`, or `generate --autopilot` (CI, offline, or a lockfile you do not want a package manager to touch)."
9861
+ },
9862
+ {
9863
+ flag: "--no-update-check",
9864
+ type: "boolean",
9865
+ default: false,
9866
+ appliesTo: optionAppliesTo("no-update-check"),
9867
+ summary: "Skip the once-a-day check for a newer published version. The check is already skipped when stdout is not a terminal, in CI, in a JSON invocation, and in `mcp`, which makes no network requests."
9633
9868
  }
9634
9869
  ],
9635
9870
  presets: PRESETS.map((preset) => ({
@@ -9917,17 +10152,17 @@ var LEGACY_AGENTS_MARKER = "<!-- codebase-snapshot:skill:start -->";
9917
10152
  function targetPath(cwd, target) {
9918
10153
  switch (target) {
9919
10154
  case "claude":
9920
- return path12__namespace.join(cwd, ".claude", "skills", SKILL_NAME, "SKILL.md");
10155
+ return path13__namespace.join(cwd, ".claude", "skills", SKILL_NAME, "SKILL.md");
9921
10156
  case "cursor":
9922
- return path12__namespace.join(cwd, ".cursor", "rules", `${SKILL_NAME}.mdc`);
10157
+ return path13__namespace.join(cwd, ".cursor", "rules", `${SKILL_NAME}.mdc`);
9923
10158
  }
9924
10159
  }
9925
10160
  function assertWritableInsideRepository(cwd, filePath) {
9926
- const root = fs11__namespace.realpathSync(cwd);
9927
- const shown = path12__namespace.relative(root, filePath) || filePath;
10161
+ const root = fs12__namespace.realpathSync(cwd);
10162
+ const shown = path13__namespace.relative(root, filePath) || filePath;
9928
10163
  let stat = null;
9929
10164
  try {
9930
- stat = fs11__namespace.lstatSync(filePath);
10165
+ stat = fs12__namespace.lstatSync(filePath);
9931
10166
  } catch {
9932
10167
  stat = null;
9933
10168
  }
@@ -9943,32 +10178,32 @@ function assertWritableInsideRepository(cwd, filePath) {
9943
10178
  }
9944
10179
  let existing = filePath;
9945
10180
  const missing = [];
9946
- while (!fs11__namespace.existsSync(existing)) {
9947
- missing.unshift(path12__namespace.basename(existing));
9948
- const parent = path12__namespace.dirname(existing);
10181
+ while (!fs12__namespace.existsSync(existing)) {
10182
+ missing.unshift(path13__namespace.basename(existing));
10183
+ const parent = path13__namespace.dirname(existing);
9949
10184
  if (parent === existing) break;
9950
10185
  existing = parent;
9951
10186
  }
9952
- const realAncestor = fs11__namespace.realpathSync(existing);
9953
- const resolved = missing.length === 0 ? realAncestor : path12__namespace.join(realAncestor, ...missing);
9954
- if (resolved !== root && !resolved.startsWith(`${root}${path12__namespace.sep}`)) {
10187
+ const realAncestor = fs12__namespace.realpathSync(existing);
10188
+ const resolved = missing.length === 0 ? realAncestor : path13__namespace.join(realAncestor, ...missing);
10189
+ if (resolved !== root && !resolved.startsWith(`${root}${path13__namespace.sep}`)) {
9955
10190
  throw new Error(
9956
10191
  `${REFUSED}: ${shown} resolves outside the repository (${resolved}). Move it back inside ${root}, or remove the link, and run again.`
9957
10192
  );
9958
10193
  }
9959
10194
  }
9960
10195
  function writeIfChanged(target, filePath, content) {
9961
- const existing = fs11__namespace.existsSync(filePath) ? fs11__namespace.readFileSync(filePath, "utf8") : null;
10196
+ const existing = fs12__namespace.existsSync(filePath) ? fs12__namespace.readFileSync(filePath, "utf8") : null;
9962
10197
  if (existing === content) return { target, path: filePath, action: "unchanged" };
9963
- fs11__namespace.mkdirSync(path12__namespace.dirname(filePath), { recursive: true });
9964
- fs11__namespace.writeFileSync(filePath, content, "utf8");
10198
+ fs12__namespace.mkdirSync(path13__namespace.dirname(filePath), { recursive: true });
10199
+ fs12__namespace.writeFileSync(filePath, content, "utf8");
9965
10200
  return { target, path: filePath, action: existing === null ? "created" : "updated" };
9966
10201
  }
9967
10202
  function legacyAgentsNote(cwd) {
9968
- const filePath = path12__namespace.join(cwd, "AGENTS.md");
10203
+ const filePath = path13__namespace.join(cwd, "AGENTS.md");
9969
10204
  try {
9970
- if (!fs11__namespace.existsSync(filePath)) return null;
9971
- if (!fs11__namespace.readFileSync(filePath, "utf8").includes(LEGACY_AGENTS_MARKER)) return null;
10205
+ if (!fs12__namespace.existsSync(filePath)) return null;
10206
+ if (!fs12__namespace.readFileSync(filePath, "utf8").includes(LEGACY_AGENTS_MARKER)) return null;
9972
10207
  } catch {
9973
10208
  return null;
9974
10209
  }
@@ -9980,9 +10215,9 @@ function installSkill(cwd, target = "all") {
9980
10215
  const notes = [];
9981
10216
  const wanted = target === "all" ? ["claude", "cursor"] : [target];
9982
10217
  for (const item of wanted) assertWritableInsideRepository(cwd, targetPath(cwd, item));
9983
- const createsSomething = wanted.some((item) => !fs11__namespace.existsSync(targetPath(cwd, item)));
10218
+ const createsSomething = wanted.some((item) => !fs12__namespace.existsSync(targetPath(cwd, item)));
9984
10219
  if (createsSomething) {
9985
- assertWritableInsideRepository(cwd, path12__namespace.join(cwd, ".gitignore"));
10220
+ assertWritableInsideRepository(cwd, path13__namespace.join(cwd, ".gitignore"));
9986
10221
  }
9987
10222
  for (const item of wanted) {
9988
10223
  written.push(writeIfChanged(item, targetPath(cwd, item), skill));
@@ -10117,52 +10352,52 @@ function validateArguments(schema, value) {
10117
10352
  }
10118
10353
  return problems;
10119
10354
  }
10120
- function checkValue(path18, schema, value) {
10355
+ function checkValue(path19, schema, value) {
10121
10356
  if (schema.enum && !schema.enum.includes(value)) {
10122
- return [`"${path18}" must be one of: ${schema.enum.join(", ")}`];
10357
+ return [`"${path19}" must be one of: ${schema.enum.join(", ")}`];
10123
10358
  }
10124
10359
  switch (schema.type) {
10125
10360
  case "string": {
10126
- if (typeof value !== "string") return [`"${path18}" must be a string`];
10361
+ if (typeof value !== "string") return [`"${path19}" must be a string`];
10127
10362
  const problems = [];
10128
10363
  if (schema.minLength !== void 0 && value.length < schema.minLength) {
10129
- problems.push(`"${path18}" must be at least ${schema.minLength} character(s)`);
10364
+ problems.push(`"${path19}" must be at least ${schema.minLength} character(s)`);
10130
10365
  }
10131
10366
  if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
10132
- problems.push(`"${path18}" must be at most ${schema.maxLength} character(s)`);
10367
+ problems.push(`"${path19}" must be at most ${schema.maxLength} character(s)`);
10133
10368
  }
10134
10369
  return problems;
10135
10370
  }
10136
10371
  case "number":
10137
10372
  case "integer": {
10138
10373
  if (typeof value !== "number" || Number.isNaN(value)) {
10139
- return [`"${path18}" must be a number`];
10374
+ return [`"${path19}" must be a number`];
10140
10375
  }
10141
10376
  if (schema.type === "integer" && !Number.isInteger(value)) {
10142
- return [`"${path18}" must be an integer`];
10377
+ return [`"${path19}" must be an integer`];
10143
10378
  }
10144
10379
  const problems = [];
10145
10380
  if (schema.minimum !== void 0 && value < schema.minimum) {
10146
- problems.push(`"${path18}" must be >= ${schema.minimum}`);
10381
+ problems.push(`"${path19}" must be >= ${schema.minimum}`);
10147
10382
  }
10148
10383
  if (schema.maximum !== void 0 && value > schema.maximum) {
10149
- problems.push(`"${path18}" must be <= ${schema.maximum}`);
10384
+ problems.push(`"${path19}" must be <= ${schema.maximum}`);
10150
10385
  }
10151
10386
  return problems;
10152
10387
  }
10153
10388
  case "boolean":
10154
- return typeof value === "boolean" ? [] : [`"${path18}" must be a boolean`];
10389
+ return typeof value === "boolean" ? [] : [`"${path19}" must be a boolean`];
10155
10390
  case "array": {
10156
- if (!Array.isArray(value)) return [`"${path18}" must be an array`];
10391
+ if (!Array.isArray(value)) return [`"${path19}" must be an array`];
10157
10392
  if (!schema.items) return [];
10158
10393
  const problems = [];
10159
10394
  value.forEach((item, index) => {
10160
- problems.push(...checkValue(`${path18}[${index}]`, schema.items, item));
10395
+ problems.push(...checkValue(`${path19}[${index}]`, schema.items, item));
10161
10396
  });
10162
10397
  return problems;
10163
10398
  }
10164
10399
  case "object":
10165
- return isJsonObject(value) ? [] : [`"${path18}" must be an object`];
10400
+ return isJsonObject(value) ? [] : [`"${path19}" must be an object`];
10166
10401
  default:
10167
10402
  return [];
10168
10403
  }
@@ -10176,6 +10411,18 @@ function applyDefaults(schema, value) {
10176
10411
  }
10177
10412
  return out;
10178
10413
  }
10414
+ function coerceNumericStrings(schema, value) {
10415
+ const out = { ...value };
10416
+ for (const [key, propertySchema] of Object.entries(schema.properties)) {
10417
+ const raw = out[key];
10418
+ if (typeof raw !== "string") continue;
10419
+ if (propertySchema.type !== "number" && propertySchema.type !== "integer") continue;
10420
+ if (raw.trim().length === 0) continue;
10421
+ const parsed = Number(raw);
10422
+ if (Number.isFinite(parsed)) out[key] = parsed;
10423
+ }
10424
+ return out;
10425
+ }
10179
10426
 
10180
10427
  // src/mcp/server.ts
10181
10428
  function capabilities() {
@@ -10264,7 +10511,8 @@ function createMcpServer(options) {
10264
10511
  if (!isJsonObject(rawArguments)) {
10265
10512
  return errorResponse(id, ERROR_CODES.invalidParams, '"arguments" must be a JSON object.');
10266
10513
  }
10267
- const problems = validateArguments(tool.inputSchema, rawArguments);
10514
+ const supplied = coerceNumericStrings(tool.inputSchema, rawArguments);
10515
+ const problems = validateArguments(tool.inputSchema, supplied);
10268
10516
  if (problems.length > 0) {
10269
10517
  return ok(
10270
10518
  id,
@@ -10276,7 +10524,7 @@ function createMcpServer(options) {
10276
10524
  modern
10277
10525
  );
10278
10526
  }
10279
- const args = applyDefaults(tool.inputSchema, rawArguments);
10527
+ const args = applyDefaults(tool.inputSchema, supplied);
10280
10528
  let outcome;
10281
10529
  try {
10282
10530
  outcome = await tool.handler(args, options.context);
@@ -10474,7 +10722,7 @@ async function workspaceFor(context) {
10474
10722
  }
10475
10723
  function readFileIfPresent(file) {
10476
10724
  try {
10477
- return fs11__namespace.readFileSync(file, "utf8");
10725
+ return fs12__namespace.readFileSync(file, "utf8");
10478
10726
  } catch {
10479
10727
  return null;
10480
10728
  }
@@ -10553,7 +10801,7 @@ function buildResourceProvider() {
10553
10801
  const report = REPORT_URIS.get(uri);
10554
10802
  if (report) {
10555
10803
  const text2 = readFileIfPresent(
10556
- path12__namespace.resolve(workspace.root, workspace.config.outDir, "reports", report.file)
10804
+ path13__namespace.resolve(workspace.root, workspace.config.outDir, "reports", report.file)
10557
10805
  );
10558
10806
  if (text2 === null) return null;
10559
10807
  return { uri, mimeType: "text/markdown", text: capUtf8(text2, MAX_RESOURCE_BYTES).text };
@@ -10572,7 +10820,7 @@ function buildResourceProvider() {
10572
10820
  const part = read.manifest.parts.find((candidate) => candidate.index === index);
10573
10821
  if (!part) return null;
10574
10822
  const text2 = readFileIfPresent(
10575
- path12__namespace.resolve(workspace.root, workspace.config.outDir, "parts", part.filename)
10823
+ path13__namespace.resolve(workspace.root, workspace.config.outDir, "parts", part.filename)
10576
10824
  );
10577
10825
  if (text2 === null) return null;
10578
10826
  return { uri, mimeType: "text/markdown", text: capUtf8(text2, MAX_RESOURCE_BYTES).text };
@@ -10810,6 +11058,7 @@ var CLI_OPTIONS = {
10810
11058
  install: { type: "boolean" },
10811
11059
  "no-install": { type: "boolean" },
10812
11060
  target: { type: "string" },
11061
+ "no-update-check": { type: "boolean" },
10813
11062
  help: { type: "boolean", short: "h" },
10814
11063
  version: { type: "boolean", short: "v" }
10815
11064
  };
@@ -10884,6 +11133,8 @@ Options:
10884
11133
  --install Write the skill into the repository instead of printing
10885
11134
  --target <name> claude | cursor | all (default: all)
10886
11135
 
11136
+ --no-update-check Skip the daily check for a newer published version
11137
+
10887
11138
  -h, --help Display this help message
10888
11139
  -v, --version Display version
10889
11140
 
@@ -10960,10 +11211,10 @@ function parseCliArgs(argv) {
10960
11211
  }
10961
11212
  if (values.cwd !== void 0) {
10962
11213
  const target = String(values.cwd);
10963
- if (!fs11__namespace.existsSync(target)) {
11214
+ if (!fs12__namespace.existsSync(target)) {
10964
11215
  throw new UsageError(`--cwd directory does not exist: ${target}`);
10965
11216
  }
10966
- if (!fs11__namespace.statSync(target).isDirectory()) {
11217
+ if (!fs12__namespace.statSync(target).isDirectory()) {
10967
11218
  throw new UsageError(`--cwd is not a directory: ${target}`);
10968
11219
  }
10969
11220
  }
@@ -11109,7 +11360,7 @@ function parseCliArgs(argv) {
11109
11360
  install: values.install === true,
11110
11361
  noInstall: values["no-install"] === true,
11111
11362
  target: values.target === void 0 ? void 0 : String(values.target),
11112
- cwd: values.cwd === void 0 ? process.cwd() : path12__namespace.resolve(String(values.cwd)),
11363
+ cwd: values.cwd === void 0 ? process.cwd() : path13__namespace.resolve(String(values.cwd)),
11113
11364
  outDir: values["out-dir"] === void 0 ? void 0 : String(values["out-dir"]),
11114
11365
  includeMonolith: values["include-monolith"] === true || onlyNamesMonolith === true ? true : void 0,
11115
11366
  includeSensitiveFiles: values["include-sensitive-files"] === true ? true : void 0,
@@ -11166,24 +11417,24 @@ function splitList(value) {
11166
11417
  return value.split(",").map((entry) => entry.trim()).filter(Boolean);
11167
11418
  }
11168
11419
  function displayOutPath(cwd, outDir, ...segments) {
11169
- const absolute = path12__namespace.resolve(cwd, outDir, ...segments);
11170
- const relative11 = path12__namespace.relative(cwd, absolute);
11171
- if (relative11 && !relative11.startsWith("..") && !path12__namespace.isAbsolute(relative11)) return relative11;
11420
+ const absolute = path13__namespace.resolve(cwd, outDir, ...segments);
11421
+ const relative11 = path13__namespace.relative(cwd, absolute);
11422
+ if (relative11 && !relative11.startsWith("..") && !path13__namespace.isAbsolute(relative11)) return relative11;
11172
11423
  return absolute;
11173
11424
  }
11174
11425
  function nextStepHint(cwd, scriptsAddedNow) {
11175
11426
  let hasScript = scriptsAddedNow;
11176
11427
  if (!hasScript) {
11177
11428
  try {
11178
- const parsed = JSON.parse(fs11__namespace.readFileSync(path12__namespace.join(cwd, "package.json"), "utf8"));
11429
+ const parsed = JSON.parse(fs12__namespace.readFileSync(path13__namespace.join(cwd, "package.json"), "utf8"));
11179
11430
  hasScript = typeof parsed.scripts?.snapshot === "string";
11180
11431
  } catch {
11181
11432
  hasScript = false;
11182
11433
  }
11183
11434
  }
11184
11435
  if (!hasScript) return `npx ${GENERATOR_NAME} generate`;
11185
- const bin = path12__namespace.join(cwd, "node_modules", ".bin", "codebase-snapshot");
11186
- const installed = fs11__namespace.existsSync(bin) || fs11__namespace.existsSync(`${bin}.cmd`);
11436
+ const bin = path13__namespace.join(cwd, "node_modules", ".bin", "codebase-snapshot");
11437
+ const installed = fs12__namespace.existsSync(bin) || fs12__namespace.existsSync(`${bin}.cmd`);
11187
11438
  return installed ? "npm run snapshot" : "npm install && npm run snapshot";
11188
11439
  }
11189
11440
  function presetSummary(init) {
@@ -11213,7 +11464,7 @@ async function runInitCommand(invocation) {
11213
11464
  info(result.configText);
11214
11465
  return 0;
11215
11466
  }
11216
- info(`\u2705 Created ${path12__namespace.basename(result.configPath)} (${presetSummary(result)})`);
11467
+ info(`\u2705 Created ${path13__namespace.basename(result.configPath)} (${presetSummary(result)})`);
11217
11468
  if (result.scripts.length > 0) info(` Added npm scripts: ${result.scripts.join(", ")}`);
11218
11469
  if (result.dependency.added && result.dependency.range !== null) {
11219
11470
  info(` Added devDependency: ${result.dependency.name} ${result.dependency.range}`);
@@ -11233,7 +11484,7 @@ async function runInitCommand(invocation) {
11233
11484
  }
11234
11485
  }
11235
11486
  function detectPackageManager(cwd) {
11236
- const has = (name) => fs11__namespace.existsSync(path12__namespace.join(cwd, name));
11487
+ const has = (name) => fs12__namespace.existsSync(path13__namespace.join(cwd, name));
11237
11488
  if (has("bun.lockb") || has("bun.lock")) return { name: "bun", command: "bun", args: ["install"] };
11238
11489
  if (has("pnpm-lock.yaml")) return { name: "pnpm", command: "pnpm", args: ["install"] };
11239
11490
  if (has("yarn.lock")) return { name: "yarn", command: "yarn", args: ["install"] };
@@ -11322,7 +11573,7 @@ async function runSetupCommand(invocation, options = {}) {
11322
11573
  }
11323
11574
  info("\n\u{1F9EA} Dry run \u2014 setup would:");
11324
11575
  info(
11325
- ` 1. ${init.reused ? `keep ${path12__namespace.basename(init.configPath)}` : `write ${path12__namespace.basename(init.configPath)} (preset: ${init.preset})`}`
11576
+ ` 1. ${init.reused ? `keep ${path13__namespace.basename(init.configPath)}` : `write ${path13__namespace.basename(init.configPath)} (preset: ${init.preset})`}`
11326
11577
  );
11327
11578
  info(" 2. add the npm scripts, the devDependency and the .gitignore entries");
11328
11579
  if (manager !== null) info(` 3. install with ${manager}`);
@@ -11334,9 +11585,9 @@ async function runSetupCommand(invocation, options = {}) {
11334
11585
  if (invocation.format !== "json") {
11335
11586
  if (!interactive) info(`\u{1F680} Setup for: ${invocation.cwd}`);
11336
11587
  if (init.reused) {
11337
- info(`\u267B Keeping ${path12__namespace.basename(init.configPath)} (${presetSummary(init)})`);
11588
+ info(`\u267B Keeping ${path13__namespace.basename(init.configPath)} (${presetSummary(init)})`);
11338
11589
  } else {
11339
- info(`\u2705 Created ${path12__namespace.basename(init.configPath)} (${presetSummary(init)})`);
11590
+ info(`\u2705 Created ${path13__namespace.basename(init.configPath)} (${presetSummary(init)})`);
11340
11591
  }
11341
11592
  if (init.scripts.length > 0) info(` Added npm scripts: ${init.scripts.join(", ")}`);
11342
11593
  if (init.dependency.added && init.dependency.range !== null) {
@@ -11444,7 +11695,7 @@ function runSkillCommand(invocation) {
11444
11695
  }
11445
11696
  info(`\u2705 Agent skill installed (${SKILL_NAME}):`);
11446
11697
  for (const item of result.written) {
11447
- const shown = path12__namespace.relative(invocation.cwd, item.path) || item.path;
11698
+ const shown = path13__namespace.relative(invocation.cwd, item.path) || item.path;
11448
11699
  info(` - ${item.action.padEnd(9)} ${shown}`);
11449
11700
  }
11450
11701
  if (result.gitignored.length > 0) {
@@ -11508,6 +11759,17 @@ function requestsJsonFormat(argv) {
11508
11759
  return format === "json";
11509
11760
  }
11510
11761
  async function main(argv = process.argv.slice(2)) {
11762
+ const pending = process.stdout.isTTY === true && shouldCheck(argv, process.env) ? checkForUpdate({ current: GENERATOR_VERSION, cacheFile: cacheFilePath() }) : null;
11763
+ const code = await runCommand(argv);
11764
+ if (pending) {
11765
+ const notice = await pending;
11766
+ if (notice) process.stderr.write(`
11767
+ ${formatUpdateNotice(notice)}
11768
+ `);
11769
+ }
11770
+ return code;
11771
+ }
11772
+ async function runCommand(argv) {
11511
11773
  let invocation;
11512
11774
  try {
11513
11775
  invocation = parseCliArgs(argv);
@@ -11540,7 +11802,7 @@ ${USAGE}
11540
11802
  return runSkillCommand(invocation);
11541
11803
  }
11542
11804
  if (invocation.command === "mcp") {
11543
- return await runStdioServer({ cwd: path12__namespace.resolve(invocation.cwd) });
11805
+ return await runStdioServer({ cwd: path13__namespace.resolve(invocation.cwd) });
11544
11806
  }
11545
11807
  if (invocation.command === "setup") {
11546
11808
  return runSetupCommand(invocation);
@@ -11557,7 +11819,7 @@ ${USAGE}
11557
11819
  warn("\u274C The config file could not be read. Fix it, or delete it to use the defaults.");
11558
11820
  return 1;
11559
11821
  }
11560
- if (loaded.file) info(`\u2699 Using config ${path12__namespace.relative(process.cwd(), loaded.file) || loaded.file}`);
11822
+ if (loaded.file) info(`\u2699 Using config ${path13__namespace.relative(process.cwd(), loaded.file) || loaded.file}`);
11561
11823
  const resolved = resolveConfig(
11562
11824
  loaded.config,
11563
11825
  {
@@ -11579,10 +11841,10 @@ ${USAGE}
11579
11841
  if (invocation.command === "validate") {
11580
11842
  const result = validateSnapshot(resolved);
11581
11843
  if (result.valid) {
11582
- const manifestPath = path12__namespace.resolve(resolved.cwd, resolved.outDir, "manifest.json");
11844
+ const manifestPath = path13__namespace.resolve(resolved.cwd, resolved.outDir, "manifest.json");
11583
11845
  let manifest;
11584
11846
  try {
11585
- manifest = JSON.parse(fs11__namespace.readFileSync(manifestPath, "utf8"));
11847
+ manifest = JSON.parse(fs12__namespace.readFileSync(manifestPath, "utf8"));
11586
11848
  } catch {
11587
11849
  manifest = void 0;
11588
11850
  }
@@ -11595,13 +11857,13 @@ ${USAGE}
11595
11857
  return result.valid ? 0 : 1;
11596
11858
  }
11597
11859
  if (invocation.command === "report") {
11598
- const manifestPath = path12__namespace.resolve(resolved.cwd, resolved.outDir, "manifest.json");
11599
- if (!fs11__namespace.existsSync(manifestPath)) {
11860
+ const manifestPath = path13__namespace.resolve(resolved.cwd, resolved.outDir, "manifest.json");
11861
+ if (!fs12__namespace.existsSync(manifestPath)) {
11600
11862
  return fail(invocation.format, `Manifest not found at ${manifestPath}. Run generate first.`);
11601
11863
  }
11602
11864
  let manifest;
11603
11865
  try {
11604
- manifest = JSON.parse(fs11__namespace.readFileSync(manifestPath, "utf8"));
11866
+ manifest = JSON.parse(fs12__namespace.readFileSync(manifestPath, "utf8"));
11605
11867
  } catch (err) {
11606
11868
  return fail(invocation.format, `Could not read ${manifestPath}: ${err.message}`);
11607
11869
  }
@@ -11765,20 +12027,20 @@ function finishWatchRun(state, now) {
11765
12027
  };
11766
12028
  }
11767
12029
  function comparablePath(value) {
11768
- const absolute = path12__namespace.resolve(value);
12030
+ const absolute = path13__namespace.resolve(value);
11769
12031
  return process.platform === "win32" ? absolute.toLowerCase() : absolute;
11770
12032
  }
11771
12033
  function isSameOrInside(parent, candidate) {
11772
- const relative11 = path12__namespace.relative(parent, candidate);
11773
- return relative11 === "" || relative11 !== ".." && !relative11.startsWith(`..${path12__namespace.sep}`) && !path12__namespace.isAbsolute(relative11);
12034
+ const relative11 = path13__namespace.relative(parent, candidate);
12035
+ return relative11 === "" || relative11 !== ".." && !relative11.startsWith(`..${path13__namespace.sep}`) && !path13__namespace.isAbsolute(relative11);
11774
12036
  }
11775
12037
  function isGeneratedWatchPath(candidate, paths) {
11776
- const absolute = comparablePath(path12__namespace.resolve(paths.cwd, candidate));
11777
- const outDir = comparablePath(path12__namespace.resolve(paths.cwd, paths.outDir));
11778
- const tmpDir = comparablePath(path12__namespace.resolve(paths.cwd, paths.tmpDir));
12038
+ const absolute = comparablePath(path13__namespace.resolve(paths.cwd, candidate));
12039
+ const outDir = comparablePath(path13__namespace.resolve(paths.cwd, paths.outDir));
12040
+ const tmpDir = comparablePath(path13__namespace.resolve(paths.cwd, paths.tmpDir));
11779
12041
  if (isSameOrInside(outDir, absolute) || isSameOrInside(tmpDir, absolute)) return true;
11780
- const parent = path12__namespace.dirname(absolute);
11781
- if (parent === path12__namespace.dirname(outDir) && path12__namespace.basename(absolute).startsWith(`${path12__namespace.basename(outDir)}.backup-`)) {
12042
+ const parent = path13__namespace.dirname(absolute);
12043
+ if (parent === path13__namespace.dirname(outDir) && path13__namespace.basename(absolute).startsWith(`${path13__namespace.basename(outDir)}.backup-`)) {
11782
12044
  return true;
11783
12045
  }
11784
12046
  return absolute.split(/[\\/]+/).some((segment) => VCS_SEGMENTS.has(segment));
@@ -11795,8 +12057,8 @@ function decideWatchEvent(state, event, paths) {
11795
12057
  return { state, action: "schedule" };
11796
12058
  }
11797
12059
  async function runWatchLoop(invocation, resolved) {
11798
- const outDir = path12__namespace.resolve(resolved.cwd, resolved.outDir);
11799
- const tmpDir = path12__namespace.resolve(resolved.cwd, resolved.tmpDir);
12060
+ const outDir = path13__namespace.resolve(resolved.cwd, resolved.outDir);
12061
+ const tmpDir = path13__namespace.resolve(resolved.cwd, resolved.tmpDir);
11800
12062
  const paths = { cwd: resolved.cwd, outDir, tmpDir };
11801
12063
  let state = initialWatchState();
11802
12064
  let timer = null;
@@ -11861,11 +12123,11 @@ async function runWatchLoop(invocation, resolved) {
11861
12123
  };
11862
12124
  info("\u{1F440} Watching for changes. Press Ctrl+C to stop.");
11863
12125
  void regenerate();
11864
- const watcher = fs11__namespace.watch(resolved.cwd, { recursive: true }, (_event, filename) => {
12126
+ const watcher = fs12__namespace.watch(resolved.cwd, { recursive: true }, (_event, filename) => {
11865
12127
  const decision = decideWatchEvent(
11866
12128
  state,
11867
12129
  {
11868
- path: filename ? path12__namespace.resolve(resolved.cwd, filename.toString()) : null,
12130
+ path: filename ? path13__namespace.resolve(resolved.cwd, filename.toString()) : null,
11869
12131
  now: performance.now()
11870
12132
  },
11871
12133
  paths
@@ -11893,7 +12155,7 @@ async function runWatchLoop(invocation, resolved) {
11893
12155
  return 0;
11894
12156
  }
11895
12157
  var entryFile = process.argv[1] ?? "";
11896
- var entryName = path12__namespace.basename(entryFile).toLowerCase();
12158
+ var entryName = path13__namespace.basename(entryFile).toLowerCase();
11897
12159
  var invokedDirectly = entryName === "cli.js" || entryName === "cli.cjs";
11898
12160
  if (invokedDirectly) {
11899
12161
  void main().then(