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/index.d.cts CHANGED
@@ -422,7 +422,58 @@ 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.4";
425
+ declare const GENERATOR_VERSION = "0.9.6";
426
+
427
+ /** The one endpoint this package will ever request. */
428
+ declare const PACKAGE_LATEST_URL = "https://registry.npmjs.org/codebase-snapshot/latest";
429
+ /** A result younger than this is trusted without asking again. */
430
+ declare const CHECK_INTERVAL_MS: number;
431
+ /**
432
+ * How long a *failed* check is remembered.
433
+ *
434
+ * Shorter than the success interval on purpose: one offline moment must not hide a release for a
435
+ * day, and one hostile network must not cause a retry on every single run.
436
+ */
437
+ declare const FAILURE_INTERVAL_MS: number;
438
+ /** Bounds the whole request. A slow registry is not the user's problem. */
439
+ declare const REQUEST_TIMEOUT_MS = 1200;
440
+ interface UpdateNotice {
441
+ current: string;
442
+ latest: string;
443
+ }
444
+ interface UpdateCheckOptions {
445
+ current: string;
446
+ /** Absolute path to the cache file. */
447
+ cacheFile: string;
448
+ /** Milliseconds since the epoch. Injectable so tests do not sleep. */
449
+ now?: () => number;
450
+ /** Returns the published version, or null when it could not be determined. */
451
+ fetchLatest?: (url: string, timeoutMs: number) => Promise<string | null>;
452
+ enabled?: boolean;
453
+ }
454
+ /** True when `candidate` is a strictly higher release than `current`. */
455
+ declare function isNewer(candidate: string, current: string): boolean;
456
+ /** The per-user cache directory, following each platform's convention. */
457
+ declare function cacheDirectory(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): string;
458
+ declare function cacheFilePath(env?: NodeJS.ProcessEnv): string;
459
+ /**
460
+ * Whether this invocation should ask at all.
461
+ *
462
+ * Conservative by design: anything it does not recognise as an interactive, human-facing run is
463
+ * skipped. Being wrong in that direction costs a feature nobody sees; being wrong the other way
464
+ * spends a CI job's network and pollutes a machine-readable stream.
465
+ */
466
+ declare function shouldCheck(argv: readonly string[], env: NodeJS.ProcessEnv): boolean;
467
+ /** One HTTPS GET with a hard timeout. Resolves null for every failure. */
468
+ declare function fetchLatestVersion(url?: string, timeoutMs?: number): Promise<string | null>;
469
+ /**
470
+ * Returns a notice when a newer version is published, or null.
471
+ *
472
+ * Never throws: the caller runs this alongside a real command and must not be affected by it.
473
+ */
474
+ declare function checkForUpdate(options: UpdateCheckOptions): Promise<UpdateNotice | null>;
475
+ /** The two lines a user sees, or an empty string when there is nothing to say. */
476
+ declare function formatUpdateNotice(notice: UpdateNotice): string;
426
477
 
427
478
  declare const DEFAULT_SECRET_PATTERNS: SecretRule[];
428
479
 
@@ -773,6 +824,7 @@ declare function profileForPath(path: string): LanguageProfile | null;
773
824
  declare function summarizeWithProfile(path: string, content: string): HeuristicResult | null;
774
825
 
775
826
  declare const SCHEMA_VERSION = "3.0.0";
827
+
776
828
  interface GenerateOptions {
777
829
  /** Compute the full manifest but write nothing to disk. */
778
830
  dryRun?: boolean;
@@ -813,4 +865,4 @@ declare function generateSnapshot(configInput?: SnapshotConfig | ResolvedSnapsho
813
865
  /** Promise-returning wrapper for consumers that prefer an async call site. */
814
866
  declare function generateSnapshotAsync(configInput?: SnapshotConfig | ResolvedSnapshotConfig | null, options?: GenerateOptions): Promise<Manifest>;
815
867
 
816
- export { ARTIFACT_NAMES, ArtifactSelection, ByteSize, CliOptions, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, DiscoveryMode, type ExplainResult, 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, PRESETS, PartMetadata, PromptCancelled, ResolvedSnapshotConfig, SCHEMA_VERSION, SecretFinding, SecretRule, SkipRecord, SnapshotConfig, SourceSummary, TextEncoding, ValidationResult, type WizardAnswers, anchorForPath, assertReplaceable, assertUsableConfigInput, collectFiles, compareManifests, countInvalidUtf8Bytes, countLines, decodeText, defineConfig, detectLanguage, detectPreset, explainPath, fenceForContent, fenceForText, firstRunMessage, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, hasPriorSnapshot, isBinaryBuffer, isBinaryExtension, isBinaryFile, isEffectivelyEmpty, isInteractive, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, planFirstRun, profileForPath, renderConfig, renderDiffText, renderExplainText, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, validateSnapshot };
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 };
package/dist/index.d.ts CHANGED
@@ -422,7 +422,58 @@ 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.4";
425
+ declare const GENERATOR_VERSION = "0.9.6";
426
+
427
+ /** The one endpoint this package will ever request. */
428
+ declare const PACKAGE_LATEST_URL = "https://registry.npmjs.org/codebase-snapshot/latest";
429
+ /** A result younger than this is trusted without asking again. */
430
+ declare const CHECK_INTERVAL_MS: number;
431
+ /**
432
+ * How long a *failed* check is remembered.
433
+ *
434
+ * Shorter than the success interval on purpose: one offline moment must not hide a release for a
435
+ * day, and one hostile network must not cause a retry on every single run.
436
+ */
437
+ declare const FAILURE_INTERVAL_MS: number;
438
+ /** Bounds the whole request. A slow registry is not the user's problem. */
439
+ declare const REQUEST_TIMEOUT_MS = 1200;
440
+ interface UpdateNotice {
441
+ current: string;
442
+ latest: string;
443
+ }
444
+ interface UpdateCheckOptions {
445
+ current: string;
446
+ /** Absolute path to the cache file. */
447
+ cacheFile: string;
448
+ /** Milliseconds since the epoch. Injectable so tests do not sleep. */
449
+ now?: () => number;
450
+ /** Returns the published version, or null when it could not be determined. */
451
+ fetchLatest?: (url: string, timeoutMs: number) => Promise<string | null>;
452
+ enabled?: boolean;
453
+ }
454
+ /** True when `candidate` is a strictly higher release than `current`. */
455
+ declare function isNewer(candidate: string, current: string): boolean;
456
+ /** The per-user cache directory, following each platform's convention. */
457
+ declare function cacheDirectory(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): string;
458
+ declare function cacheFilePath(env?: NodeJS.ProcessEnv): string;
459
+ /**
460
+ * Whether this invocation should ask at all.
461
+ *
462
+ * Conservative by design: anything it does not recognise as an interactive, human-facing run is
463
+ * skipped. Being wrong in that direction costs a feature nobody sees; being wrong the other way
464
+ * spends a CI job's network and pollutes a machine-readable stream.
465
+ */
466
+ declare function shouldCheck(argv: readonly string[], env: NodeJS.ProcessEnv): boolean;
467
+ /** One HTTPS GET with a hard timeout. Resolves null for every failure. */
468
+ declare function fetchLatestVersion(url?: string, timeoutMs?: number): Promise<string | null>;
469
+ /**
470
+ * Returns a notice when a newer version is published, or null.
471
+ *
472
+ * Never throws: the caller runs this alongside a real command and must not be affected by it.
473
+ */
474
+ declare function checkForUpdate(options: UpdateCheckOptions): Promise<UpdateNotice | null>;
475
+ /** The two lines a user sees, or an empty string when there is nothing to say. */
476
+ declare function formatUpdateNotice(notice: UpdateNotice): string;
426
477
 
427
478
  declare const DEFAULT_SECRET_PATTERNS: SecretRule[];
428
479
 
@@ -773,6 +824,7 @@ declare function profileForPath(path: string): LanguageProfile | null;
773
824
  declare function summarizeWithProfile(path: string, content: string): HeuristicResult | null;
774
825
 
775
826
  declare const SCHEMA_VERSION = "3.0.0";
827
+
776
828
  interface GenerateOptions {
777
829
  /** Compute the full manifest but write nothing to disk. */
778
830
  dryRun?: boolean;
@@ -813,4 +865,4 @@ declare function generateSnapshot(configInput?: SnapshotConfig | ResolvedSnapsho
813
865
  /** Promise-returning wrapper for consumers that prefer an async call site. */
814
866
  declare function generateSnapshotAsync(configInput?: SnapshotConfig | ResolvedSnapshotConfig | null, options?: GenerateOptions): Promise<Manifest>;
815
867
 
816
- export { ARTIFACT_NAMES, ArtifactSelection, ByteSize, CliOptions, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, DiscoveryMode, type ExplainResult, 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, PRESETS, PartMetadata, PromptCancelled, ResolvedSnapshotConfig, SCHEMA_VERSION, SecretFinding, SecretRule, SkipRecord, SnapshotConfig, SourceSummary, TextEncoding, ValidationResult, type WizardAnswers, anchorForPath, assertReplaceable, assertUsableConfigInput, collectFiles, compareManifests, countInvalidUtf8Bytes, countLines, decodeText, defineConfig, detectLanguage, detectPreset, explainPath, fenceForContent, fenceForText, firstRunMessage, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, hasPriorSnapshot, isBinaryBuffer, isBinaryExtension, isBinaryFile, isEffectivelyEmpty, isInteractive, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, planFirstRun, profileForPath, renderConfig, renderDiffText, renderExplainText, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, validateSnapshot };
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 };
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export { ARTIFACT_NAMES, DEFAULT_ANSWERS, DEFAULT_SECRET_PATTERNS, GENERATOR_NAME, GENERATOR_VERSION, LANGUAGE_PROFILES, MIN_MAX_PART_BYTES, PRESETS, PromptCancelled, SCHEMA_VERSION, anchorForPath, assertReplaceable, assertUsableConfigInput, collectFiles, compareManifests, countInvalidUtf8Bytes, countLines, decodeText, defineConfig, detectLanguage, detectPreset, explainPath, fenceForContent, fenceForText, firstRunMessage, generateProjectTree, generateSnapshot, generateSnapshotAsync, getPreset, globToRegExp, hasPriorSnapshot, isBinaryBuffer, isBinaryExtension, isBinaryFile, isEffectivelyEmpty, isInteractive, isResolvedConfig, isSensitivePath, listPresetNames, loadConfigFile, loadConfigFileDetailed, loadManifest, markResolvedConfig, matchRule, matchesExclude, normalizeResolvedConfig, parseByteSize, partitionFiles, planFirstRun, profileForPath, renderConfig, renderDiffText, renderExplainText, renumberParts, resolveConfig, resolveSafeOutputDirs, runInit, scanAndRedactSecrets, stripJsonComments, summarizeJson, summarizeMarkdown, summarizeTypeScriptSource, summarizeWithProfile, supportsTypeScriptImports, truncatePreview, truncateToBytes, validateSnapshot } from './chunk-FCWD4LY7.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, 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';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
package/dist/mcp.cjs CHANGED
@@ -273,6 +273,18 @@ function applyDefaults(schema, value) {
273
273
  }
274
274
  return out;
275
275
  }
276
+ function coerceNumericStrings(schema, value) {
277
+ const out = { ...value };
278
+ for (const [key, propertySchema] of Object.entries(schema.properties)) {
279
+ const raw = out[key];
280
+ if (typeof raw !== "string") continue;
281
+ if (propertySchema.type !== "number" && propertySchema.type !== "integer") continue;
282
+ if (raw.trim().length === 0) continue;
283
+ const parsed = Number(raw);
284
+ if (Number.isFinite(parsed)) out[key] = parsed;
285
+ }
286
+ return out;
287
+ }
276
288
 
277
289
  // src/mcp/server.ts
278
290
  function capabilities() {
@@ -361,7 +373,8 @@ function createMcpServer(options) {
361
373
  if (!isJsonObject(rawArguments)) {
362
374
  return errorResponse(id, ERROR_CODES.invalidParams, '"arguments" must be a JSON object.');
363
375
  }
364
- const problems = validateArguments(tool.inputSchema, rawArguments);
376
+ const supplied = coerceNumericStrings(tool.inputSchema, rawArguments);
377
+ const problems = validateArguments(tool.inputSchema, supplied);
365
378
  if (problems.length > 0) {
366
379
  return ok(
367
380
  id,
@@ -373,7 +386,7 @@ function createMcpServer(options) {
373
386
  modern
374
387
  );
375
388
  }
376
- const args = applyDefaults(tool.inputSchema, rawArguments);
389
+ const args = applyDefaults(tool.inputSchema, supplied);
377
390
  let outcome;
378
391
  try {
379
392
  outcome = await tool.handler(args, options.context);
@@ -6115,7 +6128,7 @@ function validateSnapshot(configInput) {
6115
6128
 
6116
6129
  // src/version.ts
6117
6130
  var GENERATOR_NAME = "codebase-snapshot";
6118
- var GENERATOR_VERSION = "0.9.4";
6131
+ var GENERATOR_VERSION = "0.9.6";
6119
6132
  var LEGACY_GENERATOR_NAMES = ["@ankurhalder/codebase-snapshot"];
6120
6133
  function isOurGeneratorName(name) {
6121
6134
  if (typeof name !== "string") return false;
@@ -8316,6 +8329,7 @@ var VALIDATE_OPTIONS = [
8316
8329
  "no-config",
8317
8330
  "discovery",
8318
8331
  "format",
8332
+ "no-update-check",
8319
8333
  "mode",
8320
8334
  "help",
8321
8335
  "version"
@@ -8339,6 +8353,7 @@ var COMMAND_OPTION_SCOPE = {
8339
8353
  "watch",
8340
8354
  "autopilot",
8341
8355
  "no-install",
8356
+ "no-update-check",
8342
8357
  "help",
8343
8358
  "version"
8344
8359
  ],
@@ -8354,6 +8369,7 @@ var COMMAND_OPTION_SCOPE = {
8354
8369
  "skip-artifacts",
8355
8370
  "only-artifacts",
8356
8371
  "no-config",
8372
+ "no-update-check",
8357
8373
  "format",
8358
8374
  "mode",
8359
8375
  "help",
@@ -8371,12 +8387,13 @@ var COMMAND_OPTION_SCOPE = {
8371
8387
  "only-artifacts",
8372
8388
  "no-config",
8373
8389
  "discovery",
8390
+ "no-update-check",
8374
8391
  "format",
8375
8392
  "mode",
8376
8393
  "help",
8377
8394
  "version"
8378
8395
  ],
8379
- diff: ["format", "mode", "no-config", "help", "version"],
8396
+ diff: ["format", "mode", "no-config", "no-update-check", "help", "version"],
8380
8397
  describe: ["format", "mode", "help", "version"],
8381
8398
  init: [
8382
8399
  "cwd",
@@ -8391,6 +8408,7 @@ var COMMAND_OPTION_SCOPE = {
8391
8408
  "yes",
8392
8409
  "force",
8393
8410
  "dry-run",
8411
+ "no-update-check",
8394
8412
  "format",
8395
8413
  "mode",
8396
8414
  "help",
@@ -8414,6 +8432,7 @@ var COMMAND_OPTION_SCOPE = {
8414
8432
  "force",
8415
8433
  "no-install",
8416
8434
  "dry-run",
8435
+ "no-update-check",
8417
8436
  "format",
8418
8437
  "mode",
8419
8438
  "help",
@@ -8777,6 +8796,13 @@ function buildAgentContract() {
8777
8796
  default: false,
8778
8797
  appliesTo: optionAppliesTo("no-install"),
8779
8798
  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)."
8799
+ },
8800
+ {
8801
+ flag: "--no-update-check",
8802
+ type: "boolean",
8803
+ default: false,
8804
+ appliesTo: optionAppliesTo("no-update-check"),
8805
+ 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."
8780
8806
  }
8781
8807
  ],
8782
8808
  presets: PRESETS.map((preset) => ({
@@ -9385,6 +9411,7 @@ exports.buildPrompts = buildPrompts;
9385
9411
  exports.buildResourceProvider = buildResourceProvider;
9386
9412
  exports.buildTools = buildTools;
9387
9413
  exports.classifyRequest = classifyRequest;
9414
+ exports.coerceNumericStrings = coerceNumericStrings;
9388
9415
  exports.createLineReader = createLineReader;
9389
9416
  exports.createMcpServer = createMcpServer;
9390
9417
  exports.createServer = createServer;
package/dist/mcp.d.cts CHANGED
@@ -395,5 +395,18 @@ declare const SERVER_INSTRUCTIONS: string;
395
395
 
396
396
  /** Human-readable problems, each prefixed with the argument path that caused it. */
397
397
  declare function validateArguments(schema: InputSchema, value: unknown): string[];
398
+ /**
399
+ * Accepts a numeric argument that arrived as a digit string.
400
+ *
401
+ * Reported from a real client: the same `snapshot_read` call succeeded through one code path and
402
+ * was rejected through another, because one of them serialised `fromLine` as `"1"`. A digit string
403
+ * is the same value in a different spelling, and the caller cannot fix what their client did — so
404
+ * refusing it makes the tool unusable there while teaching nobody anything.
405
+ *
406
+ * This is not a relaxation of type checking: only fields the schema declares as numbers are
407
+ * touched, only strings that parse to a finite number are converted, and anything else still fails
408
+ * validation with the type message. `"ten"`, `""` and `"1.5"` for an integer all still fail.
409
+ */
410
+ declare function coerceNumericStrings(schema: InputSchema, value: JsonObject): JsonObject;
398
411
 
399
- export { ERROR_CODES, type JsonRpcResponse, type JsonSchema, LEGACY_PROTOCOL_VERSIONS, type LineReaderOptions, MAX_LINE_BYTES, METHOD, MODERN_PROTOCOL_VERSIONS, type McpPrompt, type McpResourceContents, type McpResourceDescriptor, type McpResourceTemplate, type McpServer, type McpServerInfo, type McpServerOptions, type McpTool, type MessageWriter, type ProtocolEra, type ResourceProvider, SERVER_INSTRUCTIONS, SUPPORTED_PROTOCOL_VERSIONS, type ServerOptions, type SessionState, type ToolAnnotations, type ToolContext, type ToolOutcome, buildPrompts, buildResourceProvider, buildTools, classifyRequest, createLineReader, createMcpServer, createServer, createSession, createWriter, inspectModernMeta, negotiateLegacyVersion, runStdioServer, validateArguments };
412
+ export { ERROR_CODES, type JsonRpcResponse, type JsonSchema, LEGACY_PROTOCOL_VERSIONS, type LineReaderOptions, MAX_LINE_BYTES, METHOD, MODERN_PROTOCOL_VERSIONS, type McpPrompt, type McpResourceContents, type McpResourceDescriptor, type McpResourceTemplate, type McpServer, type McpServerInfo, type McpServerOptions, type McpTool, type MessageWriter, type ProtocolEra, type ResourceProvider, SERVER_INSTRUCTIONS, SUPPORTED_PROTOCOL_VERSIONS, type ServerOptions, type SessionState, type ToolAnnotations, type ToolContext, type ToolOutcome, buildPrompts, buildResourceProvider, buildTools, classifyRequest, coerceNumericStrings, createLineReader, createMcpServer, createServer, createSession, createWriter, inspectModernMeta, negotiateLegacyVersion, runStdioServer, validateArguments };
package/dist/mcp.d.ts CHANGED
@@ -395,5 +395,18 @@ declare const SERVER_INSTRUCTIONS: string;
395
395
 
396
396
  /** Human-readable problems, each prefixed with the argument path that caused it. */
397
397
  declare function validateArguments(schema: InputSchema, value: unknown): string[];
398
+ /**
399
+ * Accepts a numeric argument that arrived as a digit string.
400
+ *
401
+ * Reported from a real client: the same `snapshot_read` call succeeded through one code path and
402
+ * was rejected through another, because one of them serialised `fromLine` as `"1"`. A digit string
403
+ * is the same value in a different spelling, and the caller cannot fix what their client did — so
404
+ * refusing it makes the tool unusable there while teaching nobody anything.
405
+ *
406
+ * This is not a relaxation of type checking: only fields the schema declares as numbers are
407
+ * touched, only strings that parse to a finite number are converted, and anything else still fails
408
+ * validation with the type message. `"ten"`, `""` and `"1.5"` for an integer all still fail.
409
+ */
410
+ declare function coerceNumericStrings(schema: InputSchema, value: JsonObject): JsonObject;
398
411
 
399
- export { ERROR_CODES, type JsonRpcResponse, type JsonSchema, LEGACY_PROTOCOL_VERSIONS, type LineReaderOptions, MAX_LINE_BYTES, METHOD, MODERN_PROTOCOL_VERSIONS, type McpPrompt, type McpResourceContents, type McpResourceDescriptor, type McpResourceTemplate, type McpServer, type McpServerInfo, type McpServerOptions, type McpTool, type MessageWriter, type ProtocolEra, type ResourceProvider, SERVER_INSTRUCTIONS, SUPPORTED_PROTOCOL_VERSIONS, type ServerOptions, type SessionState, type ToolAnnotations, type ToolContext, type ToolOutcome, buildPrompts, buildResourceProvider, buildTools, classifyRequest, createLineReader, createMcpServer, createServer, createSession, createWriter, inspectModernMeta, negotiateLegacyVersion, runStdioServer, validateArguments };
412
+ export { ERROR_CODES, type JsonRpcResponse, type JsonSchema, LEGACY_PROTOCOL_VERSIONS, type LineReaderOptions, MAX_LINE_BYTES, METHOD, MODERN_PROTOCOL_VERSIONS, type McpPrompt, type McpResourceContents, type McpResourceDescriptor, type McpResourceTemplate, type McpServer, type McpServerInfo, type McpServerOptions, type McpTool, type MessageWriter, type ProtocolEra, type ResourceProvider, SERVER_INSTRUCTIONS, SUPPORTED_PROTOCOL_VERSIONS, type ServerOptions, type SessionState, type ToolAnnotations, type ToolContext, type ToolOutcome, buildPrompts, buildResourceProvider, buildTools, classifyRequest, coerceNumericStrings, createLineReader, createMcpServer, createServer, createSession, createWriter, inspectModernMeta, negotiateLegacyVersion, runStdioServer, validateArguments };
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, createLineReader, createMcpServer, createServer, createSession, createWriter, inspectModernMeta, negotiateLegacyVersion, runStdioServer, validateArguments } from './chunk-EWZYK3VX.js';
2
- import './chunk-FCWD4LY7.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-ZKZOGGM3.js';
2
+ import './chunk-3KUL3QRH.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.4
177
+ Added devDependency: codebase-snapshot ^0.9.6
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.4
214
+ Added devDependency: codebase-snapshot ^0.9.6
215
215
  Added to .gitignore: snapshot/, snapshot.tmp/
216
216
  ```
217
217
 
@@ -225,6 +225,16 @@ It also has three side effects on files you own, and it says so when it does the
225
225
  - `snapshot/` and `snapshot.tmp/` are appended to `.gitignore` if they are not already listed;
226
226
  the file is created if missing, and entries already present are not duplicated.
227
227
 
228
+ ### Going back
229
+
230
+ At a terminal, `init` asks five questions and every one of them can be revisited: **`←`** goes back
231
+ on a list or a text field, **`b`** on a list or a confirmation. `text` takes `←` alone because `b` is
232
+ a character you may be typing, and `confirm` takes `b` alone because `←`/`→` already mean yes/no.
233
+
234
+ Back steps to the previous question with your earlier answer still selected; back from the first one
235
+ returns to *"How should I set this up?"*. Answering **No** at the review steps back rather than
236
+ abandoning the run — Ctrl+C is how you abandon.
237
+
228
238
  Nothing else in the repository is touched: no `AGENTS.md`, no `.claude/`, no `.cursor/`. In a
229
239
  repository with a `package.json` and no config, `git status` shows the config as the only new
230
240
  file.
@@ -475,6 +485,23 @@ So `codebase-snapshot describe --format json > contract.json`,
475
485
  `codebase-snapshot validate --format json | jq .drift` and
476
486
  `codebase-snapshot report --format json || jq -r .error.message` all work.
477
487
 
488
+ ## Update notice
489
+
490
+ Once a day, after a command finishes, `snapshot` asks the npm registry whether a newer version is
491
+ published and prints two lines on stderr if there is one:
492
+
493
+ ```
494
+ ↑ codebase-snapshot 0.9.6 is available — you have 0.9.5.
495
+ npm install -g codebase-snapshot
496
+ ```
497
+
498
+ The request goes to `registry.npmjs.org/codebase-snapshot/latest`, carries no identifier of any
499
+ kind, and its answer is remembered for 24 hours — one request per machine per day at most. It is
500
+ skipped when stdout is not a terminal, in CI, in any `--format json` run, and in `mcp`, whose server
501
+ makes no outbound connections at all.
502
+
503
+ `--no-update-check` or `CODEBASE_SNAPSHOT_NO_UPDATE_CHECK=1` turns it off entirely.
504
+
478
505
  ## Examples
479
506
 
480
507
  ```bash
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.4 mcp
13
+ npx -y codebase-snapshot@0.9.6 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.4", "mcp", "--cwd", "/absolute/path/to/repo"]
28
+ "args": ["-y", "codebase-snapshot@0.9.6", "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.4 mcp --cwd /absolute/path/to/repo
37
+ claude mcp add codebase-snapshot -- npx -y codebase-snapshot@0.9.6 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.4",
3
+ "version": "0.9.6",
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",