@codluv/versionguard 0.4.0 → 0.5.0

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.
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-B3R60bYJ.js","sources":["../../src/calver.ts","../../src/changelog.ts","../../src/hooks.ts","../../src/sources/git-tag.ts","../../src/sources/utils.ts","../../src/sources/json.ts","../../src/sources/regex.ts","../../src/sources/toml.ts","../../src/sources/version-file.ts","../../src/sources/yaml.ts","../../src/sources/resolve.ts","../../src/project.ts","../../src/semver.ts","../../src/sync.ts","../../src/types.ts","../../src/config.ts","../../src/feedback/index.ts","../../src/fix/index.ts","../../src/guard.ts","../../src/tag/index.ts","../../src/index.ts"],"sourcesContent":["/**\n * Calendar version parsing, formatting, and comparison helpers.\n *\n * @remarks\n * Supports the full calver.org specification with all standard tokens:\n * Year (`YYYY`, `YY`, `0Y`), Month (`MM`, `M`, `0M`), Week (`WW`, `0W`),\n * Day (`DD`, `D`, `0D`), and Counter (`MICRO`/`PATCH`).\n *\n * `MICRO` is the CalVer-standard name for the counter segment.\n * `PATCH` is accepted as a SemVer-familiar alias and behaves identically.\n *\n * @packageDocumentation\n */\n\nimport type {\n CalVer,\n CalVerFormat,\n CalVerToken,\n SchemeRules,\n ValidationError,\n ValidationResult,\n} from './types';\n\n/** All recognized CalVer tokens. */\nconst VALID_TOKENS = new Set<string>([\n 'YYYY',\n 'YY',\n '0Y',\n 'MM',\n 'M',\n '0M',\n 'WW',\n '0W',\n 'DD',\n 'D',\n '0D',\n 'MICRO',\n 'PATCH',\n]);\n\n/** Year tokens. */\nconst YEAR_TOKENS = new Set<string>(['YYYY', 'YY', '0Y']);\n/** Month tokens. */\nconst MONTH_TOKENS = new Set<string>(['MM', 'M', '0M']);\n/** Week tokens. */\nconst WEEK_TOKENS = new Set<string>(['WW', '0W']);\n/** Day tokens. */\nconst DAY_TOKENS = new Set<string>(['DD', 'D', '0D']);\n/** Counter tokens (MICRO is canonical, PATCH is alias). */\nconst COUNTER_TOKENS = new Set<string>(['MICRO', 'PATCH']);\n\n/**\n * Validates that a CalVer format string is composed of valid tokens\n * and follows structural rules.\n *\n * @remarks\n * Structural rules enforced:\n * - Must have at least 2 segments\n * - First segment must be a year token\n * - Week tokens and Month/Day tokens are mutually exclusive\n * - Counter (MICRO/PATCH) can only appear as the last segment\n *\n * @param formatStr - Format string to validate.\n * @returns `true` when the format is valid.\n *\n * @example\n * ```ts\n * import { isValidCalVerFormat } from 'versionguard';\n *\n * isValidCalVerFormat('YYYY.MM.MICRO'); // true\n * isValidCalVerFormat('INVALID'); // false\n * ```\n *\n * @public\n * @since 0.3.0\n */\nexport function isValidCalVerFormat(formatStr: string): formatStr is CalVerFormat {\n const tokens = formatStr.split('.');\n if (tokens.length < 2) return false;\n\n // All tokens must be recognized\n if (!tokens.every((t) => VALID_TOKENS.has(t))) return false;\n\n // First token must be a year\n if (!YEAR_TOKENS.has(tokens[0])) return false;\n\n // Mutual exclusion: week vs month/day\n const hasWeek = tokens.some((t) => WEEK_TOKENS.has(t));\n const hasMonthOrDay = tokens.some((t) => MONTH_TOKENS.has(t) || DAY_TOKENS.has(t));\n if (hasWeek && hasMonthOrDay) return false;\n\n // Counter must be last if present\n const counterIndex = tokens.findIndex((t) => COUNTER_TOKENS.has(t));\n if (counterIndex !== -1 && counterIndex !== tokens.length - 1) return false;\n\n return true;\n}\n\n/**\n * Parsed token layout for a supported CalVer format string.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface ParsedCalVerFormat {\n /**\n * Year token captured from the format string.\n */\n year: 'YYYY' | 'YY' | '0Y';\n\n /**\n * Month token captured from the format string when present.\n *\n * @defaultValue undefined\n */\n month?: 'MM' | 'M' | '0M';\n\n /**\n * Week token captured from the format string when present.\n *\n * @defaultValue undefined\n */\n week?: 'WW' | '0W';\n\n /**\n * Day token captured from the format string when present.\n *\n * @defaultValue undefined\n */\n day?: 'DD' | 'D' | '0D';\n\n /**\n * Counter token captured from the format string when present.\n * Both `MICRO` and `PATCH` map to the same numeric counter.\n *\n * @defaultValue undefined\n */\n counter?: 'MICRO' | 'PATCH';\n}\n\n/**\n * Breaks a CalVer format string into its component tokens.\n *\n * @remarks\n * This helper is used internally by parsing, formatting, and version generation helpers\n * to decide which date parts or counters are present in a given CalVer layout.\n *\n * @param calverFormat - Format string to inspect.\n * @returns The parsed token definition for the requested format.\n *\n * @example\n * ```ts\n * import { parseFormat } from 'versionguard';\n *\n * parseFormat('YYYY.MM.MICRO');\n * // => { year: 'YYYY', month: 'MM', counter: 'MICRO' }\n * ```\n *\n * @public\n * @since 0.1.0\n */\nexport function parseFormat(calverFormat: CalVerFormat): ParsedCalVerFormat {\n const tokens = calverFormat.split('.');\n const result: ParsedCalVerFormat = {\n year: tokens[0] as ParsedCalVerFormat['year'],\n };\n\n for (let i = 1; i < tokens.length; i++) {\n const token = tokens[i] as CalVerToken;\n if (MONTH_TOKENS.has(token)) {\n result.month = token as ParsedCalVerFormat['month'];\n } else if (WEEK_TOKENS.has(token)) {\n result.week = token as ParsedCalVerFormat['week'];\n } else if (DAY_TOKENS.has(token)) {\n result.day = token as ParsedCalVerFormat['day'];\n } else if (COUNTER_TOKENS.has(token)) {\n result.counter = token as ParsedCalVerFormat['counter'];\n }\n }\n\n return result;\n}\n\n/** The optional modifier suffix pattern (e.g., `-alpha.1`, `-rc2`). */\nconst MODIFIER_PATTERN = '(?:-([0-9A-Za-z-]+(?:\\\\.[0-9A-Za-z-]+)*))?';\n\n/**\n * Maps a CalVer token to a strict regex capture group.\n *\n * Patterns enforce value-level constraints (e.g., month 1-12, day 1-31)\n * at the regex level, not just structurally.\n */\nfunction tokenPattern(token: string): string {\n switch (token) {\n case 'YYYY':\n return '([1-9]\\\\d{3})';\n case 'YY':\n return '(\\\\d{1,3})';\n case '0Y':\n return '(\\\\d{2,3})';\n case 'MM':\n case 'M':\n return '([1-9]|1[0-2])';\n case '0M':\n return '(0[1-9]|1[0-2])';\n case 'WW':\n return '([1-9]|[1-4]\\\\d|5[0-3])';\n case '0W':\n return '(0[1-9]|[1-4]\\\\d|5[0-3])';\n case 'DD':\n case 'D':\n return '([1-9]|[12]\\\\d|3[01])';\n case '0D':\n return '(0[1-9]|[12]\\\\d|3[01])';\n case 'MICRO':\n case 'PATCH':\n return '(0|[1-9]\\\\d*)';\n default:\n throw new Error(`Unsupported CalVer token: ${token}`);\n }\n}\n\n/**\n * Builds a regular expression that matches a supported CalVer format.\n *\n * @remarks\n * The returned regular expression is anchored to the start and end of the string so it can\n * be used directly for strict validation of a complete version value.\n *\n * @param calverFormat - Format string to convert into a regular expression.\n * @returns A strict regular expression for the supplied CalVer format.\n *\n * @example\n * ```ts\n * import { getRegexForFormat } from 'versionguard';\n *\n * getRegexForFormat('YYYY.0M.0D').test('2026.03.21');\n * // => true\n * ```\n *\n * @public\n * @since 0.1.0\n */\nexport function getRegexForFormat(calverFormat: CalVerFormat): RegExp {\n const tokens = calverFormat.split('.');\n const pattern = tokens.map(tokenPattern).join('\\\\.');\n // Append optional MODIFIER suffix (e.g., -alpha.1, -rc2)\n return new RegExp(`^${pattern}${MODIFIER_PATTERN}$`);\n}\n\n/**\n * Parses a CalVer string using the supplied format.\n *\n * @remarks\n * The parser returns `null` when the string does not structurally match the requested format.\n * It does not enforce range rules such as future-date rejection; use {@link validate} for that.\n *\n * @param version - Version string to parse.\n * @param calverFormat - Format expected for the version string.\n * @returns Parsed CalVer components, or `null` when the string does not match the format.\n *\n * @example\n * ```ts\n * import { parse } from 'versionguard';\n *\n * parse('2026.3.0', 'YYYY.M.MICRO')?.month;\n * // => 3\n * ```\n *\n * @see {@link validate} to apply date-range and future-date validation.\n * @public\n * @since 0.1.0\n */\nexport function parse(version: string, calverFormat: CalVerFormat): CalVer | null {\n const match = version.match(getRegexForFormat(calverFormat));\n\n if (!match) {\n return null;\n }\n\n const definition = parseFormat(calverFormat);\n const yearToken = definition.year;\n let year = Number.parseInt(match[1], 10);\n if (yearToken === 'YY' || yearToken === '0Y') {\n year = 2000 + year;\n }\n\n let cursor = 2;\n let month: number | undefined;\n let day: number | undefined;\n let patch: number | undefined;\n\n if (definition.month) {\n month = Number.parseInt(match[cursor], 10);\n cursor += 1;\n }\n\n if (definition.week) {\n // Week stored in month field for simplicity in comparison\n month = Number.parseInt(match[cursor], 10);\n cursor += 1;\n }\n\n if (definition.day) {\n day = Number.parseInt(match[cursor], 10);\n cursor += 1;\n }\n\n if (definition.counter) {\n patch = Number.parseInt(match[cursor], 10);\n cursor += 1;\n }\n\n // MODIFIER is always the last capture group from the regex\n const modifierGroup = match[cursor];\n const modifier = modifierGroup || undefined;\n\n return {\n year,\n month: month ?? 1,\n day,\n patch,\n modifier,\n format: calverFormat,\n raw: version,\n };\n}\n\n/**\n * Validates a CalVer string against formatting and date rules.\n *\n * @remarks\n * Validation checks the requested CalVer format, month and day ranges, and optionally rejects\n * future dates relative to the current system date.\n *\n * @param version - Version string to validate.\n * @param calverFormat - Format expected for the version string.\n * @param preventFutureDates - Whether future dates should be reported as errors.\n * @returns A validation result containing any discovered errors and the parsed version on success.\n *\n * @example\n * ```ts\n * import { validate } from 'versionguard';\n *\n * validate('2026.3.0', 'YYYY.M.MICRO', false).valid;\n * // => true\n * ```\n *\n * @public\n * @since 0.1.0\n */\nexport function validate(\n version: string,\n calverFormat: CalVerFormat,\n preventFutureDates: boolean = true,\n schemeRules?: SchemeRules,\n): ValidationResult {\n const errors: ValidationError[] = [];\n const parsed = parse(version, calverFormat);\n\n if (!parsed) {\n return {\n valid: false,\n errors: [\n {\n message: `Invalid CalVer format: \"${version}\". Expected format: ${calverFormat}`,\n severity: 'error',\n },\n ],\n };\n }\n\n const definition = parseFormat(calverFormat);\n\n // Month validation (only when format uses month tokens)\n if (definition.month && (parsed.month < 1 || parsed.month > 12)) {\n errors.push({\n message: `Invalid month: ${parsed.month}. Must be between 1 and 12.`,\n severity: 'error',\n });\n }\n\n // Week validation\n if (definition.week && (parsed.month < 1 || parsed.month > 53)) {\n errors.push({\n message: `Invalid week: ${parsed.month}. Must be between 1 and 53.`,\n severity: 'error',\n });\n }\n\n if (parsed.day !== undefined) {\n if (parsed.day < 1 || parsed.day > 31) {\n errors.push({\n message: `Invalid day: ${parsed.day}. Must be between 1 and 31.`,\n severity: 'error',\n });\n } else if (definition.month) {\n const daysInMonth = new Date(parsed.year, parsed.month, 0).getDate();\n if (parsed.day > daysInMonth) {\n errors.push({\n message: `Invalid day: ${parsed.day}. ${parsed.year}-${String(parsed.month).padStart(2, '0')} has only ${daysInMonth} days.`,\n severity: 'error',\n });\n }\n }\n }\n\n if (preventFutureDates) {\n const now = new Date();\n const currentYear = now.getFullYear();\n const currentMonth = now.getMonth() + 1;\n const currentDay = now.getDate();\n\n if (parsed.year > currentYear) {\n errors.push({\n message: `Future year not allowed: ${parsed.year}. Current year is ${currentYear}.`,\n severity: 'error',\n });\n } else if (definition.month && parsed.year === currentYear && parsed.month > currentMonth) {\n errors.push({\n message: `Future month not allowed: ${parsed.year}.${parsed.month}. Current month is ${currentMonth}.`,\n severity: 'error',\n });\n } else if (\n definition.month &&\n parsed.year === currentYear &&\n parsed.month === currentMonth &&\n parsed.day !== undefined &&\n parsed.day > currentDay\n ) {\n errors.push({\n message: `Future day not allowed: ${parsed.year}.${parsed.month}.${parsed.day}. Current day is ${currentDay}.`,\n severity: 'error',\n });\n }\n }\n\n // Modifier validation against allowed list\n if (parsed.modifier && schemeRules?.allowedModifiers) {\n // Extract base modifier name: \"alpha.1\" → \"alpha\", \"rc2\" → \"rc\", \"dev\" → \"dev\"\n const baseModifier = parsed.modifier.replace(/[\\d.]+$/, '') || parsed.modifier;\n if (!schemeRules.allowedModifiers.includes(baseModifier)) {\n errors.push({\n message: `Modifier \"${parsed.modifier}\" is not allowed. Allowed: ${schemeRules.allowedModifiers.join(', ')}`,\n severity: 'error',\n });\n }\n }\n\n // Segment count warning\n if (schemeRules?.maxNumericSegments) {\n const segmentCount = calverFormat.split('.').length;\n if (segmentCount > schemeRules.maxNumericSegments) {\n errors.push({\n message: `Format has ${segmentCount} segments, convention recommends ${schemeRules.maxNumericSegments} or fewer`,\n severity: 'warning',\n });\n }\n }\n\n return {\n valid: errors.filter((e) => e.severity === 'error').length === 0,\n errors,\n version: { type: 'calver', version: parsed },\n };\n}\n\nfunction formatToken(token: string, value: number): string {\n switch (token) {\n case '0M':\n case '0D':\n case '0W':\n case '0Y':\n return String(token === '0Y' ? value % 100 : value).padStart(2, '0');\n case 'YY':\n return String(value % 100).padStart(2, '0');\n default:\n return String(value);\n }\n}\n\n/**\n * Formats a parsed CalVer object back into a version string.\n *\n * @remarks\n * Missing `day` and `patch` values fall back to `1` and `0` respectively when the selected\n * format requires those tokens.\n *\n * @param version - Parsed CalVer value to serialize.\n * @returns The formatted CalVer string.\n *\n * @example\n * ```ts\n * import { format } from 'versionguard';\n *\n * const version = { year: 2026, month: 3, day: 21, format: 'YYYY.0M.0D', raw: '2026.03.21' };\n *\n * format(version);\n * // => '2026.03.21'\n * ```\n *\n * @public\n * @since 0.1.0\n */\nexport function format(version: CalVer): string {\n const definition = parseFormat(version.format);\n const parts: string[] = [formatToken(definition.year, version.year)];\n\n if (definition.month) {\n parts.push(formatToken(definition.month, version.month));\n }\n\n if (definition.week) {\n parts.push(formatToken(definition.week, version.month));\n }\n\n if (definition.day) {\n parts.push(formatToken(definition.day, version.day ?? 1));\n }\n\n if (definition.counter) {\n parts.push(formatToken(definition.counter, version.patch ?? 0));\n }\n\n const base = parts.join('.');\n return version.modifier ? `${base}-${version.modifier}` : base;\n}\n\n/**\n * Creates the current CalVer string for a format.\n *\n * @remarks\n * This helper derives its values from the provided date and initializes any counter to `0`.\n * It is useful for generating a same-day baseline before incrementing counter-based formats.\n *\n * @param calverFormat - Format to generate.\n * @param now - Date used as the source for year, month, and day values.\n * @returns The current version string for the requested format.\n *\n * @example\n * ```ts\n * import { getCurrentVersion } from 'versionguard';\n *\n * getCurrentVersion('YYYY.M.MICRO', new Date('2026-03-21T00:00:00Z'));\n * // => '2026.3.0'\n * ```\n *\n * @public\n * @since 0.1.0\n */\nexport function getCurrentVersion(calverFormat: CalVerFormat, now: Date = new Date()): string {\n const definition = parseFormat(calverFormat);\n const base: CalVer = {\n year: now.getFullYear(),\n month: now.getMonth() + 1,\n day: definition.day ? now.getDate() : undefined,\n patch: definition.counter ? 0 : undefined,\n format: calverFormat,\n raw: '',\n };\n\n return format(base);\n}\n\n/**\n * Compares two CalVer strings using a shared format.\n *\n * @remarks\n * Comparison is performed component-by-component in year, month, day, then counter order.\n * Missing day and counter values are treated as `0` during comparison.\n *\n * @param a - Left-hand version string.\n * @param b - Right-hand version string.\n * @param calverFormat - Format used to parse both versions.\n * @returns `1` when `a` is greater, `-1` when `b` is greater, or `0` when they are equal.\n *\n * @example\n * ```ts\n * import { compare } from 'versionguard';\n *\n * compare('2026.3.2', '2026.3.1', 'YYYY.M.MICRO');\n * // => 1\n * ```\n *\n * @public\n * @since 0.1.0\n */\nexport function compare(a: string, b: string, calverFormat: CalVerFormat): number {\n const left = parse(a, calverFormat);\n const right = parse(b, calverFormat);\n\n if (!left || !right) {\n throw new Error(`Invalid CalVer comparison between \"${a}\" and \"${b}\"`);\n }\n\n for (const key of ['year', 'month', 'day', 'patch'] as const) {\n const leftValue = left[key] ?? 0;\n const rightValue = right[key] ?? 0;\n if (leftValue !== rightValue) {\n return leftValue > rightValue ? 1 : -1;\n }\n }\n\n return 0;\n}\n\n/**\n * Increments a CalVer string.\n *\n * @remarks\n * Counter-based formats increment the existing counter. Formats without a counter are\n * promoted to a counter-based output by appending `.MICRO` with an initial value of `0`.\n *\n * @param version - Current version string.\n * @param calverFormat - Format used to parse the current version.\n * @returns The next version string.\n *\n * @example\n * ```ts\n * import { increment } from 'versionguard';\n *\n * increment('2026.3.1', 'YYYY.M.MICRO');\n * // => '2026.3.2'\n * ```\n *\n * @public\n * @since 0.1.0\n */\nexport function increment(version: string, calverFormat: CalVerFormat): string {\n const parsed = parse(version, calverFormat);\n\n if (!parsed) {\n throw new Error(`Invalid CalVer version: ${version}`);\n }\n\n const definition = parseFormat(calverFormat);\n const next: CalVer = {\n ...parsed,\n raw: version,\n };\n\n if (definition.counter) {\n next.patch = (parsed.patch ?? 0) + 1;\n } else {\n next.patch = 0;\n next.format = `${calverFormat}.MICRO` as CalVerFormat;\n }\n\n return format(next);\n}\n\n/**\n * Returns the most likely next CalVer candidates.\n *\n * @remarks\n * The first candidate is the version derived from the current date. The second candidate is the\n * incremented form of the supplied current version.\n *\n * @param currentVersion - Existing project version.\n * @param calverFormat - Format used to generate both candidates.\n * @returns Two candidate version strings ordered as current-date then incremented version.\n *\n * @example\n * ```ts\n * import { getNextVersions } from 'versionguard';\n *\n * getNextVersions('2026.3.1', 'YYYY.M.MICRO').length;\n * // => 2\n * ```\n *\n * @public\n * @since 0.1.0\n */\nexport function getNextVersions(currentVersion: string, calverFormat: CalVerFormat): string[] {\n return [getCurrentVersion(calverFormat), increment(currentVersion, calverFormat)];\n}\n","import * as fs from 'node:fs';\n\n/**\n * Describes the outcome of validating a changelog file.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface ChangelogValidationResult {\n /**\n * Indicates whether the changelog satisfies all requested checks.\n */\n valid: boolean;\n /**\n * Human-readable validation errors.\n */\n errors: string[];\n /**\n * Indicates whether the changelog contains an entry for the requested version.\n */\n hasEntryForVersion: boolean;\n}\n\nconst CHANGELOG_DATE_REGEX = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/**\n * Validates a changelog file for release readiness.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * The validator checks for a top-level changelog heading, an `[Unreleased]`\n * section, and optionally a dated entry for the requested version.\n *\n * @param changelogPath - Path to the changelog file.\n * @param version - Version that must be present in the changelog.\n * @param strict - Whether to require compare links and dated release headings.\n * @param requireEntry - Whether the requested version must already have an entry.\n * @returns The result of validating the changelog file.\n * @example\n * ```ts\n * import { validateChangelog } from 'versionguard';\n *\n * const result = validateChangelog('CHANGELOG.md', '1.2.0', true, true);\n * ```\n */\nexport function validateChangelog(\n changelogPath: string,\n version: string,\n strict: boolean = true,\n requireEntry: boolean = true,\n): ChangelogValidationResult {\n if (!fs.existsSync(changelogPath)) {\n return {\n valid: !requireEntry,\n errors: requireEntry ? [`Changelog not found: ${changelogPath}`] : [],\n hasEntryForVersion: false,\n };\n }\n\n const errors: string[] = [];\n const content = fs.readFileSync(changelogPath, 'utf-8');\n\n if (!content.startsWith('# Changelog')) {\n errors.push('Changelog must start with \"# Changelog\"');\n }\n\n if (!content.includes('## [Unreleased]')) {\n errors.push('Changelog must have an [Unreleased] section');\n }\n\n const versionHeader = `## [${version}]`;\n const hasEntryForVersion = content.includes(versionHeader);\n if (requireEntry && !hasEntryForVersion) {\n errors.push(`Changelog must have an entry for version ${version}`);\n }\n\n if (strict) {\n if (!content.includes('[Unreleased]:')) {\n errors.push('Changelog should include compare links at the bottom');\n }\n\n const versionHeaderMatch = content.match(\n new RegExp(`## \\\\[${escapeRegExp(version)}\\\\] - ([^\\r\\n]+)`),\n );\n if (requireEntry && hasEntryForVersion) {\n if (!versionHeaderMatch) {\n errors.push(`Version ${version} entry must use \"## [${version}] - YYYY-MM-DD\" format`);\n } else if (!CHANGELOG_DATE_REGEX.test(versionHeaderMatch[1])) {\n errors.push(`Version ${version} entry date must use YYYY-MM-DD format`);\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n hasEntryForVersion,\n };\n}\n\n/**\n * Gets the most recent released version from a changelog.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * The `[Unreleased]` section is skipped so the first concrete version heading is\n * treated as the latest release.\n *\n * @param changelogPath - Path to the changelog file.\n * @returns The latest released version, or `null` when no release entry exists.\n * @example\n * ```ts\n * import { getLatestVersion } from 'versionguard';\n *\n * const latest = getLatestVersion('CHANGELOG.md');\n * ```\n */\nexport function getLatestVersion(changelogPath: string): string | null {\n if (!fs.existsSync(changelogPath)) {\n return null;\n }\n\n const content = fs.readFileSync(changelogPath, 'utf-8');\n const match = content.match(/^## \\[(?!Unreleased\\])(.*?)\\]/m);\n return match?.[1] ?? null;\n}\n\n/**\n * Inserts a new version entry beneath the `[Unreleased]` section.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * If the changelog already contains the requested version, no changes are made.\n * The inserted entry includes a starter `Added` subsection for follow-up edits.\n *\n * @param changelogPath - Path to the changelog file.\n * @param version - Version to add.\n * @param date - Release date to write in `YYYY-MM-DD` format.\n * @example\n * ```ts\n * import { addVersionEntry } from 'versionguard';\n *\n * addVersionEntry('CHANGELOG.md', '1.2.0', '2026-03-21');\n * ```\n */\nexport function addVersionEntry(\n changelogPath: string,\n version: string,\n date: string = new Date().toISOString().slice(0, 10),\n): void {\n if (!fs.existsSync(changelogPath)) {\n throw new Error(`Changelog not found: ${changelogPath}`);\n }\n\n const content = fs.readFileSync(changelogPath, 'utf-8');\n if (content.includes(`## [${version}]`)) {\n return;\n }\n\n const block = `## [${version}] - ${date}\\n\\n### Added\\n\\n- Describe changes here.\\n\\n`;\n const unreleasedMatch = content.match(/## \\[Unreleased\\]\\r?\\n(?:\\r?\\n)?/);\n if (!unreleasedMatch || unreleasedMatch.index === undefined) {\n throw new Error('Changelog must have an [Unreleased] section');\n }\n\n const insertIndex = unreleasedMatch.index + unreleasedMatch[0].length;\n const updated = `${content.slice(0, insertIndex)}${block}${content.slice(insertIndex)}`;\n fs.writeFileSync(changelogPath, updated, 'utf-8');\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport type { GitConfig } from './types';\n\nconst HOOK_NAMES = ['pre-commit', 'pre-push', 'post-tag'] as const;\n\n/**\n * Installs VersionGuard-managed Git hooks in a repository.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * Only hooks enabled in `config.hooks` are written. Each installed hook runs\n * `versionguard validate` for its corresponding hook name.\n *\n * @param config - Git configuration that selects which hooks to install.\n * @param cwd - Repository directory where hooks should be installed.\n * @example\n * ```ts\n * import { getDefaultConfig, installHooks } from 'versionguard';\n *\n * installHooks(getDefaultConfig().git, process.cwd());\n * ```\n */\nexport function installHooks(config: GitConfig, cwd: string = process.cwd()): void {\n const gitDir = findGitDir(cwd);\n if (!gitDir) {\n throw new Error('Not a git repository. Run `git init` first.');\n }\n\n const hooksDir = path.join(gitDir, 'hooks');\n fs.mkdirSync(hooksDir, { recursive: true });\n\n for (const hookName of HOOK_NAMES) {\n if (config.hooks[hookName]) {\n const hookPath = path.join(hooksDir, hookName);\n fs.writeFileSync(hookPath, generateHookScript(hookName), { encoding: 'utf-8', mode: 0o755 });\n }\n }\n}\n\n/**\n * Removes VersionGuard-managed Git hooks from a repository.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * Only hook files containing `versionguard` are removed so unrelated custom\n * hooks are left untouched.\n *\n * @param cwd - Repository directory whose hooks should be cleaned up.\n * @example\n * ```ts\n * import { uninstallHooks } from 'versionguard';\n *\n * uninstallHooks(process.cwd());\n * ```\n */\nexport function uninstallHooks(cwd: string = process.cwd()): void {\n const gitDir = findGitDir(cwd);\n if (!gitDir) {\n return;\n }\n\n const hooksDir = path.join(gitDir, 'hooks');\n for (const hookName of HOOK_NAMES) {\n const hookPath = path.join(hooksDir, hookName);\n if (fs.existsSync(hookPath) && fs.readFileSync(hookPath, 'utf-8').includes('versionguard')) {\n fs.unlinkSync(hookPath);\n }\n }\n}\n\n/**\n * Finds the nearest `.git` directory by walking up from a starting directory.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * This only resolves `.git` directories and returns `null` when the search\n * reaches the filesystem root without finding a repository.\n *\n * @param cwd - Directory to start searching from.\n * @returns The resolved `.git` directory path, or `null` when none is found.\n * @example\n * ```ts\n * import { findGitDir } from 'versionguard';\n *\n * const gitDir = findGitDir(process.cwd());\n * ```\n */\nexport function findGitDir(cwd: string): string | null {\n let current = cwd;\n\n while (true) {\n const gitPath = path.join(current, '.git');\n if (fs.existsSync(gitPath) && fs.statSync(gitPath).isDirectory()) {\n return gitPath;\n }\n\n const parent = path.dirname(current);\n if (parent === current) {\n return null;\n }\n current = parent;\n }\n}\n\n/**\n * Checks whether all VersionGuard-managed hooks are installed.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * A hook counts as installed only when the file exists and contains the\n * `versionguard` invocation written by this package.\n *\n * @param cwd - Repository directory to inspect.\n * @returns `true` when every managed hook is installed.\n * @example\n * ```ts\n * import { areHooksInstalled } from 'versionguard';\n *\n * const installed = areHooksInstalled(process.cwd());\n * ```\n */\nexport function areHooksInstalled(cwd: string = process.cwd()): boolean {\n const gitDir = findGitDir(cwd);\n if (!gitDir) {\n return false;\n }\n\n return HOOK_NAMES.every((hookName) => {\n const hookPath = path.join(gitDir, 'hooks', hookName);\n return fs.existsSync(hookPath) && fs.readFileSync(hookPath, 'utf-8').includes('versionguard');\n });\n}\n\n/**\n * Generates the shell script content for a Git hook.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * The generated script delegates to `npx versionguard validate` and exits with\n * the validation status code.\n *\n * @param hookName - Name of the Git hook to generate.\n * @returns Executable shell script contents for the hook.\n * @example\n * ```ts\n * import { generateHookScript } from 'versionguard';\n *\n * const script = generateHookScript('pre-commit');\n * ```\n */\nexport function generateHookScript(hookName: (typeof HOOK_NAMES)[number]): string {\n return `#!/bin/sh\n# versionguard\n# VersionGuard ${hookName} hook\n# --no-install prevents accidentally downloading an unscoped package\n# if @codluv/versionguard is not installed locally\nnpx --no-install versionguard validate --hook=${hookName}\nstatus=$?\nif [ $status -ne 0 ]; then\n echo \"VersionGuard validation failed.\"\n exit $status\nfi\n`;\n}\n","/**\n * Git tag-based version source for Go, Swift, and similar ecosystems.\n *\n * @packageDocumentation\n */\n\nimport { execFileSync } from 'node:child_process';\n\nimport type { VersionSourceProvider } from './provider';\n\n/**\n * Reads version from the latest Git tag. Writing creates a new annotated tag.\n *\n * @remarks\n * This provider is used for languages where the version is determined\n * entirely by Git tags (Go, Swift, PHP/Packagist).\n *\n * The tag prefix (`v` by default) is auto-detected from existing tags\n * when writing, so projects using unprefixed tags (e.g. `1.0.0`) stay\n * consistent.\n *\n * @public\n * @since 0.3.0\n */\nexport class GitTagSource implements VersionSourceProvider {\n /** Human-readable provider name. */\n readonly name = 'git-tag';\n\n /** Empty string since git-tag has no manifest file. */\n readonly manifestFile = '';\n\n /**\n * Returns `true` when `cwd` is inside a Git repository.\n *\n * @param cwd - Project directory to check.\n * @returns Whether a Git repository is found.\n */\n exists(cwd: string): boolean {\n try {\n execFileSync('git', ['rev-parse', '--git-dir'], {\n cwd,\n stdio: ['pipe', 'pipe', 'ignore'],\n });\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Reads the version string from the latest Git tag.\n *\n * @param cwd - Project directory containing the Git repository.\n * @returns The version string extracted from the latest version tag.\n */\n getVersion(cwd: string): string {\n try {\n // L-006: Use --match to prefer version-like tags over arbitrary ones\n const tag = this.describeVersionTag(cwd);\n return tag.replace(/^v/, '');\n } catch {\n throw new Error('No version tags found. Create a tag first (e.g., git tag v0.1.0)');\n }\n }\n\n /**\n * Creates a new annotated Git tag for the given version.\n *\n * @param version - Version string to tag.\n * @param cwd - Project directory containing the Git repository.\n */\n setVersion(version: string, cwd: string): void {\n // H-005: Detect prefix convention from existing tags\n const prefix = this.detectPrefix(cwd);\n const tagName = `${prefix}${version}`;\n execFileSync('git', ['tag', '-a', tagName, '-m', `Release ${version}`], {\n cwd,\n stdio: ['pipe', 'pipe', 'ignore'],\n });\n }\n\n /** Try version-like tag patterns, fall back to any tag. */\n private describeVersionTag(cwd: string): string {\n // Try v-prefixed semver tags first\n try {\n return execFileSync('git', ['describe', '--tags', '--abbrev=0', '--match', 'v[0-9]*'], {\n cwd,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'ignore'],\n }).trim();\n } catch {\n // Fall through\n }\n\n // Try unprefixed semver tags\n try {\n return execFileSync('git', ['describe', '--tags', '--abbrev=0', '--match', '[0-9]*'], {\n cwd,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'ignore'],\n }).trim();\n } catch {\n throw new Error('No version tags found');\n }\n }\n\n /** Detect whether existing tags use a `v` prefix or not. */\n private detectPrefix(cwd: string): string {\n try {\n const tag = this.describeVersionTag(cwd);\n return tag.startsWith('v') ? 'v' : '';\n } catch {\n // No existing tags — default to `v` prefix\n return 'v';\n }\n }\n}\n","/**\n * Shared utilities for version source providers.\n *\n * @packageDocumentation\n */\n\n/**\n * Traverses a nested object using a dotted key path.\n *\n * @remarks\n * Walks each segment of the dotted path in order, returning `undefined` as\n * soon as a missing or non-object segment is encountered.\n *\n * @param obj - Object to traverse.\n * @param dotPath - Dot-separated key path (e.g. `'package.version'`).\n * @returns The value at the path, or `undefined` if any segment is missing.\n *\n * @example\n * ```ts\n * import { getNestedValue } from './utils';\n *\n * const obj = { package: { version: '1.0.0' } };\n * const version = getNestedValue(obj, 'package.version'); // '1.0.0'\n * ```\n *\n * @public\n * @since 0.3.0\n */\nexport function getNestedValue(obj: Record<string, unknown>, dotPath: string): unknown {\n let current: unknown = obj;\n for (const key of dotPath.split('.')) {\n if (current === null || typeof current !== 'object') {\n return undefined;\n }\n current = (current as Record<string, unknown>)[key];\n }\n return current;\n}\n\n/**\n * Sets a value at a dotted key path, throwing if intermediate segments are missing.\n *\n * @remarks\n * Traverses each intermediate segment and throws when a segment is missing or\n * not an object. The final key is created or overwritten.\n *\n * @param obj - Object to mutate.\n * @param dotPath - Dot-separated key path.\n * @param value - Value to set at the final key.\n *\n * @example\n * ```ts\n * import { setNestedValue } from './utils';\n *\n * const obj = { package: { version: '1.0.0' } };\n * setNestedValue(obj, 'package.version', '2.0.0');\n * ```\n *\n * @public\n * @since 0.3.0\n */\nexport function setNestedValue(\n obj: Record<string, unknown>,\n dotPath: string,\n value: unknown,\n): void {\n const keys = dotPath.split('.');\n let current: Record<string, unknown> = obj;\n for (let i = 0; i < keys.length - 1; i++) {\n const next = current[keys[i]];\n if (typeof next !== 'object' || next === null) {\n throw new Error(`Missing intermediate key '${keys.slice(0, i + 1).join('.')}' in manifest`);\n }\n current = next as Record<string, unknown>;\n }\n current[keys[keys.length - 1]] = value;\n}\n\n/**\n * Escapes special regex characters in a string for safe use in `new RegExp()`.\n *\n * @remarks\n * Prefixes every character that has special meaning in a regular expression\n * with a backslash so the resulting string matches literally.\n *\n * @param value - Raw string to escape.\n * @returns The escaped string safe for embedding in a `RegExp` constructor.\n *\n * @example\n * ```ts\n * import { escapeRegExp } from './utils';\n *\n * const escaped = escapeRegExp('file.txt'); // 'file\\\\.txt'\n * ```\n *\n * @public\n * @since 0.3.0\n */\nexport function escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","/**\n * JSON-based version source provider for package.json and composer.json.\n *\n * @packageDocumentation\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport type { VersionSourceProvider } from './provider';\nimport { getNestedValue, setNestedValue } from './utils';\n\n/**\n * Reads and writes version strings from JSON manifest files.\n *\n * @remarks\n * Supports dotted key paths for nested version fields and preserves the\n * original indentation style when writing back to disk.\n *\n * @public\n * @since 0.3.0\n */\nexport class JsonVersionSource implements VersionSourceProvider {\n /** Human-readable provider name. */\n readonly name: string;\n\n /** Filename of the JSON manifest (e.g. `'package.json'`). */\n readonly manifestFile: string;\n\n /** Dotted key path to the version field within the JSON document. */\n private readonly versionPath: string;\n\n /**\n * Creates a new JSON version source.\n *\n * @param manifestFile - JSON manifest filename.\n * @param versionPath - Dotted key path to the version field.\n */\n constructor(manifestFile: string = 'package.json', versionPath: string = 'version') {\n this.name = manifestFile;\n this.manifestFile = manifestFile;\n this.versionPath = versionPath;\n }\n\n /**\n * Returns `true` when the manifest file exists in `cwd`.\n *\n * @param cwd - Project directory to check.\n * @returns Whether the manifest file exists.\n */\n exists(cwd: string): boolean {\n return fs.existsSync(path.join(cwd, this.manifestFile));\n }\n\n /**\n * Reads the version string from the JSON manifest.\n *\n * @param cwd - Project directory containing the manifest.\n * @returns The version string extracted from the manifest.\n */\n getVersion(cwd: string): string {\n const filePath = path.join(cwd, this.manifestFile);\n if (!fs.existsSync(filePath)) {\n throw new Error(`${this.manifestFile} not found in ${cwd}`);\n }\n\n const content = JSON.parse(fs.readFileSync(filePath, 'utf-8')) as Record<string, unknown>;\n const version = getNestedValue(content, this.versionPath);\n\n if (typeof version !== 'string' || version.length === 0) {\n throw new Error(`No version field in ${this.manifestFile}`);\n }\n\n return version;\n }\n\n /**\n * Writes a version string to the JSON manifest, preserving indentation.\n *\n * @param version - Version string to write.\n * @param cwd - Project directory containing the manifest.\n */\n setVersion(version: string, cwd: string): void {\n const filePath = path.join(cwd, this.manifestFile);\n if (!fs.existsSync(filePath)) {\n throw new Error(`${this.manifestFile} not found in ${cwd}`);\n }\n\n // M-008: Detect original indentation to preserve formatting\n const raw = fs.readFileSync(filePath, 'utf-8');\n const indentMatch = raw.match(/^(\\s+)\"/m);\n const indent = indentMatch?.[1]?.length ?? 2;\n\n const content = JSON.parse(raw) as Record<string, unknown>;\n setNestedValue(content, this.versionPath, version);\n fs.writeFileSync(filePath, `${JSON.stringify(content, null, indent)}\\n`, 'utf-8');\n }\n}\n","/**\n * Regex-based version source for source-code manifests.\n *\n * Handles gemspec, mix.exs, setup.py, build.gradle, etc.\n *\n * @packageDocumentation\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport type { VersionSourceProvider } from './provider';\n\n/**\n * Reads and writes version strings using regex extraction from source files.\n *\n * @remarks\n * Capture group 1 of the provided regex must match the version string.\n * Uses position-based replacement to avoid wrong-match corruption when\n * writing back to disk.\n *\n * @public\n * @since 0.3.0\n */\nexport class RegexVersionSource implements VersionSourceProvider {\n /** Human-readable provider name. */\n readonly name: string;\n\n /** Filename of the source manifest (e.g. `'setup.py'`). */\n readonly manifestFile: string;\n\n /** Compiled regex used to locate the version string. */\n private readonly versionRegex: RegExp;\n\n /**\n * Creates a new regex version source.\n *\n * @param manifestFile - Source manifest filename.\n * @param versionRegex - Regex string with at least one capture group for the version.\n */\n constructor(manifestFile: string, versionRegex: string) {\n this.name = manifestFile;\n this.manifestFile = manifestFile;\n\n // C-001: Validate regex compiles and has at least one capture group\n try {\n this.versionRegex = new RegExp(versionRegex, 'm');\n } catch (err) {\n throw new Error(`Invalid version regex for ${manifestFile}: ${(err as Error).message}`);\n }\n\n // Verify at least one capture group exists\n if (!/\\((?!\\?)/.test(versionRegex)) {\n throw new Error(`Version regex for ${manifestFile} must contain at least one capture group`);\n }\n }\n\n /**\n * Returns `true` when the manifest file exists in `cwd`.\n *\n * @param cwd - Project directory to check.\n * @returns Whether the manifest file exists.\n */\n exists(cwd: string): boolean {\n return fs.existsSync(path.join(cwd, this.manifestFile));\n }\n\n /**\n * Reads the version string from the source manifest using regex extraction.\n *\n * @param cwd - Project directory containing the manifest.\n * @returns The version string captured by group 1 of the regex.\n */\n getVersion(cwd: string): string {\n const filePath = path.join(cwd, this.manifestFile);\n if (!fs.existsSync(filePath)) {\n throw new Error(`${this.manifestFile} not found in ${cwd}`);\n }\n\n const content = fs.readFileSync(filePath, 'utf-8');\n const match = content.match(this.versionRegex);\n\n if (!match?.[1]) {\n throw new Error(`No version match found in ${this.manifestFile}`);\n }\n\n return match[1];\n }\n\n /**\n * Writes a version string to the source manifest using position-based replacement.\n *\n * @param version - Version string to write.\n * @param cwd - Project directory containing the manifest.\n */\n setVersion(version: string, cwd: string): void {\n const filePath = path.join(cwd, this.manifestFile);\n if (!fs.existsSync(filePath)) {\n throw new Error(`${this.manifestFile} not found in ${cwd}`);\n }\n\n const content = fs.readFileSync(filePath, 'utf-8');\n const match = this.versionRegex.exec(content);\n\n if (!match || match.index === undefined) {\n throw new Error(`No version match found in ${this.manifestFile}`);\n }\n\n // C-003: Use position-based replacement to avoid wrong-match corruption\n const captureStart = match.index + match[0].indexOf(match[1]);\n const captureEnd = captureStart + match[1].length;\n const updated = content.slice(0, captureStart) + version + content.slice(captureEnd);\n\n fs.writeFileSync(filePath, updated, 'utf-8');\n }\n}\n","/**\n * TOML-based version source provider for Cargo.toml and pyproject.toml.\n *\n * @packageDocumentation\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport { parse } from 'smol-toml';\n\nimport type { VersionSourceProvider } from './provider';\nimport { escapeRegExp, getNestedValue } from './utils';\n\n/**\n * Reads and writes version strings from TOML manifest files.\n *\n * @remarks\n * Uses targeted regex replacement for writes to preserve file formatting,\n * comments, and whitespace. Supports standard section headers, dotted keys,\n * and inline table syntax.\n *\n * @public\n * @since 0.3.0\n */\nexport class TomlVersionSource implements VersionSourceProvider {\n /** Human-readable provider name. */\n readonly name: string;\n\n /** Filename of the TOML manifest (e.g. `'Cargo.toml'`). */\n readonly manifestFile: string;\n\n /** Dotted key path to the version field within the TOML document. */\n private readonly versionPath: string;\n\n /**\n * Creates a new TOML version source.\n *\n * @param manifestFile - TOML manifest filename.\n * @param versionPath - Dotted key path to the version field.\n */\n constructor(manifestFile: string = 'Cargo.toml', versionPath: string = 'package.version') {\n this.name = manifestFile;\n this.manifestFile = manifestFile;\n this.versionPath = versionPath;\n }\n\n /**\n * Returns `true` when the manifest file exists in `cwd`.\n *\n * @param cwd - Project directory to check.\n * @returns Whether the manifest file exists.\n */\n exists(cwd: string): boolean {\n return fs.existsSync(path.join(cwd, this.manifestFile));\n }\n\n /**\n * Reads the version string from the TOML manifest.\n *\n * @param cwd - Project directory containing the manifest.\n * @returns The version string extracted from the manifest.\n */\n getVersion(cwd: string): string {\n const filePath = path.join(cwd, this.manifestFile);\n if (!fs.existsSync(filePath)) {\n throw new Error(`${this.manifestFile} not found in ${cwd}`);\n }\n\n const content = fs.readFileSync(filePath, 'utf-8');\n const parsed = parse(content) as Record<string, unknown>;\n const version = getNestedValue(parsed, this.versionPath);\n\n if (typeof version !== 'string' || version.length === 0) {\n throw new Error(`No version field at '${this.versionPath}' in ${this.manifestFile}`);\n }\n\n return version;\n }\n\n /**\n * Writes a version string to the TOML manifest, preserving formatting.\n *\n * @param version - Version string to write.\n * @param cwd - Project directory containing the manifest.\n */\n setVersion(version: string, cwd: string): void {\n const filePath = path.join(cwd, this.manifestFile);\n if (!fs.existsSync(filePath)) {\n throw new Error(`${this.manifestFile} not found in ${cwd}`);\n }\n\n const content = fs.readFileSync(filePath, 'utf-8');\n const sectionKey = this.getSectionKey();\n const updated = replaceTomlVersion(content, sectionKey, version);\n\n if (updated === content) {\n throw new Error(`Could not find version field to update in ${this.manifestFile}`);\n }\n\n fs.writeFileSync(filePath, updated, 'utf-8');\n }\n\n /**\n * Splits the dotted version path into a TOML section name and key name.\n *\n * @returns An object with `section` and `key` components.\n */\n private getSectionKey(): { section: string; key: string } {\n const parts = this.versionPath.split('.');\n if (parts.length === 1) {\n return { section: '', key: parts[0] };\n }\n return {\n section: parts.slice(0, -1).join('.'),\n key: parts[parts.length - 1],\n };\n }\n}\n\n/**\n * Replace a version value within a TOML file, preserving formatting.\n *\n * Tries three patterns in order:\n * 1. [section] header + key = \"value\" line (standard)\n * 2. Dotted key syntax: section.key = \"value\" (M-004)\n * 3. Inline table: section = { ..., key = \"value\", ... } (M-010)\n */\nfunction replaceTomlVersion(\n content: string,\n target: { section: string; key: string },\n newVersion: string,\n): string {\n // Pattern 1: Standard [section] header + key line\n const result = replaceInSection(content, target, newVersion);\n if (result !== content) return result;\n\n // Pattern 2: Dotted key syntax (M-004)\n if (target.section) {\n const dottedRegex = new RegExp(\n `^(\\\\s*${escapeRegExp(target.section)}\\\\.${escapeRegExp(target.key)}\\\\s*=\\\\s*)([\"'])([^\"']*)(\\\\2)`,\n 'm',\n );\n const dottedResult = content.replace(dottedRegex, `$1$2${newVersion}$4`);\n if (dottedResult !== content) return dottedResult;\n }\n\n // Pattern 3: Inline table (M-010)\n if (target.section) {\n const inlineRegex = new RegExp(\n `^(\\\\s*${escapeRegExp(target.section)}\\\\s*=\\\\s*\\\\{[^}]*${escapeRegExp(target.key)}\\\\s*=\\\\s*)([\"'])([^\"']*)(\\\\2)`,\n 'm',\n );\n const inlineResult = content.replace(inlineRegex, `$1$2${newVersion}$4`);\n if (inlineResult !== content) return inlineResult;\n }\n\n return content;\n}\n\n/** Standard section-header-based replacement. */\nfunction replaceInSection(\n content: string,\n target: { section: string; key: string },\n newVersion: string,\n): string {\n const lines = content.split('\\n');\n const sectionHeader = target.section ? `[${target.section}]` : null;\n let inSection = sectionHeader === null;\n const versionRegex = new RegExp(`^(\\\\s*${escapeRegExp(target.key)}\\\\s*=\\\\s*)([\"'])([^\"']*)(\\\\2)`);\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trim();\n\n if (sectionHeader !== null) {\n if (trimmed === sectionHeader) {\n inSection = true;\n continue;\n }\n if (inSection && trimmed.startsWith('[') && trimmed !== sectionHeader) {\n inSection = false;\n continue;\n }\n }\n\n if (inSection) {\n const match = lines[i].match(versionRegex);\n if (match) {\n lines[i] = lines[i].replace(versionRegex, `$1$2${newVersion}$4`);\n return lines.join('\\n');\n }\n }\n }\n\n return content;\n}\n","/**\n * Plain text VERSION file provider.\n *\n * @packageDocumentation\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport type { VersionSourceProvider } from './provider';\n\n/**\n * Reads and writes version strings from a plain text VERSION file.\n *\n * @remarks\n * The file is expected to contain only the version string, optionally\n * followed by a trailing newline. Binary files and empty files are\n * rejected with a descriptive error.\n *\n * @public\n * @since 0.3.0\n */\nexport class VersionFileSource implements VersionSourceProvider {\n /** Human-readable provider name. */\n readonly name: string;\n\n /** Filename of the version file (e.g. `'VERSION'`). */\n readonly manifestFile: string;\n\n /**\n * Creates a new plain text version file source.\n *\n * @param manifestFile - Version filename.\n */\n constructor(manifestFile: string = 'VERSION') {\n this.name = manifestFile;\n this.manifestFile = manifestFile;\n }\n\n /**\n * Returns `true` when the version file exists in `cwd`.\n *\n * @param cwd - Project directory to check.\n * @returns Whether the version file exists.\n */\n exists(cwd: string): boolean {\n return fs.existsSync(path.join(cwd, this.manifestFile));\n }\n\n /**\n * Reads the version string from the plain text version file.\n *\n * @param cwd - Project directory containing the version file.\n * @returns The version string from the first line of the file.\n */\n getVersion(cwd: string): string {\n const filePath = path.join(cwd, this.manifestFile);\n if (!fs.existsSync(filePath)) {\n throw new Error(`${this.manifestFile} not found in ${cwd}`);\n }\n\n const raw = fs.readFileSync(filePath, 'utf-8');\n\n // L-003: Guard against binary files\n if (raw.includes('\\0')) {\n throw new Error(`${this.manifestFile} appears to be a binary file`);\n }\n\n // L-004: Only use the first line as the version\n const version = raw.split('\\n')[0].trim();\n if (version.length === 0) {\n throw new Error(`${this.manifestFile} is empty`);\n }\n\n return version;\n }\n\n /**\n * Writes a version string to the plain text version file.\n *\n * @param version - Version string to write.\n * @param cwd - Project directory containing the version file.\n */\n setVersion(version: string, cwd: string): void {\n const filePath = path.join(cwd, this.manifestFile);\n if (!fs.existsSync(filePath)) {\n throw new Error(`${this.manifestFile} not found in ${cwd}`);\n }\n fs.writeFileSync(filePath, `${version}\\n`, 'utf-8');\n }\n}\n","/**\n * YAML-based version source provider for pubspec.yaml and similar manifests.\n *\n * @packageDocumentation\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport * as yaml from 'js-yaml';\n\nimport type { VersionSourceProvider } from './provider';\nimport { escapeRegExp, getNestedValue } from './utils';\n\n/**\n * Reads and writes version strings from YAML manifest files.\n *\n * @remarks\n * Supports dotted key paths (e.g. `'flutter.version'`) for nested values.\n * Uses targeted regex replacement for writes to preserve comments and formatting.\n *\n * @public\n * @since 0.3.0\n */\nexport class YamlVersionSource implements VersionSourceProvider {\n /** Human-readable provider name. */\n readonly name: string;\n\n /** Filename of the YAML manifest (e.g. `'pubspec.yaml'`). */\n readonly manifestFile: string;\n\n /** Dotted key path to the version field within the YAML document. */\n private readonly versionKey: string;\n\n /**\n * Creates a new YAML version source.\n *\n * @param manifestFile - YAML manifest filename.\n * @param versionKey - Dotted key path to the version field.\n */\n constructor(manifestFile: string = 'pubspec.yaml', versionKey: string = 'version') {\n this.name = manifestFile;\n this.manifestFile = manifestFile;\n this.versionKey = versionKey;\n }\n\n /**\n * Returns `true` when the manifest file exists in `cwd`.\n *\n * @param cwd - Project directory to check.\n * @returns Whether the manifest file exists.\n */\n exists(cwd: string): boolean {\n return fs.existsSync(path.join(cwd, this.manifestFile));\n }\n\n /**\n * Reads the version string from the YAML manifest.\n *\n * @param cwd - Project directory containing the manifest.\n * @returns The version string extracted from the manifest.\n */\n getVersion(cwd: string): string {\n const filePath = path.join(cwd, this.manifestFile);\n if (!fs.existsSync(filePath)) {\n throw new Error(`${this.manifestFile} not found in ${cwd}`);\n }\n\n const content = fs.readFileSync(filePath, 'utf-8');\n const parsed = yaml.load(content) as Record<string, unknown> | undefined;\n\n if (!parsed || typeof parsed !== 'object') {\n throw new Error(`Failed to parse ${this.manifestFile}`);\n }\n\n // L-005: Support nested dotted paths\n const version = getNestedValue(parsed, this.versionKey);\n if (typeof version !== 'string' || version.length === 0) {\n if (typeof version === 'number') {\n return String(version);\n }\n throw new Error(`No version field in ${this.manifestFile}`);\n }\n\n return version;\n }\n\n /**\n * Writes a version string to the YAML manifest, preserving formatting.\n *\n * @param version - Version string to write.\n * @param cwd - Project directory containing the manifest.\n */\n setVersion(version: string, cwd: string): void {\n const filePath = path.join(cwd, this.manifestFile);\n if (!fs.existsSync(filePath)) {\n throw new Error(`${this.manifestFile} not found in ${cwd}`);\n }\n\n // The last segment of the dotted key is the YAML key to match in the file\n const keyParts = this.versionKey.split('.');\n const leafKey = keyParts[keyParts.length - 1];\n\n // Use regex replacement to preserve comments, formatting, and quote style\n const content = fs.readFileSync(filePath, 'utf-8');\n const regex = new RegExp(`^(\\\\s*${escapeRegExp(leafKey)}:\\\\s*)([\"']?)(.+?)\\\\2\\\\s*$`, 'm');\n const updated = content.replace(regex, `$1$2${version}$2`);\n\n if (updated === content) {\n throw new Error(`Could not find version field to update in ${this.manifestFile}`);\n }\n\n fs.writeFileSync(filePath, updated, 'utf-8');\n }\n}\n","/**\n * Version source auto-detection and resolution.\n *\n * @packageDocumentation\n */\n\nimport * as path from 'node:path';\n\nimport type { ManifestConfig, ManifestSourceType } from '../types';\nimport { GitTagSource } from './git-tag';\nimport { JsonVersionSource } from './json';\nimport type { VersionSourceProvider } from './provider';\nimport { RegexVersionSource } from './regex';\nimport { TomlVersionSource } from './toml';\nimport { VersionFileSource } from './version-file';\nimport { YamlVersionSource } from './yaml';\n\n/** Valid manifest source types for config validation (H-006). */\nconst VALID_SOURCES = new Set<ManifestSourceType>([\n 'auto',\n 'package.json',\n 'composer.json',\n 'Cargo.toml',\n 'pyproject.toml',\n 'pubspec.yaml',\n 'pom.xml',\n 'VERSION',\n 'git-tag',\n 'custom',\n]);\n\n/**\n * Known manifest detection entries, ordered by priority.\n *\n * When `source` is `'auto'`, the first entry whose file exists wins.\n */\nconst DETECTION_TABLE: {\n file: string;\n source: ManifestSourceType;\n factory: () => VersionSourceProvider;\n}[] = [\n {\n file: 'package.json',\n source: 'package.json',\n factory: () => new JsonVersionSource('package.json', 'version'),\n },\n {\n file: 'Cargo.toml',\n source: 'Cargo.toml',\n factory: () => new TomlVersionSource('Cargo.toml', 'package.version'),\n },\n {\n file: 'pyproject.toml',\n source: 'pyproject.toml',\n factory: () => new TomlVersionSource('pyproject.toml', 'project.version'),\n },\n {\n file: 'pubspec.yaml',\n source: 'pubspec.yaml',\n factory: () => new YamlVersionSource('pubspec.yaml', 'version'),\n },\n {\n file: 'composer.json',\n source: 'composer.json',\n factory: () => new JsonVersionSource('composer.json', 'version'),\n },\n {\n // H-002: Use regex that skips <parent> blocks for pom.xml\n file: 'pom.xml',\n source: 'pom.xml',\n factory: () =>\n new RegexVersionSource('pom.xml', '<project[^>]*>[\\\\s\\\\S]*?<version>([^<]+)</version>'),\n },\n { file: 'VERSION', source: 'VERSION', factory: () => new VersionFileSource('VERSION') },\n];\n\n/**\n * Validates that a file path does not escape the project directory (C-002).\n */\nfunction assertPathContained(manifestFile: string, cwd: string): void {\n const resolved = path.resolve(cwd, manifestFile);\n const root = path.resolve(cwd);\n if (!resolved.startsWith(`${root}${path.sep}`) && resolved !== root) {\n throw new Error(`Manifest path \"${manifestFile}\" resolves outside the project directory`);\n }\n}\n\n/**\n * Creates a provider for a specific manifest source type.\n */\nfunction createProvider(\n source: ManifestSourceType,\n config: ManifestConfig,\n cwd: string,\n): VersionSourceProvider {\n // H-006: Validate source type\n if (!VALID_SOURCES.has(source)) {\n throw new Error(\n `Invalid manifest source \"${source}\". Valid sources: ${[...VALID_SOURCES].join(', ')}`,\n );\n }\n\n switch (source) {\n case 'package.json':\n return new JsonVersionSource('package.json', config.path ?? 'version');\n case 'composer.json':\n return new JsonVersionSource('composer.json', config.path ?? 'version');\n case 'Cargo.toml':\n return new TomlVersionSource('Cargo.toml', config.path ?? 'package.version');\n case 'pyproject.toml':\n return new TomlVersionSource('pyproject.toml', config.path ?? 'project.version');\n case 'pubspec.yaml':\n return new YamlVersionSource('pubspec.yaml', config.path ?? 'version');\n case 'pom.xml':\n return new RegexVersionSource(\n 'pom.xml',\n config.regex ?? '<project[^>]*>[\\\\s\\\\S]*?<version>([^<]+)</version>',\n );\n case 'VERSION':\n return new VersionFileSource(config.path ?? 'VERSION');\n case 'git-tag':\n return new GitTagSource();\n case 'custom': {\n if (!config.regex) {\n throw new Error(\"Custom manifest source requires a 'regex' field in manifest config\");\n }\n if (!config.path) {\n throw new Error(\n \"Custom manifest source requires a 'path' field (manifest filename) in manifest config\",\n );\n }\n // C-002: Validate path containment for custom sources\n assertPathContained(config.path, cwd);\n return new RegexVersionSource(config.path, config.regex);\n }\n default:\n throw new Error(`Unknown manifest source: ${source}`);\n }\n}\n\n/**\n * Resolves the version source provider for a project.\n *\n * @remarks\n * When `source` is `'auto'`, scans the project directory for known manifest\n * files and returns the first match. Throws with helpful guidance if no\n * supported manifest is found.\n *\n * @param config - Manifest configuration from `.versionguard.yml`.\n * @param cwd - Project directory to scan.\n * @returns The resolved version source provider.\n *\n * @example\n * ```ts\n * import { resolveVersionSource } from './resolve';\n *\n * const provider = resolveVersionSource({ source: 'auto' }, process.cwd());\n * const version = provider.getVersion(process.cwd());\n * ```\n *\n * @public\n * @since 0.3.0\n */\nexport function resolveVersionSource(\n config: ManifestConfig,\n cwd: string = process.cwd(),\n): VersionSourceProvider {\n if (config.source !== 'auto') {\n return createProvider(config.source, config, cwd);\n }\n\n // Auto-detect: scan for known manifests in priority order\n for (const entry of DETECTION_TABLE) {\n const provider = entry.factory();\n if (provider.exists(cwd)) {\n return provider;\n }\n }\n\n // M-009: Throw immediately with helpful guidance instead of silent fallback\n const supported = DETECTION_TABLE.map((e) => e.file).join(', ');\n throw new Error(\n `No supported manifest file found in ${cwd}. ` +\n `Looked for: ${supported}. ` +\n `Set manifest.source explicitly in .versionguard.yml or create a supported manifest file.`,\n );\n}\n\n/**\n * Detects all manifest files present in a project directory.\n *\n * @remarks\n * Useful for polyglot projects that may have multiple version sources.\n * Scans the detection table in priority order and returns all matches.\n *\n * @param cwd - Project directory to scan.\n * @returns Array of detected manifest source types.\n *\n * @example\n * ```ts\n * import { detectManifests } from './resolve';\n *\n * const manifests = detectManifests(process.cwd());\n * // ['package.json', 'Cargo.toml']\n * ```\n *\n * @public\n * @since 0.3.0\n */\nexport function detectManifests(cwd: string = process.cwd()): ManifestSourceType[] {\n const detected: ManifestSourceType[] = [];\n\n for (const entry of DETECTION_TABLE) {\n const provider = entry.factory();\n if (provider.exists(cwd)) {\n detected.push(entry.source);\n }\n }\n\n return detected;\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { VersionSourceProvider } from './sources/provider';\nimport { resolveVersionSource } from './sources/resolve';\nimport type { ManifestConfig } from './types';\n\n/**\n * JSON-compatible scalar, array, or object value used by package metadata.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport type PackageJsonValue =\n | boolean\n | null\n | number\n | string\n | PackageJsonArray\n | PackageJsonObject;\n\n/**\n * Recursive array type used for arbitrary JSON-compatible package values.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport type PackageJsonArray = PackageJsonValue[];\n\n/**\n * Recursive object type used for arbitrary JSON-compatible package values.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface PackageJsonObject {\n [key: string]: PackageJsonValue;\n}\n\n/**\n * Minimal shape of a `package.json` document used by VersionGuard.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface PackageJson {\n /**\n * Package name.\n *\n * @defaultValue `undefined`\n */\n name?: string;\n /**\n * Package version string.\n *\n * @defaultValue `undefined`\n */\n version?: string;\n [key: string]: PackageJsonValue | undefined;\n}\n\n/**\n * Gets the `package.json` path for a project directory.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * This is a convenience helper used by the package read and write helpers.\n *\n * @param cwd - Project directory containing `package.json`.\n * @returns The resolved `package.json` path.\n * @example\n * ```ts\n * import { getPackageJsonPath } from 'versionguard';\n *\n * const packagePath = getPackageJsonPath(process.cwd());\n * ```\n */\nexport function getPackageJsonPath(cwd: string = process.cwd()): string {\n return path.join(cwd, 'package.json');\n}\n\n/**\n * Reads and parses a project's `package.json` file.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * An error is thrown when `package.json` does not exist in the requested\n * directory.\n *\n * @param cwd - Project directory containing `package.json`.\n * @returns The parsed `package.json` document.\n * @example\n * ```ts\n * import { readPackageJson } from 'versionguard';\n *\n * const pkg = readPackageJson(process.cwd());\n * ```\n */\nexport function readPackageJson(cwd: string = process.cwd()): PackageJson {\n const packagePath = getPackageJsonPath(cwd);\n\n if (!fs.existsSync(packagePath)) {\n throw new Error(`package.json not found in ${cwd}`);\n }\n\n return JSON.parse(fs.readFileSync(packagePath, 'utf-8')) as PackageJson;\n}\n\n/**\n * Writes a `package.json` document back to disk.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * Output is formatted with two-space indentation and always ends with a\n * trailing newline.\n *\n * @param pkg - Parsed `package.json` data to write.\n * @param cwd - Project directory containing `package.json`.\n * @example\n * ```ts\n * import { readPackageJson, writePackageJson } from 'versionguard';\n *\n * const pkg = readPackageJson(process.cwd());\n * writePackageJson(pkg, process.cwd());\n * ```\n */\nexport function writePackageJson(pkg: PackageJson, cwd: string = process.cwd()): void {\n fs.writeFileSync(getPackageJsonPath(cwd), `${JSON.stringify(pkg, null, 2)}\\n`, 'utf-8');\n}\n\n/**\n * Gets the version string from the project manifest.\n *\n * When a `manifest` config is provided, uses the configured version source\n * provider (auto-detection or explicit). Falls back to `package.json` for\n * backwards compatibility when no config is provided.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * This throws when the manifest file does not exist or does not contain\n * a version field.\n *\n * @param cwd - Project directory containing the manifest.\n * @param manifest - Optional manifest configuration for language-agnostic support.\n * @returns The project version string.\n * @example\n * ```ts\n * import { getPackageVersion } from 'versionguard';\n *\n * // Read from package.json (legacy fallback)\n * const version = getPackageVersion(process.cwd());\n *\n * // Read from a configured manifest source\n * const versionAlt = getPackageVersion(process.cwd(), { source: 'Cargo.toml' });\n * ```\n */\nexport function getPackageVersion(cwd: string = process.cwd(), manifest?: ManifestConfig): string {\n if (manifest) {\n const provider = resolveVersionSource(manifest, cwd);\n return provider.getVersion(cwd);\n }\n\n // Legacy fallback: read directly from package.json\n const pkg = readPackageJson(cwd);\n\n if (typeof pkg.version !== 'string' || pkg.version.length === 0) {\n throw new Error('No version field in package.json');\n }\n\n return pkg.version;\n}\n\n/**\n * Sets the version field in the project manifest.\n *\n * When a `manifest` config is provided, uses the configured version source\n * provider. Falls back to `package.json` for backwards compatibility when\n * no config is provided.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * The existing document is read, the version field is replaced, and the\n * file is written back to disk.\n *\n * @param version - Version string to persist.\n * @param cwd - Project directory containing the manifest.\n * @param manifest - Optional manifest configuration for language-agnostic support.\n * @example\n * ```ts\n * import { setPackageVersion } from 'versionguard';\n *\n * // Write to package.json (legacy fallback)\n * setPackageVersion('1.2.3', process.cwd());\n *\n * // Write to a configured manifest source\n * setPackageVersion('1.2.3', process.cwd(), { source: 'Cargo.toml' });\n * ```\n */\nexport function setPackageVersion(\n version: string,\n cwd: string = process.cwd(),\n manifest?: ManifestConfig,\n): void {\n if (manifest) {\n const provider = resolveVersionSource(manifest, cwd);\n provider.setVersion(version, cwd);\n return;\n }\n\n // Legacy fallback: write directly to package.json\n const pkg = readPackageJson(cwd);\n pkg.version = version;\n writePackageJson(pkg, cwd);\n}\n\n/**\n * Resolves the version source provider for a project.\n *\n * @remarks\n * Delegates to `resolveVersionSource` to create the appropriate provider\n * for the configured manifest type. Use this when you need direct access\n * to the provider's `exists`, `getVersion`, and `setVersion` methods.\n *\n * @param manifest - Manifest configuration.\n * @param cwd - Project directory.\n * @returns The resolved provider instance.\n *\n * @example\n * ```ts\n * import { getVersionSource } from 'versionguard';\n *\n * const source = getVersionSource({ source: 'package.json' }, process.cwd());\n * const version = source.getVersion(process.cwd());\n * ```\n *\n * @public\n * @since 0.3.0\n */\nexport function getVersionSource(\n manifest: ManifestConfig,\n cwd: string = process.cwd(),\n): VersionSourceProvider {\n return resolveVersionSource(manifest, cwd);\n}\n","/**\n * Semantic version parsing, validation, comparison, and increment helpers.\n *\n * @packageDocumentation\n */\n\nimport type { SemVer, ValidationError, ValidationResult } from './types';\n\nconst SEMVER_REGEX =\n /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/;\n\n/**\n * Parses a semantic version string.\n *\n * @remarks\n * This helper enforces the standard SemVer structure and returns `null` when the input does not\n * match. It preserves prerelease and build identifiers as ordered string segments.\n *\n * @param version - Version string to parse.\n * @returns Parsed semantic version components, or `null` when the input is invalid.\n *\n * @example\n * ```ts\n * import { parse } from 'versionguard';\n *\n * parse('1.2.3-alpha.1+build.5')?.prerelease;\n * // => ['alpha', '1']\n * ```\n *\n * @public\n * @since 0.1.0\n */\nexport function parse(version: string): SemVer | null {\n const match = version.match(SEMVER_REGEX);\n\n if (!match) {\n return null;\n }\n\n return {\n major: Number.parseInt(match[1], 10),\n minor: Number.parseInt(match[2], 10),\n patch: Number.parseInt(match[3], 10),\n prerelease: match[4] ? match[4].split('.') : [],\n build: match[5] ? match[5].split('.') : [],\n raw: version,\n };\n}\n\nfunction getStructuralErrors(version: string): ValidationError[] {\n const errors: ValidationError[] = [];\n\n if (version.startsWith('v')) {\n errors.push({\n message: `Version should not start with 'v': ${version}`,\n severity: 'error',\n });\n return errors;\n }\n\n const mainPart = version.split(/[+-]/, 1)[0];\n const segments = mainPart.split('.');\n if (segments.length === 3) {\n const leadingZeroSegment = segments.find((segment) => /^0\\d+$/.test(segment));\n if (leadingZeroSegment) {\n errors.push({\n message: `Invalid SemVer: numeric segment \"${leadingZeroSegment}\" has a leading zero`,\n severity: 'error',\n });\n return errors;\n }\n }\n\n const prerelease = version.match(/-([^+]+)/)?.[1];\n if (prerelease) {\n const invalidPrerelease = prerelease.split('.').find((segment) => /^0\\d+$/.test(segment));\n if (invalidPrerelease) {\n errors.push({\n message: `Invalid SemVer: prerelease identifier \"${invalidPrerelease}\" has a leading zero`,\n severity: 'error',\n });\n return errors;\n }\n }\n\n errors.push({\n message: `Invalid SemVer format: \"${version}\". Expected MAJOR.MINOR.PATCH[-prerelease][+build].`,\n severity: 'error',\n });\n return errors;\n}\n\n/**\n * Validates that a string is a supported semantic version.\n *\n * @remarks\n * When validation fails, the result includes targeted structural errors for common cases such as\n * leading `v` prefixes and numeric segments with leading zeroes.\n *\n * @param version - Version string to validate.\n * @returns A validation result containing any detected errors and the parsed version on success.\n *\n * @example\n * ```ts\n * import { validate } from 'versionguard';\n *\n * validate('1.2.3').valid;\n * // => true\n * ```\n *\n * @public\n * @since 0.1.0\n */\nexport function validate(version: string): ValidationResult {\n const parsed = parse(version);\n\n if (!parsed) {\n return {\n valid: false,\n errors: getStructuralErrors(version),\n };\n }\n\n return {\n valid: true,\n errors: [],\n version: { type: 'semver', version: parsed },\n };\n}\n\n/**\n * Compares two semantic version strings.\n *\n * @remarks\n * Comparison follows SemVer precedence rules, including special handling for prerelease\n * identifiers and ignoring build metadata.\n *\n * @param a - Left-hand version string.\n * @param b - Right-hand version string.\n * @returns `1` when `a` is greater, `-1` when `b` is greater, or `0` when they are equal.\n *\n * @example\n * ```ts\n * import { compare } from 'versionguard';\n *\n * compare('1.2.3', '1.2.3-alpha.1');\n * // => 1\n * ```\n *\n * @public\n * @since 0.1.0\n */\nexport function compare(a: string, b: string): number {\n const left = parse(a);\n const right = parse(b);\n\n if (!left || !right) {\n throw new Error(`Invalid SemVer comparison between \"${a}\" and \"${b}\"`);\n }\n\n for (const key of ['major', 'minor', 'patch'] as const) {\n if (left[key] !== right[key]) {\n return left[key] > right[key] ? 1 : -1;\n }\n }\n\n const leftHasPrerelease = left.prerelease.length > 0;\n const rightHasPrerelease = right.prerelease.length > 0;\n\n if (leftHasPrerelease && !rightHasPrerelease) {\n return -1;\n }\n\n if (!leftHasPrerelease && rightHasPrerelease) {\n return 1;\n }\n\n const length = Math.max(left.prerelease.length, right.prerelease.length);\n for (let index = 0; index < length; index += 1) {\n const leftValue = left.prerelease[index];\n const rightValue = right.prerelease[index];\n\n if (leftValue === undefined) {\n return -1;\n }\n\n if (rightValue === undefined) {\n return 1;\n }\n\n const leftNumeric = /^\\d+$/.test(leftValue) ? Number.parseInt(leftValue, 10) : null;\n const rightNumeric = /^\\d+$/.test(rightValue) ? Number.parseInt(rightValue, 10) : null;\n\n if (leftNumeric !== null && rightNumeric !== null) {\n if (leftNumeric !== rightNumeric) {\n return leftNumeric > rightNumeric ? 1 : -1;\n }\n continue;\n }\n\n if (leftNumeric !== null) {\n return -1;\n }\n\n if (rightNumeric !== null) {\n return 1;\n }\n\n if (leftValue !== rightValue) {\n return leftValue > rightValue ? 1 : -1;\n }\n }\n\n return 0;\n}\n\n/**\n * Checks whether one semantic version is greater than another.\n *\n * @remarks\n * This is a convenience wrapper around {@link compare} for callers that only need a boolean.\n *\n * @param a - Left-hand version string.\n * @param b - Right-hand version string.\n * @returns `true` when `a` has higher precedence than `b`.\n *\n * @example\n * ```ts\n * import { gt } from 'versionguard';\n *\n * gt('1.2.4', '1.2.3');\n * // => true\n * ```\n *\n * @see {@link compare} for full precedence ordering.\n * @public\n * @since 0.1.0\n */\nexport function gt(a: string, b: string): boolean {\n return compare(a, b) > 0;\n}\n\n/**\n * Checks whether one semantic version is less than another.\n *\n * @remarks\n * This is a convenience wrapper around {@link compare} for callers that only need a boolean.\n *\n * @param a - Left-hand version string.\n * @param b - Right-hand version string.\n * @returns `true` when `a` has lower precedence than `b`.\n *\n * @example\n * ```ts\n * import { lt } from 'versionguard';\n *\n * lt('1.2.3-alpha.1', '1.2.3');\n * // => true\n * ```\n *\n * @see {@link compare} for full precedence ordering.\n * @public\n * @since 0.1.0\n */\nexport function lt(a: string, b: string): boolean {\n return compare(a, b) < 0;\n}\n\n/**\n * Checks whether two semantic versions are equal in precedence.\n *\n * @remarks\n * This is a convenience wrapper around {@link compare}. Build metadata is ignored because\n * precedence comparisons in SemVer do not consider it.\n *\n * @param a - Left-hand version string.\n * @param b - Right-hand version string.\n * @returns `true` when both versions compare as equal.\n *\n * @example\n * ```ts\n * import { eq } from 'versionguard';\n *\n * eq('1.2.3', '1.2.3');\n * // => true\n * ```\n *\n * @see {@link compare} for full precedence ordering.\n * @public\n * @since 0.1.0\n */\nexport function eq(a: string, b: string): boolean {\n return compare(a, b) === 0;\n}\n\n/**\n * Increments a semantic version string by release type.\n *\n * @remarks\n * Incrementing `major` or `minor` resets lower-order numeric segments. When a prerelease label is\n * provided, it is appended to the newly generated version.\n *\n * @param version - Current semantic version string.\n * @param release - Segment to increment.\n * @param prerelease - Optional prerelease suffix to append to the next version.\n * @returns The incremented semantic version string.\n *\n * @example\n * ```ts\n * import { increment } from 'versionguard';\n *\n * increment('1.2.3', 'minor', 'beta.1');\n * // => '1.3.0-beta.1'\n * ```\n *\n * @public\n * @since 0.1.0\n */\nexport function increment(\n version: string,\n release: 'major' | 'minor' | 'patch',\n prerelease?: string,\n): string {\n const parsed = parse(version);\n\n if (!parsed) {\n throw new Error(`Invalid SemVer version: ${version}`);\n }\n\n if (release === 'major') {\n return `${parsed.major + 1}.0.0${prerelease ? `-${prerelease}` : ''}`;\n }\n\n if (release === 'minor') {\n return `${parsed.major}.${parsed.minor + 1}.0${prerelease ? `-${prerelease}` : ''}`;\n }\n\n return `${parsed.major}.${parsed.minor}.${parsed.patch + 1}${prerelease ? `-${prerelease}` : ''}`;\n}\n\n/**\n * Formats a parsed semantic version object.\n *\n * @remarks\n * Prerelease and build metadata segments are only included when their arrays contain values.\n *\n * @param version - Parsed semantic version to serialize.\n * @returns The normalized semantic version string.\n *\n * @example\n * ```ts\n * import { format } from 'versionguard';\n *\n * const version = { major: 1, minor: 2, patch: 3, prerelease: ['rc', '1'], build: ['build', '5'], raw: '1.2.3-rc.1+build.5' };\n *\n * format(version);\n * // => '1.2.3-rc.1+build.5'\n * ```\n *\n * @public\n * @since 0.1.0\n */\nexport function format(version: SemVer): string {\n let output = `${version.major}.${version.minor}.${version.patch}`;\n\n if (version.prerelease.length > 0) {\n output += `-${version.prerelease.join('.')}`;\n }\n\n if (version.build.length > 0) {\n output += `+${version.build.join('.')}`;\n }\n\n return output;\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport { globSync } from 'glob';\n\nimport type { SyncConfig, SyncPattern, SyncResult, VersionMismatch } from './types';\n\nfunction resolveFiles(patterns: string[], cwd: string, ignore: string[] = []): string[] {\n return [\n ...new Set(patterns.flatMap((pattern) => globSync(pattern, { cwd, absolute: true, ignore }))),\n ].sort();\n}\n\nfunction getLineNumber(content: string, offset: number): number {\n return content.slice(0, offset).split('\\n').length;\n}\n\nfunction extractVersion(groups: string[]): string {\n return groups[1] ?? groups[0] ?? '';\n}\n\nfunction applyTemplate(template: string, groups: string[], version: string): string {\n return template.replace(/\\$(\\d+)|\\{\\{version\\}\\}/g, (match, groupIndex: string | undefined) => {\n if (match === '{{version}}') {\n return version;\n }\n\n return groups[Number.parseInt(groupIndex ?? '0', 10) - 1] ?? '';\n });\n}\n\nfunction stringifyCapture(value: unknown): string {\n return typeof value === 'string' ? value : '';\n}\n\n/**\n * Synchronizes configured files to a single version string.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * File globs are resolved relative to `cwd`, then each matched file is updated\n * with the configured replacement patterns.\n *\n * @param version - Version string to write into matching files.\n * @param config - Sync configuration describing files and replacement patterns.\n * @param cwd - Project directory used to resolve file globs.\n * @returns A sync result for each resolved file.\n * @example\n * ```ts\n * import { getDefaultConfig, syncVersion } from 'versionguard';\n *\n * const results = syncVersion('1.2.3', getDefaultConfig().sync, process.cwd());\n * ```\n */\nexport function syncVersion(\n version: string,\n config: SyncConfig,\n cwd: string = process.cwd(),\n): SyncResult[] {\n return resolveFiles(config.files, cwd).map((filePath) =>\n syncFile(filePath, version, config.patterns),\n );\n}\n\n/**\n * Synchronizes a single file to a target version.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * Each configured regex is applied globally, and `{{version}}` placeholders in\n * templates are replaced with the supplied version.\n *\n * @param filePath - Absolute or relative path to the file to update.\n * @param version - Version string to write.\n * @param patterns - Replacement patterns to apply.\n * @returns A result describing whether the file changed and what changed.\n * @example\n * ```ts\n * import { getDefaultConfig, syncFile } from 'versionguard';\n *\n * const result = syncFile('README.md', '1.2.3', getDefaultConfig().sync.patterns);\n * ```\n */\nexport function syncFile(filePath: string, version: string, patterns: SyncPattern[]): SyncResult {\n const original = fs.readFileSync(filePath, 'utf-8');\n let updatedContent = original;\n const changes: SyncResult['changes'] = [];\n\n for (const pattern of patterns) {\n const regex = new RegExp(pattern.regex, 'gm');\n updatedContent = updatedContent.replace(regex, (match, ...args: unknown[]) => {\n const hasNamedGroups = typeof args.at(-1) === 'object' && args.at(-1) !== null;\n const offsetIndex = hasNamedGroups ? -3 : -2;\n const offset = args.at(offsetIndex) as number;\n const groups = args.slice(0, offsetIndex).map((value) => stringifyCapture(value));\n const found = extractVersion(groups);\n\n if (found === 'Unreleased') {\n return match;\n }\n\n if (found !== version) {\n changes.push({\n line: getLineNumber(updatedContent, offset),\n oldValue: found,\n newValue: version,\n });\n }\n\n return applyTemplate(pattern.template, groups, version) || match;\n });\n }\n\n const result: SyncResult = {\n file: filePath,\n updated: updatedContent !== original,\n changes,\n };\n\n if (result.updated) {\n fs.writeFileSync(filePath, updatedContent, 'utf-8');\n }\n\n return result;\n}\n\n/**\n * Checks configured files for hardcoded version mismatches.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * Files matching the sync config are scanned without modification, and every\n * captured version that differs from `expectedVersion` is returned.\n *\n * @param expectedVersion - Version all matching entries should use.\n * @param config - Sync configuration describing files and replacement patterns.\n * @param ignorePatterns - Glob patterns to exclude while scanning.\n * @param cwd - Project directory used to resolve file globs.\n * @returns A list of detected version mismatches.\n * @example\n * ```ts\n * import { checkHardcodedVersions, getDefaultConfig } from 'versionguard';\n *\n * const mismatches = checkHardcodedVersions(\n * '1.2.3',\n * getDefaultConfig().sync,\n * getDefaultConfig().ignore,\n * process.cwd(),\n * );\n * ```\n */\nexport function checkHardcodedVersions(\n expectedVersion: string,\n config: SyncConfig,\n ignorePatterns: string[],\n cwd: string = process.cwd(),\n): VersionMismatch[] {\n const mismatches: VersionMismatch[] = [];\n const files = resolveFiles(config.files, cwd, ignorePatterns);\n\n for (const filePath of files) {\n const content = fs.readFileSync(filePath, 'utf-8');\n\n for (const pattern of config.patterns) {\n const regex = new RegExp(pattern.regex, 'gm');\n let match: RegExpExecArray | null = regex.exec(content);\n\n while (match) {\n const found = extractVersion(match.slice(1));\n if (found !== 'Unreleased' && found !== expectedVersion) {\n mismatches.push({\n file: path.relative(cwd, filePath),\n line: getLineNumber(content, match.index),\n found,\n });\n }\n match = regex.exec(content);\n }\n }\n }\n\n return mismatches;\n}\n","/**\n * Shared public types for version parsing, validation, and configuration.\n *\n * @packageDocumentation\n */\n\n/**\n * Supported versioning strategies.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport type VersioningType = 'semver' | 'calver';\n\n/**\n * Supported manifest source types for version extraction.\n *\n * @public\n * @since 0.3.0\n * @forgeIgnore E020\n */\nexport type ManifestSourceType =\n | 'auto'\n | 'package.json'\n | 'composer.json'\n | 'Cargo.toml'\n | 'pyproject.toml'\n | 'pubspec.yaml'\n | 'pom.xml'\n | 'VERSION'\n | 'git-tag'\n | 'custom';\n\n/**\n * Configures the version source manifest.\n *\n * @public\n * @since 0.3.0\n * @forgeIgnore E020\n */\nexport interface ManifestConfig {\n /**\n * Manifest file to read the version from.\n *\n * Use `'auto'` for file-existence detection or a specific filename.\n *\n * @defaultValue 'auto'\n */\n source: ManifestSourceType;\n\n /**\n * Dotted key path to the version field within the manifest.\n *\n * For example `'version'` for package.json, `'package.version'` for Cargo.toml,\n * or `'project.version'` for pyproject.toml.\n *\n * @defaultValue undefined (uses the provider's built-in default)\n */\n path?: string;\n\n /**\n * Regex pattern to extract the version from source-code manifests.\n *\n * Capture group 1 must contain the version string.\n *\n * @defaultValue undefined\n */\n regex?: string;\n}\n\n/**\n * Valid CalVer token names for building format strings.\n *\n * @public\n * @since 0.3.0\n * @forgeIgnore E020\n */\nexport type CalVerToken =\n | 'YYYY'\n | 'YY'\n | '0Y' // Year\n | 'MM'\n | 'M'\n | '0M' // Month\n | 'WW'\n | '0W' // Week\n | 'DD'\n | 'D'\n | '0D' // Day\n | 'MICRO'\n | 'PATCH'; // Counter (MICRO is the CalVer-standard name; PATCH is the SemVer alias)\n\n/**\n * A CalVer format string composed of dot-separated tokens.\n *\n * @remarks\n * Any dot-separated combination of valid {@link CalVerToken} values is accepted.\n * Common examples: `'YYYY.MM.MICRO'`, `'YY.0M.MICRO'`, `'YYYY.0M.0D'`, `'YYYY.MM.DD.MICRO'`.\n *\n * `MICRO` and `PATCH` are interchangeable — both represent a 0-based incrementing counter.\n * The CalVer specification (calver.org) uses `MICRO`; `PATCH` is accepted as a SemVer-familiar alias.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport type CalVerFormat = string & { readonly __calverFormat?: never };\n\n/**\n * Configures scheme-level validation rules applied regardless of versioning type.\n *\n * @public\n * @since 0.3.0\n * @forgeIgnore E020\n */\nexport interface SchemeRules {\n /**\n * Maximum number of numeric segments before a warning is emitted.\n *\n * Convention is 3 (e.g., `YYYY.MM.MICRO`). Formats with 4+ segments\n * (e.g., `YYYY.0M.0D.MICRO`) are valid but trigger a warning.\n *\n * @defaultValue 3\n */\n maxNumericSegments: number;\n\n /**\n * Allowed pre-release modifier tags.\n *\n * When set, version modifiers (e.g., `-alpha`, `-rc1`) are validated\n * against this whitelist. An empty array disallows all modifiers.\n *\n * @defaultValue ['dev', 'alpha', 'beta', 'rc']\n */\n allowedModifiers: string[];\n}\n\n/**\n * Configures CalVer validation rules.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface CalVerConfig {\n /**\n * Calendar format used when parsing and validating versions.\n */\n format: CalVerFormat;\n\n /**\n * Rejects versions that point to a future date.\n *\n * @defaultValue true\n */\n preventFutureDates: boolean;\n\n /**\n * Enforces that week tokens (WW/0W) cannot be mixed with month/day tokens.\n *\n * @defaultValue true\n */\n strictMutualExclusion?: boolean;\n}\n\n/**\n * Describes a search-and-replace pattern used during version synchronization.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface SyncPattern {\n /**\n * Regular expression string used to locate a version value.\n */\n regex: string;\n\n /**\n * Replacement template applied when a match is updated.\n */\n template: string;\n}\n\n/**\n * Configures files and patterns that should stay in sync with the canonical version.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface SyncConfig {\n /**\n * File globs or paths that should be scanned for version updates.\n */\n files: string[];\n\n /**\n * Replacement patterns applied to matching files.\n */\n patterns: SyncPattern[];\n}\n\n/**\n * Controls changelog validation behavior.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface ChangelogConfig {\n /**\n * Enables changelog validation.\n *\n * @defaultValue false\n */\n enabled: boolean;\n\n /**\n * Path to the changelog file to inspect.\n */\n file: string;\n\n /**\n * Treats changelog problems as hard failures.\n *\n * @defaultValue false\n */\n strict: boolean;\n\n /**\n * Requires an entry for the current version.\n *\n * @defaultValue false\n */\n requireEntry: boolean;\n}\n\n/**\n * Toggles each supported git hook integration.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface GitHooksConfig {\n /**\n * Enables validation during the `pre-commit` hook.\n *\n * @defaultValue false\n */\n 'pre-commit': boolean;\n\n /**\n * Enables validation during the `pre-push` hook.\n *\n * @defaultValue false\n */\n 'pre-push': boolean;\n\n /**\n * Enables follow-up tasks after a tag is created.\n *\n * @defaultValue false\n */\n 'post-tag': boolean;\n}\n\n/**\n * Configures git-related enforcement.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface GitConfig {\n /**\n * Hook toggles used by the CLI and validation workflow.\n */\n hooks: GitHooksConfig;\n\n /**\n * Fails validation when required hooks are missing.\n *\n * @defaultValue false\n */\n enforceHooks: boolean;\n}\n\n/**\n * Configures the active versioning mode.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface VersioningConfig {\n /**\n * Versioning strategy used for the project.\n */\n type: VersioningType;\n\n /**\n * Scheme-level validation rules applied regardless of versioning type.\n *\n * @defaultValue `{ maxNumericSegments: 3, allowedModifiers: ['dev', 'alpha', 'beta', 'rc'] }`\n */\n schemeRules?: SchemeRules;\n\n /**\n * CalVer-specific settings when `type` is `'calver'`.\n *\n * @defaultValue undefined\n */\n calver?: CalVerConfig;\n}\n\n/**\n * Top-level configuration consumed by versionguard.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface VersionGuardConfig {\n /**\n * Active versioning settings.\n */\n versioning: VersioningConfig;\n\n /**\n * Version source manifest settings.\n *\n * @defaultValue `{ source: 'auto' }`\n */\n manifest: ManifestConfig;\n\n /**\n * Synchronization settings for mirrored version strings.\n */\n sync: SyncConfig;\n\n /**\n * Changelog validation settings.\n */\n changelog: ChangelogConfig;\n\n /**\n * Git enforcement settings.\n */\n git: GitConfig;\n\n /**\n * Files or patterns excluded from validation.\n */\n ignore: string[];\n}\n\n/**\n * Extracts the CalVer config from a VersionGuard config, throwing if missing.\n *\n * @remarks\n * This is a convenience helper that validates the `calver` block exists\n * before returning it. Use this instead of accessing `config.versioning.calver`\n * directly to get a clear error when the config is misconfigured.\n *\n * @param config - The full VersionGuard configuration object.\n * @returns The validated CalVer configuration.\n *\n * @example\n * ```ts\n * import { getCalVerConfig } from './types';\n *\n * const calver = getCalVerConfig(config);\n * console.log(calver.format); // 'YYYY.MM.DD'\n * ```\n *\n * @public\n * @since 0.3.0\n */\nexport function getCalVerConfig(config: VersionGuardConfig): CalVerConfig {\n if (!config.versioning.calver) {\n throw new Error('CalVer configuration is required when versioning.type is \"calver\"');\n }\n return config.versioning.calver;\n}\n\n/**\n * Parsed semantic version components.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface SemVer {\n /**\n * Major version number.\n */\n major: number;\n\n /**\n * Minor version number.\n */\n minor: number;\n\n /**\n * Patch version number.\n */\n patch: number;\n\n /**\n * Ordered prerelease identifiers.\n *\n * @defaultValue []\n */\n prerelease: string[];\n\n /**\n * Ordered build metadata identifiers.\n *\n * @defaultValue []\n */\n build: string[];\n\n /**\n * Original version string.\n */\n raw: string;\n}\n\n/**\n * Parsed calendar version components.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface CalVer {\n /**\n * Four-digit year value.\n */\n year: number;\n\n /**\n * Month or week value (1-12 for months, 1-53 for weeks).\n */\n month: number;\n\n /**\n * Day-of-month value when the selected format includes a day token.\n *\n * @defaultValue undefined\n */\n day?: number;\n\n /**\n * Micro/patch counter when the selected format includes a counter token.\n *\n * @defaultValue undefined\n */\n patch?: number;\n\n /**\n * Pre-release modifier string (e.g., `'alpha'`, `'rc1'`, `'dev'`).\n *\n * @defaultValue undefined\n */\n modifier?: string;\n\n /**\n * Source format used to interpret the raw string.\n */\n format: CalVerFormat;\n\n /**\n * Original version string.\n */\n raw: string;\n}\n\n/**\n * Parsed semantic version result wrapper.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface ParsedSemVer {\n /**\n * Discriminator for semantic version results.\n */\n type: 'semver';\n\n /**\n * Parsed semantic version value.\n */\n version: SemVer;\n}\n\n/**\n * Parsed calendar version result wrapper.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface ParsedCalVer {\n /**\n * Discriminator for calendar version results.\n */\n type: 'calver';\n\n /**\n * Parsed calendar version value.\n */\n version: CalVer;\n}\n\n/**\n * Union of supported parsed version payloads.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport type ParsedVersion = ParsedSemVer | ParsedCalVer;\n\n/**\n * Describes a single validation problem.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface ValidationError {\n /**\n * Source file associated with the error when available.\n *\n * @defaultValue undefined\n */\n file?: string;\n\n /**\n * One-based source line associated with the error when available.\n *\n * @defaultValue undefined\n */\n line?: number;\n\n /**\n * Human-readable validation message.\n */\n message: string;\n\n /**\n * Severity of the reported problem.\n */\n severity: 'error' | 'warning';\n}\n\n/**\n * Result returned by version parsing and validation helpers.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface ValidationResult {\n /**\n * Indicates whether validation completed without errors.\n */\n valid: boolean;\n\n /**\n * Collected validation issues.\n */\n errors: ValidationError[];\n\n /**\n * Parsed version details when validation succeeds.\n *\n * @defaultValue undefined\n */\n version?: ParsedVersion;\n}\n\n/**\n * Describes a single in-file version replacement.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface SyncChange {\n /**\n * One-based line number where the replacement occurred.\n */\n line: number;\n\n /**\n * Previously matched value.\n */\n oldValue: string;\n\n /**\n * Replacement value written to the file.\n */\n newValue: string;\n}\n\n/**\n * Reports the result of synchronizing a single file.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface SyncResult {\n /**\n * File that was inspected or updated.\n */\n file: string;\n\n /**\n * Indicates whether the file content changed.\n */\n updated: boolean;\n\n /**\n * Detailed replacements applied within the file.\n */\n changes: SyncChange[];\n}\n\n/**\n * Reports a discovered version mismatch.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface VersionMismatch {\n /**\n * File containing the mismatched value.\n */\n file: string;\n\n /**\n * One-based line number of the mismatch.\n */\n line: number;\n\n /**\n * Version string found in the file.\n */\n found: string;\n}\n\n/**\n * Combined result from a full project validation run.\n *\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface FullValidationResult {\n /**\n * Indicates whether all checks passed.\n */\n valid: boolean;\n\n /**\n * Canonical version string used for validation.\n */\n version: string;\n\n /**\n * Indicates whether the root version string is valid.\n */\n versionValid: boolean;\n\n /**\n * Indicates whether synchronized files are in sync.\n */\n syncValid: boolean;\n\n /**\n * Indicates whether changelog checks passed.\n */\n changelogValid: boolean;\n\n /**\n * Human-readable validation failures collected during the run.\n */\n errors: string[];\n}\n\n/**\n * Reports whether a project is ready to pass VersionGuard checks.\n *\n * @packageDocumentation\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface DoctorReport {\n /**\n * Indicates whether all doctor checks passed.\n */\n ready: boolean;\n\n /**\n * Package version resolved from the configured manifest source.\n */\n version: string;\n\n /**\n * Indicates whether the package version matches the configured scheme.\n */\n versionValid: boolean;\n\n /**\n * Indicates whether synced files match the package version.\n */\n syncValid: boolean;\n\n /**\n * Indicates whether changelog validation passed.\n */\n changelogValid: boolean;\n\n /**\n * Indicates whether the current working directory is inside a Git repository.\n */\n gitRepository: boolean;\n\n /**\n * Indicates whether VersionGuard-managed Git hooks are installed.\n */\n hooksInstalled: boolean;\n\n /**\n * Indicates whether `git status --porcelain` reports a clean worktree.\n */\n worktreeClean: boolean;\n\n /**\n * Human-readable validation and readiness errors.\n */\n errors: string[];\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport * as yaml from 'js-yaml';\n\nimport type { VersionGuardConfig } from './types';\n\nconst CONFIG_FILE_NAMES = [\n '.versionguard.yml',\n '.versionguard.yaml',\n 'versionguard.yml',\n 'versionguard.yaml',\n];\n\nconst DEFAULT_CONFIG: VersionGuardConfig = {\n versioning: {\n type: 'semver',\n schemeRules: {\n maxNumericSegments: 3,\n allowedModifiers: ['dev', 'alpha', 'beta', 'rc'],\n },\n calver: {\n format: 'YYYY.MM.PATCH',\n preventFutureDates: true,\n strictMutualExclusion: true,\n },\n },\n manifest: {\n source: 'auto',\n },\n sync: {\n files: ['README.md', 'CHANGELOG.md'],\n patterns: [\n {\n regex: '(version\\\\s*[=:]\\\\s*[\"\\'])(.+?)([\"\\'])',\n template: '$1{{version}}$3',\n },\n {\n regex: '(##\\\\s*\\\\[)(.+?)(\\\\])',\n template: '$1{{version}}$3',\n },\n ],\n },\n changelog: {\n enabled: true,\n file: 'CHANGELOG.md',\n strict: true,\n requireEntry: true,\n },\n git: {\n hooks: {\n 'pre-commit': true,\n 'pre-push': true,\n 'post-tag': true,\n },\n enforceHooks: true,\n },\n ignore: ['node_modules/**', 'dist/**', '.git/**', '*.lock', 'package-lock.json'],\n};\n\nconst MODULE_DIR = path.dirname(fileURLToPath(import.meta.url));\n\n/**\n * Returns a deep-cloned copy of the built-in VersionGuard configuration.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * A fresh clone is returned so callers can safely modify the result without\n * mutating shared defaults.\n *\n * @returns The default VersionGuard configuration.\n * @example\n * ```ts\n * import { getDefaultConfig } from 'versionguard';\n *\n * const config = getDefaultConfig();\n * ```\n */\nexport function getDefaultConfig(): VersionGuardConfig {\n return structuredClone(DEFAULT_CONFIG);\n}\n\n/**\n * Finds the first supported VersionGuard config file in a directory.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * Search order follows `CONFIG_FILE_NAMES`, so `.versionguard.yml` takes\n * precedence over the other supported filenames.\n *\n * @param cwd - Directory to search.\n * @returns The resolved config path, or `null` when no config file exists.\n * @example\n * ```ts\n * import { findConfig } from 'versionguard';\n *\n * const configPath = findConfig(process.cwd());\n * ```\n */\nexport function findConfig(cwd: string = process.cwd()): string | null {\n for (const fileName of CONFIG_FILE_NAMES) {\n const fullPath = path.join(cwd, fileName);\n if (fs.existsSync(fullPath)) {\n return fullPath;\n }\n }\n\n return null;\n}\n\n/**\n * Loads a VersionGuard config file from disk.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * The parsed YAML object is merged with the built-in defaults so omitted keys\n * inherit their default values.\n *\n * @param configPath - Path to the YAML config file.\n * @returns The merged VersionGuard configuration.\n * @example\n * ```ts\n * import { loadConfig } from 'versionguard';\n *\n * const config = loadConfig('.versionguard.yml');\n * ```\n */\nexport function loadConfig(configPath: string): VersionGuardConfig {\n const content = fs.readFileSync(configPath, 'utf-8');\n const parsed = yaml.load(content);\n\n if (parsed === undefined) {\n return getDefaultConfig();\n }\n\n if (!isPlainObject(parsed)) {\n throw new Error(`Config file must contain a YAML object: ${configPath}`);\n }\n\n return mergeDeep(getDefaultConfig(), parsed);\n}\n\n/**\n * Resolves the active VersionGuard configuration for a project.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * If no config file is present, this falls back to the built-in defaults.\n *\n * @param cwd - Project directory to inspect.\n * @returns The resolved VersionGuard configuration.\n * @example\n * ```ts\n * import { getConfig } from 'versionguard';\n *\n * const config = getConfig(process.cwd());\n * ```\n */\nexport function getConfig(cwd: string = process.cwd()): VersionGuardConfig {\n const configPath = findConfig(cwd);\n return configPath ? loadConfig(configPath) : getDefaultConfig();\n}\n\n/**\n * Initializes a new VersionGuard config file in a project.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * This writes `.versionguard.yml` using the bundled example when available,\n * otherwise it writes a generated default configuration.\n *\n * @param cwd - Project directory where the config should be created.\n * @returns The path to the created config file.\n * @example\n * ```ts\n * import { initConfig } from 'versionguard';\n *\n * const configPath = initConfig(process.cwd());\n * ```\n */\nexport function initConfig(cwd: string = process.cwd()): string {\n const configPath = path.join(cwd, '.versionguard.yml');\n const existingConfigPath = findConfig(cwd);\n\n if (existingConfigPath) {\n throw new Error(`Config file already exists: ${existingConfigPath}`);\n }\n\n const examplePath = path.join(MODULE_DIR, '..', '.versionguard.yml.example');\n const content = fs.existsSync(examplePath)\n ? fs.readFileSync(examplePath, 'utf-8')\n : generateDefaultConfig();\n\n fs.writeFileSync(configPath, content, 'utf-8');\n return configPath;\n}\n\nfunction generateDefaultConfig(): string {\n return `# VersionGuard Configuration\nversioning:\n type: semver\n\nsync:\n files:\n - \"README.md\"\n - \"CHANGELOG.md\"\n patterns:\n - regex: '(version\\\\s*[=:]\\\\s*[\"''])(.+?)([\"''])'\n template: '$1{{version}}$3'\n - regex: '(##\\\\s*\\\\[)(.+?)(\\\\])'\n template: '$1{{version}}$3'\n\nchangelog:\n enabled: true\n file: \"CHANGELOG.md\"\n strict: true\n requireEntry: true\n\ngit:\n hooks:\n pre-commit: true\n pre-push: true\n post-tag: true\n enforceHooks: true\n\nignore:\n - \"node_modules/**\"\n - \"dist/**\"\n - \".git/**\"\n`;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction mergeDeep<T>(target: T, source: Partial<T>): T {\n /* v8 ignore next 3 -- defensive fallback for non-object nested overrides */\n if (!isPlainObject(target) || !isPlainObject(source)) {\n return (source ?? target) as T;\n }\n\n const output: Record<string, unknown> = { ...target };\n\n for (const [key, value] of Object.entries(source)) {\n const current = output[key];\n output[key] =\n isPlainObject(current) && isPlainObject(value) ? mergeDeep(current, value) : value;\n }\n\n return output as T;\n}\n","import * as calver from '../calver';\nimport * as semver from '../semver';\n\nimport {\n type CalVer,\n type CalVerConfig,\n getCalVerConfig,\n type ValidationError,\n type VersionGuardConfig,\n} from '../types';\n\n/**\n * Feedback helpers that turn validation failures into actionable suggestions.\n *\n * @packageDocumentation\n * @public\n */\n\n/**\n * Feedback entry point exports for suggestion and guidance helpers.\n *\n * @packageDocumentation\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface Suggestion {\n /**\n * Human-readable guidance for the user.\n */\n message: string;\n\n /**\n * Command or action text that can be used to address the issue.\n *\n * @defaultValue `undefined`\n */\n fix?: string;\n\n /**\n * Indicates whether VersionGuard can apply the suggestion automatically.\n */\n autoFixable: boolean;\n}\n\n/**\n * Aggregates validation errors with suggested next steps.\n *\n * @public\n * @since 0.1.0\n */\nexport interface FeedbackResult {\n /**\n * Indicates whether the inspected version state is valid.\n */\n valid: boolean;\n\n /**\n * Validation errors collected during the check.\n */\n errors: ValidationError[];\n\n /**\n * Suggested next steps for resolving the reported issues.\n */\n suggestions: Suggestion[];\n\n /**\n * Indicates whether at least one suggestion can be auto-applied.\n */\n canAutoFix: boolean;\n}\n\n/**\n * Generates actionable feedback for a version string.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * This helper dispatches to the SemVer or CalVer feedback flow based on the\n * configured versioning strategy and returns both hard validation errors and\n * softer suggestions for likely fixes.\n *\n * @param version - Version string to evaluate.\n * @param config - Loaded VersionGuard configuration.\n * @param previousVersion - Optional previous version used for progression checks.\n * @returns A feedback object with validation errors and suggested fixes.\n *\n * @example\n * ```typescript\n * const feedbackResult = getVersionFeedback('1.2.3', config, '1.2.2');\n * console.log(feedbackResult.valid);\n * ```\n */\nexport function getVersionFeedback(\n version: string,\n config: VersionGuardConfig,\n previousVersion?: string,\n): FeedbackResult {\n if (config.versioning.type === 'semver') {\n return getSemVerFeedback(version, previousVersion);\n }\n\n return getCalVerFeedback(version, getCalVerConfig(config), previousVersion);\n}\n\nfunction getSemVerFeedback(version: string, previousVersion?: string): FeedbackResult {\n const errors: ValidationError[] = [];\n const suggestions: Suggestion[] = [];\n\n // Try to parse\n const parsed = semver.parse(version);\n\n if (!parsed) {\n const validation = semver.validate(version);\n\n // Common mistakes\n if (version.startsWith('v')) {\n const cleanVersion = version.slice(1);\n errors.push({\n message: `Version should not start with 'v': ${version}`,\n severity: 'error',\n });\n suggestions.push({\n message: `Remove the 'v' prefix`,\n fix: `npx versionguard fix --version ${cleanVersion}`,\n autoFixable: true,\n });\n } else if (version.split('.').length === 2) {\n errors.push({\n message: `Version missing patch number: ${version}`,\n severity: 'error',\n });\n suggestions.push({\n message: `Add patch number (e.g., ${version}.0)`,\n fix: `npx versionguard fix --version ${version}.0`,\n autoFixable: true,\n });\n } else if (/^\\d+\\.\\d+\\.\\d+\\.\\d+$/.test(version)) {\n errors.push({\n message: `Version has too many segments: ${version}`,\n severity: 'error',\n });\n suggestions.push({\n message: `Use only 3 segments (MAJOR.MINOR.PATCH)`,\n autoFixable: false,\n });\n } else if (validation.errors.some((error) => error.message.includes('leading zero'))) {\n errors.push(...validation.errors);\n suggestions.push({\n message: `Remove leading zeros (e.g., 1.2.3 instead of 01.02.03)`,\n autoFixable: false,\n });\n } else {\n errors.push(\n ...(validation.errors.length > 0\n ? validation.errors\n : [\n {\n message: `Invalid SemVer format: ${version}`,\n severity: 'error' as const,\n },\n ]),\n );\n suggestions.push({\n message: `Use format: MAJOR.MINOR.PATCH (e.g., 1.0.0)`,\n autoFixable: false,\n });\n }\n\n return {\n valid: false,\n errors,\n suggestions,\n canAutoFix: suggestions.some((s) => s.autoFixable),\n };\n }\n\n // Check progression from previous version\n if (previousVersion) {\n const prevParsed = semver.parse(previousVersion);\n if (prevParsed) {\n const comparison = semver.compare(version, previousVersion);\n\n if (comparison < 0) {\n errors.push({\n message: `Version ${version} is older than previous ${previousVersion}`,\n severity: 'error',\n });\n suggestions.push({\n message: `Version must be greater than ${previousVersion}`,\n fix: `npx versionguard fix --version ${semver.increment(previousVersion, 'patch')}`,\n autoFixable: true,\n });\n } else if (comparison === 0) {\n errors.push({\n message: `Version ${version} is the same as previous`,\n severity: 'error',\n });\n suggestions.push({\n message: `Bump the version`,\n fix: `npx versionguard fix --version ${semver.increment(previousVersion, 'patch')}`,\n autoFixable: true,\n });\n } else {\n // Check if it's a reasonable jump\n const majorJump = parsed.major - prevParsed.major;\n const minorJump = parsed.minor - prevParsed.minor;\n const patchJump = parsed.patch - prevParsed.patch;\n\n if (majorJump > 1) {\n suggestions.push({\n message: `⚠️ Major version jumped by ${majorJump} (from ${previousVersion} to ${version})`,\n autoFixable: false,\n });\n }\n\n if (minorJump > 10) {\n suggestions.push({\n message: `⚠️ Minor version jumped by ${minorJump} - did you mean to do a major bump?`,\n autoFixable: false,\n });\n }\n\n if (patchJump > 20) {\n suggestions.push({\n message: `⚠️ Patch version jumped by ${patchJump} - consider a minor bump instead`,\n autoFixable: false,\n });\n }\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n suggestions,\n canAutoFix: suggestions.some((s) => s.autoFixable),\n };\n}\n\nfunction getCalVerFeedback(\n version: string,\n calverConfig: CalVerConfig,\n previousVersion?: string,\n): FeedbackResult {\n const errors: ValidationError[] = [];\n const suggestions: Suggestion[] = [];\n const { format, preventFutureDates } = calverConfig;\n\n const parsed = calver.parse(version, format);\n\n if (!parsed) {\n errors.push({\n message: `Invalid CalVer format: ${version}`,\n severity: 'error',\n });\n suggestions.push({\n message: `Expected format: ${format}`,\n fix: `Update version to current date: \"${calver.getCurrentVersion(format)}\"`,\n autoFixable: true,\n });\n return { valid: false, errors, suggestions, canAutoFix: true };\n }\n\n const validation = calver.validate(version, format, preventFutureDates);\n errors.push(...validation.errors);\n\n const now = new Date();\n if (validation.errors.some((error) => error.message.startsWith('Invalid month:'))) {\n suggestions.push({\n message: `Month must be between 1-12`,\n autoFixable: false,\n });\n }\n\n if (validation.errors.some((error) => error.message.startsWith('Invalid day:'))) {\n suggestions.push({\n message: `Day must be valid for the selected month`,\n autoFixable: false,\n });\n }\n\n if (preventFutureDates && parsed.year > now.getFullYear()) {\n suggestions.push({\n message: `Use current year (${now.getFullYear()}) or a past year`,\n fix: `npx versionguard fix --version ${formatCalVerVersion({ ...parsed, year: now.getFullYear() })}`,\n autoFixable: true,\n });\n }\n\n if (\n preventFutureDates &&\n parsed.year === now.getFullYear() &&\n parsed.month > now.getMonth() + 1\n ) {\n suggestions.push({\n message: `Current month is ${now.getMonth() + 1}`,\n fix: `npx versionguard fix --version ${formatCalVerVersion({ ...parsed, month: now.getMonth() + 1 })}`,\n autoFixable: true,\n });\n }\n\n if (\n preventFutureDates &&\n parsed.year === now.getFullYear() &&\n parsed.month === now.getMonth() + 1 &&\n parsed.day !== undefined &&\n parsed.day > now.getDate()\n ) {\n suggestions.push({\n message: `Current day is ${now.getDate()}`,\n fix: `npx versionguard fix --version ${formatCalVerVersion({ ...parsed, day: now.getDate() })}`,\n autoFixable: true,\n });\n }\n\n // Check progression\n if (previousVersion) {\n const prevParsed = calver.parse(previousVersion, format);\n if (prevParsed) {\n if (calver.compare(version, previousVersion, format) <= 0) {\n errors.push({\n message: `Version ${version} is not newer than previous ${previousVersion}`,\n severity: 'error',\n });\n suggestions.push({\n message: `CalVer must increase over time`,\n fix: `npx versionguard fix --version ${calver.increment(previousVersion, format)}`,\n autoFixable: true,\n });\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n suggestions,\n canAutoFix: suggestions.some((s) => s.autoFixable),\n };\n}\n\nfunction formatCalVerVersion(version: CalVer): string {\n return calver.format({\n ...version,\n raw: version.raw || '',\n });\n}\n\n/**\n * Generates suggestions for version sync mismatches in a file.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * The returned suggestions include a general sync command and may include\n * file-type-specific hints for markdown or source files.\n *\n * @param file - File containing the mismatched version string.\n * @param foundVersion - Version currently found in the file.\n * @param expectedVersion - Version that should appear in the file.\n * @returns Suggestions for resolving the mismatch.\n *\n * @example\n * ```typescript\n * const suggestions = getSyncFeedback('README.md', '1.0.0', '1.0.1');\n * console.log(suggestions[0]?.message);\n * ```\n */\nexport function getSyncFeedback(\n file: string,\n foundVersion: string,\n expectedVersion: string,\n): Suggestion[] {\n const suggestions: Suggestion[] = [\n {\n message: `${file} has version \"${foundVersion}\" but should be \"${expectedVersion}\"`,\n fix: `npx versionguard sync`,\n autoFixable: true,\n },\n ];\n\n // Common patterns\n if (file.endsWith('.md')) {\n suggestions.push({\n message: `For markdown files, check headers like \"## [${expectedVersion}]\"`,\n autoFixable: false,\n });\n }\n\n if (file.endsWith('.ts') || file.endsWith('.js')) {\n suggestions.push({\n message: `For code files, check constants like \"export const VERSION = '${expectedVersion}'\"`,\n autoFixable: false,\n });\n }\n\n return suggestions;\n}\n\n/**\n * Generates suggestions for changelog-related validation issues.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * This helper suggests either creating a missing entry or reconciling the latest\n * changelog version with the package version.\n *\n * @param hasEntry - Whether the changelog already contains an entry for the version.\n * @param version - Package version that should appear in the changelog.\n * @param latestChangelogVersion - Most recent version currently found in the changelog.\n * @returns Suggestions for bringing changelog state back into sync.\n *\n * @example\n * ```typescript\n * const suggestions = getChangelogFeedback(false, '1.2.3', '1.2.2');\n * console.log(suggestions.length > 0);\n * ```\n */\nexport function getChangelogFeedback(\n hasEntry: boolean,\n version: string,\n latestChangelogVersion?: string,\n): Suggestion[] {\n const suggestions: Suggestion[] = [];\n\n if (!hasEntry) {\n suggestions.push({\n message: `CHANGELOG.md is missing entry for version ${version}`,\n fix: `npx versionguard fix`,\n autoFixable: true,\n });\n\n suggestions.push({\n message: `Or manually add: \"## [${version}] - YYYY-MM-DD\" under [Unreleased]`,\n autoFixable: false,\n });\n }\n\n if (latestChangelogVersion && latestChangelogVersion !== version) {\n suggestions.push({\n message: `CHANGELOG.md latest entry is ${latestChangelogVersion}, but manifest version is ${version}`,\n fix: `Make sure versions are in sync`,\n autoFixable: false,\n });\n }\n\n return suggestions;\n}\n\n/**\n * Generates suggestions for git tag mismatches.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * This helper focuses on discrepancies between git tag versions, package.json,\n * and repository files that still need to be synchronized.\n *\n * @param tagVersion - Version represented by the git tag.\n * @param packageVersion - Version currently stored in `package.json`.\n * @param hasUnsyncedFiles - Whether repository files are still out of sync.\n * @returns Suggestions for correcting tag-related issues.\n *\n * @example\n * ```typescript\n * const suggestions = getTagFeedback('v1.2.2', '1.2.3', true);\n * console.log(suggestions.map((item) => item.message));\n * ```\n */\nexport function getTagFeedback(\n tagVersion: string,\n packageVersion: string,\n hasUnsyncedFiles: boolean,\n): Suggestion[] {\n const suggestions: Suggestion[] = [];\n\n if (tagVersion !== packageVersion) {\n suggestions.push({\n message: `Git tag \"${tagVersion}\" doesn't match manifest version \"${packageVersion}\"`,\n fix: `Delete tag and recreate: git tag -d ${tagVersion} && git tag ${packageVersion}`,\n autoFixable: false,\n });\n }\n\n if (hasUnsyncedFiles) {\n suggestions.push({\n message: `Files are out of sync with version ${packageVersion}`,\n fix: `npx versionguard sync`,\n autoFixable: true,\n });\n }\n\n return suggestions;\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport * as calver from '../calver';\nimport { addVersionEntry } from '../changelog';\nimport { getPackageVersion, getVersionSource, setPackageVersion } from '../project';\nimport * as semver from '../semver';\nimport { syncVersion } from '../sync';\nimport { getCalVerConfig, type ManifestConfig, type VersionGuardConfig } from '../types';\n\n/**\n * Auto-fix helpers for package versions, synced files, and changelog entries.\n *\n * @packageDocumentation\n * @public\n */\n\n/**\n * Fix entry point exports for auto-remediation helpers.\n *\n * @packageDocumentation\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface FixResult {\n /**\n * Indicates whether the operation changed repository state.\n */\n fixed: boolean;\n\n /**\n * Human-readable description of the fix attempt.\n */\n message: string;\n\n /**\n * Absolute path to the file that was updated, when applicable.\n *\n * @defaultValue `undefined`\n */\n file?: string;\n}\n\n/**\n * Updates the `package.json` version field when needed.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * This helper writes the target version only when `package.json` exists and the\n * current version differs from the requested value.\n *\n * @param targetVersion - Version that should be written to `package.json`.\n * @param cwd - Repository directory containing `package.json`.\n * @param manifest - Optional manifest configuration for language-agnostic support.\n * @returns The result of the package version fix attempt.\n *\n * @example\n * ```typescript\n * // Fix using legacy package.json fallback\n * const result = fixPackageVersion('1.2.3', process.cwd());\n * console.log(result.fixed);\n *\n * // Fix using a configured manifest source\n * const result2 = fixPackageVersion('1.2.3', process.cwd(), { source: 'Cargo.toml' });\n * ```\n */\nexport function fixPackageVersion(\n targetVersion: string,\n cwd: string = process.cwd(),\n manifest?: ManifestConfig,\n): FixResult {\n // When no manifest config, use legacy package.json path for full compat\n if (!manifest) {\n const packagePath = path.join(cwd, 'package.json');\n\n if (!fs.existsSync(packagePath)) {\n return { fixed: false, message: 'package.json not found' };\n }\n\n const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf-8')) as { version?: string };\n const oldVersion = typeof pkg.version === 'string' ? pkg.version : undefined;\n\n if (oldVersion === targetVersion) {\n return { fixed: false, message: `Already at version ${targetVersion}` };\n }\n\n setPackageVersion(targetVersion, cwd);\n\n return {\n fixed: true,\n message: `Updated package.json from ${oldVersion} to ${targetVersion}`,\n file: packagePath,\n };\n }\n\n // Language-agnostic path\n const provider = getVersionSource(manifest, cwd);\n let oldVersion: string | undefined;\n\n try {\n oldVersion = provider.getVersion(cwd);\n } catch {\n return { fixed: false, message: 'Version source not found' };\n }\n\n if (oldVersion === targetVersion) {\n return { fixed: false, message: `Already at version ${targetVersion}` };\n }\n\n provider.setVersion(targetVersion, cwd);\n\n return {\n fixed: true,\n message: `Updated version from ${oldVersion} to ${targetVersion}`,\n file: provider.manifestFile ? path.join(cwd, provider.manifestFile) : undefined,\n };\n}\n\n/**\n * Synchronizes configured files to the package version.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * This helper uses the configured sync targets to update version strings across\n * the repository and reports only the files that changed.\n *\n * @param config - Loaded VersionGuard configuration.\n * @param cwd - Repository directory to synchronize.\n * @returns A list of per-file sync results.\n *\n * @example\n * ```typescript\n * const results = fixSyncIssues(config, process.cwd());\n * console.log(results.length);\n * ```\n */\nexport function fixSyncIssues(\n config: VersionGuardConfig,\n cwd: string = process.cwd(),\n): FixResult[] {\n const version = getPackageVersion(cwd, config.manifest);\n const results: FixResult[] = syncVersion(version, config.sync, cwd)\n .filter((result) => result.updated)\n .map((result) => ({\n fixed: true,\n message: `Updated ${path.relative(cwd, result.file)} (${result.changes.length} changes)`,\n file: result.file,\n }));\n\n if (results.length === 0) {\n results.push({ fixed: false, message: 'All files already in sync' });\n }\n\n return results;\n}\n\n/**\n * Ensures the changelog contains an entry for a version.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * When the changelog file does not exist, this helper creates a starter changelog.\n * Otherwise it appends a new version entry only when one is missing.\n *\n * @param version - Version that should appear in the changelog.\n * @param config - Loaded VersionGuard configuration.\n * @param cwd - Repository directory containing the changelog file.\n * @returns The result of the changelog fix attempt.\n *\n * @example\n * ```typescript\n * const result = fixChangelog('1.2.3', config, process.cwd());\n * console.log(result.message);\n * ```\n */\nexport function fixChangelog(\n version: string,\n config: VersionGuardConfig,\n cwd: string = process.cwd(),\n): FixResult {\n const changelogPath = path.join(cwd, config.changelog.file);\n\n if (!fs.existsSync(changelogPath)) {\n // Create initial changelog\n createInitialChangelog(changelogPath, version);\n return {\n fixed: true,\n message: `Created ${config.changelog.file} with entry for ${version}`,\n file: changelogPath,\n };\n }\n\n const content = fs.readFileSync(changelogPath, 'utf-8');\n\n if (content.includes(`## [${version}]`)) {\n return { fixed: false, message: `Changelog already has entry for ${version}` };\n }\n\n addVersionEntry(changelogPath, version);\n\n return {\n fixed: true,\n message: `Added entry for ${version} to ${config.changelog.file}`,\n file: changelogPath,\n };\n}\n\n/**\n * Create initial changelog\n */\nfunction createInitialChangelog(changelogPath: string, version: string): void {\n const today = new Date().toISOString().slice(0, 10);\n const content = `# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [Unreleased]\n\n## [${version}] - ${today}\n\n### Added\n\n- Initial release\n\n[Unreleased]: https://github.com/yourorg/project/compare/v${version}...HEAD\n[${version}]: https://github.com/yourorg/project/releases/tag/v${version}\n`;\n\n fs.writeFileSync(changelogPath, content, 'utf-8');\n}\n\n/**\n * Runs all configured auto-fix operations.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * This helper optionally updates the package version first, then synchronizes\n * configured files, and finally updates the changelog when changelog support is\n * enabled.\n *\n * @param config - Loaded VersionGuard configuration.\n * @param targetVersion - Optional version to apply before running other fixes.\n * @param cwd - Repository directory where fixes should run.\n * @returns Ordered results describing every fix step that ran.\n *\n * @example\n * ```typescript\n * const results = fixAll(config, '1.2.3', process.cwd());\n * console.log(results.some((result) => result.fixed));\n * ```\n */\nexport function fixAll(\n config: VersionGuardConfig,\n targetVersion?: string,\n cwd: string = process.cwd(),\n): FixResult[] {\n const results: FixResult[] = [];\n const version = targetVersion || getPackageVersion(cwd, config.manifest);\n\n if (targetVersion && targetVersion !== getPackageVersion(cwd, config.manifest)) {\n results.push(fixPackageVersion(targetVersion, cwd, config.manifest));\n }\n\n const syncResults = fixSyncIssues(config, cwd);\n results.push(...syncResults);\n\n if (config.changelog.enabled) {\n const changelogResult = fixChangelog(version, config, cwd);\n if (changelogResult.fixed) {\n results.push(changelogResult);\n }\n }\n\n return results;\n}\n\n/**\n * Suggests candidate next versions for a release.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * The suggestions depend on the configured versioning mode. SemVer returns one or\n * more bump options, while CalVer suggests the current date-based version and an\n * incremented same-day release.\n *\n * @param currentVersion - Current package version.\n * @param config - Loaded VersionGuard configuration.\n * @param changeType - Preferred bump type, or `auto` to include common options.\n * @returns Candidate versions paired with the reason for each suggestion.\n *\n * @example\n * ```typescript\n * const suggestions = suggestNextVersion('1.2.3', config, 'minor');\n * console.log(suggestions[0]?.version);\n * ```\n */\nexport function suggestNextVersion(\n currentVersion: string,\n config: VersionGuardConfig,\n changeType?: 'major' | 'minor' | 'patch' | 'auto',\n): { version: string; reason: string }[] {\n const suggestions: { version: string; reason: string }[] = [];\n\n if (config.versioning.type === 'semver') {\n if (!changeType || changeType === 'auto' || changeType === 'patch') {\n suggestions.push({\n version: semver.increment(currentVersion, 'patch'),\n reason: 'Patch - bug fixes, small changes',\n });\n }\n\n if (!changeType || changeType === 'auto' || changeType === 'minor') {\n suggestions.push({\n version: semver.increment(currentVersion, 'minor'),\n reason: 'Minor - new features, backwards compatible',\n });\n }\n\n if (!changeType || changeType === 'auto' || changeType === 'major') {\n suggestions.push({\n version: semver.increment(currentVersion, 'major'),\n reason: 'Major - breaking changes',\n });\n }\n } else {\n // CalVer\n const format = getCalVerConfig(config).format;\n const currentCal = calver.getCurrentVersion(format);\n\n // Option 1: Current date\n suggestions.push({\n version: currentCal,\n reason: 'Current date - new release today',\n });\n\n // Option 2: Increment patch on current version\n suggestions.push({\n version: calver.increment(currentVersion, format),\n reason: 'Increment patch - additional release today',\n });\n }\n\n return suggestions;\n}\n","import { execSync } from 'node:child_process';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport { findGitDir, generateHookScript } from './hooks';\nimport type { VersionGuardConfig } from './types';\n\nconst HOOK_NAMES = ['pre-commit', 'pre-push', 'post-tag'] as const;\n\n/**\n * Describes a single guard finding.\n *\n * @public\n * @since 0.2.0\n */\nexport interface GuardWarning {\n /** Machine-readable code for filtering and automation. */\n code: string;\n /** Severity: errors block releases, warnings inform. */\n severity: 'error' | 'warning';\n /** Human-readable description of the issue. */\n message: string;\n /**\n * Suggested remediation command when available.\n *\n * @defaultValue `undefined`\n */\n fix?: string;\n}\n\n/**\n * Result of a full guard check pass.\n *\n * @public\n * @since 0.2.0\n */\nexport interface GuardReport {\n /** True when no errors were found. Warnings alone do not fail. */\n safe: boolean;\n /** All findings from the guard check. */\n warnings: GuardWarning[];\n}\n\n/**\n * Checks whether git hooks have been redirected away from the repository.\n *\n * @remarks\n * When `core.hooksPath` is set to a non-default location, git hooks installed\n * in `.git/hooks/` are silently ignored. This is a common bypass vector.\n *\n * @param cwd - Repository directory to inspect.\n * @returns A guard warning when a hooksPath override is detected.\n *\n * @example\n * ```ts\n * import { checkHooksPathOverride } from './guard';\n *\n * const warning = checkHooksPathOverride(process.cwd());\n * if (warning) console.warn(warning.message);\n * ```\n *\n * @public\n * @since 0.2.0\n */\nexport function checkHooksPathOverride(cwd: string): GuardWarning | null {\n try {\n // Safe: hardcoded command, no user input\n const hooksPath = execSync('git config core.hooksPath', {\n cwd,\n encoding: 'utf-8',\n }).trim();\n\n if (hooksPath) {\n // Resolve the hooks path relative to the project root and check if\n // it points to a legitimate .husky directory inside the project.\n // A bare substring check would let /tmp/.husky-fake bypass the error.\n const resolved = path.resolve(cwd, hooksPath);\n const huskyDir = path.resolve(cwd, '.husky');\n if (resolved === huskyDir || resolved.startsWith(`${huskyDir}${path.sep}`)) {\n return {\n code: 'HOOKS_PATH_HUSKY',\n severity: 'warning',\n message: `Husky detected — core.hooksPath is set to \"${hooksPath}\". Hooks in .git/hooks/ are bypassed. Add versionguard validate to your .husky/pre-commit manually or use a tool like forge-ts that manages .husky/ hooks cooperatively.`,\n };\n }\n\n return {\n code: 'HOOKS_PATH_OVERRIDE',\n severity: 'error',\n message: `git core.hooksPath is set to \"${hooksPath}\" — hooks in .git/hooks/ are bypassed`,\n fix: 'git config --unset core.hooksPath',\n };\n }\n } catch {\n // core.hooksPath not set — this is the expected state\n }\n\n return null;\n}\n\n/**\n * Checks whether the HUSKY environment variable is disabling hooks.\n *\n * @remarks\n * Setting `HUSKY=0` is a documented way to disable Husky hooks. Since\n * VersionGuard hooks may run alongside or through Husky, this bypass\n * can silently disable enforcement.\n *\n * @returns A guard warning when the HUSKY bypass is detected.\n *\n * @example\n * ```ts\n * import { checkHuskyBypass } from './guard';\n *\n * const warning = checkHuskyBypass();\n * if (warning) console.warn(warning.message);\n * ```\n *\n * @public\n * @since 0.2.0\n */\nexport function checkHuskyBypass(): GuardWarning | null {\n if (process.env.HUSKY === '0') {\n return {\n code: 'HUSKY_BYPASS',\n severity: 'error',\n message: 'HUSKY=0 is set — git hooks are disabled via environment variable',\n fix: 'unset HUSKY',\n };\n }\n\n return null;\n}\n\n/**\n * Verifies that installed hook scripts match the expected content.\n *\n * @remarks\n * This compares each hook file against what `generateHookScript` would produce.\n * Tampered hooks that still contain \"versionguard\" pass `areHooksInstalled` but\n * may have had critical lines removed or modified.\n *\n * @param config - VersionGuard configuration that defines which hooks should exist.\n * @param cwd - Repository directory to inspect.\n * @returns Guard warnings for each hook that has been tampered with.\n *\n * @example\n * ```ts\n * import { checkHookIntegrity } from './guard';\n *\n * const warnings = checkHookIntegrity(config, process.cwd());\n * for (const w of warnings) console.warn(w.code, w.message);\n * ```\n *\n * @public\n * @since 0.2.0\n */\nexport function checkHookIntegrity(config: VersionGuardConfig, cwd: string): GuardWarning[] {\n const warnings: GuardWarning[] = [];\n const gitDir = findGitDir(cwd);\n\n if (!gitDir) {\n return warnings;\n }\n\n const hooksDir = path.join(gitDir, 'hooks');\n\n for (const hookName of HOOK_NAMES) {\n if (!config.git.hooks[hookName]) {\n continue;\n }\n\n const hookPath = path.join(hooksDir, hookName);\n\n if (!fs.existsSync(hookPath)) {\n warnings.push({\n code: 'HOOK_MISSING',\n severity: 'error',\n message: `Required hook \"${hookName}\" is not installed`,\n fix: 'npx versionguard hooks install',\n });\n continue;\n }\n\n const actual = fs.readFileSync(hookPath, 'utf-8');\n const expected = generateHookScript(hookName);\n\n if (actual !== expected) {\n if (!actual.includes('versionguard')) {\n warnings.push({\n code: 'HOOK_REPLACED',\n severity: 'error',\n message: `Hook \"${hookName}\" has been replaced — versionguard invocation is missing`,\n fix: 'npx versionguard hooks install',\n });\n } else {\n warnings.push({\n code: 'HOOK_TAMPERED',\n severity: 'warning',\n message: `Hook \"${hookName}\" has been modified from the expected template`,\n fix: 'npx versionguard hooks install',\n });\n }\n }\n }\n\n return warnings;\n}\n\n/**\n * Checks whether hooks are configured as required but not enforced.\n *\n * @remarks\n * When hooks are enabled in the config but `enforceHooks` is false, validation\n * will not fail for missing hooks. In strict mode this is a policy gap.\n *\n * @param config - VersionGuard configuration to inspect.\n * @returns A guard warning when hooks are enabled but not enforced.\n *\n * @example\n * ```ts\n * import { checkEnforceHooksPolicy } from './guard';\n *\n * const warning = checkEnforceHooksPolicy(config);\n * if (warning) console.warn(warning.message);\n * ```\n *\n * @public\n * @since 0.2.0\n */\nexport function checkEnforceHooksPolicy(config: VersionGuardConfig): GuardWarning | null {\n const anyHookEnabled = HOOK_NAMES.some((name) => config.git.hooks[name]);\n\n if (anyHookEnabled && !config.git.enforceHooks) {\n return {\n code: 'HOOKS_NOT_ENFORCED',\n severity: 'warning',\n message:\n 'Hooks are enabled but enforceHooks is false — missing hooks will not fail validation',\n fix: 'Set git.enforceHooks: true in .versionguard.yml',\n };\n }\n\n return null;\n}\n\n/**\n * Runs all guard checks and returns a consolidated report.\n *\n * @remarks\n * This is the primary entry point for strict mode. It runs every detection\n * check and returns a report indicating whether the repository is safe from\n * known bypass patterns.\n *\n * @param config - VersionGuard configuration.\n * @param cwd - Repository directory to inspect.\n * @returns A guard report with all findings.\n *\n * @example\n * ```ts\n * import { runGuardChecks } from './guard';\n *\n * const report = runGuardChecks(config, process.cwd());\n * if (!report.safe) console.error('Guard check failed:', report.warnings);\n * ```\n *\n * @public\n * @since 0.2.0\n */\nexport function runGuardChecks(config: VersionGuardConfig, cwd: string): GuardReport {\n const warnings: GuardWarning[] = [];\n\n const hooksPathWarning = checkHooksPathOverride(cwd);\n if (hooksPathWarning) {\n warnings.push(hooksPathWarning);\n }\n\n const huskyWarning = checkHuskyBypass();\n if (huskyWarning) {\n warnings.push(huskyWarning);\n }\n\n const integrityWarnings = checkHookIntegrity(config, cwd);\n warnings.push(...integrityWarnings);\n\n const enforceWarning = checkEnforceHooksPolicy(config);\n if (enforceWarning) {\n warnings.push(enforceWarning);\n }\n\n const hasErrors = warnings.some((w) => w.severity === 'error');\n\n return {\n safe: !hasErrors,\n warnings,\n };\n}\n","import * as childProcess from 'node:child_process';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport { validate as validateCalVer } from '../calver';\nimport { validateChangelog } from '../changelog';\nimport { fixAll } from '../fix';\nimport { areHooksInstalled } from '../hooks';\nimport { getPackageVersion } from '../project';\nimport { validate as validateSemVer } from '../semver';\nimport { checkHardcodedVersions } from '../sync';\nimport type { VersionGuardConfig } from '../types';\n\n/**\n * Tag management helpers for reading, validating, and creating release tags.\n *\n * @packageDocumentation\n * @public\n */\n\n/**\n * Tag entry point exports for release-tag management helpers.\n *\n * @packageDocumentation\n * @public\n * @since 0.1.0\n * @forgeIgnore E020\n */\nexport interface TagInfo {\n /**\n * Full git tag name, including any prefix such as `v`.\n */\n name: string;\n\n /**\n * Normalized version string derived from the tag name.\n */\n version: string;\n\n /**\n * Annotated tag message when one is available.\n *\n * @defaultValue `undefined`\n */\n message?: string;\n\n /**\n * Timestamp associated with the tag lookup result.\n */\n date: Date;\n}\n\nfunction runGit(cwd: string, args: string[], encoding?: BufferEncoding): string | Buffer {\n return childProcess.execFileSync('git', args, {\n cwd,\n encoding,\n stdio: ['pipe', 'pipe', 'ignore'],\n });\n}\n\nfunction runGitText(cwd: string, args: string[]): string {\n return runGit(cwd, args, 'utf-8') as string;\n}\n\n/**\n * Returns the most recent reachable git tag for a repository.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * This helper reads the most recent annotated or lightweight tag that `git describe`\n * can resolve from the current HEAD. It returns `null` when no tags are available\n * or when git metadata cannot be read.\n *\n * @param cwd - Repository directory to inspect.\n * @returns The latest tag details, or `null` when no tag can be resolved.\n *\n * @example\n * ```typescript\n * const latestTag = getLatestTag(process.cwd());\n *\n * if (latestTag) {\n * console.log(latestTag.version);\n * }\n * ```\n */\nexport function getLatestTag(cwd: string = process.cwd()): TagInfo | null {\n try {\n const result = runGitText(cwd, ['describe', '--tags', '--abbrev=0']);\n\n const tagName = result.trim();\n const version = tagName.replace(/^v/, '');\n\n const dateResult = runGitText(cwd, ['log', '-1', '--format=%ai', tagName]);\n const messageResult = runGitText(cwd, ['tag', '-l', tagName, '--format=%(contents)']);\n const message = messageResult.trim();\n\n return {\n name: tagName,\n version,\n message: message.length > 0 ? message : undefined,\n date: new Date(dateResult.trim()),\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Lists all tags in a repository.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * This helper returns tag names in the order provided by `git tag --list`. The\n * `date` field is populated with the current time because the implementation does\n * not perform per-tag date lookups.\n *\n * @param cwd - Repository directory to inspect.\n * @returns A list of discovered tags, or an empty array when tags cannot be read.\n *\n * @example\n * ```typescript\n * const tags = getAllTags(process.cwd());\n * console.log(tags.map((tag) => tag.name));\n * ```\n */\nexport function getAllTags(cwd: string = process.cwd()): TagInfo[] {\n try {\n const result = runGitText(cwd, ['tag', '--list']);\n\n return result\n .trim()\n .split('\\n')\n .filter(Boolean)\n .map((name) => ({\n name,\n version: name.replace(/^v/, ''),\n date: new Date(), // Would need individual lookup for accurate dates\n }));\n } catch {\n return [];\n }\n}\n\n/**\n * Creates a release tag and optionally fixes version state first.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * When `autoFix` is enabled, this helper updates versioned files, stages the\n * changes, and creates a release commit before creating the annotated tag. It\n * returns a structured result instead of throwing for most expected failures.\n *\n * @param version - Version to embed in the new tag name.\n * @param message - Custom annotated tag message.\n * @param autoFix - Whether to auto-fix version mismatches before tagging.\n * @param config - Loaded VersionGuard configuration used for validation and fixes.\n * @param cwd - Repository directory where git commands should run.\n * @returns The tagging outcome and any actions performed along the way.\n *\n * @example\n * ```typescript\n * const result = createTag('1.2.3', 'Release 1.2.3', true, config, process.cwd());\n *\n * if (!result.success) {\n * console.error(result.message);\n * }\n * ```\n */\nexport function createTag(\n version: string,\n message?: string,\n autoFix: boolean = true,\n config?: VersionGuardConfig,\n cwd: string = process.cwd(),\n): { success: boolean; message: string; actions: string[] } {\n const actions: string[] = [];\n\n try {\n if (!config) {\n return {\n success: false,\n message: 'VersionGuard config is required to create tags safely',\n actions,\n };\n }\n\n const packageVersion = getPackageVersion(cwd, config.manifest);\n const shouldAutoFix = autoFix;\n const preflightError = getTagPreflightError(config, cwd, version, shouldAutoFix);\n if (preflightError) {\n return {\n success: false,\n message: preflightError,\n actions,\n };\n }\n\n if (version !== packageVersion && !autoFix) {\n return {\n success: false,\n message: `Version mismatch: manifest version is ${packageVersion}, tag is ${version}`,\n actions: [],\n };\n }\n\n if (autoFix) {\n const fixResults =\n version !== packageVersion ? fixAll(config, version, cwd) : fixAll(config, undefined, cwd);\n\n for (const result of fixResults) {\n if (result.fixed) {\n actions.push(result.message);\n }\n }\n\n if (fixResults.some((result) => result.fixed)) {\n runGit(cwd, ['add', '-A']);\n runGit(cwd, ['commit', '--no-verify', '-m', `chore(release): ${version}`]);\n actions.push('Committed version changes');\n }\n }\n\n const tagName = `v${version}`;\n const tagMessage = message || `Release ${version}`;\n\n if (getAllTags(cwd).some((tag) => tag.name === tagName)) {\n return {\n success: false,\n message: `Tag ${tagName} already exists`,\n actions,\n };\n }\n\n runGit(cwd, ['tag', '-a', tagName, '-m', tagMessage]);\n actions.push(`Created tag ${tagName}`);\n\n return {\n success: true,\n message: `Successfully created tag ${tagName}`,\n actions,\n };\n } catch (err) {\n return {\n success: false,\n message: `Failed to create tag: ${(err as Error).message}`,\n actions,\n };\n }\n}\n\n/**\n * Runs post-tag validation and sync checks.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * This helper is intended for the `post-tag` git hook flow. It validates the\n * latest tag against the configured versioning rules and reports any required\n * follow-up actions without mutating git history.\n *\n * @param config - Loaded VersionGuard configuration used during validation.\n * @param cwd - Repository directory where validation should run.\n * @returns The post-tag workflow result and any follow-up actions.\n *\n * @example\n * ```typescript\n * const result = handlePostTag(config, process.cwd());\n * console.log(result.success);\n * ```\n */\nexport function handlePostTag(\n config: VersionGuardConfig,\n cwd: string = process.cwd(),\n): { success: boolean; message: string; actions: string[] } {\n const actions: string[] = [];\n\n try {\n const preflightError = getTagPreflightError(config, cwd);\n if (preflightError) {\n return {\n success: false,\n message: preflightError,\n actions,\n };\n }\n\n const tag = getLatestTag(cwd);\n if (!tag) {\n return {\n success: false,\n message: 'No tag found',\n actions,\n };\n }\n const packageVersion = getPackageVersion(cwd, config.manifest);\n\n if (tag.version !== packageVersion) {\n return {\n success: false,\n message: `Tag version ${tag.version} doesn't match manifest version ${packageVersion}`,\n actions: [\n 'To fix: delete tag and recreate with correct version',\n ` git tag -d ${tag.name}`,\n ` Update manifest to ${tag.version}`,\n ` git tag ${tag.name}`,\n ],\n };\n }\n const syncResults = fixAll(config, packageVersion, cwd);\n\n for (const result of syncResults) {\n /* v8 ignore next 3 -- preflight blocks remaining post-tag fixes */\n if (result.fixed) {\n actions.push(result.message);\n }\n }\n\n return {\n success: true,\n message: `Post-tag workflow completed for ${tag.name}`,\n actions,\n };\n } catch (err) {\n return {\n success: false,\n message: `Post-tag workflow failed: ${(err as Error).message}`,\n actions,\n };\n }\n}\n\nfunction getTagPreflightError(\n config: VersionGuardConfig,\n cwd: string,\n expectedVersion?: string,\n allowAutoFix: boolean = false,\n): string | null {\n if (config.git.enforceHooks && !areHooksInstalled(cwd)) {\n return 'Git hooks must be installed before creating or validating release tags';\n }\n\n if (hasDirtyWorktree(cwd)) {\n return 'Working tree must be clean before creating or validating release tags';\n }\n\n const version = expectedVersion ?? getPackageVersion(cwd, config.manifest);\n const versionResult =\n config.versioning.type === 'semver'\n ? validateSemVer(version)\n : validateCalVer(\n version,\n config.versioning.calver?.format ?? 'YYYY.MM.PATCH',\n config.versioning.calver?.preventFutureDates ?? true,\n config.versioning.schemeRules,\n );\n\n if (!versionResult.valid) {\n return versionResult.errors[0]?.message ?? `Invalid version: ${version}`;\n }\n\n if (allowAutoFix) {\n return null;\n }\n\n const mismatches = checkHardcodedVersions(version, config.sync, config.ignore, cwd);\n if (mismatches.length > 0) {\n const mismatch = mismatches[0];\n return `Version mismatch in ${mismatch.file}:${mismatch.line} - found \"${mismatch.found}\" but expected \"${version}\"`;\n }\n\n const changelogResult = validateChangelog(\n path.join(cwd, config.changelog.file),\n version,\n config.changelog.strict,\n config.changelog.requireEntry,\n );\n if (!changelogResult.valid) {\n return changelogResult.errors[0] ?? 'Changelog validation failed';\n }\n\n return null;\n}\n\nfunction hasDirtyWorktree(cwd: string): boolean {\n try {\n return runGitText(cwd, ['status', '--porcelain']).trim().length > 0;\n } catch {\n return true;\n }\n}\n\n/**\n * Validates that a local tag is safe to push to the default remote.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * This helper checks that the tag exists locally and, when the tag also exists on\n * `origin`, verifies that both references point to the same commit.\n *\n * @param tagName - Name of the tag to validate.\n * @param cwd - Repository directory where git commands should run.\n * @returns A validation result with an optional suggested fix command.\n *\n * @example\n * ```typescript\n * const result = validateTagForPush('v1.2.3', process.cwd());\n * console.log(result.valid);\n * ```\n */\nexport function validateTagForPush(\n tagName: string,\n cwd: string = process.cwd(),\n): { valid: boolean; message: string; fix?: string } {\n try {\n runGit(cwd, ['rev-parse', tagName]);\n\n try {\n runGit(cwd, ['ls-remote', '--tags', 'origin', tagName]);\n\n const localHash = runGitText(cwd, ['rev-parse', tagName]).trim();\n const remoteOutput = runGitText(cwd, ['ls-remote', '--tags', 'origin', tagName]).trim();\n\n if (remoteOutput && !remoteOutput.includes(localHash)) {\n return {\n valid: false,\n message: `Tag ${tagName} exists on remote with different commit`,\n fix: `Delete remote tag first: git push origin :refs/tags/${tagName}`,\n };\n }\n } catch {\n return { valid: true, message: `Tag ${tagName} is valid for push` };\n }\n\n return { valid: true, message: `Tag ${tagName} is valid for push` };\n } catch {\n return {\n valid: false,\n message: `Tag ${tagName} not found locally`,\n fix: `Create tag: git tag ${tagName}`,\n };\n }\n}\n\n/**\n * Suggests an annotated tag message from changelog content.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * When a matching changelog entry exists, this helper uses the first bullet point\n * as a concise release summary. It falls back to a generic `Release {version}`\n * message when no changelog context is available.\n *\n * @param version - Version that the tag will represent.\n * @param cwd - Repository directory containing the changelog file.\n * @returns A suggested annotated tag message.\n *\n * @example\n * ```typescript\n * const message = suggestTagMessage('1.2.3', process.cwd());\n * console.log(message);\n * ```\n */\nexport function suggestTagMessage(version: string, cwd: string = process.cwd()): string {\n try {\n const changelogPath = path.join(cwd, 'CHANGELOG.md');\n if (fs.existsSync(changelogPath)) {\n const content = fs.readFileSync(changelogPath, 'utf-8');\n\n const versionRegex = new RegExp(\n `## \\\\[${version}\\\\].*?\\\\n(.*?)(?=\\\\n## \\\\[|\\\\n\\\\n## |$)`,\n 's',\n );\n const match = content.match(versionRegex);\n\n if (match) {\n const bulletMatch = match[1].match(/- (.+)/);\n if (bulletMatch) {\n return `Release ${version}: ${bulletMatch[1].trim()}`;\n }\n }\n }\n } catch {\n return `Release ${version}`;\n }\n\n return `Release ${version}`;\n}\n","/**\n * Public API for VersionGuard.\n *\n * @packageDocumentation\n * @public\n */\n\nimport { execSync } from 'node:child_process';\nimport * as path from 'node:path';\n\nimport * as calver from './calver';\nimport { validateChangelog } from './changelog';\nimport { areHooksInstalled, findGitDir } from './hooks';\nimport { getPackageVersion } from './project';\nimport * as semver from './semver';\nimport { checkHardcodedVersions, syncVersion } from './sync';\nimport {\n type DoctorReport,\n type FullValidationResult,\n getCalVerConfig,\n type ValidationResult,\n type VersionGuardConfig,\n} from './types';\n\nexport * as calver from './calver';\nexport { validateChangelog } from './changelog';\nexport { getConfig, initConfig } from './config';\nexport * from './feedback';\nexport * from './fix';\nexport * from './guard';\nexport { areHooksInstalled, installHooks, uninstallHooks } from './hooks';\nexport { getPackageVersion, getVersionSource } from './project';\nexport * as semver from './semver';\nexport * from './sources';\nexport { checkHardcodedVersions, syncVersion } from './sync';\nexport * from './tag';\nexport * from './types';\n\n/**\n * Validates a version string against the active versioning strategy.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * This helper dispatches to SemVer or CalVer validation based on\n * `config.versioning.type`.\n *\n * @param version - Version string to validate.\n * @param config - VersionGuard configuration that selects the validation rules.\n * @returns The validation result for the provided version.\n * @example\n * ```ts\n * import { getDefaultConfig, validateVersion } from 'versionguard';\n *\n * const result = validateVersion('1.2.3', getDefaultConfig());\n * ```\n */\nexport function validateVersion(version: string, config: VersionGuardConfig): ValidationResult {\n if (config.versioning.type === 'semver') {\n return semver.validate(version);\n }\n\n const calverConfig = getCalVerConfig(config);\n return calver.validate(\n version,\n calverConfig.format,\n calverConfig.preventFutureDates,\n config.versioning.schemeRules,\n );\n}\n\n/**\n * Validates the current project state against the supplied configuration.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * This reads the package version from `package.json`, validates the version\n * format, checks synchronized files, and optionally validates the changelog.\n *\n * @param config - VersionGuard configuration to apply.\n * @param cwd - Project directory to inspect.\n * @returns A full validation report for the project rooted at `cwd`.\n * @example\n * ```ts\n * import { getDefaultConfig, validate } from 'versionguard';\n *\n * const result = validate(getDefaultConfig(), process.cwd());\n * ```\n */\nexport function validate(\n config: VersionGuardConfig,\n cwd: string = process.cwd(),\n): FullValidationResult {\n const errors: string[] = [];\n\n let version: string;\n try {\n version = getPackageVersion(cwd, config.manifest);\n } catch (err) {\n return {\n valid: false,\n version: '',\n versionValid: false,\n syncValid: false,\n changelogValid: false,\n errors: [(err as Error).message],\n };\n }\n\n const versionResult = validateVersion(version, config);\n if (!versionResult.valid) {\n errors.push(...versionResult.errors.map((error) => error.message));\n }\n\n const hardcoded = checkHardcodedVersions(version, config.sync, config.ignore, cwd);\n\n if (hardcoded.length > 0) {\n for (const mismatch of hardcoded) {\n errors.push(\n `Version mismatch in ${mismatch.file}:${mismatch.line} - found \"${mismatch.found}\" but expected \"${version}\"`,\n );\n }\n }\n\n let changelogValid = true;\n if (config.changelog.enabled) {\n const changelogPath = path.join(cwd, config.changelog.file);\n const changelogResult = validateChangelog(\n changelogPath,\n version,\n config.changelog.strict,\n config.changelog.requireEntry,\n );\n\n if (!changelogResult.valid) {\n changelogValid = false;\n errors.push(...changelogResult.errors);\n }\n }\n\n return {\n valid: errors.length === 0,\n version,\n versionValid: versionResult.valid,\n syncValid: hardcoded.length === 0,\n changelogValid,\n errors,\n };\n}\n\n/**\n * Runs an extended readiness check for a project.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * In addition to `validate`, this inspects Git state so callers can determine\n * whether hooks are installed and the worktree is clean.\n *\n * @param config - VersionGuard configuration to apply.\n * @param cwd - Project directory to inspect.\n * @returns A readiness report that includes validation and Git diagnostics.\n * @example\n * ```ts\n * import { doctor, getDefaultConfig } from 'versionguard';\n *\n * const report = doctor(getDefaultConfig(), process.cwd());\n * ```\n */\nexport function doctor(config: VersionGuardConfig, cwd: string = process.cwd()): DoctorReport {\n const validation = validate(config, cwd);\n const gitRepository = findGitDir(cwd) !== null;\n const hooksInstalled = gitRepository ? areHooksInstalled(cwd) : false;\n const worktreeClean = gitRepository ? isWorktreeClean(cwd) : true;\n const errors = [...validation.errors];\n\n if (gitRepository && config.git.enforceHooks && !hooksInstalled) {\n errors.push('Git hooks are not installed');\n }\n\n if (gitRepository && !worktreeClean) {\n errors.push('Working tree is not clean');\n }\n\n return {\n ready: errors.length === 0,\n version: validation.version,\n versionValid: validation.versionValid,\n syncValid: validation.syncValid,\n changelogValid: validation.changelogValid,\n gitRepository,\n hooksInstalled,\n worktreeClean,\n errors,\n };\n}\n\n/**\n * Synchronizes configured files to the current package version.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * This reads the version from `package.json` and rewrites configured files\n * using the sync patterns defined in the VersionGuard config.\n *\n * @param config - VersionGuard configuration containing sync rules.\n * @param cwd - Project directory whose files should be synchronized.\n * @example\n * ```ts\n * import { getDefaultConfig, sync } from 'versionguard';\n *\n * sync(getDefaultConfig(), process.cwd());\n * ```\n */\nexport function sync(config: VersionGuardConfig, cwd: string = process.cwd()): void {\n const version = getPackageVersion(cwd, config.manifest);\n syncVersion(version, config.sync, cwd);\n}\n\n/**\n * Determines whether a project can move from one version to another.\n *\n * @public\n * @since 0.1.0\n * @remarks\n * Both the current and proposed versions must validate against the configured\n * versioning scheme, and the new version must compare greater than the current\n * version.\n *\n * @param currentVersion - Version currently in use.\n * @param newVersion - Proposed next version.\n * @param config - VersionGuard configuration that defines version rules.\n * @returns An object indicating whether the bump is allowed and why it failed.\n * @example\n * ```ts\n * import { canBump, getDefaultConfig } from 'versionguard';\n *\n * const result = canBump('1.2.3', '1.3.0', getDefaultConfig());\n * ```\n */\nexport function canBump(\n currentVersion: string,\n newVersion: string,\n config: VersionGuardConfig,\n): { canBump: boolean; error?: string } {\n const currentValid = validateVersion(currentVersion, config);\n const newValid = validateVersion(newVersion, config);\n\n if (!currentValid.valid) {\n return { canBump: false, error: `Current version is invalid: ${currentVersion}` };\n }\n\n if (!newValid.valid) {\n return { canBump: false, error: `New version is invalid: ${newVersion}` };\n }\n\n if (config.versioning.type === 'semver') {\n if (!semver.gt(newVersion, currentVersion)) {\n return {\n canBump: false,\n error: `New version ${newVersion} must be greater than current ${currentVersion}`,\n };\n }\n } else {\n const calverConfig = getCalVerConfig(config);\n const currentParsed = calver.parse(currentVersion, calverConfig.format);\n const newParsed = calver.parse(newVersion, calverConfig.format);\n\n if (!currentParsed || !newParsed) {\n return { canBump: false, error: 'Failed to parse CalVer versions' };\n }\n\n if (calver.compare(newVersion, currentVersion, calverConfig.format) <= 0) {\n return {\n canBump: false,\n error: `New CalVer ${newVersion} must be newer than current ${currentVersion}`,\n };\n }\n }\n\n return { canBump: true };\n}\n\nfunction isWorktreeClean(cwd: string): boolean {\n try {\n return execSync('git status --porcelain', { cwd, encoding: 'utf-8' }).trim().length === 0;\n } catch {\n return false;\n }\n}\n"],"names":["parse","validate","format","compare","increment","escapeRegExp","HOOK_NAMES","semver.parse","semver.validate","semver.compare","semver.increment","calver.parse","calver.getCurrentVersion","calver.validate","calver.compare","calver.increment","calver.format","oldVersion","validateSemVer","validateCalVer","semver.gt"],"mappings":"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"}