codebase-snapshot 0.9.4 → 0.9.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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.4";
4343
+ var GENERATOR_VERSION = "0.9.6";
4342
4344
  var LEGACY_GENERATOR_NAMES = ["@ankurhalder/codebase-snapshot"];
4343
4345
  function isOurGeneratorName(name) {
4344
4346
  if (typeof name !== "string") return false;
@@ -4472,6 +4474,12 @@ var PromptCancelled = class extends Error {
4472
4474
  this.name = "PromptCancelled";
4473
4475
  }
4474
4476
  };
4477
+ var PromptBack = class extends Error {
4478
+ constructor() {
4479
+ super("Prompt back");
4480
+ this.name = "PromptBack";
4481
+ }
4482
+ };
4475
4483
  function defaultIO() {
4476
4484
  return { input: process.stdin, output: process.stdout };
4477
4485
  }
@@ -4495,35 +4503,40 @@ function choiceLine(choice, active) {
4495
4503
  const hint = choice.hint ? ` ${choice.hint}` : "";
4496
4504
  return ` ${marker(active)} ${choice.label}${hint}`;
4497
4505
  }
4498
- function renderSelect(message, choices, index) {
4506
+ function listFooter(base, allowBack) {
4507
+ return allowBack ? `${base} \xB7 \u2190 back` : base;
4508
+ }
4509
+ function renderSelect(message, choices, index, allowBack = false) {
4499
4510
  const lines = [`\u25C6 ${message}`, ""];
4500
4511
  choices.forEach((choice, position) => lines.push(choiceLine(choice, position === index)));
4501
- lines.push("", " \u2191\u2193 move \xB7 enter select");
4512
+ lines.push("", ` ${listFooter("\u2191\u2193 move \xB7 enter select", allowBack)}`);
4502
4513
  return lines.join("\n");
4503
4514
  }
4504
- function renderMultiSelect(message, choices, index, selected) {
4515
+ function renderMultiSelect(message, choices, index, selected, allowBack = false) {
4505
4516
  const lines = [`\u25C6 ${message}`, ""];
4506
4517
  choices.forEach((choice, position) => {
4507
4518
  const box = selected.has(position) ? "\u25FC" : "\u25FB";
4508
4519
  const hint = choice.hint ? ` ${choice.hint}` : "";
4509
4520
  lines.push(` ${marker(position === index)} ${box} ${choice.label}${hint}`);
4510
4521
  });
4511
- lines.push("", " \u2191\u2193 move \xB7 space toggle \xB7 enter confirm");
4522
+ lines.push("", ` ${listFooter("\u2191\u2193 move \xB7 space toggle \xB7 enter confirm", allowBack)}`);
4512
4523
  return lines.join("\n");
4513
4524
  }
4514
- function renderConfirm(message, value) {
4525
+ function renderConfirm(message, value, allowBack = false) {
4526
+ const footer = allowBack ? "\u2190\u2192 or y/n \xB7 enter confirm \xB7 b back" : "\u2190\u2192 or y/n \xB7 enter confirm";
4515
4527
  return [
4516
4528
  `\u25C6 ${message}`,
4517
4529
  "",
4518
4530
  ` ${marker(value)} Yes`,
4519
4531
  ` ${marker(!value)} No`,
4520
4532
  "",
4521
- " \u2190\u2192 or y/n \xB7 enter confirm"
4533
+ ` ${footer}`
4522
4534
  ].join("\n");
4523
4535
  }
4524
- function renderText(message, value, error) {
4536
+ function renderText(message, value, error, allowBack = false) {
4525
4537
  const lines = [`\u25C6 ${message}`, "", ` ${value || "\u258F"}`];
4526
4538
  if (error) lines.push("", ` \u2716 ${error}`);
4539
+ if (allowBack) lines.push("", " enter confirm \xB7 \u2190 back");
4527
4540
  return lines.join("\n");
4528
4541
  }
4529
4542
  function keyReader(input) {
@@ -4572,14 +4585,18 @@ var Frame = class {
4572
4585
  function isCancel(key) {
4573
4586
  return key.ctrl === true && key.name === "c" || key.ctrl === true && key.name === "d";
4574
4587
  }
4588
+ function isListBack(key, allowBack) {
4589
+ return allowBack && (key.name === "left" || key.name === "b");
4590
+ }
4575
4591
  async function select(io, message, choices, options = {}) {
4576
4592
  if (choices.length === 0) throw new Error("select() requires at least one choice.");
4593
+ const allowBack = options.allowBack === true;
4577
4594
  const fallbackIndex = Math.max(
4578
4595
  0,
4579
4596
  choices.findIndex((choice) => choice.value === options.defaultValue)
4580
4597
  );
4581
4598
  if (!isInteractive(io)) {
4582
- io.output.write(`${renderSelect(message, choices, fallbackIndex)}
4599
+ io.output.write(`${renderSelect(message, choices, fallbackIndex, allowBack)}
4583
4600
  `);
4584
4601
  return choices[fallbackIndex].value;
4585
4602
  }
@@ -4588,9 +4605,10 @@ async function select(io, message, choices, options = {}) {
4588
4605
  let index = fallbackIndex;
4589
4606
  try {
4590
4607
  for (; ; ) {
4591
- frame.draw(renderSelect(message, choices, index));
4608
+ frame.draw(renderSelect(message, choices, index, allowBack));
4592
4609
  const key = await reader.next();
4593
4610
  if (isCancel(key)) throw new PromptCancelled();
4611
+ if (isListBack(key, allowBack)) throw new PromptBack();
4594
4612
  if (key.name === "up") index = moveSelection(index, -1, choices.length);
4595
4613
  else if (key.name === "down") index = moveSelection(index, 1, choices.length);
4596
4614
  else if (key.name === "return" || key.name === "enter") {
@@ -4599,18 +4617,22 @@ async function select(io, message, choices, options = {}) {
4599
4617
  } else if (key.name === "j") index = moveSelection(index, 1, choices.length);
4600
4618
  else if (key.name === "k") index = moveSelection(index, -1, choices.length);
4601
4619
  }
4620
+ } catch (error) {
4621
+ frame.erase();
4622
+ throw error;
4602
4623
  } finally {
4603
4624
  reader.close();
4604
4625
  }
4605
4626
  }
4606
4627
  async function multiSelect(io, message, choices, options = {}) {
4628
+ const allowBack = options.allowBack === true;
4607
4629
  const selected = /* @__PURE__ */ new Set();
4608
4630
  choices.forEach((choice, position) => {
4609
4631
  if (options.defaults?.includes(choice.value)) selected.add(position);
4610
4632
  });
4611
4633
  const result = () => choices.filter((_, position) => selected.has(position)).map((choice) => choice.value);
4612
4634
  if (!isInteractive(io)) {
4613
- io.output.write(`${renderMultiSelect(message, choices, 0, selected)}
4635
+ io.output.write(`${renderMultiSelect(message, choices, 0, selected, allowBack)}
4614
4636
  `);
4615
4637
  return result();
4616
4638
  }
@@ -4619,9 +4641,10 @@ async function multiSelect(io, message, choices, options = {}) {
4619
4641
  let index = 0;
4620
4642
  try {
4621
4643
  for (; ; ) {
4622
- frame.draw(renderMultiSelect(message, choices, index, selected));
4644
+ frame.draw(renderMultiSelect(message, choices, index, selected, allowBack));
4623
4645
  const key = await reader.next();
4624
4646
  if (isCancel(key)) throw new PromptCancelled();
4647
+ if (isListBack(key, allowBack)) throw new PromptBack();
4625
4648
  if (key.name === "up") index = moveSelection(index, -1, choices.length);
4626
4649
  else if (key.name === "down") index = moveSelection(index, 1, choices.length);
4627
4650
  else if (key.name === "space") {
@@ -4636,14 +4659,18 @@ async function multiSelect(io, message, choices, options = {}) {
4636
4659
  return result();
4637
4660
  }
4638
4661
  }
4662
+ } catch (error) {
4663
+ frame.erase();
4664
+ throw error;
4639
4665
  } finally {
4640
4666
  reader.close();
4641
4667
  }
4642
4668
  }
4643
4669
  async function confirm(io, message, options = {}) {
4670
+ const allowBack = options.allowBack === true;
4644
4671
  let value = options.defaultValue ?? true;
4645
4672
  if (!isInteractive(io)) {
4646
- io.output.write(`${renderConfirm(message, value)}
4673
+ io.output.write(`${renderConfirm(message, value, allowBack)}
4647
4674
  `);
4648
4675
  return value;
4649
4676
  }
@@ -4651,9 +4678,10 @@ async function confirm(io, message, options = {}) {
4651
4678
  const reader = keyReader(io.input);
4652
4679
  try {
4653
4680
  for (; ; ) {
4654
- frame.draw(renderConfirm(message, value));
4681
+ frame.draw(renderConfirm(message, value, allowBack));
4655
4682
  const key = await reader.next();
4656
4683
  if (isCancel(key)) throw new PromptCancelled();
4684
+ if (allowBack && key.name === "b") throw new PromptBack();
4657
4685
  if (key.name === "up" || key.name === "left") value = true;
4658
4686
  else if (key.name === "down" || key.name === "right") value = false;
4659
4687
  else if (key.name === "y") value = true;
@@ -4663,14 +4691,18 @@ async function confirm(io, message, options = {}) {
4663
4691
  return value;
4664
4692
  }
4665
4693
  }
4694
+ } catch (error) {
4695
+ frame.erase();
4696
+ throw error;
4666
4697
  } finally {
4667
4698
  reader.close();
4668
4699
  }
4669
4700
  }
4670
4701
  async function text(io, message, options = {}) {
4702
+ const allowBack = options.allowBack === true;
4671
4703
  const fallback = options.defaultValue ?? "";
4672
4704
  if (!isInteractive(io)) {
4673
- io.output.write(`${renderText(message, fallback)}
4705
+ io.output.write(`${renderText(message, fallback, void 0, allowBack)}
4674
4706
  `);
4675
4707
  return fallback;
4676
4708
  }
@@ -4680,9 +4712,10 @@ async function text(io, message, options = {}) {
4680
4712
  let error;
4681
4713
  try {
4682
4714
  for (; ; ) {
4683
- frame.draw(renderText(message, value, error));
4715
+ frame.draw(renderText(message, value, error, allowBack));
4684
4716
  const key = await reader.next();
4685
4717
  if (isCancel(key)) throw new PromptCancelled();
4718
+ if (allowBack && key.name === "left") throw new PromptBack();
4686
4719
  error = void 0;
4687
4720
  if (key.name === "return" || key.name === "enter") {
4688
4721
  const problem = options.validate ? options.validate(value) : null;
@@ -4703,6 +4736,9 @@ async function text(io, message, options = {}) {
4703
4736
  }
4704
4737
  if (_isPrintable(key)) value += _keyText(key);
4705
4738
  }
4739
+ } catch (error_) {
4740
+ frame.erase();
4741
+ throw error_;
4706
4742
  } finally {
4707
4743
  reader.close();
4708
4744
  }
@@ -4726,10 +4762,10 @@ var CONFIG_CANDIDATES = [
4726
4762
  ];
4727
4763
  function chooseConfigFileName(cwd) {
4728
4764
  if (!supportsTypeScriptImports()) return "snapshot.config.mjs";
4729
- const pkgPath = path12__namespace.join(cwd, "package.json");
4730
- if (!fs11__namespace.existsSync(pkgPath)) return "snapshot.config.mjs";
4765
+ const pkgPath = path13__namespace.join(cwd, "package.json");
4766
+ if (!fs12__namespace.existsSync(pkgPath)) return "snapshot.config.mjs";
4731
4767
  try {
4732
- const parsed = JSON.parse(fs11__namespace.readFileSync(pkgPath, "utf8"));
4768
+ const parsed = JSON.parse(fs12__namespace.readFileSync(pkgPath, "utf8"));
4733
4769
  return parsed.type === "module" ? "snapshot.config.ts" : "snapshot.config.mjs";
4734
4770
  } catch {
4735
4771
  return "snapshot.config.mjs";
@@ -4743,7 +4779,7 @@ var SIZE_CHOICES = [
4743
4779
  ];
4744
4780
  function packageJsonHasConfig(cwd) {
4745
4781
  try {
4746
- const parsed = JSON.parse(fs11__namespace.readFileSync(path12__namespace.join(cwd, "package.json"), "utf8"));
4782
+ const parsed = JSON.parse(fs12__namespace.readFileSync(path13__namespace.join(cwd, "package.json"), "utf8"));
4747
4783
  return typeof parsed.snapshot === "object" && parsed.snapshot !== null && !Array.isArray(parsed.snapshot);
4748
4784
  } catch {
4749
4785
  return false;
@@ -4764,7 +4800,7 @@ function artifactAnswers(options) {
4764
4800
  }
4765
4801
  function topLevelDirs(cwd) {
4766
4802
  try {
4767
- return fs11__namespace.readdirSync(cwd, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules").map((entry) => entry.name).sort();
4803
+ return fs12__namespace.readdirSync(cwd, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules").map((entry) => entry.name).sort();
4768
4804
  } catch {
4769
4805
  return [];
4770
4806
  }
@@ -4777,7 +4813,7 @@ function describeJsonValue(value) {
4777
4813
  }
4778
4814
  function writeFileOrExplain(target, content) {
4779
4815
  try {
4780
- fs11__namespace.writeFileSync(target, content, "utf8");
4816
+ fs12__namespace.writeFileSync(target, content, "utf8");
4781
4817
  } catch (err) {
4782
4818
  const code = err.code;
4783
4819
  const reason = code === "EACCES" || code === "EPERM" || code === "EROFS" ? `permission denied (${code})` : code === "EISDIR" ? "it is a directory" : `${err.message}`;
@@ -4788,7 +4824,7 @@ function canWriteModuleConfig(name, cwd) {
4788
4824
  if (name.endsWith(".mjs") || name.endsWith(".ts")) return true;
4789
4825
  if (!name.endsWith(".js")) return false;
4790
4826
  try {
4791
- const parsed = JSON.parse(fs11__namespace.readFileSync(path12__namespace.join(cwd, "package.json"), "utf8"));
4827
+ const parsed = JSON.parse(fs12__namespace.readFileSync(path13__namespace.join(cwd, "package.json"), "utf8"));
4792
4828
  return parsed.type === "module";
4793
4829
  } catch {
4794
4830
  return false;
@@ -4823,19 +4859,19 @@ function serializePackageJson(raw, value) {
4823
4859
  return `${text2}${raw.endsWith("\n") ? crlf ? "\r\n" : "\n" : ""}`;
4824
4860
  }
4825
4861
  function updatePackageJson(cwd, notes) {
4826
- const packagePath = path12__namespace.join(cwd, "package.json");
4862
+ const packagePath = path13__namespace.join(cwd, "package.json");
4827
4863
  const unchanged = {
4828
4864
  scripts: [],
4829
4865
  dependency: { name: GENERATOR_NAME, range: null, added: false }
4830
4866
  };
4831
- if (!fs11__namespace.existsSync(packagePath)) {
4867
+ if (!fs12__namespace.existsSync(packagePath)) {
4832
4868
  notes.push("No package.json found, so npm scripts and the devDependency were not added.");
4833
4869
  return unchanged;
4834
4870
  }
4835
4871
  let raw;
4836
4872
  let parsed;
4837
4873
  try {
4838
- raw = fs11__namespace.readFileSync(packagePath, "utf8");
4874
+ raw = fs12__namespace.readFileSync(packagePath, "utf8");
4839
4875
  parsed = JSON.parse(raw);
4840
4876
  } catch {
4841
4877
  notes.push("Could not parse package.json; npm scripts and the devDependency were not added.");
@@ -4959,98 +4995,108 @@ async function runInit(options) {
4959
4995
  { value: "walk", label: "Go through each setting", hint: "every question starts on its default" },
4960
4996
  { value: "choose", label: "Pick a different preset", hint: "everything else stays at the defaults" }
4961
4997
  ];
4962
- const pace = await select(io, "How should I set this up?", paceChoices, {
4963
- defaultValue: fallback ? "choose" : "recommended"
4964
- });
4965
- if (pace === "choose") {
4966
- answers.preset = await select(
4967
- io,
4968
- "What kind of project is this?",
4969
- listPresetNames().map(
4970
- (name) => resolvePresetChoice(fallback ? null : detected.presetName, name)
4971
- ),
4972
- { defaultValue: answers.preset }
4973
- );
4974
- const chosen = detectPreset(options.cwd, answers.preset);
4975
- answers.preset = chosen.presetName;
4976
- reason = null;
4977
- fallback = false;
4978
- }
4979
- if (pace === "walk") {
4980
- const scope = await select(
4981
- io,
4982
- "What should go into the snapshot?",
4983
- [
4984
- { value: "all", label: "Everything the scanner finds", hint: "recommended \xB7 respects .gitignore" },
4985
- { value: "folders", label: "Only specific folders\u2026" },
4986
- { value: "no-tests", label: "Everything, but skip tests" },
4987
- { value: "custom", label: "Let me write glob patterns" }
4988
- ],
4989
- { defaultValue: "all" }
4990
- );
4991
- if (scope === "folders") {
4992
- const dirs = topLevelDirs(options.cwd).slice(0, 40);
4993
- if (dirs.length === 0) {
4994
- notes.push("No top-level directories found; the snapshot will include everything.");
4995
- } else {
4996
- const chosen = await multiSelect(
4997
- io,
4998
- "Select folders",
4999
- dirs.map((name) => ({ value: name, label: `${name}/` })),
5000
- { defaults: dirs }
5001
- );
5002
- answers.include = chosen.map((name) => `${name}/**`);
4998
+ const baseInclude = [...answers.include];
4999
+ const baseExclude = [...answers.excludePatterns];
5000
+ let lastScope = "all";
5001
+ const artifactChoices = [
5002
+ { value: "readme", label: "README.md", hint: "orientation page" },
5003
+ { value: "manifest", label: "manifest.json", hint: "required by validate and report" },
5004
+ { value: "parts", label: "parts/", hint: "the code payload" },
5005
+ { value: "navigation", label: "reports/navigation.md", hint: "file \u2192 part index" },
5006
+ { value: "projectTree", label: "reports/project-tree.md", hint: "ASCII tree" },
5007
+ { value: "audit", label: "reports/audit.md", hint: "security and health findings" },
5008
+ { value: "monolith", label: "full-codebase.json + .md", hint: "roughly doubles output" }
5009
+ ];
5010
+ const scopeStep = async () => {
5011
+ for (; ; ) {
5012
+ const scope = await select(
5013
+ io,
5014
+ "What should go into the snapshot?",
5015
+ [
5016
+ { value: "all", label: "Everything the scanner finds", hint: "recommended \xB7 respects .gitignore" },
5017
+ { value: "folders", label: "Only specific folders\u2026" },
5018
+ { value: "no-tests", label: "Everything, but skip tests" },
5019
+ { value: "custom", label: "Let me write glob patterns" }
5020
+ ],
5021
+ { defaultValue: lastScope, allowBack: true }
5022
+ );
5023
+ lastScope = scope;
5024
+ answers.include = [...baseInclude];
5025
+ answers.excludePatterns = [...baseExclude];
5026
+ try {
5027
+ if (scope === "folders") {
5028
+ const dirs = topLevelDirs(options.cwd).slice(0, 40);
5029
+ if (dirs.length === 0) {
5030
+ notes.push("No top-level directories found; the snapshot will include everything.");
5031
+ } else {
5032
+ const chosen = await multiSelect(
5033
+ io,
5034
+ "Select folders",
5035
+ dirs.map((name) => ({ value: name, label: `${name}/` })),
5036
+ { defaults: dirs, allowBack: true }
5037
+ );
5038
+ answers.include = chosen.map((name) => `${name}/**`);
5039
+ }
5040
+ } else if (scope === "no-tests") {
5041
+ answers.excludePatterns = [...baseExclude, "**/*.test.*", "**/*.spec.*", "tests", "test"];
5042
+ } else if (scope === "custom") {
5043
+ const raw = await text(io, "Glob patterns to include (comma separated)", {
5044
+ defaultValue: baseInclude.join(", "),
5045
+ allowBack: true
5046
+ });
5047
+ answers.include = raw.split(",").map((value) => value.trim()).filter(Boolean);
5048
+ }
5049
+ return;
5050
+ } catch (error) {
5051
+ if (error instanceof PromptBack) continue;
5052
+ throw error;
5003
5053
  }
5004
- } else if (scope === "no-tests") {
5005
- answers.excludePatterns = [
5006
- ...answers.excludePatterns,
5007
- "**/*.test.*",
5008
- "**/*.spec.*",
5009
- "tests",
5010
- "test"
5011
- ];
5012
- } else if (scope === "custom") {
5013
- const raw = await text(io, "Glob patterns to include (comma separated)", {
5014
- defaultValue: ""
5015
- });
5016
- answers.include = raw.split(",").map((value) => value.trim()).filter(Boolean);
5017
5054
  }
5018
- const currentBudget = String(answers.maxPartBytes);
5019
- const sizeChoice = await select(io, "How large should each part be?", SIZE_CHOICES, {
5020
- defaultValue: SIZE_CHOICES.some((choice) => choice.value === currentBudget) ? currentBudget : "120k"
5021
- });
5022
- if (sizeChoice === "custom") {
5023
- const raw = await text(io, "Part size (e.g. 150k, 1.5mb, 900000)", {
5024
- defaultValue: String(answers.maxPartBytes),
5025
- validate: (value) => parseByteSize(value) === void 0 ? "Not a valid size." : null
5055
+ };
5056
+ const sizeStep = async () => {
5057
+ for (; ; ) {
5058
+ const currentBudget = String(answers.maxPartBytes);
5059
+ const sizeChoice = await select(io, "How large should each part be?", SIZE_CHOICES, {
5060
+ defaultValue: SIZE_CHOICES.some((choice) => choice.value === currentBudget) ? currentBudget : "custom",
5061
+ allowBack: true
5026
5062
  });
5027
- answers.maxPartBytes = parseByteSize(raw) ?? answers.maxPartBytes;
5028
- } else {
5029
- answers.maxPartBytes = sizeChoice;
5030
- }
5031
- const artifactChoices = [
5032
- { value: "readme", label: "README.md", hint: "orientation page" },
5033
- { value: "manifest", label: "manifest.json", hint: "required by validate and report" },
5034
- { value: "parts", label: "parts/", hint: "the code payload" },
5035
- { value: "navigation", label: "reports/navigation.md", hint: "file \u2192 part index" },
5036
- { value: "projectTree", label: "reports/project-tree.md", hint: "ASCII tree" },
5037
- { value: "audit", label: "reports/audit.md", hint: "security and health findings" },
5038
- { value: "monolith", label: "full-codebase.json + .md", hint: "roughly doubles output" }
5039
- ];
5040
- const presetEnabled = ARTIFACT_NAMES.filter((name) => answers.artifacts[name]);
5063
+ if (sizeChoice !== "custom") {
5064
+ answers.maxPartBytes = sizeChoice;
5065
+ return;
5066
+ }
5067
+ try {
5068
+ const raw = await text(io, "Part size (e.g. 150k, 1.5mb, 900000)", {
5069
+ defaultValue: currentBudget,
5070
+ validate: (value) => parseByteSize(value) === void 0 ? "Not a valid size." : null,
5071
+ allowBack: true
5072
+ });
5073
+ answers.maxPartBytes = parseByteSize(raw) ?? answers.maxPartBytes;
5074
+ return;
5075
+ } catch (error) {
5076
+ if (error instanceof PromptBack) continue;
5077
+ throw error;
5078
+ }
5079
+ }
5080
+ };
5081
+ const artifactsStep = async () => {
5082
+ const enabled = ARTIFACT_NAMES.filter((name) => answers.artifacts[name]);
5041
5083
  const selectedArtifacts = await multiSelect(
5042
5084
  io,
5043
5085
  "Which artifacts should be generated?",
5044
5086
  artifactChoices,
5045
- { defaults: presetEnabled }
5087
+ { defaults: enabled, allowBack: true }
5046
5088
  );
5047
5089
  for (const name of ARTIFACT_NAMES) answers.artifacts[name] = selectedArtifacts.includes(name);
5048
- const enabledCount = ARTIFACT_NAMES.filter((name) => answers.artifacts[name]).length;
5090
+ };
5091
+ const credentialsStep = async () => {
5049
5092
  answers.includeSensitiveFiles = await confirm(
5050
5093
  io,
5051
- "Include credential files (.env, *.pem, .npmrc, .ssh/)?",
5052
- { defaultValue: false }
5094
+ "Include credential files (.env, *.pem, *.npmrc, *.ssh/)?",
5095
+ { defaultValue: answers.includeSensitiveFiles, allowBack: true }
5053
5096
  );
5097
+ };
5098
+ const reviewStep = async () => {
5099
+ const enabledCount = ARTIFACT_NAMES.filter((name) => answers.artifacts[name]).length;
5054
5100
  io.output.write("\n Review\n\n");
5055
5101
  io.output.write(` project ${answers.preset}
5056
5102
  `);
@@ -5065,14 +5111,59 @@ async function runInit(options) {
5065
5111
  `);
5066
5112
  io.output.write(" Will write snapshot.config with your answers, plus every other setting\n");
5067
5113
  io.output.write(" at its default \u2014 so nothing is hidden behind the docs.\n\n");
5068
- const proceed = await confirm(io, "Write this and continue?", { defaultValue: true });
5069
- if (!proceed) throw new PromptCancelled();
5114
+ const proceed = await confirm(io, "Write this and continue?", {
5115
+ defaultValue: true,
5116
+ allowBack: true
5117
+ });
5118
+ if (!proceed) throw new PromptBack();
5119
+ };
5120
+ const walk = async () => {
5121
+ const steps = [scopeStep, sizeStep, artifactsStep, credentialsStep, reviewStep];
5122
+ let index = 0;
5123
+ while (index < steps.length) {
5124
+ try {
5125
+ await steps[index]();
5126
+ index += 1;
5127
+ } catch (error) {
5128
+ if (!(error instanceof PromptBack)) throw error;
5129
+ if (index === 0) return false;
5130
+ index -= 1;
5131
+ io.output.write("\n");
5132
+ }
5133
+ }
5134
+ return true;
5135
+ };
5136
+ for (; ; ) {
5137
+ const pace = await select(io, "How should I set this up?", paceChoices, {
5138
+ defaultValue: fallback ? "choose" : "recommended"
5139
+ });
5140
+ if (pace === "choose") {
5141
+ try {
5142
+ answers.preset = await select(
5143
+ io,
5144
+ "What kind of project is this?",
5145
+ listPresetNames().map(
5146
+ (name) => resolvePresetChoice(fallback ? null : detected.presetName, name)
5147
+ ),
5148
+ { defaultValue: answers.preset, allowBack: true }
5149
+ );
5150
+ } catch (error) {
5151
+ if (error instanceof PromptBack) continue;
5152
+ throw error;
5153
+ }
5154
+ const chosen = detectPreset(options.cwd, answers.preset);
5155
+ answers.preset = chosen.presetName;
5156
+ reason = null;
5157
+ fallback = false;
5158
+ }
5159
+ if (pace === "walk" && !await walk()) continue;
5160
+ break;
5070
5161
  }
5071
5162
  }
5072
5163
  const configText = renderConfig(answers);
5073
5164
  const preferredName = chooseConfigFileName(options.cwd);
5074
5165
  const presentConfigs = CONFIG_CANDIDATES.filter(
5075
- (name) => fs11__namespace.existsSync(path12__namespace.join(options.cwd, name))
5166
+ (name) => fs12__namespace.existsSync(path13__namespace.join(options.cwd, name))
5076
5167
  );
5077
5168
  const present = presentConfigs[0] ?? null;
5078
5169
  if (presentConfigs.length > 1) {
@@ -5081,7 +5172,7 @@ async function runInit(options) {
5081
5172
  );
5082
5173
  }
5083
5174
  const configName = present !== null && options.force ? present : preferredName;
5084
- const configPath = path12__namespace.join(options.cwd, configName);
5175
+ const configPath = path13__namespace.join(options.cwd, configName);
5085
5176
  const reused = present !== null && options.force !== true && options.reuseConfig === true;
5086
5177
  if (reused) notes.push(`Kept the existing ${present} instead of writing a new one.`);
5087
5178
  if (options.dryRun) {
@@ -5114,7 +5205,7 @@ async function runInit(options) {
5114
5205
  '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.'
5115
5206
  );
5116
5207
  }
5117
- if (fs11__namespace.existsSync(configPath) && !options.force && !reused) {
5208
+ if (fs12__namespace.existsSync(configPath) && !options.force && !reused) {
5118
5209
  throw new Error(`${configName} already exists. Re-run with --force to replace it.`);
5119
5210
  }
5120
5211
  if (!reused) writeFileOrExplain(configPath, configText);
@@ -5136,9 +5227,9 @@ async function runInit(options) {
5136
5227
  };
5137
5228
  }
5138
5229
  function describeTarget(cwd) {
5139
- const relative11 = path12__namespace.relative(process.cwd(), cwd);
5230
+ const relative11 = path13__namespace.relative(process.cwd(), cwd);
5140
5231
  if (relative11 === "") return "this directory";
5141
- if (relative11.startsWith("..") || path12__namespace.isAbsolute(relative11)) return cwd;
5232
+ if (relative11.startsWith("..") || path13__namespace.isAbsolute(relative11)) return cwd;
5142
5233
  return relative11;
5143
5234
  }
5144
5235
  function firstRunMessage(reason, cwd) {
@@ -5162,7 +5253,7 @@ function planFirstRun(facts) {
5162
5253
  var NOT_CONTENT = /* @__PURE__ */ new Set([".git", ".hg", ".svn", ".bzr", ".DS_Store", "Thumbs.db"]);
5163
5254
  function isEffectivelyEmpty(cwd) {
5164
5255
  try {
5165
- return fs11__namespace.readdirSync(cwd).every((entry) => NOT_CONTENT.has(entry));
5256
+ return fs12__namespace.readdirSync(cwd).every((entry) => NOT_CONTENT.has(entry));
5166
5257
  } catch {
5167
5258
  return false;
5168
5259
  }
@@ -5170,7 +5261,7 @@ function isEffectivelyEmpty(cwd) {
5170
5261
  function hasPriorSnapshot(cwd, outDir) {
5171
5262
  let parsed;
5172
5263
  try {
5173
- parsed = JSON.parse(fs11__namespace.readFileSync(path12__namespace.join(cwd, outDir, ".codebase-snapshot"), "utf8"));
5264
+ parsed = JSON.parse(fs12__namespace.readFileSync(path13__namespace.join(cwd, outDir, ".codebase-snapshot"), "utf8"));
5174
5265
  } catch {
5175
5266
  return false;
5176
5267
  }
@@ -5400,9 +5491,9 @@ var JAVA_METHOD = /^\s+(?:public|private|protected)\s+(?:static\s+)?(?:final\s+)
5400
5491
  var jvmProfile = {
5401
5492
  id: "jvm",
5402
5493
  extensions: [".java", ".kt", ".kts", ".scala"],
5403
- summarize(path18, content) {
5494
+ summarize(path19, content) {
5404
5495
  const summary = emptySummary();
5405
- const lower = path18.toLowerCase();
5496
+ const lower = path19.toLowerCase();
5406
5497
  const isJava = lower.endsWith(".java");
5407
5498
  const isKotlin = lower.endsWith(".kt") || lower.endsWith(".kts");
5408
5499
  eachLine(content, (line) => {
@@ -5855,16 +5946,16 @@ function summarizeTypeScriptSource(relativePath, content) {
5855
5946
  // src/ast/profiles/sfc.ts
5856
5947
  var SCRIPT_BLOCK = /<script[^>]*>([\s\S]*?)<\/script>/gi;
5857
5948
  var ASTRO_FRONTMATTER = /^\uFEFF?---[ \t]*\r?\n([\s\S]*?)\r?\n---[ \t]*(?=\r?\n|$)/;
5858
- function componentName(path18) {
5859
- const base = path18.split("/").pop() ?? path18;
5949
+ function componentName(path19) {
5950
+ const base = path19.split("/").pop() ?? path19;
5860
5951
  return base.replace(/\.[^.]+$/, "");
5861
5952
  }
5862
5953
  var sfcProfile = {
5863
5954
  id: "sfc",
5864
5955
  extensions: [".vue", ".svelte", ".astro"],
5865
- summarize(path18, content) {
5956
+ summarize(path19, content) {
5866
5957
  let script = "";
5867
- if (path18.toLowerCase().endsWith(".astro")) {
5958
+ if (path19.toLowerCase().endsWith(".astro")) {
5868
5959
  const frontmatter = ASTRO_FRONTMATTER.exec(content);
5869
5960
  if (frontmatter) script += `${frontmatter[1]}
5870
5961
  `;
@@ -5873,7 +5964,7 @@ var sfcProfile = {
5873
5964
  script += `${match[1]}
5874
5965
  `;
5875
5966
  }
5876
- const name = componentName(path18);
5967
+ const name = componentName(path19);
5877
5968
  if (!script.trim()) {
5878
5969
  const summary2 = emptySummary();
5879
5970
  if (name) {
@@ -5907,15 +5998,15 @@ for (const profile of LANGUAGE_PROFILES) {
5907
5998
  BY_EXTENSION.set(extension.toLowerCase(), profile);
5908
5999
  }
5909
6000
  }
5910
- function profileForPath(path18) {
5911
- const lower = path18.toLowerCase();
6001
+ function profileForPath(path19) {
6002
+ const lower = path19.toLowerCase();
5912
6003
  const dot = lower.lastIndexOf(".");
5913
6004
  if (dot === -1) return null;
5914
6005
  return BY_EXTENSION.get(lower.slice(dot)) ?? null;
5915
6006
  }
5916
- function summarizeWithProfile(path18, content) {
5917
- const profile = profileForPath(path18);
5918
- return profile ? profile.summarize(path18, content) : null;
6007
+ function summarizeWithProfile(path19, content) {
6008
+ const profile = profileForPath(path19);
6009
+ return profile ? profile.summarize(path19, content) : null;
5919
6010
  }
5920
6011
 
5921
6012
  // src/ast/structured.ts
@@ -6760,6 +6851,162 @@ function generateProjectTree(filePaths) {
6760
6851
  const fence = fenceForText(lines.join("\n"), 3);
6761
6852
  return ["# Project Tree", "", `${fence}text`, ...lines, fence, ""].join("\n");
6762
6853
  }
6854
+ var PACKAGE_LATEST_URL = "https://registry.npmjs.org/codebase-snapshot/latest";
6855
+ var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
6856
+ var FAILURE_INTERVAL_MS = 60 * 60 * 1e3;
6857
+ var REQUEST_TIMEOUT_MS = 1200;
6858
+ function versionParts(value) {
6859
+ const core = value.trim().replace(/^v/i, "").split("-")[0];
6860
+ return core.split(".").map((part) => {
6861
+ const parsed = Number(part);
6862
+ return Number.isFinite(parsed) ? parsed : 0;
6863
+ });
6864
+ }
6865
+ function isNewer(candidate, current) {
6866
+ const left = versionParts(candidate);
6867
+ const right = versionParts(current);
6868
+ const length = Math.max(left.length, right.length);
6869
+ for (let index = 0; index < length; index += 1) {
6870
+ const a = left[index] ?? 0;
6871
+ const b = right[index] ?? 0;
6872
+ if (a !== b) return a > b;
6873
+ }
6874
+ return false;
6875
+ }
6876
+ function cacheDirectory(env = process.env, platform = process.platform) {
6877
+ if (platform === "win32") {
6878
+ const base2 = env.LOCALAPPDATA ?? path13__namespace.join(os__namespace.homedir(), "AppData", "Local");
6879
+ return path13__namespace.join(base2, "codebase-snapshot");
6880
+ }
6881
+ if (platform === "darwin") {
6882
+ return path13__namespace.join(os__namespace.homedir(), "Library", "Caches", "codebase-snapshot");
6883
+ }
6884
+ const base = env.XDG_CACHE_HOME ?? path13__namespace.join(os__namespace.homedir(), ".cache");
6885
+ return path13__namespace.join(base, "codebase-snapshot");
6886
+ }
6887
+ function cacheFilePath(env = process.env) {
6888
+ return path13__namespace.join(cacheDirectory(env), "update-check.json");
6889
+ }
6890
+ function shouldCheck(argv, env) {
6891
+ const disabled = ["1", "true", "yes"].includes(
6892
+ String(env.CODEBASE_SNAPSHOT_NO_UPDATE_CHECK ?? "").toLowerCase()
6893
+ );
6894
+ if (disabled) return false;
6895
+ if (env.CI !== void 0 && env.CI !== "" && env.CI !== "false" && env.CI !== "0") return false;
6896
+ const args = argv.map((argument) => argument.toLowerCase());
6897
+ if (args.includes("--no-update-check")) return false;
6898
+ for (const skip of ["mcp", "describe", "skill", "--version", "-v", "--help", "-h"]) {
6899
+ if (args.includes(skip)) return false;
6900
+ }
6901
+ if (args.some((argument) => argument.includes("json"))) return false;
6902
+ return true;
6903
+ }
6904
+ function readCache(file) {
6905
+ let raw;
6906
+ try {
6907
+ raw = fs12__namespace.readFileSync(file, "utf8");
6908
+ } catch {
6909
+ return null;
6910
+ }
6911
+ try {
6912
+ const parsed = JSON.parse(raw);
6913
+ if (typeof parsed !== "object" || parsed === null) return null;
6914
+ const candidate = parsed;
6915
+ if (typeof candidate.checkedAt !== "number") return null;
6916
+ const latest = typeof candidate.latest === "string" ? candidate.latest : null;
6917
+ return { checkedAt: candidate.checkedAt, latest };
6918
+ } catch {
6919
+ return null;
6920
+ }
6921
+ }
6922
+ function writeCache(file, entry) {
6923
+ try {
6924
+ fs12__namespace.mkdirSync(path13__namespace.dirname(file), { recursive: true });
6925
+ fs12__namespace.writeFileSync(file, `${JSON.stringify(entry)}
6926
+ `, "utf8");
6927
+ } catch {
6928
+ }
6929
+ }
6930
+ function fetchLatestVersion(url = PACKAGE_LATEST_URL, timeoutMs = REQUEST_TIMEOUT_MS) {
6931
+ return new Promise((resolve9) => {
6932
+ let settled = false;
6933
+ const finish = (value) => {
6934
+ if (settled) return;
6935
+ settled = true;
6936
+ resolve9(value);
6937
+ };
6938
+ const request = https__namespace.get(
6939
+ url,
6940
+ {
6941
+ headers: {
6942
+ accept: "application/json",
6943
+ "user-agent": "codebase-snapshot (update check)"
6944
+ }
6945
+ },
6946
+ (response) => {
6947
+ if (response.statusCode !== 200) {
6948
+ response.resume();
6949
+ finish(null);
6950
+ return;
6951
+ }
6952
+ let body = "";
6953
+ response.setEncoding("utf8");
6954
+ response.on("data", (chunk) => {
6955
+ body += chunk;
6956
+ if (body.length > 64 * 1024) {
6957
+ request.destroy();
6958
+ finish(null);
6959
+ }
6960
+ });
6961
+ response.on("end", () => {
6962
+ try {
6963
+ const parsed = JSON.parse(body);
6964
+ finish(typeof parsed.version === "string" ? parsed.version : null);
6965
+ } catch {
6966
+ finish(null);
6967
+ }
6968
+ });
6969
+ }
6970
+ );
6971
+ request.on("error", () => finish(null));
6972
+ request.setTimeout(timeoutMs, () => {
6973
+ request.destroy();
6974
+ finish(null);
6975
+ });
6976
+ });
6977
+ }
6978
+ async function checkForUpdate(options) {
6979
+ if (options.enabled === false) return null;
6980
+ const now = options.now ?? (() => Date.now());
6981
+ const fetchLatest = options.fetchLatest ?? fetchLatestVersion;
6982
+ let latest = null;
6983
+ try {
6984
+ const cached = readCache(options.cacheFile);
6985
+ let needsFetch = cached === null;
6986
+ if (cached) {
6987
+ const age = now() - cached.checkedAt;
6988
+ if (cached.latest === null) {
6989
+ needsFetch = age >= FAILURE_INTERVAL_MS;
6990
+ } else {
6991
+ latest = cached.latest;
6992
+ needsFetch = age >= CHECK_INTERVAL_MS;
6993
+ }
6994
+ }
6995
+ if (needsFetch) {
6996
+ const fetched = await fetchLatest(PACKAGE_LATEST_URL, REQUEST_TIMEOUT_MS);
6997
+ writeCache(options.cacheFile, { checkedAt: now(), latest: fetched });
6998
+ latest = fetched;
6999
+ }
7000
+ } catch {
7001
+ return null;
7002
+ }
7003
+ if (!latest) return null;
7004
+ return isNewer(latest, options.current) ? { current: options.current, latest } : null;
7005
+ }
7006
+ function formatUpdateNotice(notice) {
7007
+ return `\u2191 codebase-snapshot ${notice.latest} is available \u2014 you have ${notice.current}.
7008
+ npm install -g codebase-snapshot`;
7009
+ }
6763
7010
 
6764
7011
  // src/index.ts
6765
7012
  var SCHEMA_VERSION = "3.0.0";
@@ -6841,13 +7088,13 @@ function buildImportResolver(files) {
6841
7088
  const relativePath = file.relativePath;
6842
7089
  remember(byPath, relativePath, relativePath);
6843
7090
  remember(byPathFolded, relativePath.toLowerCase(), relativePath);
6844
- const extension = path12__namespace.posix.extname(relativePath);
7091
+ const extension = path13__namespace.posix.extname(relativePath);
6845
7092
  if (!SOURCE_EXTENSIONS.has(extension)) continue;
6846
7093
  const stem = relativePath.slice(0, -extension.length);
6847
7094
  remember(byStem, stem, relativePath);
6848
7095
  remember(byStemFolded, stem.toLowerCase(), relativePath);
6849
- if (path12__namespace.posix.basename(stem) === "index") {
6850
- const directory = path12__namespace.posix.dirname(stem);
7096
+ if (path13__namespace.posix.basename(stem) === "index") {
7097
+ const directory = path13__namespace.posix.dirname(stem);
6851
7098
  remember(byStem, directory, relativePath);
6852
7099
  remember(byStemFolded, directory.toLowerCase(), relativePath);
6853
7100
  }
@@ -6856,8 +7103,8 @@ function buildImportResolver(files) {
6856
7103
  }
6857
7104
  function resolveSpecifier(fromFile, specifier, resolver) {
6858
7105
  if (!RELATIVE_SPECIFIER.test(specifier)) return null;
6859
- const joined = path12__namespace.posix.normalize(
6860
- path12__namespace.posix.join(path12__namespace.posix.dirname(fromFile), specifier)
7106
+ const joined = path13__namespace.posix.normalize(
7107
+ path13__namespace.posix.join(path13__namespace.posix.dirname(fromFile), specifier)
6861
7108
  );
6862
7109
  const exact = (key) => resolver.byPath.get(key) ?? resolver.byPathFolded.get(key.toLowerCase()) ?? null;
6863
7110
  const direct = exact(joined);
@@ -6950,11 +7197,11 @@ function verifyInMemory(files, parts, maxPartBytes) {
6950
7197
  return errors;
6951
7198
  }
6952
7199
  function resolveSafeOutputDirs(config) {
6953
- const cwd = path12__namespace.resolve(config.cwd);
6954
- const outDir = path12__namespace.resolve(cwd, config.outDir);
6955
- const tmpDir = path12__namespace.resolve(cwd, config.tmpDir);
6956
- const root = path12__namespace.parse(cwd).root;
6957
- const contains = (parent, child) => child === parent || child.startsWith(`${parent}${path12__namespace.sep}`);
7200
+ const cwd = path13__namespace.resolve(config.cwd);
7201
+ const outDir = path13__namespace.resolve(cwd, config.outDir);
7202
+ const tmpDir = path13__namespace.resolve(cwd, config.tmpDir);
7203
+ const root = path13__namespace.parse(cwd).root;
7204
+ const contains = (parent, child) => child === parent || child.startsWith(`${parent}${path13__namespace.sep}`);
6958
7205
  const reject = (reason) => {
6959
7206
  throw new Error(
6960
7207
  `Refusing to generate: ${reason}. outDir=${outDir} tmpDir=${tmpDir} cwd=${cwd}`
@@ -7010,14 +7257,14 @@ function listEntries(dir) {
7010
7257
  const walk = (absolute, prefix) => {
7011
7258
  let children;
7012
7259
  try {
7013
- children = fs11__namespace.readdirSync(absolute, { withFileTypes: true });
7260
+ children = fs12__namespace.readdirSync(absolute, { withFileTypes: true });
7014
7261
  } catch {
7015
7262
  return;
7016
7263
  }
7017
7264
  for (const child of children) {
7018
7265
  const relative11 = prefix === "" ? child.name : `${prefix}/${child.name}`;
7019
7266
  entries.push(relative11);
7020
- if (child.isDirectory()) walk(path12__namespace.join(absolute, child.name), relative11);
7267
+ if (child.isDirectory()) walk(path13__namespace.join(absolute, child.name), relative11);
7021
7268
  }
7022
7269
  };
7023
7270
  walk(dir, "");
@@ -7034,28 +7281,28 @@ function markerPayload(dir, state, id, createdAt) {
7034
7281
  pid: process.pid,
7035
7282
  entries: listEntries(dir)
7036
7283
  };
7037
- const manifestPath = path12__namespace.join(dir, "manifest.json");
7038
- if (fs11__namespace.existsSync(manifestPath)) {
7039
- marker2.manifestSha256 = sha256Hex2(fs11__namespace.readFileSync(manifestPath));
7284
+ const manifestPath = path13__namespace.join(dir, "manifest.json");
7285
+ if (fs12__namespace.existsSync(manifestPath)) {
7286
+ marker2.manifestSha256 = sha256Hex2(fs12__namespace.readFileSync(manifestPath));
7040
7287
  }
7041
7288
  return marker2;
7042
7289
  }
7043
7290
  function writeOwnershipMarker(dir, marker2) {
7044
- fs11__namespace.writeFileSync(
7045
- path12__namespace.join(dir, OWNERSHIP_MARKER),
7291
+ fs12__namespace.writeFileSync(
7292
+ path13__namespace.join(dir, OWNERSHIP_MARKER),
7046
7293
  `${JSON.stringify(marker2, null, 2)}
7047
7294
  `,
7048
7295
  "utf8"
7049
7296
  );
7050
7297
  }
7051
7298
  function readOwnershipMarker(dir) {
7052
- const markerPath = path12__namespace.join(dir, OWNERSHIP_MARKER);
7053
- if (!fs11__namespace.existsSync(markerPath)) {
7299
+ const markerPath = path13__namespace.join(dir, OWNERSHIP_MARKER);
7300
+ if (!fs12__namespace.existsSync(markerPath)) {
7054
7301
  return { marker: null, problem: "it holds no .codebase-snapshot marker" };
7055
7302
  }
7056
7303
  let raw;
7057
7304
  try {
7058
- raw = fs11__namespace.readFileSync(markerPath, "utf8");
7305
+ raw = fs12__namespace.readFileSync(markerPath, "utf8");
7059
7306
  } catch {
7060
7307
  return { marker: null, problem: "its .codebase-snapshot marker could not be read" };
7061
7308
  }
@@ -7123,11 +7370,11 @@ function assessSnapshotDirectory(dir) {
7123
7370
  marker: marker2
7124
7371
  };
7125
7372
  }
7126
- const manifestPath = path12__namespace.join(dir, "manifest.json");
7127
- if (fs11__namespace.existsSync(manifestPath)) {
7373
+ const manifestPath = path13__namespace.join(dir, "manifest.json");
7374
+ if (fs12__namespace.existsSync(manifestPath)) {
7128
7375
  let raw;
7129
7376
  try {
7130
- raw = fs11__namespace.readFileSync(manifestPath, "utf8");
7377
+ raw = fs12__namespace.readFileSync(manifestPath, "utf8");
7131
7378
  } catch {
7132
7379
  return {
7133
7380
  owned: false,
@@ -7209,13 +7456,13 @@ function containsNoFiles(dir) {
7209
7456
  const current = pending.pop();
7210
7457
  let entries;
7211
7458
  try {
7212
- entries = fs11__namespace.readdirSync(current, { withFileTypes: true });
7459
+ entries = fs12__namespace.readdirSync(current, { withFileTypes: true });
7213
7460
  } catch {
7214
7461
  return false;
7215
7462
  }
7216
7463
  for (const entry of entries) {
7217
7464
  if (entry.isDirectory()) {
7218
- pending.push(path12__namespace.join(current, entry.name));
7465
+ pending.push(path13__namespace.join(current, entry.name));
7219
7466
  } else if (!IGNORABLE_ENTRIES.has(entry.name)) {
7220
7467
  return false;
7221
7468
  }
@@ -7224,13 +7471,13 @@ function containsNoFiles(dir) {
7224
7471
  return true;
7225
7472
  }
7226
7473
  function assertReplaceable(target, label, secretRules) {
7227
- if (!fs11__namespace.existsSync(target)) return;
7228
- if (!fs11__namespace.statSync(target).isDirectory()) {
7474
+ if (!fs12__namespace.existsSync(target)) return;
7475
+ if (!fs12__namespace.statSync(target).isDirectory()) {
7229
7476
  throw new Error(
7230
7477
  `Refusing to write into ${label} ${target}: it exists but is not a directory.`
7231
7478
  );
7232
7479
  }
7233
- const entries = fs11__namespace.readdirSync(target);
7480
+ const entries = fs12__namespace.readdirSync(target);
7234
7481
  if (entries.length === 0) return;
7235
7482
  if (entries.every((name) => IGNORABLE_ENTRIES.has(name))) return;
7236
7483
  if (containsNoFiles(target)) return;
@@ -7250,18 +7497,18 @@ function assertReplaceable(target, label, secretRules) {
7250
7497
  );
7251
7498
  }
7252
7499
  function assertStagingRootUsable(tmpDir, secretRules) {
7253
- if (!fs11__namespace.existsSync(tmpDir)) return;
7254
- if (!fs11__namespace.statSync(tmpDir).isDirectory()) {
7500
+ if (!fs12__namespace.existsSync(tmpDir)) return;
7501
+ if (!fs12__namespace.statSync(tmpDir).isDirectory()) {
7255
7502
  throw new Error(`Refusing to write into tmpDir ${tmpDir}: it exists but is not a directory.`);
7256
7503
  }
7257
- const entries = fs11__namespace.readdirSync(tmpDir);
7504
+ const entries = fs12__namespace.readdirSync(tmpDir);
7258
7505
  if (entries.length === 0) return;
7259
7506
  const foreign = entries.filter((name) => {
7260
- const full = path12__namespace.join(tmpDir, name);
7507
+ const full = path13__namespace.join(tmpDir, name);
7261
7508
  if (!name.startsWith(RUN_DIR_PREFIX)) return true;
7262
7509
  let stats;
7263
7510
  try {
7264
- stats = fs11__namespace.statSync(full);
7511
+ stats = fs12__namespace.statSync(full);
7265
7512
  } catch {
7266
7513
  return true;
7267
7514
  }
@@ -7269,7 +7516,7 @@ function assertStagingRootUsable(tmpDir, secretRules) {
7269
7516
  const { marker: marker2 } = readOwnershipMarker(full);
7270
7517
  if (marker2) return false;
7271
7518
  try {
7272
- return fs11__namespace.readdirSync(full).length > 0;
7519
+ return fs12__namespace.readdirSync(full).length > 0;
7273
7520
  } catch {
7274
7521
  return true;
7275
7522
  }
@@ -7284,13 +7531,13 @@ function assertStagingRootUsable(tmpDir, secretRules) {
7284
7531
  function cleanStaleRunDirs(tmpDir) {
7285
7532
  let entries;
7286
7533
  try {
7287
- entries = fs11__namespace.readdirSync(tmpDir);
7534
+ entries = fs12__namespace.readdirSync(tmpDir);
7288
7535
  } catch {
7289
7536
  return;
7290
7537
  }
7291
7538
  for (const name of entries) {
7292
7539
  if (!name.startsWith(RUN_DIR_PREFIX)) continue;
7293
- const full = path12__namespace.join(tmpDir, name);
7540
+ const full = path13__namespace.join(tmpDir, name);
7294
7541
  const { marker: marker2 } = readOwnershipMarker(full);
7295
7542
  if (marker2) {
7296
7543
  const created = Date.parse(marker2.createdAt);
@@ -7298,33 +7545,33 @@ function cleanStaleRunDirs(tmpDir) {
7298
7545
  const abandoned = typeof marker2.pid === "number" && !isProcessAlive(marker2.pid);
7299
7546
  if (aged || abandoned) {
7300
7547
  try {
7301
- fs11__namespace.rmSync(full, { recursive: true, force: true });
7548
+ fs12__namespace.rmSync(full, { recursive: true, force: true });
7302
7549
  } catch {
7303
7550
  }
7304
7551
  }
7305
7552
  continue;
7306
7553
  }
7307
7554
  try {
7308
- if (fs11__namespace.readdirSync(full).length === 0) fs11__namespace.rmSync(full, { recursive: true, force: true });
7555
+ if (fs12__namespace.readdirSync(full).length === 0) fs12__namespace.rmSync(full, { recursive: true, force: true });
7309
7556
  } catch {
7310
7557
  }
7311
7558
  }
7312
7559
  }
7313
7560
  function removeIfEmpty(dir) {
7314
7561
  try {
7315
- if (fs11__namespace.readdirSync(dir).length === 0) fs11__namespace.rmSync(dir, { recursive: true, force: true });
7562
+ if (fs12__namespace.readdirSync(dir).length === 0) fs12__namespace.rmSync(dir, { recursive: true, force: true });
7316
7563
  } catch {
7317
7564
  }
7318
7565
  }
7319
7566
  function ensureParentDirectory(target, label) {
7320
- const parent = path12__namespace.dirname(target);
7321
- if (fs11__namespace.existsSync(parent) && !fs11__namespace.statSync(parent).isDirectory()) {
7567
+ const parent = path13__namespace.dirname(target);
7568
+ if (fs12__namespace.existsSync(parent) && !fs12__namespace.statSync(parent).isDirectory()) {
7322
7569
  throw new Error(
7323
7570
  `Refusing to create ${label} ${target}: ${parent} exists but is not a directory.`
7324
7571
  );
7325
7572
  }
7326
7573
  try {
7327
- fs11__namespace.mkdirSync(parent, { recursive: true });
7574
+ fs12__namespace.mkdirSync(parent, { recursive: true });
7328
7575
  } catch (err) {
7329
7576
  throw new Error(
7330
7577
  `Refusing to create ${label} ${target}: its parent ${parent} could not be created (${err.message}).`
@@ -7333,7 +7580,7 @@ function ensureParentDirectory(target, label) {
7333
7580
  }
7334
7581
  function acquireRunLock(stagingRoot) {
7335
7582
  const key = lockKeyFor(stagingRoot);
7336
- const lockPath = path12__namespace.join(os__namespace.tmpdir(), `codebase-snapshot-${key}.lock`);
7583
+ const lockPath = path13__namespace.join(os__namespace.tmpdir(), `codebase-snapshot-${key}.lock`);
7337
7584
  const payload = `${JSON.stringify({
7338
7585
  pid: process.pid,
7339
7586
  stagingRoot,
@@ -7342,22 +7589,22 @@ function acquireRunLock(stagingRoot) {
7342
7589
  `;
7343
7590
  for (let attempt = 0; attempt < 2; attempt += 1) {
7344
7591
  try {
7345
- const handle = fs11__namespace.openSync(lockPath, "wx");
7592
+ const handle = fs12__namespace.openSync(lockPath, "wx");
7346
7593
  try {
7347
- fs11__namespace.writeSync(handle, payload);
7594
+ fs12__namespace.writeSync(handle, payload);
7348
7595
  } finally {
7349
- fs11__namespace.closeSync(handle);
7596
+ fs12__namespace.closeSync(handle);
7350
7597
  }
7351
7598
  return () => {
7352
7599
  try {
7353
- fs11__namespace.rmSync(lockPath, { force: true });
7600
+ fs12__namespace.rmSync(lockPath, { force: true });
7354
7601
  } catch {
7355
7602
  }
7356
7603
  };
7357
7604
  } catch (err) {
7358
7605
  if (err.code !== "EEXIST") throw err;
7359
7606
  if (attempt === 0 && lockOwnerIsGone(lockPath)) {
7360
- fs11__namespace.rmSync(lockPath, { force: true });
7607
+ fs12__namespace.rmSync(lockPath, { force: true });
7361
7608
  continue;
7362
7609
  }
7363
7610
  throw new Error(
@@ -7370,7 +7617,7 @@ function acquireRunLock(stagingRoot) {
7370
7617
  function lockKeyFor(stagingRoot) {
7371
7618
  let key = stagingRoot;
7372
7619
  try {
7373
- key = fs11__namespace.realpathSync(stagingRoot);
7620
+ key = fs12__namespace.realpathSync(stagingRoot);
7374
7621
  } catch {
7375
7622
  }
7376
7623
  if (process.platform === "win32" || process.platform === "darwin") key = key.toLowerCase();
@@ -7379,7 +7626,7 @@ function lockKeyFor(stagingRoot) {
7379
7626
  function lockOwnerIsGone(lockPath) {
7380
7627
  let raw;
7381
7628
  try {
7382
- raw = fs11__namespace.readFileSync(lockPath, "utf8");
7629
+ raw = fs12__namespace.readFileSync(lockPath, "utf8");
7383
7630
  } catch {
7384
7631
  return false;
7385
7632
  }
@@ -7399,12 +7646,12 @@ function lockOwnerIsGone(lockPath) {
7399
7646
  }
7400
7647
  function writeManifestAtomically(manifestPath, manifest) {
7401
7648
  const tempPath = `${manifestPath}.${process.pid}.tmp`;
7402
- fs11__namespace.writeFileSync(tempPath, JSON.stringify(manifest, null, 2), "utf8");
7649
+ fs12__namespace.writeFileSync(tempPath, JSON.stringify(manifest, null, 2), "utf8");
7403
7650
  try {
7404
- fs11__namespace.renameSync(tempPath, manifestPath);
7651
+ fs12__namespace.renameSync(tempPath, manifestPath);
7405
7652
  } catch (err) {
7406
7653
  try {
7407
- fs11__namespace.rmSync(tempPath, { force: true });
7654
+ fs12__namespace.rmSync(tempPath, { force: true });
7408
7655
  } catch {
7409
7656
  }
7410
7657
  throw err;
@@ -7427,31 +7674,31 @@ function swapIntoPlace(stagingDir, outDir) {
7427
7674
  }
7428
7675
  function swapOnce(stagingDir, outDir) {
7429
7676
  const backupDir = `${outDir}.backup-${process.pid}-${Date.now()}`;
7430
- const hadPrevious = fs11__namespace.existsSync(outDir);
7431
- if (hadPrevious) fs11__namespace.renameSync(outDir, backupDir);
7677
+ const hadPrevious = fs12__namespace.existsSync(outDir);
7678
+ if (hadPrevious) fs12__namespace.renameSync(outDir, backupDir);
7432
7679
  try {
7433
7680
  try {
7434
- fs11__namespace.renameSync(stagingDir, outDir);
7681
+ fs12__namespace.renameSync(stagingDir, outDir);
7435
7682
  } catch (err) {
7436
7683
  if (err.code !== "EXDEV") throw err;
7437
7684
  const partialDir = `${outDir}.partial-${process.pid}-${Date.now()}`;
7438
7685
  try {
7439
- fs11__namespace.cpSync(stagingDir, partialDir, { recursive: true });
7440
- fs11__namespace.renameSync(partialDir, outDir);
7441
- fs11__namespace.rmSync(stagingDir, { recursive: true, force: true });
7686
+ fs12__namespace.cpSync(stagingDir, partialDir, { recursive: true });
7687
+ fs12__namespace.renameSync(partialDir, outDir);
7688
+ fs12__namespace.rmSync(stagingDir, { recursive: true, force: true });
7442
7689
  } catch (copyErr) {
7443
7690
  try {
7444
- fs11__namespace.rmSync(partialDir, { recursive: true, force: true });
7691
+ fs12__namespace.rmSync(partialDir, { recursive: true, force: true });
7445
7692
  } catch {
7446
7693
  }
7447
7694
  throw copyErr;
7448
7695
  }
7449
7696
  }
7450
- if (hadPrevious) fs11__namespace.rmSync(backupDir, { recursive: true, force: true });
7697
+ if (hadPrevious) fs12__namespace.rmSync(backupDir, { recursive: true, force: true });
7451
7698
  } catch (err) {
7452
- if (hadPrevious && fs11__namespace.existsSync(backupDir)) {
7453
- if (fs11__namespace.existsSync(outDir)) fs11__namespace.rmSync(outDir, { recursive: true, force: true });
7454
- fs11__namespace.renameSync(backupDir, outDir);
7699
+ if (hadPrevious && fs12__namespace.existsSync(backupDir)) {
7700
+ if (fs12__namespace.existsSync(outDir)) fs12__namespace.rmSync(outDir, { recursive: true, force: true });
7701
+ fs12__namespace.renameSync(backupDir, outDir);
7455
7702
  }
7456
7703
  throw err;
7457
7704
  }
@@ -7546,7 +7793,7 @@ function generateSnapshot(configInput, options) {
7546
7793
  // first run cannot have marked them yet, so the name alone keeps a run from recording its own
7547
7794
  // output — but only at these exact paths, not at every directory that shares the name.
7548
7795
  toolOwnedPaths: [config.outDir, config.tmpDir].map(
7549
- (directory) => path12__namespace.relative(config.cwd, path12__namespace.resolve(config.cwd, directory)).replace(/\\/g, "/")
7796
+ (directory) => path13__namespace.relative(config.cwd, path13__namespace.resolve(config.cwd, directory)).replace(/\\/g, "/")
7550
7797
  ).filter((relative11) => relative11.length > 0 && !relative11.startsWith(".."))
7551
7798
  });
7552
7799
  const files = [];
@@ -7567,12 +7814,12 @@ function generateSnapshot(configInput, options) {
7567
7814
  let totalSizeBytes = 0;
7568
7815
  let largeFileCount = 0;
7569
7816
  for (const relativePath of collection.files) {
7570
- const absolutePath = path12__namespace.join(config.cwd, relativePath);
7817
+ const absolutePath = path13__namespace.join(config.cwd, relativePath);
7571
7818
  let stats;
7572
7819
  try {
7573
- stats = fs11__namespace.statSync(absolutePath);
7820
+ stats = fs12__namespace.statSync(absolutePath);
7574
7821
  if (!stats.isFile()) {
7575
- const nestedRepository = stats.isDirectory() && fs11__namespace.existsSync(path12__namespace.join(absolutePath, ".git"));
7822
+ const nestedRepository = stats.isDirectory() && fs12__namespace.existsSync(path13__namespace.join(absolutePath, ".git"));
7576
7823
  skipped.push(
7577
7824
  nestedRepository ? {
7578
7825
  path: relativePath,
@@ -7592,7 +7839,7 @@ function generateSnapshot(configInput, options) {
7592
7839
  }
7593
7840
  let buffer;
7594
7841
  try {
7595
- buffer = fs11__namespace.readFileSync(absolutePath);
7842
+ buffer = fs12__namespace.readFileSync(absolutePath);
7596
7843
  } catch {
7597
7844
  skipped.push({ path: relativePath, reason: "read-error" });
7598
7845
  continue;
@@ -7922,12 +8169,12 @@ function generateSnapshot(configInput, options) {
7922
8169
  let stagingDir = null;
7923
8170
  try {
7924
8171
  ensureParentDirectory(outDir, "outDir");
7925
- fs11__namespace.mkdirSync(tmpDir, { recursive: true });
8172
+ fs12__namespace.mkdirSync(tmpDir, { recursive: true });
7926
8173
  cleanStaleRunDirs(tmpDir);
7927
8174
  const snapshotId = crypto2__namespace.randomUUID();
7928
8175
  const createdAt = (/* @__PURE__ */ new Date()).toISOString();
7929
- stagingDir = path12__namespace.join(tmpDir, `${RUN_DIR_PREFIX}${process.pid}-${snapshotId.slice(0, 8)}`);
7930
- fs11__namespace.mkdirSync(stagingDir);
8176
+ stagingDir = path13__namespace.join(tmpDir, `${RUN_DIR_PREFIX}${process.pid}-${snapshotId.slice(0, 8)}`);
8177
+ fs12__namespace.mkdirSync(stagingDir);
7931
8178
  writeOwnershipMarker(stagingDir, {
7932
8179
  generator: GENERATOR_NAME,
7933
8180
  version: GENERATOR_VERSION,
@@ -7937,41 +8184,41 @@ function generateSnapshot(configInput, options) {
7937
8184
  id: snapshotId,
7938
8185
  pid: process.pid
7939
8186
  });
7940
- const partsDir = path12__namespace.join(stagingDir, "parts");
7941
- const reportsDir = path12__namespace.join(stagingDir, "reports");
7942
- if (artifacts.parts) fs11__namespace.mkdirSync(partsDir, { recursive: true });
8187
+ const partsDir = path13__namespace.join(stagingDir, "parts");
8188
+ const reportsDir = path13__namespace.join(stagingDir, "reports");
8189
+ if (artifacts.parts) fs12__namespace.mkdirSync(partsDir, { recursive: true });
7943
8190
  if (artifacts.navigation || artifacts.projectTree || artifacts.audit) {
7944
- fs11__namespace.mkdirSync(reportsDir, { recursive: true });
8191
+ fs12__namespace.mkdirSync(reportsDir, { recursive: true });
7945
8192
  }
7946
8193
  if (artifacts.parts) {
7947
8194
  for (const part of parts) {
7948
- fs11__namespace.writeFileSync(path12__namespace.join(partsDir, part.filename), part.markdown, "utf8");
8195
+ fs12__namespace.writeFileSync(path13__namespace.join(partsDir, part.filename), part.markdown, "utf8");
7949
8196
  }
7950
8197
  }
7951
8198
  if (projectTree !== null) {
7952
- fs11__namespace.writeFileSync(path12__namespace.join(reportsDir, "project-tree.md"), projectTree, "utf8");
8199
+ fs12__namespace.writeFileSync(path13__namespace.join(reportsDir, "project-tree.md"), projectTree, "utf8");
7953
8200
  }
7954
8201
  if (artifacts.navigation) {
7955
- fs11__namespace.writeFileSync(path12__namespace.join(reportsDir, "navigation.md"), generateNavigation(manifest), "utf8");
8202
+ fs12__namespace.writeFileSync(path13__namespace.join(reportsDir, "navigation.md"), generateNavigation(manifest), "utf8");
7956
8203
  }
7957
8204
  if (artifacts.audit) {
7958
- fs11__namespace.writeFileSync(
7959
- path12__namespace.join(reportsDir, "audit.md"),
8205
+ fs12__namespace.writeFileSync(
8206
+ path13__namespace.join(reportsDir, "audit.md"),
7960
8207
  generateAuditReport(manifest, secretFindings, config.secretRules),
7961
8208
  "utf8"
7962
8209
  );
7963
8210
  }
7964
8211
  if (artifacts.readme) {
7965
- fs11__namespace.writeFileSync(path12__namespace.join(stagingDir, "README.md"), generateReadme(manifest, artifacts), "utf8");
8212
+ fs12__namespace.writeFileSync(path13__namespace.join(stagingDir, "README.md"), generateReadme(manifest, artifacts), "utf8");
7966
8213
  }
7967
8214
  if (artifacts.manifest) {
7968
- fs11__namespace.writeFileSync(path12__namespace.join(stagingDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf8");
8215
+ fs12__namespace.writeFileSync(path13__namespace.join(stagingDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf8");
7969
8216
  }
7970
8217
  if (monolithJson !== null) {
7971
- fs11__namespace.writeFileSync(path12__namespace.join(stagingDir, "full-codebase.json"), monolithJson, "utf8");
8218
+ fs12__namespace.writeFileSync(path13__namespace.join(stagingDir, "full-codebase.json"), monolithJson, "utf8");
7972
8219
  }
7973
8220
  if (monolithMarkdown !== null) {
7974
- fs11__namespace.writeFileSync(path12__namespace.join(stagingDir, "full-codebase.md"), monolithMarkdown, "utf8");
8221
+ fs12__namespace.writeFileSync(path13__namespace.join(stagingDir, "full-codebase.md"), monolithMarkdown, "utf8");
7975
8222
  }
7976
8223
  writeOwnershipMarker(stagingDir, markerPayload(stagingDir, "complete", snapshotId, createdAt));
7977
8224
  swapIntoPlace(stagingDir, outDir);
@@ -7980,7 +8227,7 @@ function generateSnapshot(configInput, options) {
7980
8227
  const pendingHook = runAfterGenerate(config, manifest);
7981
8228
  const shipHookState = () => {
7982
8229
  if (artifacts.manifest && manifest.warnings.length !== warningsBeforeHook) {
7983
- writeManifestAtomically(path12__namespace.join(outDir, "manifest.json"), manifest);
8230
+ writeManifestAtomically(path13__namespace.join(outDir, "manifest.json"), manifest);
7984
8231
  }
7985
8232
  writeOwnershipMarker(outDir, markerPayload(outDir, "complete", snapshotId, createdAt));
7986
8233
  };
@@ -8003,7 +8250,7 @@ function generateSnapshot(configInput, options) {
8003
8250
  } catch (err) {
8004
8251
  if (stagingDir !== null) {
8005
8252
  try {
8006
- fs11__namespace.rmSync(stagingDir, { recursive: true, force: true });
8253
+ fs12__namespace.rmSync(stagingDir, { recursive: true, force: true });
8007
8254
  } catch {
8008
8255
  }
8009
8256
  }
@@ -8100,9 +8347,9 @@ function foldForComparison(value) {
8100
8347
  return process.platform === "win32" || process.platform === "darwin" ? value.toLowerCase() : value;
8101
8348
  }
8102
8349
  function canonicalPath(value) {
8103
- const absolute = path12__namespace.resolve(value);
8350
+ const absolute = path13__namespace.resolve(value);
8104
8351
  try {
8105
- return fs11__namespace.realpathSync(absolute);
8352
+ return fs12__namespace.realpathSync(absolute);
8106
8353
  } catch {
8107
8354
  return absolute;
8108
8355
  }
@@ -8110,17 +8357,17 @@ function canonicalPath(value) {
8110
8357
  function isInside2(parent, child) {
8111
8358
  const foldedParent = foldForComparison(parent);
8112
8359
  const foldedChild = foldForComparison(child);
8113
- return foldedChild === foldedParent || foldedChild.startsWith(`${foldedParent}${path12__namespace.sep}`);
8360
+ return foldedChild === foldedParent || foldedChild.startsWith(`${foldedParent}${path13__namespace.sep}`);
8114
8361
  }
8115
8362
  function resolveRoot(requested, context) {
8116
8363
  if (requested !== void 0 && (typeof requested !== "string" || requested.trim().length === 0)) {
8117
8364
  return { ok: false, message: '"root" must be a non-empty string when provided.' };
8118
8365
  }
8119
8366
  const wanted = typeof requested === "string" ? requested.trim() : context.cwd;
8120
- const absolute = path12__namespace.resolve(context.cwd, wanted);
8367
+ const absolute = path13__namespace.resolve(context.cwd, wanted);
8121
8368
  let stats;
8122
8369
  try {
8123
- stats = fs11__namespace.statSync(absolute);
8370
+ stats = fs12__namespace.statSync(absolute);
8124
8371
  } catch {
8125
8372
  return { ok: false, message: `"${wanted}" does not exist, so it cannot be a repository root.` };
8126
8373
  }
@@ -8171,14 +8418,14 @@ async function openWorkspace(root, overrides = {}) {
8171
8418
  }
8172
8419
  var manifestCache = /* @__PURE__ */ new Map();
8173
8420
  function manifestPathFor(workspace) {
8174
- return path12__namespace.resolve(workspace.root, workspace.config.outDir, "manifest.json");
8421
+ return path13__namespace.resolve(workspace.root, workspace.config.outDir, "manifest.json");
8175
8422
  }
8176
8423
  function readManifest3(workspace) {
8177
8424
  const file = manifestPathFor(workspace);
8178
- const shown = path12__namespace.relative(workspace.root, file).split(path12__namespace.sep).join("/") || file;
8425
+ const shown = path13__namespace.relative(workspace.root, file).split(path13__namespace.sep).join("/") || file;
8179
8426
  let stats;
8180
8427
  try {
8181
- stats = fs11__namespace.statSync(file);
8428
+ stats = fs12__namespace.statSync(file);
8182
8429
  } catch {
8183
8430
  return {
8184
8431
  ok: false,
@@ -8192,7 +8439,7 @@ function readManifest3(workspace) {
8192
8439
  }
8193
8440
  let raw;
8194
8441
  try {
8195
- raw = fs11__namespace.readFileSync(file, "utf8");
8442
+ raw = fs12__namespace.readFileSync(file, "utf8");
8196
8443
  } catch (error) {
8197
8444
  return {
8198
8445
  ok: false,
@@ -8250,7 +8497,7 @@ function formatBytes(bytes) {
8250
8497
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
8251
8498
  }
8252
8499
  function relativeFor(workspace, absolute) {
8253
- return path12__namespace.relative(workspace.root, absolute).split(path12__namespace.sep).join("/");
8500
+ return path13__namespace.relative(workspace.root, absolute).split(path13__namespace.sep).join("/");
8254
8501
  }
8255
8502
  function capped(values, limit = 20) {
8256
8503
  return { count: values.length, sample: values.slice(0, limit) };
@@ -8269,12 +8516,12 @@ function summarizeDrift(drift) {
8269
8516
  function toRelativePath(root, value) {
8270
8517
  const cleaned = value.trim();
8271
8518
  if (cleaned.length === 0) return null;
8272
- if (!path12__namespace.isAbsolute(cleaned)) {
8519
+ if (!path13__namespace.isAbsolute(cleaned)) {
8273
8520
  return cleaned.replace(/\\/g, "/").replace(/^\.\//, "");
8274
8521
  }
8275
- const relative11 = path12__namespace.relative(root, cleaned);
8276
- if (relative11.startsWith("..") || path12__namespace.isAbsolute(relative11)) return null;
8277
- return relative11.split(path12__namespace.sep).join("/");
8522
+ const relative11 = path13__namespace.relative(root, cleaned);
8523
+ if (relative11.startsWith("..") || path13__namespace.isAbsolute(relative11)) return null;
8524
+ return relative11.split(path13__namespace.sep).join("/");
8278
8525
  }
8279
8526
  function symbolsOf(entry) {
8280
8527
  const summary = entry.summary;
@@ -8485,7 +8732,7 @@ var generateTool = {
8485
8732
  return failure(error instanceof Error ? error.message : String(error));
8486
8733
  }
8487
8734
  forgetManifest(manifestPathFor(workspace));
8488
- const written = relativeFor(workspace, path12__namespace.resolve(workspace.root, workspace.config.outDir));
8735
+ const written = relativeFor(workspace, path13__namespace.resolve(workspace.root, workspace.config.outDir));
8489
8736
  const lines = [
8490
8737
  `Wrote ${written}/`,
8491
8738
  `Files: ${manifest.counts.totalFiles} included, ${manifest.counts.skippedCount} skipped, ${plural(manifest.counts.partsCount, "part")}`,
@@ -8750,10 +8997,10 @@ var readTool = {
8750
8997
  `${relativePath} is not in the snapshot. Call snapshot_locate to find the path, or snapshot_explain to learn why it was excluded.`
8751
8998
  );
8752
8999
  }
8753
- const partPath = path12__namespace.resolve(workspace.root, workspace.config.outDir, "parts", entry.part);
9000
+ const partPath = path13__namespace.resolve(workspace.root, workspace.config.outDir, "parts", entry.part);
8754
9001
  let partText;
8755
9002
  try {
8756
- partText = fs11__namespace.readFileSync(partPath, "utf8");
9003
+ partText = fs12__namespace.readFileSync(partPath, "utf8");
8757
9004
  } catch {
8758
9005
  return failure(
8759
9006
  `${entry.part} could not be read, so the snapshot is damaged. Run snapshot_generate to rebuild it.`
@@ -9011,6 +9258,7 @@ var VALIDATE_OPTIONS = [
9011
9258
  "no-config",
9012
9259
  "discovery",
9013
9260
  "format",
9261
+ "no-update-check",
9014
9262
  "mode",
9015
9263
  "help",
9016
9264
  "version"
@@ -9034,6 +9282,7 @@ var COMMAND_OPTION_SCOPE = {
9034
9282
  "watch",
9035
9283
  "autopilot",
9036
9284
  "no-install",
9285
+ "no-update-check",
9037
9286
  "help",
9038
9287
  "version"
9039
9288
  ],
@@ -9049,6 +9298,7 @@ var COMMAND_OPTION_SCOPE = {
9049
9298
  "skip-artifacts",
9050
9299
  "only-artifacts",
9051
9300
  "no-config",
9301
+ "no-update-check",
9052
9302
  "format",
9053
9303
  "mode",
9054
9304
  "help",
@@ -9066,12 +9316,13 @@ var COMMAND_OPTION_SCOPE = {
9066
9316
  "only-artifacts",
9067
9317
  "no-config",
9068
9318
  "discovery",
9319
+ "no-update-check",
9069
9320
  "format",
9070
9321
  "mode",
9071
9322
  "help",
9072
9323
  "version"
9073
9324
  ],
9074
- diff: ["format", "mode", "no-config", "help", "version"],
9325
+ diff: ["format", "mode", "no-config", "no-update-check", "help", "version"],
9075
9326
  describe: ["format", "mode", "help", "version"],
9076
9327
  init: [
9077
9328
  "cwd",
@@ -9086,6 +9337,7 @@ var COMMAND_OPTION_SCOPE = {
9086
9337
  "yes",
9087
9338
  "force",
9088
9339
  "dry-run",
9340
+ "no-update-check",
9089
9341
  "format",
9090
9342
  "mode",
9091
9343
  "help",
@@ -9109,6 +9361,7 @@ var COMMAND_OPTION_SCOPE = {
9109
9361
  "force",
9110
9362
  "no-install",
9111
9363
  "dry-run",
9364
+ "no-update-check",
9112
9365
  "format",
9113
9366
  "mode",
9114
9367
  "help",
@@ -9541,6 +9794,13 @@ function buildAgentContract() {
9541
9794
  default: false,
9542
9795
  appliesTo: optionAppliesTo("no-install"),
9543
9796
  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)."
9797
+ },
9798
+ {
9799
+ flag: "--no-update-check",
9800
+ type: "boolean",
9801
+ default: false,
9802
+ appliesTo: optionAppliesTo("no-update-check"),
9803
+ 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."
9544
9804
  }
9545
9805
  ],
9546
9806
  presets: PRESETS.map((preset) => ({
@@ -9828,17 +10088,17 @@ var LEGACY_AGENTS_MARKER = "<!-- codebase-snapshot:skill:start -->";
9828
10088
  function targetPath(cwd, target) {
9829
10089
  switch (target) {
9830
10090
  case "claude":
9831
- return path12__namespace.join(cwd, ".claude", "skills", SKILL_NAME, "SKILL.md");
10091
+ return path13__namespace.join(cwd, ".claude", "skills", SKILL_NAME, "SKILL.md");
9832
10092
  case "cursor":
9833
- return path12__namespace.join(cwd, ".cursor", "rules", `${SKILL_NAME}.mdc`);
10093
+ return path13__namespace.join(cwd, ".cursor", "rules", `${SKILL_NAME}.mdc`);
9834
10094
  }
9835
10095
  }
9836
10096
  function assertWritableInsideRepository(cwd, filePath) {
9837
- const root = fs11__namespace.realpathSync(cwd);
9838
- const shown = path12__namespace.relative(root, filePath) || filePath;
10097
+ const root = fs12__namespace.realpathSync(cwd);
10098
+ const shown = path13__namespace.relative(root, filePath) || filePath;
9839
10099
  let stat = null;
9840
10100
  try {
9841
- stat = fs11__namespace.lstatSync(filePath);
10101
+ stat = fs12__namespace.lstatSync(filePath);
9842
10102
  } catch {
9843
10103
  stat = null;
9844
10104
  }
@@ -9854,32 +10114,32 @@ function assertWritableInsideRepository(cwd, filePath) {
9854
10114
  }
9855
10115
  let existing = filePath;
9856
10116
  const missing = [];
9857
- while (!fs11__namespace.existsSync(existing)) {
9858
- missing.unshift(path12__namespace.basename(existing));
9859
- const parent = path12__namespace.dirname(existing);
10117
+ while (!fs12__namespace.existsSync(existing)) {
10118
+ missing.unshift(path13__namespace.basename(existing));
10119
+ const parent = path13__namespace.dirname(existing);
9860
10120
  if (parent === existing) break;
9861
10121
  existing = parent;
9862
10122
  }
9863
- const realAncestor = fs11__namespace.realpathSync(existing);
9864
- const resolved = missing.length === 0 ? realAncestor : path12__namespace.join(realAncestor, ...missing);
9865
- if (resolved !== root && !resolved.startsWith(`${root}${path12__namespace.sep}`)) {
10123
+ const realAncestor = fs12__namespace.realpathSync(existing);
10124
+ const resolved = missing.length === 0 ? realAncestor : path13__namespace.join(realAncestor, ...missing);
10125
+ if (resolved !== root && !resolved.startsWith(`${root}${path13__namespace.sep}`)) {
9866
10126
  throw new Error(
9867
10127
  `${REFUSED}: ${shown} resolves outside the repository (${resolved}). Move it back inside ${root}, or remove the link, and run again.`
9868
10128
  );
9869
10129
  }
9870
10130
  }
9871
10131
  function writeIfChanged(target, filePath, content) {
9872
- const existing = fs11__namespace.existsSync(filePath) ? fs11__namespace.readFileSync(filePath, "utf8") : null;
10132
+ const existing = fs12__namespace.existsSync(filePath) ? fs12__namespace.readFileSync(filePath, "utf8") : null;
9873
10133
  if (existing === content) return { target, path: filePath, action: "unchanged" };
9874
- fs11__namespace.mkdirSync(path12__namespace.dirname(filePath), { recursive: true });
9875
- fs11__namespace.writeFileSync(filePath, content, "utf8");
10134
+ fs12__namespace.mkdirSync(path13__namespace.dirname(filePath), { recursive: true });
10135
+ fs12__namespace.writeFileSync(filePath, content, "utf8");
9876
10136
  return { target, path: filePath, action: existing === null ? "created" : "updated" };
9877
10137
  }
9878
10138
  function legacyAgentsNote(cwd) {
9879
- const filePath = path12__namespace.join(cwd, "AGENTS.md");
10139
+ const filePath = path13__namespace.join(cwd, "AGENTS.md");
9880
10140
  try {
9881
- if (!fs11__namespace.existsSync(filePath)) return null;
9882
- if (!fs11__namespace.readFileSync(filePath, "utf8").includes(LEGACY_AGENTS_MARKER)) return null;
10141
+ if (!fs12__namespace.existsSync(filePath)) return null;
10142
+ if (!fs12__namespace.readFileSync(filePath, "utf8").includes(LEGACY_AGENTS_MARKER)) return null;
9883
10143
  } catch {
9884
10144
  return null;
9885
10145
  }
@@ -9891,9 +10151,9 @@ function installSkill(cwd, target = "all") {
9891
10151
  const notes = [];
9892
10152
  const wanted = target === "all" ? ["claude", "cursor"] : [target];
9893
10153
  for (const item of wanted) assertWritableInsideRepository(cwd, targetPath(cwd, item));
9894
- const createsSomething = wanted.some((item) => !fs11__namespace.existsSync(targetPath(cwd, item)));
10154
+ const createsSomething = wanted.some((item) => !fs12__namespace.existsSync(targetPath(cwd, item)));
9895
10155
  if (createsSomething) {
9896
- assertWritableInsideRepository(cwd, path12__namespace.join(cwd, ".gitignore"));
10156
+ assertWritableInsideRepository(cwd, path13__namespace.join(cwd, ".gitignore"));
9897
10157
  }
9898
10158
  for (const item of wanted) {
9899
10159
  written.push(writeIfChanged(item, targetPath(cwd, item), skill));
@@ -10028,52 +10288,52 @@ function validateArguments(schema, value) {
10028
10288
  }
10029
10289
  return problems;
10030
10290
  }
10031
- function checkValue(path18, schema, value) {
10291
+ function checkValue(path19, schema, value) {
10032
10292
  if (schema.enum && !schema.enum.includes(value)) {
10033
- return [`"${path18}" must be one of: ${schema.enum.join(", ")}`];
10293
+ return [`"${path19}" must be one of: ${schema.enum.join(", ")}`];
10034
10294
  }
10035
10295
  switch (schema.type) {
10036
10296
  case "string": {
10037
- if (typeof value !== "string") return [`"${path18}" must be a string`];
10297
+ if (typeof value !== "string") return [`"${path19}" must be a string`];
10038
10298
  const problems = [];
10039
10299
  if (schema.minLength !== void 0 && value.length < schema.minLength) {
10040
- problems.push(`"${path18}" must be at least ${schema.minLength} character(s)`);
10300
+ problems.push(`"${path19}" must be at least ${schema.minLength} character(s)`);
10041
10301
  }
10042
10302
  if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
10043
- problems.push(`"${path18}" must be at most ${schema.maxLength} character(s)`);
10303
+ problems.push(`"${path19}" must be at most ${schema.maxLength} character(s)`);
10044
10304
  }
10045
10305
  return problems;
10046
10306
  }
10047
10307
  case "number":
10048
10308
  case "integer": {
10049
10309
  if (typeof value !== "number" || Number.isNaN(value)) {
10050
- return [`"${path18}" must be a number`];
10310
+ return [`"${path19}" must be a number`];
10051
10311
  }
10052
10312
  if (schema.type === "integer" && !Number.isInteger(value)) {
10053
- return [`"${path18}" must be an integer`];
10313
+ return [`"${path19}" must be an integer`];
10054
10314
  }
10055
10315
  const problems = [];
10056
10316
  if (schema.minimum !== void 0 && value < schema.minimum) {
10057
- problems.push(`"${path18}" must be >= ${schema.minimum}`);
10317
+ problems.push(`"${path19}" must be >= ${schema.minimum}`);
10058
10318
  }
10059
10319
  if (schema.maximum !== void 0 && value > schema.maximum) {
10060
- problems.push(`"${path18}" must be <= ${schema.maximum}`);
10320
+ problems.push(`"${path19}" must be <= ${schema.maximum}`);
10061
10321
  }
10062
10322
  return problems;
10063
10323
  }
10064
10324
  case "boolean":
10065
- return typeof value === "boolean" ? [] : [`"${path18}" must be a boolean`];
10325
+ return typeof value === "boolean" ? [] : [`"${path19}" must be a boolean`];
10066
10326
  case "array": {
10067
- if (!Array.isArray(value)) return [`"${path18}" must be an array`];
10327
+ if (!Array.isArray(value)) return [`"${path19}" must be an array`];
10068
10328
  if (!schema.items) return [];
10069
10329
  const problems = [];
10070
10330
  value.forEach((item, index) => {
10071
- problems.push(...checkValue(`${path18}[${index}]`, schema.items, item));
10331
+ problems.push(...checkValue(`${path19}[${index}]`, schema.items, item));
10072
10332
  });
10073
10333
  return problems;
10074
10334
  }
10075
10335
  case "object":
10076
- return isJsonObject(value) ? [] : [`"${path18}" must be an object`];
10336
+ return isJsonObject(value) ? [] : [`"${path19}" must be an object`];
10077
10337
  default:
10078
10338
  return [];
10079
10339
  }
@@ -10087,6 +10347,18 @@ function applyDefaults(schema, value) {
10087
10347
  }
10088
10348
  return out;
10089
10349
  }
10350
+ function coerceNumericStrings(schema, value) {
10351
+ const out = { ...value };
10352
+ for (const [key, propertySchema] of Object.entries(schema.properties)) {
10353
+ const raw = out[key];
10354
+ if (typeof raw !== "string") continue;
10355
+ if (propertySchema.type !== "number" && propertySchema.type !== "integer") continue;
10356
+ if (raw.trim().length === 0) continue;
10357
+ const parsed = Number(raw);
10358
+ if (Number.isFinite(parsed)) out[key] = parsed;
10359
+ }
10360
+ return out;
10361
+ }
10090
10362
 
10091
10363
  // src/mcp/server.ts
10092
10364
  function capabilities() {
@@ -10175,7 +10447,8 @@ function createMcpServer(options) {
10175
10447
  if (!isJsonObject(rawArguments)) {
10176
10448
  return errorResponse(id, ERROR_CODES.invalidParams, '"arguments" must be a JSON object.');
10177
10449
  }
10178
- const problems = validateArguments(tool.inputSchema, rawArguments);
10450
+ const supplied = coerceNumericStrings(tool.inputSchema, rawArguments);
10451
+ const problems = validateArguments(tool.inputSchema, supplied);
10179
10452
  if (problems.length > 0) {
10180
10453
  return ok(
10181
10454
  id,
@@ -10187,7 +10460,7 @@ function createMcpServer(options) {
10187
10460
  modern
10188
10461
  );
10189
10462
  }
10190
- const args = applyDefaults(tool.inputSchema, rawArguments);
10463
+ const args = applyDefaults(tool.inputSchema, supplied);
10191
10464
  let outcome;
10192
10465
  try {
10193
10466
  outcome = await tool.handler(args, options.context);
@@ -10385,7 +10658,7 @@ async function workspaceFor(context) {
10385
10658
  }
10386
10659
  function readFileIfPresent(file) {
10387
10660
  try {
10388
- return fs11__namespace.readFileSync(file, "utf8");
10661
+ return fs12__namespace.readFileSync(file, "utf8");
10389
10662
  } catch {
10390
10663
  return null;
10391
10664
  }
@@ -10464,7 +10737,7 @@ function buildResourceProvider() {
10464
10737
  const report = REPORT_URIS.get(uri);
10465
10738
  if (report) {
10466
10739
  const text2 = readFileIfPresent(
10467
- path12__namespace.resolve(workspace.root, workspace.config.outDir, "reports", report.file)
10740
+ path13__namespace.resolve(workspace.root, workspace.config.outDir, "reports", report.file)
10468
10741
  );
10469
10742
  if (text2 === null) return null;
10470
10743
  return { uri, mimeType: "text/markdown", text: capUtf8(text2, MAX_RESOURCE_BYTES).text };
@@ -10483,7 +10756,7 @@ function buildResourceProvider() {
10483
10756
  const part = read.manifest.parts.find((candidate) => candidate.index === index);
10484
10757
  if (!part) return null;
10485
10758
  const text2 = readFileIfPresent(
10486
- path12__namespace.resolve(workspace.root, workspace.config.outDir, "parts", part.filename)
10759
+ path13__namespace.resolve(workspace.root, workspace.config.outDir, "parts", part.filename)
10487
10760
  );
10488
10761
  if (text2 === null) return null;
10489
10762
  return { uri, mimeType: "text/markdown", text: capUtf8(text2, MAX_RESOURCE_BYTES).text };
@@ -10721,6 +10994,7 @@ var CLI_OPTIONS = {
10721
10994
  install: { type: "boolean" },
10722
10995
  "no-install": { type: "boolean" },
10723
10996
  target: { type: "string" },
10997
+ "no-update-check": { type: "boolean" },
10724
10998
  help: { type: "boolean", short: "h" },
10725
10999
  version: { type: "boolean", short: "v" }
10726
11000
  };
@@ -10795,6 +11069,8 @@ Options:
10795
11069
  --install Write the skill into the repository instead of printing
10796
11070
  --target <name> claude | cursor | all (default: all)
10797
11071
 
11072
+ --no-update-check Skip the daily check for a newer published version
11073
+
10798
11074
  -h, --help Display this help message
10799
11075
  -v, --version Display version
10800
11076
 
@@ -10871,10 +11147,10 @@ function parseCliArgs(argv) {
10871
11147
  }
10872
11148
  if (values.cwd !== void 0) {
10873
11149
  const target = String(values.cwd);
10874
- if (!fs11__namespace.existsSync(target)) {
11150
+ if (!fs12__namespace.existsSync(target)) {
10875
11151
  throw new UsageError(`--cwd directory does not exist: ${target}`);
10876
11152
  }
10877
- if (!fs11__namespace.statSync(target).isDirectory()) {
11153
+ if (!fs12__namespace.statSync(target).isDirectory()) {
10878
11154
  throw new UsageError(`--cwd is not a directory: ${target}`);
10879
11155
  }
10880
11156
  }
@@ -11020,7 +11296,7 @@ function parseCliArgs(argv) {
11020
11296
  install: values.install === true,
11021
11297
  noInstall: values["no-install"] === true,
11022
11298
  target: values.target === void 0 ? void 0 : String(values.target),
11023
- cwd: values.cwd === void 0 ? process.cwd() : path12__namespace.resolve(String(values.cwd)),
11299
+ cwd: values.cwd === void 0 ? process.cwd() : path13__namespace.resolve(String(values.cwd)),
11024
11300
  outDir: values["out-dir"] === void 0 ? void 0 : String(values["out-dir"]),
11025
11301
  includeMonolith: values["include-monolith"] === true || onlyNamesMonolith === true ? true : void 0,
11026
11302
  includeSensitiveFiles: values["include-sensitive-files"] === true ? true : void 0,
@@ -11077,24 +11353,24 @@ function splitList(value) {
11077
11353
  return value.split(",").map((entry) => entry.trim()).filter(Boolean);
11078
11354
  }
11079
11355
  function displayOutPath(cwd, outDir, ...segments) {
11080
- const absolute = path12__namespace.resolve(cwd, outDir, ...segments);
11081
- const relative11 = path12__namespace.relative(cwd, absolute);
11082
- if (relative11 && !relative11.startsWith("..") && !path12__namespace.isAbsolute(relative11)) return relative11;
11356
+ const absolute = path13__namespace.resolve(cwd, outDir, ...segments);
11357
+ const relative11 = path13__namespace.relative(cwd, absolute);
11358
+ if (relative11 && !relative11.startsWith("..") && !path13__namespace.isAbsolute(relative11)) return relative11;
11083
11359
  return absolute;
11084
11360
  }
11085
11361
  function nextStepHint(cwd, scriptsAddedNow) {
11086
11362
  let hasScript = scriptsAddedNow;
11087
11363
  if (!hasScript) {
11088
11364
  try {
11089
- const parsed = JSON.parse(fs11__namespace.readFileSync(path12__namespace.join(cwd, "package.json"), "utf8"));
11365
+ const parsed = JSON.parse(fs12__namespace.readFileSync(path13__namespace.join(cwd, "package.json"), "utf8"));
11090
11366
  hasScript = typeof parsed.scripts?.snapshot === "string";
11091
11367
  } catch {
11092
11368
  hasScript = false;
11093
11369
  }
11094
11370
  }
11095
11371
  if (!hasScript) return `npx ${GENERATOR_NAME} generate`;
11096
- const bin = path12__namespace.join(cwd, "node_modules", ".bin", "codebase-snapshot");
11097
- const installed = fs11__namespace.existsSync(bin) || fs11__namespace.existsSync(`${bin}.cmd`);
11372
+ const bin = path13__namespace.join(cwd, "node_modules", ".bin", "codebase-snapshot");
11373
+ const installed = fs12__namespace.existsSync(bin) || fs12__namespace.existsSync(`${bin}.cmd`);
11098
11374
  return installed ? "npm run snapshot" : "npm install && npm run snapshot";
11099
11375
  }
11100
11376
  function presetSummary(init) {
@@ -11124,7 +11400,7 @@ async function runInitCommand(invocation) {
11124
11400
  info(result.configText);
11125
11401
  return 0;
11126
11402
  }
11127
- info(`\u2705 Created ${path12__namespace.basename(result.configPath)} (${presetSummary(result)})`);
11403
+ info(`\u2705 Created ${path13__namespace.basename(result.configPath)} (${presetSummary(result)})`);
11128
11404
  if (result.scripts.length > 0) info(` Added npm scripts: ${result.scripts.join(", ")}`);
11129
11405
  if (result.dependency.added && result.dependency.range !== null) {
11130
11406
  info(` Added devDependency: ${result.dependency.name} ${result.dependency.range}`);
@@ -11144,7 +11420,7 @@ async function runInitCommand(invocation) {
11144
11420
  }
11145
11421
  }
11146
11422
  function detectPackageManager(cwd) {
11147
- const has = (name) => fs11__namespace.existsSync(path12__namespace.join(cwd, name));
11423
+ const has = (name) => fs12__namespace.existsSync(path13__namespace.join(cwd, name));
11148
11424
  if (has("bun.lockb") || has("bun.lock")) return { name: "bun", command: "bun", args: ["install"] };
11149
11425
  if (has("pnpm-lock.yaml")) return { name: "pnpm", command: "pnpm", args: ["install"] };
11150
11426
  if (has("yarn.lock")) return { name: "yarn", command: "yarn", args: ["install"] };
@@ -11163,14 +11439,13 @@ function installDependencies(cwd) {
11163
11439
  const manager = detectPackageManager(cwd);
11164
11440
  const command = `${manager.command} ${manager.args.join(" ")}`;
11165
11441
  const started = performance.now();
11166
- const result = childProcess.spawnSync(manager.command, manager.args, {
11442
+ const spawnOptions = {
11167
11443
  cwd,
11168
11444
  encoding: "utf8",
11169
- // npm, pnpm and yarn ship as `.cmd` shims on Windows, which spawnSync cannot exec directly.
11170
- shell: process.platform === "win32",
11171
11445
  timeout: INSTALL_TIMEOUT_MS,
11172
11446
  env: cleanInstallEnv()
11173
- });
11447
+ };
11448
+ const result = process.platform === "win32" ? childProcess.spawnSync(command, { ...spawnOptions, shell: true }) : childProcess.spawnSync(manager.command, manager.args, spawnOptions);
11174
11449
  const seconds = `${((performance.now() - started) / 1e3).toFixed(1)}s`;
11175
11450
  if (result.error) {
11176
11451
  return { manager: manager.name, command, ok: false, detail: `${result.error.message} (${seconds})` };
@@ -11234,7 +11509,7 @@ async function runSetupCommand(invocation, options = {}) {
11234
11509
  }
11235
11510
  info("\n\u{1F9EA} Dry run \u2014 setup would:");
11236
11511
  info(
11237
- ` 1. ${init.reused ? `keep ${path12__namespace.basename(init.configPath)}` : `write ${path12__namespace.basename(init.configPath)} (preset: ${init.preset})`}`
11512
+ ` 1. ${init.reused ? `keep ${path13__namespace.basename(init.configPath)}` : `write ${path13__namespace.basename(init.configPath)} (preset: ${init.preset})`}`
11238
11513
  );
11239
11514
  info(" 2. add the npm scripts, the devDependency and the .gitignore entries");
11240
11515
  if (manager !== null) info(` 3. install with ${manager}`);
@@ -11246,9 +11521,9 @@ async function runSetupCommand(invocation, options = {}) {
11246
11521
  if (invocation.format !== "json") {
11247
11522
  if (!interactive) info(`\u{1F680} Setup for: ${invocation.cwd}`);
11248
11523
  if (init.reused) {
11249
- info(`\u267B Keeping ${path12__namespace.basename(init.configPath)} (${presetSummary(init)})`);
11524
+ info(`\u267B Keeping ${path13__namespace.basename(init.configPath)} (${presetSummary(init)})`);
11250
11525
  } else {
11251
- info(`\u2705 Created ${path12__namespace.basename(init.configPath)} (${presetSummary(init)})`);
11526
+ info(`\u2705 Created ${path13__namespace.basename(init.configPath)} (${presetSummary(init)})`);
11252
11527
  }
11253
11528
  if (init.scripts.length > 0) info(` Added npm scripts: ${init.scripts.join(", ")}`);
11254
11529
  if (init.dependency.added && init.dependency.range !== null) {
@@ -11356,7 +11631,7 @@ function runSkillCommand(invocation) {
11356
11631
  }
11357
11632
  info(`\u2705 Agent skill installed (${SKILL_NAME}):`);
11358
11633
  for (const item of result.written) {
11359
- const shown = path12__namespace.relative(invocation.cwd, item.path) || item.path;
11634
+ const shown = path13__namespace.relative(invocation.cwd, item.path) || item.path;
11360
11635
  info(` - ${item.action.padEnd(9)} ${shown}`);
11361
11636
  }
11362
11637
  if (result.gitignored.length > 0) {
@@ -11420,6 +11695,17 @@ function requestsJsonFormat(argv) {
11420
11695
  return format === "json";
11421
11696
  }
11422
11697
  async function main(argv = process.argv.slice(2)) {
11698
+ const pending = process.stdout.isTTY === true && shouldCheck(argv, process.env) ? checkForUpdate({ current: GENERATOR_VERSION, cacheFile: cacheFilePath() }) : null;
11699
+ const code = await runCommand(argv);
11700
+ if (pending) {
11701
+ const notice = await pending;
11702
+ if (notice) process.stderr.write(`
11703
+ ${formatUpdateNotice(notice)}
11704
+ `);
11705
+ }
11706
+ return code;
11707
+ }
11708
+ async function runCommand(argv) {
11423
11709
  let invocation;
11424
11710
  try {
11425
11711
  invocation = parseCliArgs(argv);
@@ -11452,7 +11738,7 @@ ${USAGE}
11452
11738
  return runSkillCommand(invocation);
11453
11739
  }
11454
11740
  if (invocation.command === "mcp") {
11455
- return await runStdioServer({ cwd: path12__namespace.resolve(invocation.cwd) });
11741
+ return await runStdioServer({ cwd: path13__namespace.resolve(invocation.cwd) });
11456
11742
  }
11457
11743
  if (invocation.command === "setup") {
11458
11744
  return runSetupCommand(invocation);
@@ -11469,7 +11755,7 @@ ${USAGE}
11469
11755
  warn("\u274C The config file could not be read. Fix it, or delete it to use the defaults.");
11470
11756
  return 1;
11471
11757
  }
11472
- if (loaded.file) info(`\u2699 Using config ${path12__namespace.relative(process.cwd(), loaded.file) || loaded.file}`);
11758
+ if (loaded.file) info(`\u2699 Using config ${path13__namespace.relative(process.cwd(), loaded.file) || loaded.file}`);
11473
11759
  const resolved = resolveConfig(
11474
11760
  loaded.config,
11475
11761
  {
@@ -11491,10 +11777,10 @@ ${USAGE}
11491
11777
  if (invocation.command === "validate") {
11492
11778
  const result = validateSnapshot(resolved);
11493
11779
  if (result.valid) {
11494
- const manifestPath = path12__namespace.resolve(resolved.cwd, resolved.outDir, "manifest.json");
11780
+ const manifestPath = path13__namespace.resolve(resolved.cwd, resolved.outDir, "manifest.json");
11495
11781
  let manifest;
11496
11782
  try {
11497
- manifest = JSON.parse(fs11__namespace.readFileSync(manifestPath, "utf8"));
11783
+ manifest = JSON.parse(fs12__namespace.readFileSync(manifestPath, "utf8"));
11498
11784
  } catch {
11499
11785
  manifest = void 0;
11500
11786
  }
@@ -11507,13 +11793,13 @@ ${USAGE}
11507
11793
  return result.valid ? 0 : 1;
11508
11794
  }
11509
11795
  if (invocation.command === "report") {
11510
- const manifestPath = path12__namespace.resolve(resolved.cwd, resolved.outDir, "manifest.json");
11511
- if (!fs11__namespace.existsSync(manifestPath)) {
11796
+ const manifestPath = path13__namespace.resolve(resolved.cwd, resolved.outDir, "manifest.json");
11797
+ if (!fs12__namespace.existsSync(manifestPath)) {
11512
11798
  return fail(invocation.format, `Manifest not found at ${manifestPath}. Run generate first.`);
11513
11799
  }
11514
11800
  let manifest;
11515
11801
  try {
11516
- manifest = JSON.parse(fs11__namespace.readFileSync(manifestPath, "utf8"));
11802
+ manifest = JSON.parse(fs12__namespace.readFileSync(manifestPath, "utf8"));
11517
11803
  } catch (err) {
11518
11804
  return fail(invocation.format, `Could not read ${manifestPath}: ${err.message}`);
11519
11805
  }
@@ -11677,20 +11963,20 @@ function finishWatchRun(state, now) {
11677
11963
  };
11678
11964
  }
11679
11965
  function comparablePath(value) {
11680
- const absolute = path12__namespace.resolve(value);
11966
+ const absolute = path13__namespace.resolve(value);
11681
11967
  return process.platform === "win32" ? absolute.toLowerCase() : absolute;
11682
11968
  }
11683
11969
  function isSameOrInside(parent, candidate) {
11684
- const relative11 = path12__namespace.relative(parent, candidate);
11685
- return relative11 === "" || relative11 !== ".." && !relative11.startsWith(`..${path12__namespace.sep}`) && !path12__namespace.isAbsolute(relative11);
11970
+ const relative11 = path13__namespace.relative(parent, candidate);
11971
+ return relative11 === "" || relative11 !== ".." && !relative11.startsWith(`..${path13__namespace.sep}`) && !path13__namespace.isAbsolute(relative11);
11686
11972
  }
11687
11973
  function isGeneratedWatchPath(candidate, paths) {
11688
- const absolute = comparablePath(path12__namespace.resolve(paths.cwd, candidate));
11689
- const outDir = comparablePath(path12__namespace.resolve(paths.cwd, paths.outDir));
11690
- const tmpDir = comparablePath(path12__namespace.resolve(paths.cwd, paths.tmpDir));
11974
+ const absolute = comparablePath(path13__namespace.resolve(paths.cwd, candidate));
11975
+ const outDir = comparablePath(path13__namespace.resolve(paths.cwd, paths.outDir));
11976
+ const tmpDir = comparablePath(path13__namespace.resolve(paths.cwd, paths.tmpDir));
11691
11977
  if (isSameOrInside(outDir, absolute) || isSameOrInside(tmpDir, absolute)) return true;
11692
- const parent = path12__namespace.dirname(absolute);
11693
- if (parent === path12__namespace.dirname(outDir) && path12__namespace.basename(absolute).startsWith(`${path12__namespace.basename(outDir)}.backup-`)) {
11978
+ const parent = path13__namespace.dirname(absolute);
11979
+ if (parent === path13__namespace.dirname(outDir) && path13__namespace.basename(absolute).startsWith(`${path13__namespace.basename(outDir)}.backup-`)) {
11694
11980
  return true;
11695
11981
  }
11696
11982
  return absolute.split(/[\\/]+/).some((segment) => VCS_SEGMENTS.has(segment));
@@ -11707,8 +11993,8 @@ function decideWatchEvent(state, event, paths) {
11707
11993
  return { state, action: "schedule" };
11708
11994
  }
11709
11995
  async function runWatchLoop(invocation, resolved) {
11710
- const outDir = path12__namespace.resolve(resolved.cwd, resolved.outDir);
11711
- const tmpDir = path12__namespace.resolve(resolved.cwd, resolved.tmpDir);
11996
+ const outDir = path13__namespace.resolve(resolved.cwd, resolved.outDir);
11997
+ const tmpDir = path13__namespace.resolve(resolved.cwd, resolved.tmpDir);
11712
11998
  const paths = { cwd: resolved.cwd, outDir, tmpDir };
11713
11999
  let state = initialWatchState();
11714
12000
  let timer = null;
@@ -11773,11 +12059,11 @@ async function runWatchLoop(invocation, resolved) {
11773
12059
  };
11774
12060
  info("\u{1F440} Watching for changes. Press Ctrl+C to stop.");
11775
12061
  void regenerate();
11776
- const watcher = fs11__namespace.watch(resolved.cwd, { recursive: true }, (_event, filename) => {
12062
+ const watcher = fs12__namespace.watch(resolved.cwd, { recursive: true }, (_event, filename) => {
11777
12063
  const decision = decideWatchEvent(
11778
12064
  state,
11779
12065
  {
11780
- path: filename ? path12__namespace.resolve(resolved.cwd, filename.toString()) : null,
12066
+ path: filename ? path13__namespace.resolve(resolved.cwd, filename.toString()) : null,
11781
12067
  now: performance.now()
11782
12068
  },
11783
12069
  paths
@@ -11805,7 +12091,7 @@ async function runWatchLoop(invocation, resolved) {
11805
12091
  return 0;
11806
12092
  }
11807
12093
  var entryFile = process.argv[1] ?? "";
11808
- var entryName = path12__namespace.basename(entryFile).toLowerCase();
12094
+ var entryName = path13__namespace.basename(entryFile).toLowerCase();
11809
12095
  var invokedDirectly = entryName === "cli.js" || entryName === "cli.cjs";
11810
12096
  if (invokedDirectly) {
11811
12097
  void main().then(