codebase-snapshot 0.9.6 → 0.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -21,6 +21,40 @@ Two versions exist on the registry that are not releases, and both are deprecate
21
21
  Deleting them requires account-level rights that the release pipeline does not have, so they are
22
22
  deprecated with an explanatory message instead. `latest` has pointed at 0.9.0 since it existed.
23
23
 
24
+ ## 0.9.7
25
+
26
+ ### The setup menu stops eating its own screen
27
+
28
+ Reported with a screenshot from a terminal about 70 columns wide: every keypress on `snapshot`'s
29
+ first question added another `◆ How should I set this up?` line, until 28 of them were piled above
30
+ the live menu.
31
+
32
+ The wizard repaints a prompt in place by moving the cursor up by the height of the last frame it
33
+ drew — and it counted that height in *lines*, while a terminal lays out *rows*. The recommended
34
+ answer carries the hint `node-lib · config · npm scripts · install · generate`, which makes that
35
+ line 83 cells wide. In a narrow terminal the terminal wrapped it into two rows itself, so the frame
36
+ was one row taller than the erase believed, and moving up one row short left the top of the old
37
+ frame behind. Every keypress. Notice that the leftover was always exactly one line: the question.
38
+
39
+ Frames are now wrapped to the visible width before they are drawn, so the height that is counted is
40
+ the height that is shown. Continuation lines keep their indent, a token longer than the line breaks
41
+ rather than overflowing it, and the width is re-read on every draw so a window that changed size is
42
+ measured as it is now rather than as it was. Two cells of slack are left for `◆ ❯ ◻ ←`, which some
43
+ fonts draw double-width.
44
+
45
+ No existing test could have caught this: every one of them pinned `columns` to 120, where nothing
46
+ wraps and the two counts agree. `tests/wizard-frame.test.js` drives the real wizard at 70, 60 and 50
47
+ columns, replays the escape sequences through a small terminal simulator, and asserts that the
48
+ screen shows one question rather than one per keypress. Putting the old arithmetic back turns three
49
+ of its seven tests red.
50
+
51
+ ### Install pins in the docs are now maintained, not remembered
52
+
53
+ `docs/mcp.md` told clients to run `codebase-snapshot@0.9.6` in four places that have to change at
54
+ every release, and a comment marker cannot live inside a JSON fence. `sync-docs` now rewrites any
55
+ `codebase-snapshot@x.y.z` pin and the `Added devDependency:` examples by shape, so the next release
56
+ cannot leave a copy-pasteable snippet pointing at an old version. `@latest` is untouched.
57
+
24
58
  ## 0.9.6
25
59
 
26
60
  ### It tells you when it is out of date
package/README.md CHANGED
@@ -200,7 +200,7 @@ Everything an agent needs is available as data, and the tool can install its own
200
200
  ```bash
201
201
  npx codebase-snapshot describe --format json # contract: workflow, options, exit codes
202
202
  npx codebase-snapshot skill --install # into .claude/skills + .cursor/rules
203
- npx -y codebase-snapshot@0.9.6 mcp # or serve it over MCP
203
+ npx -y codebase-snapshot@0.9.7 mcp # or serve it over MCP
204
204
  ```
205
205
 
206
206
  An agent told only "use `npx codebase-snapshot`" can read the contract, follow its ordered
package/dist/bin.js CHANGED
@@ -4346,7 +4346,7 @@ function gitignorePath(cwd, filePath) {
4346
4346
 
4347
4347
  // src/version.ts
4348
4348
  var GENERATOR_NAME = "codebase-snapshot";
4349
- var GENERATOR_VERSION = "0.9.6";
4349
+ var GENERATOR_VERSION = "0.9.7";
4350
4350
  var LEGACY_GENERATOR_NAMES = ["@ankurhalder/codebase-snapshot"];
4351
4351
  function isOurGeneratorName(name) {
4352
4352
  if (typeof name !== "string") return false;
@@ -4509,6 +4509,57 @@ function toggleIndex(selected, index) {
4509
4509
  else next.add(index);
4510
4510
  return next;
4511
4511
  }
4512
+ function isWideCodePoint(code) {
4513
+ return code >= 4352 && code <= 4447 || // Hangul Jamo
4514
+ code >= 11904 && code <= 12350 || // CJK radicals, Kangxi, CJK symbols
4515
+ code >= 12353 && code <= 13311 || // kana through CJK compatibility
4516
+ code >= 13312 && code <= 19903 || // CJK extension A
4517
+ code >= 19968 && code <= 40959 || // CJK unified ideographs
4518
+ code >= 40960 && code <= 42191 || // Yi
4519
+ code >= 44032 && code <= 55203 || // Hangul syllables
4520
+ code >= 63744 && code <= 64255 || // CJK compatibility ideographs
4521
+ code >= 65072 && code <= 65135 || // CJK compatibility forms
4522
+ code >= 65280 && code <= 65376 || // fullwidth forms
4523
+ code >= 65504 && code <= 65510 || code >= 127744 && code <= 129535 || // emoji and pictographs
4524
+ code >= 131072 && code <= 262141;
4525
+ }
4526
+ var ANSI_PATTERN = /\u001b\[[0-9;?]*[A-Za-z]/g;
4527
+ function displayWidth(line) {
4528
+ let width = 0;
4529
+ for (const character of line.replace(ANSI_PATTERN, "")) {
4530
+ width += isWideCodePoint(character.codePointAt(0) ?? 0) ? 2 : 1;
4531
+ }
4532
+ return width;
4533
+ }
4534
+ function wrapOneLine(line, limit) {
4535
+ if (displayWidth(line) <= limit) return [line];
4536
+ const indent = /^[ \t]*/.exec(line)?.[0] ?? "";
4537
+ const continuation = `${indent} `;
4538
+ const rows = [];
4539
+ let prefix = indent;
4540
+ let rest = line.slice(indent.length).trimEnd();
4541
+ while (rest.length > 0) {
4542
+ const room = limit - displayWidth(prefix);
4543
+ if (room <= 0 || displayWidth(rest) <= room) {
4544
+ rows.push(prefix + rest);
4545
+ break;
4546
+ }
4547
+ let cut = room;
4548
+ const space = rest.slice(0, room).lastIndexOf(" ");
4549
+ if (space > 0) cut = space;
4550
+ const taken = rest.slice(0, cut).trimEnd();
4551
+ rows.push(`${prefix}${taken.length > 0 ? taken : rest.slice(0, cut)}`);
4552
+ rest = rest.slice(cut).trimStart();
4553
+ prefix = continuation;
4554
+ }
4555
+ return rows;
4556
+ }
4557
+ function wrapLines(text2, limit) {
4558
+ const width = Math.max(8, Math.floor(limit));
4559
+ const rows = [];
4560
+ for (const line of text2.split("\n")) rows.push(...wrapOneLine(line, width));
4561
+ return rows;
4562
+ }
4512
4563
  function marker(active) {
4513
4564
  return active ? "\u276F" : " ";
4514
4565
  }
@@ -4586,14 +4637,27 @@ var Frame = class {
4586
4637
  drawn = 0;
4587
4638
  draw(text2) {
4588
4639
  this.erase();
4589
- this.output.write(`${text2}
4640
+ const rows = wrapLines(text2, this.width());
4641
+ this.output.write(`${rows.join("\n")}
4590
4642
  `);
4591
- this.drawn = text2.split("\n").length;
4643
+ this.drawn = rows.length;
4592
4644
  }
4593
4645
  erase() {
4594
4646
  if (this.drawn > 0) this.output.write(`\x1B[${this.drawn}A\x1B[0J`);
4595
4647
  this.drawn = 0;
4596
4648
  }
4649
+ /**
4650
+ * The usable width, in cells.
4651
+ *
4652
+ * Two cells of slack: an ambiguous-width glyph (`◆`, `❯`, `←`) renders two cells in some fonts
4653
+ * and one in others, and a row that lands exactly on the last column is the one case a terminal
4654
+ * may or may not wrap. Below that, a line cannot reach the edge to begin with.
4655
+ */
4656
+ width() {
4657
+ const columns = this.output.columns;
4658
+ if (typeof columns !== "number" || !Number.isFinite(columns) || columns <= 0) return 80;
4659
+ return Math.max(8, Math.floor(columns) - 2);
4660
+ }
4597
4661
  };
4598
4662
  function isCancel(key) {
4599
4663
  return key.ctrl === true && key.name === "c" || key.ctrl === true && key.name === "d";
@@ -1,4 +1,4 @@
1
- import { GENERATOR_VERSION, MIN_MAX_PART_BYTES, SCHEMA_VERSION, GENERATOR_NAME, ARTIFACT_NAMES, PRESETS, generateSnapshot, validateSnapshot, explainPath, renderExplainText, describeManifestShapeProblem, loadConfigFileDetailed, parseByteSize, resolveConfig } from './chunk-3KUL3QRH.js';
1
+ import { GENERATOR_VERSION, MIN_MAX_PART_BYTES, SCHEMA_VERSION, GENERATOR_NAME, ARTIFACT_NAMES, PRESETS, generateSnapshot, validateSnapshot, explainPath, renderExplainText, describeManifestShapeProblem, loadConfigFileDetailed, parseByteSize, resolveConfig } from './chunk-QABL7NRC.js';
2
2
  import * as fs from 'fs';
3
3
  import * as path2 from 'path';
4
4
 
@@ -2599,5 +2599,5 @@ async function runStdioServer(options) {
2599
2599
  }
2600
2600
 
2601
2601
  export { COMMAND_OPTION_SCOPE, ERROR_CODES, LEGACY_PROTOCOL_VERSIONS, MAX_LINE_BYTES, METHOD, MODERN_PROTOCOL_VERSIONS, SERVER_INSTRUCTIONS, SKILL_NAME, SUPPORTED_PROTOCOL_VERSIONS, buildAgentContract, buildPrompts, buildResourceProvider, buildTools, classifyRequest, coerceNumericStrings, commandsForOption, createLineReader, createMcpServer, createServer, createSession, createWriter, inspectModernMeta, negotiateLegacyVersion, renderContractText, renderSkill, runStdioServer, validateArguments };
2602
- //# sourceMappingURL=chunk-ZKZOGGM3.js.map
2603
- //# sourceMappingURL=chunk-ZKZOGGM3.js.map
2602
+ //# sourceMappingURL=chunk-DPK6ZTOG.js.map
2603
+ //# sourceMappingURL=chunk-DPK6ZTOG.js.map
@@ -5474,7 +5474,7 @@ function validateSnapshot(configInput) {
5474
5474
 
5475
5475
  // src/version.ts
5476
5476
  var GENERATOR_NAME = "codebase-snapshot";
5477
- var GENERATOR_VERSION = "0.9.6";
5477
+ var GENERATOR_VERSION = "0.9.7";
5478
5478
  var LEGACY_GENERATOR_NAMES = ["@ankurhalder/codebase-snapshot"];
5479
5479
  function isOurGeneratorName(name) {
5480
5480
  if (typeof name !== "string") return false;
@@ -6228,6 +6228,57 @@ function toggleIndex(selected, index) {
6228
6228
  else next.add(index);
6229
6229
  return next;
6230
6230
  }
6231
+ function isWideCodePoint(code) {
6232
+ return code >= 4352 && code <= 4447 || // Hangul Jamo
6233
+ code >= 11904 && code <= 12350 || // CJK radicals, Kangxi, CJK symbols
6234
+ code >= 12353 && code <= 13311 || // kana through CJK compatibility
6235
+ code >= 13312 && code <= 19903 || // CJK extension A
6236
+ code >= 19968 && code <= 40959 || // CJK unified ideographs
6237
+ code >= 40960 && code <= 42191 || // Yi
6238
+ code >= 44032 && code <= 55203 || // Hangul syllables
6239
+ code >= 63744 && code <= 64255 || // CJK compatibility ideographs
6240
+ code >= 65072 && code <= 65135 || // CJK compatibility forms
6241
+ code >= 65280 && code <= 65376 || // fullwidth forms
6242
+ code >= 65504 && code <= 65510 || code >= 127744 && code <= 129535 || // emoji and pictographs
6243
+ code >= 131072 && code <= 262141;
6244
+ }
6245
+ var ANSI_PATTERN = /\u001b\[[0-9;?]*[A-Za-z]/g;
6246
+ function displayWidth(line) {
6247
+ let width = 0;
6248
+ for (const character of line.replace(ANSI_PATTERN, "")) {
6249
+ width += isWideCodePoint(character.codePointAt(0) ?? 0) ? 2 : 1;
6250
+ }
6251
+ return width;
6252
+ }
6253
+ function wrapOneLine(line, limit) {
6254
+ if (displayWidth(line) <= limit) return [line];
6255
+ const indent = /^[ \t]*/.exec(line)?.[0] ?? "";
6256
+ const continuation = `${indent} `;
6257
+ const rows = [];
6258
+ let prefix = indent;
6259
+ let rest = line.slice(indent.length).trimEnd();
6260
+ while (rest.length > 0) {
6261
+ const room = limit - displayWidth(prefix);
6262
+ if (room <= 0 || displayWidth(rest) <= room) {
6263
+ rows.push(prefix + rest);
6264
+ break;
6265
+ }
6266
+ let cut = room;
6267
+ const space = rest.slice(0, room).lastIndexOf(" ");
6268
+ if (space > 0) cut = space;
6269
+ const taken = rest.slice(0, cut).trimEnd();
6270
+ rows.push(`${prefix}${taken.length > 0 ? taken : rest.slice(0, cut)}`);
6271
+ rest = rest.slice(cut).trimStart();
6272
+ prefix = continuation;
6273
+ }
6274
+ return rows;
6275
+ }
6276
+ function wrapLines(text2, limit) {
6277
+ const width = Math.max(8, Math.floor(limit));
6278
+ const rows = [];
6279
+ for (const line of text2.split("\n")) rows.push(...wrapOneLine(line, width));
6280
+ return rows;
6281
+ }
6231
6282
  function marker(active) {
6232
6283
  return active ? "\u276F" : " ";
6233
6284
  }
@@ -6305,14 +6356,27 @@ var Frame = class {
6305
6356
  drawn = 0;
6306
6357
  draw(text2) {
6307
6358
  this.erase();
6308
- this.output.write(`${text2}
6359
+ const rows = wrapLines(text2, this.width());
6360
+ this.output.write(`${rows.join("\n")}
6309
6361
  `);
6310
- this.drawn = text2.split("\n").length;
6362
+ this.drawn = rows.length;
6311
6363
  }
6312
6364
  erase() {
6313
6365
  if (this.drawn > 0) this.output.write(`\x1B[${this.drawn}A\x1B[0J`);
6314
6366
  this.drawn = 0;
6315
6367
  }
6368
+ /**
6369
+ * The usable width, in cells.
6370
+ *
6371
+ * Two cells of slack: an ambiguous-width glyph (`◆`, `❯`, `←`) renders two cells in some fonts
6372
+ * and one in others, and a row that lands exactly on the last column is the one case a terminal
6373
+ * may or may not wrap. Below that, a line cannot reach the edge to begin with.
6374
+ */
6375
+ width() {
6376
+ const columns = this.output.columns;
6377
+ if (typeof columns !== "number" || !Number.isFinite(columns) || columns <= 0) return 80;
6378
+ return Math.max(8, Math.floor(columns) - 2);
6379
+ }
6316
6380
  };
6317
6381
  function isCancel(key) {
6318
6382
  return key.ctrl === true && key.name === "c" || key.ctrl === true && key.name === "d";
@@ -8257,6 +8321,6 @@ async function generateSnapshotAsync(configInput, options) {
8257
8321
  return generateSnapshot(configInput, options);
8258
8322
  }
8259
8323
 
8260
- export { ARTIFACT_NAMES, CHECK_INTERVAL_MS, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, FAILURE_INTERVAL_MS, GENERATOR_NAME, GENERATOR_VERSION, LANGUAGE_PROFILES, MIN_MAX_PART_BYTES, PACKAGE_LATEST_URL, PRESETS, PromptCancelled, REQUEST_TIMEOUT_MS, SCHEMA_VERSION, anchorForPath, appendGitignoreEntries, assertReplaceable, assertUsableConfigInput, cacheDirectory, cacheFilePath, checkForUpdate, collectFiles, compareManifests, countInvalidUtf8Bytes, countLines, decodeText, defaultIO, defineConfig, describeManifestShapeProblem, detectLanguage, detectPreset, escapeControls, explainPath, fenceForContent, fenceForText, fetchLatestVersion, findConfigFile, firstRunMessage, formatNumber, formatUpdateNotice, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, gitignorePath, globToRegExp, hasPriorSnapshot, isBinaryBuffer, isBinaryExtension, isBinaryFile, isDiscoveryMode, isEffectivelyEmpty, isInteractive, isNewer, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, planFirstRun, profileForPath, renderConfig, renderDiffText, renderExplainText, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, shouldCheck, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, unknownPresetMessage, validateSnapshot };
8261
- //# sourceMappingURL=chunk-3KUL3QRH.js.map
8262
- //# sourceMappingURL=chunk-3KUL3QRH.js.map
8324
+ export { ARTIFACT_NAMES, CHECK_INTERVAL_MS, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, FAILURE_INTERVAL_MS, GENERATOR_NAME, GENERATOR_VERSION, LANGUAGE_PROFILES, MIN_MAX_PART_BYTES, PACKAGE_LATEST_URL, PRESETS, PromptBack, PromptCancelled, REQUEST_TIMEOUT_MS, SCHEMA_VERSION, anchorForPath, appendGitignoreEntries, assertReplaceable, assertUsableConfigInput, cacheDirectory, cacheFilePath, checkForUpdate, collectFiles, compareManifests, countInvalidUtf8Bytes, countLines, decodeText, defaultIO, defineConfig, describeManifestShapeProblem, detectLanguage, detectPreset, displayWidth, escapeControls, explainPath, fenceForContent, fenceForText, fetchLatestVersion, findConfigFile, firstRunMessage, formatNumber, formatUpdateNotice, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, gitignorePath, globToRegExp, hasPriorSnapshot, isBinaryBuffer, isBinaryExtension, isBinaryFile, isDiscoveryMode, isEffectivelyEmpty, isInteractive, isNewer, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, planFirstRun, profileForPath, renderConfig, renderDiffText, renderExplainText, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, shouldCheck, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, unknownPresetMessage, validateSnapshot, wrapLines };
8325
+ //# sourceMappingURL=chunk-QABL7NRC.js.map
8326
+ //# sourceMappingURL=chunk-QABL7NRC.js.map
package/dist/cli.cjs CHANGED
@@ -4340,7 +4340,7 @@ function gitignorePath(cwd, filePath) {
4340
4340
 
4341
4341
  // src/version.ts
4342
4342
  var GENERATOR_NAME = "codebase-snapshot";
4343
- var GENERATOR_VERSION = "0.9.6";
4343
+ var GENERATOR_VERSION = "0.9.7";
4344
4344
  var LEGACY_GENERATOR_NAMES = ["@ankurhalder/codebase-snapshot"];
4345
4345
  function isOurGeneratorName(name) {
4346
4346
  if (typeof name !== "string") return false;
@@ -4496,6 +4496,57 @@ function toggleIndex(selected, index) {
4496
4496
  else next.add(index);
4497
4497
  return next;
4498
4498
  }
4499
+ function isWideCodePoint(code) {
4500
+ return code >= 4352 && code <= 4447 || // Hangul Jamo
4501
+ code >= 11904 && code <= 12350 || // CJK radicals, Kangxi, CJK symbols
4502
+ code >= 12353 && code <= 13311 || // kana through CJK compatibility
4503
+ code >= 13312 && code <= 19903 || // CJK extension A
4504
+ code >= 19968 && code <= 40959 || // CJK unified ideographs
4505
+ code >= 40960 && code <= 42191 || // Yi
4506
+ code >= 44032 && code <= 55203 || // Hangul syllables
4507
+ code >= 63744 && code <= 64255 || // CJK compatibility ideographs
4508
+ code >= 65072 && code <= 65135 || // CJK compatibility forms
4509
+ code >= 65280 && code <= 65376 || // fullwidth forms
4510
+ code >= 65504 && code <= 65510 || code >= 127744 && code <= 129535 || // emoji and pictographs
4511
+ code >= 131072 && code <= 262141;
4512
+ }
4513
+ var ANSI_PATTERN = /\u001b\[[0-9;?]*[A-Za-z]/g;
4514
+ function displayWidth(line) {
4515
+ let width = 0;
4516
+ for (const character of line.replace(ANSI_PATTERN, "")) {
4517
+ width += isWideCodePoint(character.codePointAt(0) ?? 0) ? 2 : 1;
4518
+ }
4519
+ return width;
4520
+ }
4521
+ function wrapOneLine(line, limit) {
4522
+ if (displayWidth(line) <= limit) return [line];
4523
+ const indent = /^[ \t]*/.exec(line)?.[0] ?? "";
4524
+ const continuation = `${indent} `;
4525
+ const rows = [];
4526
+ let prefix = indent;
4527
+ let rest = line.slice(indent.length).trimEnd();
4528
+ while (rest.length > 0) {
4529
+ const room = limit - displayWidth(prefix);
4530
+ if (room <= 0 || displayWidth(rest) <= room) {
4531
+ rows.push(prefix + rest);
4532
+ break;
4533
+ }
4534
+ let cut = room;
4535
+ const space = rest.slice(0, room).lastIndexOf(" ");
4536
+ if (space > 0) cut = space;
4537
+ const taken = rest.slice(0, cut).trimEnd();
4538
+ rows.push(`${prefix}${taken.length > 0 ? taken : rest.slice(0, cut)}`);
4539
+ rest = rest.slice(cut).trimStart();
4540
+ prefix = continuation;
4541
+ }
4542
+ return rows;
4543
+ }
4544
+ function wrapLines(text2, limit) {
4545
+ const width = Math.max(8, Math.floor(limit));
4546
+ const rows = [];
4547
+ for (const line of text2.split("\n")) rows.push(...wrapOneLine(line, width));
4548
+ return rows;
4549
+ }
4499
4550
  function marker(active) {
4500
4551
  return active ? "\u276F" : " ";
4501
4552
  }
@@ -4573,14 +4624,27 @@ var Frame = class {
4573
4624
  drawn = 0;
4574
4625
  draw(text2) {
4575
4626
  this.erase();
4576
- this.output.write(`${text2}
4627
+ const rows = wrapLines(text2, this.width());
4628
+ this.output.write(`${rows.join("\n")}
4577
4629
  `);
4578
- this.drawn = text2.split("\n").length;
4630
+ this.drawn = rows.length;
4579
4631
  }
4580
4632
  erase() {
4581
4633
  if (this.drawn > 0) this.output.write(`\x1B[${this.drawn}A\x1B[0J`);
4582
4634
  this.drawn = 0;
4583
4635
  }
4636
+ /**
4637
+ * The usable width, in cells.
4638
+ *
4639
+ * Two cells of slack: an ambiguous-width glyph (`◆`, `❯`, `←`) renders two cells in some fonts
4640
+ * and one in others, and a row that lands exactly on the last column is the one case a terminal
4641
+ * may or may not wrap. Below that, a line cannot reach the edge to begin with.
4642
+ */
4643
+ width() {
4644
+ const columns = this.output.columns;
4645
+ if (typeof columns !== "number" || !Number.isFinite(columns) || columns <= 0) return 80;
4646
+ return Math.max(8, Math.floor(columns) - 2);
4647
+ }
4584
4648
  };
4585
4649
  function isCancel(key) {
4586
4650
  return key.ctrl === true && key.name === "c" || key.ctrl === true && key.name === "d";
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
- import { buildAgentContract, runStdioServer, COMMAND_OPTION_SCOPE, commandsForOption, SKILL_NAME, renderSkill, renderContractText } from './chunk-ZKZOGGM3.js';
2
- import { shouldCheck, checkForUpdate, GENERATOR_VERSION, cacheFilePath, formatUpdateNotice, loadConfigFileDetailed, resolveConfig, validateSnapshot, describeManifestShapeProblem, explainPath, compareManifests, loadManifest, renderDiffText, generateSnapshot, formatNumber, isDiscoveryMode, ARTIFACT_NAMES, getPreset, unknownPresetMessage, GENERATOR_NAME, runInit, PromptCancelled, planFirstRun, isEffectivelyEmpty, isInteractive, defaultIO, hasPriorSnapshot, DEFAULT_ANSWERS, findConfigFile, firstRunMessage, parseByteSize, gitignorePath, appendGitignoreEntries, escapeControls, MIN_MAX_PART_BYTES, renderExplainText } from './chunk-3KUL3QRH.js';
1
+ import { buildAgentContract, runStdioServer, COMMAND_OPTION_SCOPE, commandsForOption, SKILL_NAME, renderSkill, renderContractText } from './chunk-DPK6ZTOG.js';
2
+ import { shouldCheck, checkForUpdate, GENERATOR_VERSION, cacheFilePath, formatUpdateNotice, loadConfigFileDetailed, resolveConfig, validateSnapshot, describeManifestShapeProblem, explainPath, compareManifests, loadManifest, renderDiffText, generateSnapshot, formatNumber, isDiscoveryMode, ARTIFACT_NAMES, getPreset, unknownPresetMessage, GENERATOR_NAME, runInit, PromptCancelled, planFirstRun, isEffectivelyEmpty, isInteractive, defaultIO, hasPriorSnapshot, DEFAULT_ANSWERS, findConfigFile, firstRunMessage, parseByteSize, gitignorePath, appendGitignoreEntries, escapeControls, MIN_MAX_PART_BYTES, renderExplainText } from './chunk-QABL7NRC.js';
3
3
  import { spawnSync } from 'child_process';
4
4
  import * as fs from 'fs';
5
5
  import * as path2 from 'path';
package/dist/index.cjs CHANGED
@@ -5490,7 +5490,7 @@ function validateSnapshot(configInput) {
5490
5490
 
5491
5491
  // src/version.ts
5492
5492
  var GENERATOR_NAME = "codebase-snapshot";
5493
- var GENERATOR_VERSION = "0.9.6";
5493
+ var GENERATOR_VERSION = "0.9.7";
5494
5494
  var LEGACY_GENERATOR_NAMES = ["@ankurhalder/codebase-snapshot"];
5495
5495
  function isOurGeneratorName(name) {
5496
5496
  if (typeof name !== "string") return false;
@@ -6241,6 +6241,57 @@ function toggleIndex(selected, index) {
6241
6241
  else next.add(index);
6242
6242
  return next;
6243
6243
  }
6244
+ function isWideCodePoint(code) {
6245
+ return code >= 4352 && code <= 4447 || // Hangul Jamo
6246
+ code >= 11904 && code <= 12350 || // CJK radicals, Kangxi, CJK symbols
6247
+ code >= 12353 && code <= 13311 || // kana through CJK compatibility
6248
+ code >= 13312 && code <= 19903 || // CJK extension A
6249
+ code >= 19968 && code <= 40959 || // CJK unified ideographs
6250
+ code >= 40960 && code <= 42191 || // Yi
6251
+ code >= 44032 && code <= 55203 || // Hangul syllables
6252
+ code >= 63744 && code <= 64255 || // CJK compatibility ideographs
6253
+ code >= 65072 && code <= 65135 || // CJK compatibility forms
6254
+ code >= 65280 && code <= 65376 || // fullwidth forms
6255
+ code >= 65504 && code <= 65510 || code >= 127744 && code <= 129535 || // emoji and pictographs
6256
+ code >= 131072 && code <= 262141;
6257
+ }
6258
+ var ANSI_PATTERN = /\u001b\[[0-9;?]*[A-Za-z]/g;
6259
+ function displayWidth(line) {
6260
+ let width = 0;
6261
+ for (const character of line.replace(ANSI_PATTERN, "")) {
6262
+ width += isWideCodePoint(character.codePointAt(0) ?? 0) ? 2 : 1;
6263
+ }
6264
+ return width;
6265
+ }
6266
+ function wrapOneLine(line, limit) {
6267
+ if (displayWidth(line) <= limit) return [line];
6268
+ const indent = /^[ \t]*/.exec(line)?.[0] ?? "";
6269
+ const continuation = `${indent} `;
6270
+ const rows = [];
6271
+ let prefix = indent;
6272
+ let rest = line.slice(indent.length).trimEnd();
6273
+ while (rest.length > 0) {
6274
+ const room = limit - displayWidth(prefix);
6275
+ if (room <= 0 || displayWidth(rest) <= room) {
6276
+ rows.push(prefix + rest);
6277
+ break;
6278
+ }
6279
+ let cut = room;
6280
+ const space = rest.slice(0, room).lastIndexOf(" ");
6281
+ if (space > 0) cut = space;
6282
+ const taken = rest.slice(0, cut).trimEnd();
6283
+ rows.push(`${prefix}${taken.length > 0 ? taken : rest.slice(0, cut)}`);
6284
+ rest = rest.slice(cut).trimStart();
6285
+ prefix = continuation;
6286
+ }
6287
+ return rows;
6288
+ }
6289
+ function wrapLines(text2, limit) {
6290
+ const width = Math.max(8, Math.floor(limit));
6291
+ const rows = [];
6292
+ for (const line of text2.split("\n")) rows.push(...wrapOneLine(line, width));
6293
+ return rows;
6294
+ }
6244
6295
  function marker(active) {
6245
6296
  return active ? "\u276F" : " ";
6246
6297
  }
@@ -6318,14 +6369,27 @@ var Frame = class {
6318
6369
  drawn = 0;
6319
6370
  draw(text2) {
6320
6371
  this.erase();
6321
- this.output.write(`${text2}
6372
+ const rows = wrapLines(text2, this.width());
6373
+ this.output.write(`${rows.join("\n")}
6322
6374
  `);
6323
- this.drawn = text2.split("\n").length;
6375
+ this.drawn = rows.length;
6324
6376
  }
6325
6377
  erase() {
6326
6378
  if (this.drawn > 0) this.output.write(`\x1B[${this.drawn}A\x1B[0J`);
6327
6379
  this.drawn = 0;
6328
6380
  }
6381
+ /**
6382
+ * The usable width, in cells.
6383
+ *
6384
+ * Two cells of slack: an ambiguous-width glyph (`◆`, `❯`, `←`) renders two cells in some fonts
6385
+ * and one in others, and a row that lands exactly on the last column is the one case a terminal
6386
+ * may or may not wrap. Below that, a line cannot reach the edge to begin with.
6387
+ */
6388
+ width() {
6389
+ const columns = this.output.columns;
6390
+ if (typeof columns !== "number" || !Number.isFinite(columns) || columns <= 0) return 80;
6391
+ return Math.max(8, Math.floor(columns) - 2);
6392
+ }
6329
6393
  };
6330
6394
  function isCancel(key) {
6331
6395
  return key.ctrl === true && key.name === "c" || key.ctrl === true && key.name === "d";
@@ -8281,6 +8345,7 @@ exports.LANGUAGE_PROFILES = LANGUAGE_PROFILES;
8281
8345
  exports.MIN_MAX_PART_BYTES = MIN_MAX_PART_BYTES;
8282
8346
  exports.PACKAGE_LATEST_URL = PACKAGE_LATEST_URL;
8283
8347
  exports.PRESETS = PRESETS;
8348
+ exports.PromptBack = PromptBack;
8284
8349
  exports.PromptCancelled = PromptCancelled;
8285
8350
  exports.REQUEST_TIMEOUT_MS = REQUEST_TIMEOUT_MS;
8286
8351
  exports.SCHEMA_VERSION = SCHEMA_VERSION;
@@ -8298,6 +8363,7 @@ exports.decodeText = decodeText;
8298
8363
  exports.defineConfig = defineConfig;
8299
8364
  exports.detectLanguage = detectLanguage;
8300
8365
  exports.detectPreset = detectPreset;
8366
+ exports.displayWidth = displayWidth;
8301
8367
  exports.explainPath = explainPath;
8302
8368
  exports.fenceForContent = fenceForContent;
8303
8369
  exports.fenceForText = fenceForText;
@@ -8348,5 +8414,6 @@ exports.supportsTypeScriptImports = supportsTypeScriptImports;
8348
8414
  exports.truncatePreview = truncatePreview;
8349
8415
  exports.truncateToBytes = truncateToBytes;
8350
8416
  exports.validateSnapshot = validateSnapshot;
8417
+ exports.wrapLines = wrapLines;
8351
8418
  //# sourceMappingURL=index.cjs.map
8352
8419
  //# sourceMappingURL=index.cjs.map
package/dist/index.d.cts CHANGED
@@ -422,7 +422,7 @@ declare function validateSnapshot(configInput: ResolvedSnapshotConfig | Snapshot
422
422
  * `package.json` carries the same version; `npm run verify` compares the two.
423
423
  */
424
424
  declare const GENERATOR_NAME = "codebase-snapshot";
425
- declare const GENERATOR_VERSION = "0.9.6";
425
+ declare const GENERATOR_VERSION = "0.9.7";
426
426
 
427
427
  /** The one endpoint this package will ever request. */
428
428
  declare const PACKAGE_LATEST_URL = "https://registry.npmjs.org/codebase-snapshot/latest";
@@ -613,8 +613,22 @@ interface PromptIO {
613
613
  declare class PromptCancelled extends Error {
614
614
  constructor();
615
615
  }
616
+ /** Thrown when the developer asks to return to the previous question. */
617
+ declare class PromptBack extends Error {
618
+ constructor();
619
+ }
616
620
  /** Both ends must be a TTY before anything interactive is attempted. */
617
621
  declare function isInteractive(io: PromptIO): boolean;
622
+ /** Cells a line occupies on screen. Escape sequences occupy none. */
623
+ declare function displayWidth(line: string): number;
624
+ /**
625
+ * Breaks a block so that no row is wider than `limit` cells.
626
+ *
627
+ * A terminal wraps anything wider than itself without saying so, which is the whole reason this
628
+ * exists: a frame that wraps behind the renderer's back is one row taller than it claims to be.
629
+ * See {@link Frame}.
630
+ */
631
+ declare function wrapLines(text: string, limit: number): string[];
618
632
 
619
633
  interface InitOptions {
620
634
  cwd: string;
@@ -865,4 +879,4 @@ declare function generateSnapshot(configInput?: SnapshotConfig | ResolvedSnapsho
865
879
  /** Promise-returning wrapper for consumers that prefer an async call site. */
866
880
  declare function generateSnapshotAsync(configInput?: SnapshotConfig | ResolvedSnapshotConfig | null, options?: GenerateOptions): Promise<Manifest>;
867
881
 
868
- export { ARTIFACT_NAMES, ArtifactSelection, ByteSize, CHECK_INTERVAL_MS, CliOptions, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, DiscoveryMode, type ExplainResult, FAILURE_INTERVAL_MS, FileEntry, type FirstRunFacts, type FirstRunPlan, type FirstRunRefusal, GENERATOR_NAME, GENERATOR_VERSION, type GenerateOptions, type HeuristicResult, type InitDependency, type InitOptions, type InitResult, JsonSummary, KindRule, LANGUAGE_PROFILES, type LanguageProfile, LayerRule, MIN_MAX_PART_BYTES, Manifest, type ManifestDiff, MarkdownSummary, PACKAGE_LATEST_URL, PRESETS, PartMetadata, PromptCancelled, REQUEST_TIMEOUT_MS, ResolvedSnapshotConfig, SCHEMA_VERSION, SecretFinding, SecretRule, SkipRecord, SnapshotConfig, SourceSummary, TextEncoding, type UpdateCheckOptions, type UpdateNotice, ValidationResult, type WizardAnswers, anchorForPath, assertReplaceable, assertUsableConfigInput, cacheDirectory, cacheFilePath, checkForUpdate, collectFiles, compareManifests, countInvalidUtf8Bytes, countLines, decodeText, defineConfig, detectLanguage, detectPreset, explainPath, fenceForContent, fenceForText, fetchLatestVersion, firstRunMessage, formatUpdateNotice, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, hasPriorSnapshot, isBinaryBuffer, isBinaryExtension, isBinaryFile, isEffectivelyEmpty, isInteractive, isNewer, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, planFirstRun, profileForPath, renderConfig, renderDiffText, renderExplainText, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, shouldCheck, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, validateSnapshot };
882
+ export { ARTIFACT_NAMES, ArtifactSelection, ByteSize, CHECK_INTERVAL_MS, CliOptions, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, DiscoveryMode, type ExplainResult, FAILURE_INTERVAL_MS, FileEntry, type FirstRunFacts, type FirstRunPlan, type FirstRunRefusal, GENERATOR_NAME, GENERATOR_VERSION, type GenerateOptions, type HeuristicResult, type InitDependency, type InitOptions, type InitResult, JsonSummary, KindRule, LANGUAGE_PROFILES, type LanguageProfile, LayerRule, MIN_MAX_PART_BYTES, Manifest, type ManifestDiff, MarkdownSummary, PACKAGE_LATEST_URL, PRESETS, PartMetadata, PromptBack, PromptCancelled, REQUEST_TIMEOUT_MS, ResolvedSnapshotConfig, SCHEMA_VERSION, SecretFinding, SecretRule, SkipRecord, SnapshotConfig, SourceSummary, TextEncoding, type UpdateCheckOptions, type UpdateNotice, ValidationResult, type WizardAnswers, anchorForPath, assertReplaceable, assertUsableConfigInput, cacheDirectory, cacheFilePath, checkForUpdate, collectFiles, compareManifests, countInvalidUtf8Bytes, countLines, decodeText, defineConfig, detectLanguage, detectPreset, displayWidth, explainPath, fenceForContent, fenceForText, fetchLatestVersion, firstRunMessage, formatUpdateNotice, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, hasPriorSnapshot, isBinaryBuffer, isBinaryExtension, isBinaryFile, isEffectivelyEmpty, isInteractive, isNewer, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, planFirstRun, profileForPath, renderConfig, renderDiffText, renderExplainText, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, shouldCheck, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, validateSnapshot, wrapLines };
package/dist/index.d.ts CHANGED
@@ -422,7 +422,7 @@ declare function validateSnapshot(configInput: ResolvedSnapshotConfig | Snapshot
422
422
  * `package.json` carries the same version; `npm run verify` compares the two.
423
423
  */
424
424
  declare const GENERATOR_NAME = "codebase-snapshot";
425
- declare const GENERATOR_VERSION = "0.9.6";
425
+ declare const GENERATOR_VERSION = "0.9.7";
426
426
 
427
427
  /** The one endpoint this package will ever request. */
428
428
  declare const PACKAGE_LATEST_URL = "https://registry.npmjs.org/codebase-snapshot/latest";
@@ -613,8 +613,22 @@ interface PromptIO {
613
613
  declare class PromptCancelled extends Error {
614
614
  constructor();
615
615
  }
616
+ /** Thrown when the developer asks to return to the previous question. */
617
+ declare class PromptBack extends Error {
618
+ constructor();
619
+ }
616
620
  /** Both ends must be a TTY before anything interactive is attempted. */
617
621
  declare function isInteractive(io: PromptIO): boolean;
622
+ /** Cells a line occupies on screen. Escape sequences occupy none. */
623
+ declare function displayWidth(line: string): number;
624
+ /**
625
+ * Breaks a block so that no row is wider than `limit` cells.
626
+ *
627
+ * A terminal wraps anything wider than itself without saying so, which is the whole reason this
628
+ * exists: a frame that wraps behind the renderer's back is one row taller than it claims to be.
629
+ * See {@link Frame}.
630
+ */
631
+ declare function wrapLines(text: string, limit: number): string[];
618
632
 
619
633
  interface InitOptions {
620
634
  cwd: string;
@@ -865,4 +879,4 @@ declare function generateSnapshot(configInput?: SnapshotConfig | ResolvedSnapsho
865
879
  /** Promise-returning wrapper for consumers that prefer an async call site. */
866
880
  declare function generateSnapshotAsync(configInput?: SnapshotConfig | ResolvedSnapshotConfig | null, options?: GenerateOptions): Promise<Manifest>;
867
881
 
868
- export { ARTIFACT_NAMES, ArtifactSelection, ByteSize, CHECK_INTERVAL_MS, CliOptions, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, DiscoveryMode, type ExplainResult, FAILURE_INTERVAL_MS, FileEntry, type FirstRunFacts, type FirstRunPlan, type FirstRunRefusal, GENERATOR_NAME, GENERATOR_VERSION, type GenerateOptions, type HeuristicResult, type InitDependency, type InitOptions, type InitResult, JsonSummary, KindRule, LANGUAGE_PROFILES, type LanguageProfile, LayerRule, MIN_MAX_PART_BYTES, Manifest, type ManifestDiff, MarkdownSummary, PACKAGE_LATEST_URL, PRESETS, PartMetadata, PromptCancelled, REQUEST_TIMEOUT_MS, ResolvedSnapshotConfig, SCHEMA_VERSION, SecretFinding, SecretRule, SkipRecord, SnapshotConfig, SourceSummary, TextEncoding, type UpdateCheckOptions, type UpdateNotice, ValidationResult, type WizardAnswers, anchorForPath, assertReplaceable, assertUsableConfigInput, cacheDirectory, cacheFilePath, checkForUpdate, collectFiles, compareManifests, countInvalidUtf8Bytes, countLines, decodeText, defineConfig, detectLanguage, detectPreset, explainPath, fenceForContent, fenceForText, fetchLatestVersion, firstRunMessage, formatUpdateNotice, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, hasPriorSnapshot, isBinaryBuffer, isBinaryExtension, isBinaryFile, isEffectivelyEmpty, isInteractive, isNewer, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, planFirstRun, profileForPath, renderConfig, renderDiffText, renderExplainText, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, shouldCheck, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, validateSnapshot };
882
+ export { ARTIFACT_NAMES, ArtifactSelection, ByteSize, CHECK_INTERVAL_MS, CliOptions, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, DiscoveryMode, type ExplainResult, FAILURE_INTERVAL_MS, FileEntry, type FirstRunFacts, type FirstRunPlan, type FirstRunRefusal, GENERATOR_NAME, GENERATOR_VERSION, type GenerateOptions, type HeuristicResult, type InitDependency, type InitOptions, type InitResult, JsonSummary, KindRule, LANGUAGE_PROFILES, type LanguageProfile, LayerRule, MIN_MAX_PART_BYTES, Manifest, type ManifestDiff, MarkdownSummary, PACKAGE_LATEST_URL, PRESETS, PartMetadata, PromptBack, PromptCancelled, REQUEST_TIMEOUT_MS, ResolvedSnapshotConfig, SCHEMA_VERSION, SecretFinding, SecretRule, SkipRecord, SnapshotConfig, SourceSummary, TextEncoding, type UpdateCheckOptions, type UpdateNotice, ValidationResult, type WizardAnswers, anchorForPath, assertReplaceable, assertUsableConfigInput, cacheDirectory, cacheFilePath, checkForUpdate, collectFiles, compareManifests, countInvalidUtf8Bytes, countLines, decodeText, defineConfig, detectLanguage, detectPreset, displayWidth, explainPath, fenceForContent, fenceForText, fetchLatestVersion, firstRunMessage, formatUpdateNotice, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, hasPriorSnapshot, isBinaryBuffer, isBinaryExtension, isBinaryFile, isEffectivelyEmpty, isInteractive, isNewer, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, planFirstRun, profileForPath, renderConfig, renderDiffText, renderExplainText, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, shouldCheck, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, validateSnapshot, wrapLines };
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export { ARTIFACT_NAMES, CHECK_INTERVAL_MS, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, FAILURE_INTERVAL_MS, GENERATOR_NAME, GENERATOR_VERSION, LANGUAGE_PROFILES, MIN_MAX_PART_BYTES, PACKAGE_LATEST_URL, PRESETS, PromptCancelled, REQUEST_TIMEOUT_MS, SCHEMA_VERSION, anchorForPath, assertReplaceable, assertUsableConfigInput, cacheDirectory, cacheFilePath, checkForUpdate, collectFiles, compareManifests, countInvalidUtf8Bytes, countLines, decodeText, defineConfig, detectLanguage, detectPreset, explainPath, fenceForContent, fenceForText, fetchLatestVersion, firstRunMessage, formatUpdateNotice, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, hasPriorSnapshot, isBinaryBuffer, isBinaryExtension, isBinaryFile, isEffectivelyEmpty, isInteractive, isNewer, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, planFirstRun, profileForPath, renderConfig, renderDiffText, renderExplainText, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, shouldCheck, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, validateSnapshot } from './chunk-3KUL3QRH.js';
1
+ export { ARTIFACT_NAMES, CHECK_INTERVAL_MS, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, FAILURE_INTERVAL_MS, GENERATOR_NAME, GENERATOR_VERSION, LANGUAGE_PROFILES, MIN_MAX_PART_BYTES, PACKAGE_LATEST_URL, PRESETS, PromptBack, PromptCancelled, REQUEST_TIMEOUT_MS, SCHEMA_VERSION, anchorForPath, assertReplaceable, assertUsableConfigInput, cacheDirectory, cacheFilePath, checkForUpdate, collectFiles, compareManifests, countInvalidUtf8Bytes, countLines, decodeText, defineConfig, detectLanguage, detectPreset, displayWidth, explainPath, fenceForContent, fenceForText, fetchLatestVersion, firstRunMessage, formatUpdateNotice, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, hasPriorSnapshot, isBinaryBuffer, isBinaryExtension, isBinaryFile, isEffectivelyEmpty, isInteractive, isNewer, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, planFirstRun, profileForPath, renderConfig, renderDiffText, renderExplainText, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, shouldCheck, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, validateSnapshot, wrapLines } from './chunk-QABL7NRC.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
package/dist/mcp.cjs CHANGED
@@ -6128,7 +6128,7 @@ function validateSnapshot(configInput) {
6128
6128
 
6129
6129
  // src/version.ts
6130
6130
  var GENERATOR_NAME = "codebase-snapshot";
6131
- var GENERATOR_VERSION = "0.9.6";
6131
+ var GENERATOR_VERSION = "0.9.7";
6132
6132
  var LEGACY_GENERATOR_NAMES = ["@ankurhalder/codebase-snapshot"];
6133
6133
  function isOurGeneratorName(name) {
6134
6134
  if (typeof name !== "string") return false;
package/dist/mcp.js CHANGED
@@ -1,4 +1,4 @@
1
- export { ERROR_CODES, LEGACY_PROTOCOL_VERSIONS, MAX_LINE_BYTES, METHOD, MODERN_PROTOCOL_VERSIONS, SERVER_INSTRUCTIONS, SUPPORTED_PROTOCOL_VERSIONS, buildPrompts, buildResourceProvider, buildTools, classifyRequest, coerceNumericStrings, createLineReader, createMcpServer, createServer, createSession, createWriter, inspectModernMeta, negotiateLegacyVersion, runStdioServer, validateArguments } from './chunk-ZKZOGGM3.js';
2
- import './chunk-3KUL3QRH.js';
1
+ export { ERROR_CODES, LEGACY_PROTOCOL_VERSIONS, MAX_LINE_BYTES, METHOD, MODERN_PROTOCOL_VERSIONS, SERVER_INSTRUCTIONS, SUPPORTED_PROTOCOL_VERSIONS, buildPrompts, buildResourceProvider, buildTools, classifyRequest, coerceNumericStrings, createLineReader, createMcpServer, createServer, createSession, createWriter, inspectModernMeta, negotiateLegacyVersion, runStdioServer, validateArguments } from './chunk-DPK6ZTOG.js';
2
+ import './chunk-QABL7NRC.js';
3
3
  //# sourceMappingURL=mcp.js.map
4
4
  //# sourceMappingURL=mcp.js.map
package/docs/cli.md CHANGED
@@ -174,7 +174,7 @@ The whole first run in one command, with defaults and no prompts. This is the sa
174
174
  🚀 Setup for: /path/to/repo
175
175
  ✅ Created snapshot.config.ts (preset: nextjs)
176
176
  Added npm scripts: snapshot, snapshot:validate
177
- Added devDependency: codebase-snapshot ^0.9.6
177
+ Added devDependency: codebase-snapshot ^0.9.7
178
178
  Added to .gitignore: snapshot/, snapshot.tmp/
179
179
  ⏳ Installing dependencies…
180
180
  ✅ Installed dependencies (npm install, 2.1s)
@@ -211,7 +211,7 @@ It also has three side effects on files you own, and it says so when it does the
211
211
  ```
212
212
  ✅ Created snapshot.config.ts (preset: node-lib)
213
213
  Added npm scripts: snapshot, snapshot:validate
214
- Added devDependency: codebase-snapshot ^0.9.6
214
+ Added devDependency: codebase-snapshot ^0.9.7
215
215
  Added to .gitignore: snapshot/, snapshot.tmp/
216
216
  ```
217
217
 
package/docs/mcp.md CHANGED
@@ -10,7 +10,7 @@ walk — that the client sees.
10
10
  ## Start it
11
11
 
12
12
  ```bash
13
- npx -y codebase-snapshot@0.9.6 mcp
13
+ npx -y codebase-snapshot@0.9.7 mcp
14
14
  ```
15
15
 
16
16
  The server serves the directory it was started in. `--cwd <path>` points it elsewhere, and that
@@ -25,7 +25,7 @@ Claude Desktop and Cursor:
25
25
  "mcpServers": {
26
26
  "codebase-snapshot": {
27
27
  "command": "npx",
28
- "args": ["-y", "codebase-snapshot@0.9.6", "mcp", "--cwd", "/absolute/path/to/repo"]
28
+ "args": ["-y", "codebase-snapshot@0.9.7", "mcp", "--cwd", "/absolute/path/to/repo"]
29
29
  }
30
30
  }
31
31
  }
@@ -34,7 +34,7 @@ Claude Desktop and Cursor:
34
34
  Claude Code registers the same thing from a shell:
35
35
 
36
36
  ```bash
37
- claude mcp add codebase-snapshot -- npx -y codebase-snapshot@0.9.6 mcp --cwd /absolute/path/to/repo
37
+ claude mcp add codebase-snapshot -- npx -y codebase-snapshot@0.9.7 mcp --cwd /absolute/path/to/repo
38
38
  ```
39
39
 
40
40
  On Windows, wrap the command as `cmd /c npx` with the same arguments — `npx` is a `.cmd` shim
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codebase-snapshot",
3
- "version": "0.9.6",
3
+ "version": "0.9.7",
4
4
  "description": "Pack a codebase for an LLM into budgeted Markdown parts, with a manifest of every file and skip, and validate to prove the snapshot is current.",
5
5
  "keywords": [
6
6
  "codebase",