aronrepo 2.2.1 → 3.0.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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["export const packages = [\n '@aronrepo/commitlint-config',\n '@aronrepo/conventional-commits',\n '@aronrepo/conventional-changelog-config',\n '@aronrepo/semantic-release-config',\n '@aronrepo/semantic-release-pnpm'\n] as const\n"],"mappings":";AAAA,MAAa,WAAW;CACpB;CACA;CACA;CACA;CACA;AACJ"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/commits.ts","../src/policy.ts","../src/agent.ts","../src/version.ts","../src/notes.ts"],"sourcesContent":["export type ReleaseType = 'major' | 'minor' | 'patch' | false\n\nexport interface ConventionalCommitType {\n type: string\n scope?: string\n /**\n * Release level in `auto` mode. The `explicit` mode caps every type except\n * `Bump` at `patch`; see `getReleaseType()` and `resolveCommitRelease()`.\n */\n release: ReleaseType\n /** When to use the type, written for people and coding agents. */\n description: string\n /** Release notes section. Types without a group never appear in release notes. */\n group?: string\n}\n\nexport interface LegacyCommitType {\n type: string\n /** The type that replaces it. Legacy commits release and group like their replacement. */\n replacement: string\n}\n\n/** Release levels in descending order. */\nexport const releaseLevels = ['major', 'minor', 'patch'] as const\n\nexport function compareRelease(a: ReleaseType | undefined, b: ReleaseType | undefined) {\n const rank = (release: ReleaseType | undefined) => release ? 3 - releaseLevels.indexOf(release) : 0\n return rank(a) - rank(b)\n}\n\nexport function maxRelease(...releases: Array<ReleaseType | undefined>): ReleaseType {\n return releases.reduce<ReleaseType>((highest, release) =>\n compareRelease(release, highest) > 0 ? release as ReleaseType : highest, false)\n}\n\n/**\n * The Aronrepo commit types. The table is fixed: repositories choose a release\n * mode and release paths, not their own types.\n *\n * Release notes list the groups in this order.\n */\nexport const commits: readonly ConventionalCommitType[] = [\n { type: 'Bump', scope: 'Major', release: 'major', description: 'Release a major version. Only the repository owner decides it.' },\n { type: 'Bump', scope: 'Minor', release: 'minor', description: 'Release a minor version. Only the repository owner decides it.' },\n { type: 'Bump', scope: 'Patch', release: 'patch', description: 'Release a patch version without another release commit.' },\n { type: 'Add', release: 'minor', group: 'Additions', description: 'A new capability: a new API, export, option, command, or package.' },\n { type: 'Improve', release: 'patch', group: 'Improvements', description: 'A better existing capability without new API: behavior, output, messages, or defaults.' },\n { type: 'Perf', release: 'patch', group: 'Performance', description: 'Faster or lighter published code with the same behavior.' },\n { type: 'Fix', release: 'patch', group: 'Bug Fixes', description: 'A bug fix in published behavior.' },\n { type: 'Deprecate', release: 'patch', group: 'Deprecations', description: 'Mark a published capability as deprecated while it keeps working.' },\n { type: 'Drop', release: 'patch', group: 'Removals', description: 'Remove a published capability.' },\n { type: 'Upgrade', release: 'patch', group: 'Dependencies', description: 'Change a runtime dependency of a published package.' },\n { type: 'Revert', release: 'patch', group: 'Reverts', description: 'Revert a commit. It releases what the reverted commit released.' },\n { type: 'Docs', scope: 'README', release: 'patch', group: 'Documentation', description: 'Change a published package README.' },\n { type: 'Docs', release: false, description: 'Documentation that is not a published package README.' },\n { type: 'Test', release: false, description: 'Tests that cover existing behavior.' },\n { type: 'Benchmark', release: false, description: 'Benchmark harnesses, fixtures, and reports.' },\n { type: 'Example', release: false, description: 'Examples that do not ship in a package.' },\n { type: 'Build', release: false, description: 'Build tooling and development configuration.' },\n { type: 'CI', release: false, description: 'CI workflows and automation.' },\n { type: 'Style', release: false, description: 'Formatting and lint-only changes.' },\n { type: 'Refactor', release: false, description: 'Code changes that keep published behavior.' },\n { type: 'Chore', release: false, description: 'Maintenance: development dependencies, lockfiles, metadata, agent guidance, and unpublished workspaces.' }\n]\n\n/**\n * Types from earlier Aronrepo versions. They still resolve in history so old\n * commits release as before, but `aronrepo check` rejects them in new commits.\n */\nexport const legacyCommits: readonly LegacyCommitType[] = [\n { type: 'Feat', replacement: 'Add' },\n { type: 'New', replacement: 'Add' },\n { type: 'Update', replacement: 'Improve' },\n { type: 'Misc', replacement: 'Chore' }\n]\n\nexport const types: string[] = [...new Set(commits.map(({ type }) => type))]\n\nexport const legacyTypes: string[] = legacyCommits.map(({ type }) => type)\n\nexport const releaseCommits: ConventionalCommitType[] = commits.filter(({ release }) => release !== false)\n\nexport const nonReleaseCommits: ConventionalCommitType[] = commits.filter(({ release }) => release === false)\n\nexport const releaseTypes: string[] = [...new Set(releaseCommits.map(({ type }) => type))]\n\nexport const nonReleaseTypes: string[] = [...new Set(nonReleaseCommits.map(({ type }) => type))]\n\n/** Release notes groups in display order. */\nexport const releaseGroups: string[] = [...new Set(commits.flatMap(({ group }) => group ? [group] : []))]\n\n/** The current type for a legacy type, or the type itself. */\nexport function normalizeType(type: string): string\nexport function normalizeType(type: string | undefined): string | undefined\nexport function normalizeType(type: string | undefined) {\n return legacyCommits.find((legacy) => legacy.type === type)?.replacement ?? type\n}\n\nexport function findCommitRule(type: string | undefined, scope?: string): ConventionalCommitType | undefined {\n const current = normalizeType(type)\n if (!current) return undefined\n\n return commits.find((commit) => commit.type === current && commit.scope === scope)\n ?? commits.find((commit) => commit.type === current && commit.scope === undefined)\n}\n","import picomatch from 'picomatch'\nimport { commits, findCommitRule, legacyTypes, maxRelease, normalizeType, types, type ReleaseType } from './commits'\n\n/**\n * - `explicit`: only `Bump(Major)` and `Bump(Minor)` raise major and minor versions.\n * `Feat` and `New` release a patch, and breaking markers never change the level.\n * - `auto`: `Feat` and `New` release a minor version and a `BREAKING CHANGE:` footer\n * releases a major version, following Conventional Commits.\n */\nexport type ReleaseMode = 'explicit' | 'auto'\n\nexport const releaseModes = ['explicit', 'auto'] as const satisfies readonly ReleaseMode[]\n\nexport const defaultReleaseMode: ReleaseMode = 'explicit'\n\nexport interface ReleasePathsConfig {\n /** Globs, relative to the repository root, of files that ship in published packages. */\n include?: string[]\n /** Globs removed from `include`. Defaults to `defaultReleasePathExcludes`. */\n exclude?: string[]\n}\n\nexport interface AronrepoConfig {\n release?: {\n mode?: ReleaseMode\n /**\n * Files whose changes can release a version. Omit it to derive the paths from\n * public workspace packages, or set `false` to turn the path check off.\n */\n paths?: ReleasePathsConfig | false\n }\n}\n\nexport interface ReleasePolicy {\n mode: ReleaseMode\n paths?: ReleasePathsConfig | false\n}\n\nexport const defaultReleasePathExcludes = [\n '**/tests/**',\n '**/test/**',\n '**/__tests__/**',\n '**/*.{test,spec}.*',\n '**/benchmarks/**',\n '**/examples/**',\n '**/CHANGELOG.md',\n '.github/**',\n '.husky/**'\n]\n\nexport function defineConfig(config: AronrepoConfig) {\n return config\n}\n\nexport function getReleasePolicy(config: AronrepoConfig = {}): ReleasePolicy {\n const mode = config.release?.mode ?? defaultReleaseMode\n if (!releaseModes.includes(mode)) {\n throw new Error(`Unknown Aronrepo release mode \"${String(mode)}\". Use one of: ${releaseModes.join(', ')}.`)\n }\n return {\n mode,\n ...(config.release?.paths !== undefined ? { paths: config.release.paths } : {})\n }\n}\n\nexport const defaultReleasePolicy: ReleasePolicy = { mode: defaultReleaseMode }\n\n/** Returns a matcher for release paths, or `undefined` when every path may release. */\nexport function createReleasePathMatcher(paths: ReleasePathsConfig | false | undefined) {\n if (!paths || !paths.include) return undefined\n const include = picomatch(paths.include.length ? paths.include : ['!**'], { dot: true })\n const exclude = picomatch(paths.exclude ?? defaultReleasePathExcludes, { dot: true })\n return (file: string) => include(file) && !exclude(file)\n}\n\n/**\n * Release level of a commit type in the given mode, ignoring breaking markers and paths.\n * Use `resolveCommitRelease()` for the full decision.\n */\nexport function getReleaseType(type: string | undefined, scope?: string, policy: ReleasePolicy = defaultReleasePolicy): ReleaseType | undefined {\n const release = findCommitRule(type, scope)?.release\n if (release === undefined) return undefined\n return capRelease(release, type, policy)\n}\n\nfunction capRelease(release: ReleaseType, type: string | undefined, policy: ReleasePolicy): ReleaseType {\n if (policy.mode === 'explicit' && type !== 'Bump' && (release === 'major' || release === 'minor')) return 'patch'\n return release\n}\n\nexport const headerPattern = /^([A-Z]\\w*)(?:\\(([0-9A-Z`_#~].*)\\))?: ([0-9A-Z`_#~].*)$/\nconst breakingHeaderPattern = /^([A-Z]\\w*)(?:\\(([^)]*)\\))?!: (.+)$/\nconst breakingNotePattern = /^BREAKING[ -]CHANGE:/m\nconst footerLinePattern = /^BREAKING[ -]CHANGE:/\nconst githubRevertPattern = /^Revert \"([\\s\\S]+)\"$/\nconst revertHashPattern = /This reverts commit ([0-9a-f]{7,40})/i\n\nexport interface ParsedCommit {\n hash?: string\n header: string\n body: string\n type?: string\n scope?: string\n subject?: string\n /** Where a breaking marker was found, if any. */\n breaking?: 'header' | 'footer'\n /** Texts of `BREAKING CHANGE:` footers. */\n breakingNotes?: string[]\n /** Message layout problems that do not change the release. */\n layout?: Array<'body-leading-blank' | 'footer-leading-blank'>\n revert?: {\n header?: string\n hash?: string\n }\n}\n\nconst trailerPattern = /^[\\w-]+: /\n\n/** `BREAKING CHANGE:` footer texts; each runs until a blank line, another footer, or a git trailer. */\nfunction readBreakingNotes(lines: string[]) {\n const notes: string[] = []\n let current: string[] | undefined\n for (const line of lines) {\n const start = /^BREAKING[ -]CHANGE:\\s*(.*)$/.exec(line)\n if (start) {\n if (current) notes.push(current.join(' ').trim())\n current = [start[1]]\n } else if (current && line.trim() && !trailerPattern.test(line)) {\n current.push(line.trim())\n } else if (current) {\n notes.push(current.join(' ').trim())\n current = undefined\n }\n }\n if (current) notes.push(current.join(' ').trim())\n return notes.filter(Boolean)\n}\n\nexport function parseCommit(message: string, hash?: string): ParsedCommit {\n const normalized = message.replace(/\\r\\n/g, '\\n').trim()\n const [header = '', ...rest] = normalized.split('\\n')\n const body = rest.join('\\n').trim()\n const parsed: ParsedCommit = { header, body, ...(hash ? { hash } : {}) }\n\n const layout: NonNullable<ParsedCommit['layout']> = []\n if (rest.length && rest[0].trim()) layout.push('body-leading-blank')\n if (rest.some((line, index) => index > 0 && footerLinePattern.test(line) && rest[index - 1].trim())) layout.push('footer-leading-blank')\n if (layout.length) parsed.layout = layout\n const breakingNotes = readBreakingNotes(rest)\n if (breakingNotes.length) parsed.breakingNotes = breakingNotes\n\n const regular = headerPattern.exec(header)\n const match = regular ?? breakingHeaderPattern.exec(header)\n if (match) {\n parsed.type = match[1]\n if (match[2]) parsed.scope = match[2]\n parsed.subject = match[3]\n if (!regular) parsed.breaking = 'header'\n }\n if (!parsed.breaking && breakingNotePattern.test(body)) parsed.breaking = 'footer'\n\n const githubRevert = githubRevertPattern.exec(header)\n if (githubRevert || parsed.type === 'Revert') {\n const revertedHeader = githubRevert?.[1] ?? (parsed.subject && headerPattern.test(parsed.subject) ? parsed.subject : undefined)\n const revertedHash = revertHashPattern.exec(body)?.[1]\n parsed.revert = {\n ...(revertedHeader ? { header: revertedHeader } : {}),\n ...(revertedHash ? { hash: revertedHash } : {})\n }\n }\n return parsed\n}\n\nexport type CommitViolationRule =\n | 'header-format'\n | 'subject-full-stop'\n | 'unknown-type'\n | 'legacy-type'\n | 'implicit-breaking'\n | 'release-paths'\n | 'body-leading-blank'\n | 'footer-leading-blank'\n\nexport interface CommitViolation {\n rule: CommitViolationRule\n /** Errors fail `aronrepo check`; warnings are printed only. Defaults to `error`. */\n severity?: 'error' | 'warning'\n message: string\n /** A header that satisfies the policy, when one can be derived. */\n suggestion?: string\n}\n\nexport interface CommitDecision {\n hash?: string\n header: string\n type?: string\n scope?: string\n subject?: string\n /** Texts of `BREAKING CHANGE:` footers, kept for `Bump(Major)` release notes. */\n breakingNotes?: string[]\n /** Effective release level after mode, breaking markers, reverts, and paths. */\n release: ReleaseType\n reasons: string[]\n violations: CommitViolation[]\n}\n\nexport interface ResolveCommitOptions {\n /** Files the commit changes. Omit it to skip the release path check. */\n files?: string[]\n /** Decides whether a changed file ships in a published package. */\n isReleasePath?: (file: string) => boolean\n}\n\nexport const nonReleaseAlternatives = ['Chore', 'Refactor', 'Style', 'Test', 'Docs', 'Build', 'CI', 'Benchmark', 'Example']\n\nfunction suggestNonReleaseHeader(commit: ParsedCommit) {\n const subject = commit.subject ?? ''\n const scope = commit.scope ? `(${commit.scope})` : ''\n switch (commit.type) {\n case 'Docs':\n return `Docs: ${subject}`\n case 'Upgrade':\n return `Chore(Deps): ${subject}`\n default:\n return `Chore${scope}: ${subject}`\n }\n}\n\nconst looseHeaderPattern = /^(\\w+)(?:\\(([^)]*)\\))?(!)?: ?(.*)$/\n\nfunction diagnoseHeader(header: string) {\n const format = 'Use `Type(Scope): Summary` or `Type: Summary` with an Aronrepo commit type.'\n const match = looseHeaderPattern.exec(header)\n if (!match) return format\n const [, type, scope, bang, subject] = match\n if (!/^[A-Z]/.test(type)) return `The type \\`${type}\\` must be PascalCase, such as \\`${type[0].toUpperCase()}${type.slice(1)}\\`. ${format}`\n if (bang) return `Aronrepo headers do not use \\`!\\`. ${format}`\n if (scope !== undefined && !/^[0-9A-Z`_#~]/.test(scope)) return `The scope \\`${scope}\\` must start with an uppercase letter or digit. ${format}`\n if (!subject) return `The summary is empty. ${format}`\n if (!/^[0-9A-Z`_#~]/.test(subject)) return `The summary must start with an uppercase letter or digit. ${format}`\n return format\n}\n\nfunction formatRelease(release: ReleaseType | undefined) {\n return release ? release : 'none'\n}\n\nexport function resolveCommitRelease(\n input: string | ParsedCommit,\n policy: ReleasePolicy = defaultReleasePolicy,\n options: ResolveCommitOptions = {}\n): CommitDecision {\n const commit = typeof input === 'string' ? parseCommit(input) : input\n const decision: CommitDecision = {\n ...(commit.hash ? { hash: commit.hash } : {}),\n header: commit.header,\n ...(commit.type ? { type: commit.type } : {}),\n ...(commit.scope ? { scope: commit.scope } : {}),\n ...(commit.subject ? { subject: commit.subject } : {}),\n ...(commit.breakingNotes ? { breakingNotes: commit.breakingNotes } : {}),\n release: false,\n reasons: [],\n violations: []\n }\n\n if (commit.revert?.header && !commit.type) {\n // GitHub's default `Revert \"Type(Scope): Summary\"` header.\n decision.type = 'Revert'\n } else if (!commit.type) {\n decision.reasons.push('Header does not follow `Type(Scope): Summary`; no release.')\n decision.violations.push({\n rule: 'header-format',\n message: diagnoseHeader(commit.header)\n })\n return decision\n } else if (!types.includes(commit.type) && !legacyTypes.includes(commit.type)) {\n decision.reasons.push(`Unknown type \\`${commit.type}\\`; no release.`)\n decision.violations.push({\n rule: 'unknown-type',\n message: `\\`${commit.type}\\` is not an Aronrepo commit type. Use one of: ${types.join(', ')}.`\n })\n return decision\n } else if (!findCommitRule(commit.type, commit.scope)) {\n decision.reasons.push(`\\`${commit.type}${commit.scope ? `(${commit.scope})` : ''}\\` is not an Aronrepo commit type; no release.`)\n decision.violations.push({\n rule: 'unknown-type',\n message: `\\`${commit.type}\\` needs a scope: ${commits.filter(({ type }) => type === commit.type).map(({ type, scope }) => `\\`${type}(${scope})\\``).join(', ')}.`\n })\n return decision\n }\n\n if (commit.subject?.endsWith('.')) {\n decision.violations.push({\n rule: 'subject-full-stop',\n message: 'The summary must not end with a period.',\n suggestion: commit.header.replace(/\\.+$/, '')\n })\n }\n for (const rule of commit.layout ?? []) {\n decision.violations.push({\n rule,\n severity: 'warning',\n message: rule === 'body-leading-blank'\n ? 'Leave a blank line between the header and the body.'\n : 'Leave a blank line before a `BREAKING CHANGE:` footer.'\n })\n }\n\n if (commit.type && legacyTypes.includes(commit.type)) {\n const replacement = normalizeType(commit.type)\n const scope = commit.scope ? `(${commit.scope})` : ''\n decision.reasons.push(`\\`${commit.type}\\` is a legacy type; it releases like \\`${replacement}\\`.`)\n decision.violations.push({\n rule: 'legacy-type',\n message: `\\`${commit.type}\\` is a legacy Aronrepo type. Use \\`${replacement}\\`.`,\n suggestion: `${replacement}${scope}: ${commit.subject ?? ''}`\n })\n }\n\n let release: ReleaseType\n if (decision.type === 'Revert' && commit.revert?.header) {\n const reverted = resolveCommitRelease(commit.revert.header, policy, options)\n release = reverted.release\n decision.reasons.push(`Reverts \\`${commit.revert.header}\\`, which releases ${formatRelease(release)}.`)\n } else {\n const rule = findCommitRule(decision.type, decision.scope)!\n release = capRelease(rule.release, decision.type, policy)\n decision.reasons.push(`\\`${decision.type}${decision.scope ? `(${decision.scope})` : ''}\\` releases ${formatRelease(release)} in ${policy.mode} mode.`)\n if (release !== rule.release) {\n decision.reasons.push(`Explicit mode caps \\`${decision.type}\\` at patch; only \\`Bump(Minor)\\` or \\`Bump(Major)\\` raise the version further.`)\n }\n }\n\n const isBumpMajor = decision.type === 'Bump' && decision.scope === 'Major'\n if (commit.breaking && !isBumpMajor) {\n const marker = commit.breaking === 'header' ? '`!` header' : '`BREAKING CHANGE:` footer'\n if (policy.mode === 'auto') {\n release = 'major'\n decision.reasons.push(`The ${marker} releases major in auto mode.`)\n } else {\n decision.reasons.push(`The ${marker} is ignored in explicit mode; only \\`Bump(Major)\\` releases major.`)\n decision.violations.push({\n rule: 'implicit-breaking',\n message: `A ${marker} does not release a major version in explicit mode. Describe the change without the breaking marker, or ask the repository owner whether to add a \\`Bump(Major)\\` commit.`\n })\n }\n }\n\n const isBump = decision.type === 'Bump'\n if (release && !isBump && options.files && options.isReleasePath) {\n const releaseFiles = options.files.filter(options.isReleasePath)\n if (!releaseFiles.length) {\n decision.reasons.push('No changed file ships in a published package; no release.')\n decision.violations.push({\n rule: 'release-paths',\n message: `\\`${decision.type}${decision.scope ? `(${decision.scope})` : ''}\\` releases ${formatRelease(release)}, but the commit changes no release paths. Use a non-release type: ${nonReleaseAlternatives.join(', ')}.`,\n suggestion: suggestNonReleaseHeader({ ...commit, type: decision.type })\n })\n release = false\n }\n }\n\n decision.release = release\n return decision\n}\n\nexport interface CommitInput {\n message: string\n hash?: string\n files?: string[]\n}\n\nexport interface ReleaseDecision {\n release: ReleaseType\n commits: CommitDecision[]\n}\n\nexport function resolveRelease(\n inputs: CommitInput[],\n policy: ReleasePolicy = defaultReleasePolicy,\n options: Omit<ResolveCommitOptions, 'files'> = {}\n): ReleaseDecision {\n const parsed = inputs.map((input) => parseCommit(input.message, input.hash))\n const decisions = parsed.map((commit, index) =>\n resolveCommitRelease(commit, policy, { ...options, ...(inputs[index].files ? { files: inputs[index].files } : {}) }))\n\n // A revert and the commit it reverts cancel each other when both are unreleased.\n parsed.forEach((commit, index) => {\n const revertedHash = commit.revert?.hash\n if (!revertedHash) return\n const revertedIndex = parsed.findIndex((candidate) => candidate.hash?.startsWith(revertedHash) || (candidate.hash && revertedHash.startsWith(candidate.hash)))\n if (revertedIndex === -1 || revertedIndex === index) return\n for (const [target, other] of [[index, revertedIndex], [revertedIndex, index]]) {\n decisions[target].release = false\n decisions[target].reasons.push(`Cancelled by \\`${parsed[other].header}\\` in the same release.`)\n }\n })\n\n return {\n release: maxRelease(...decisions.map(({ release }) => release)),\n commits: decisions\n }\n}\n","import { commits, legacyCommits, type ReleaseType } from './commits'\nimport {\n defaultReleasePathExcludes,\n defaultReleasePolicy,\n getReleaseType,\n nonReleaseAlternatives,\n type ReleasePathsConfig,\n type ReleasePolicy\n} from './policy'\n\nexport interface AgentCommitPolicyExample {\n commit: string\n use: string\n release: ReleaseType\n avoid?: string\n}\n\nexport interface AgentCommitPolicy {\n mode: ReleasePolicy['mode']\n defaultInternalCommit: string\n defaultInternalType: string\n defaultInternalScope: string\n releaseImpactRule: string\n /** Release decisions that belong to the repository owner, not to a coding agent. */\n ownerDecisions: string[]\n releaseWorthyChanges: string[]\n nonReleaseDefaults: string[]\n /** Commands an agent runs to check its commits before handing them off. */\n verification: string[]\n examples: AgentCommitPolicyExample[]\n}\n\nexport interface AgentCommitPolicyOptions {\n /** How to run the CLI in this repository, such as `bun x aronrepo` or `pnpm exec aronrepo`. */\n cli?: string\n}\n\nexport function getAgentCommitPolicy(policy: ReleasePolicy = defaultReleasePolicy, options: AgentCommitPolicyOptions = {}): AgentCommitPolicy {\n const explicit = policy.mode === 'explicit'\n const cli = options.cli ?? 'npx aronrepo'\n return {\n mode: policy.mode,\n defaultInternalCommit: 'Chore(Agent): Clarify commit selection policy',\n defaultInternalType: 'Chore',\n defaultInternalScope: 'Agent',\n releaseImpactRule: 'Use a release type only when the commit changes files that ship in a published package (release paths) and affects published behavior, public API, release behavior, or published README content. Otherwise use a non-release type.',\n ownerDecisions: explicit\n ? [\n 'Never write `Bump(Major)` or `Bump(Minor)` unless the user explicitly asked for that release level in the current conversation.',\n 'Never add a `BREAKING CHANGE:` footer or a `Type!:` header. If a change breaks published behavior, stop and ask the user how to release it.',\n 'Every type except `Bump(Minor)` and `Bump(Major)` releases at most a patch. Pick the type that describes the change, not the release level you want.'\n ]\n : [\n 'Never write `Bump(Major)` or `Bump(Minor)` unless the user explicitly asked for that release level in the current conversation.',\n 'A `BREAKING CHANGE:` footer releases a major version. Add one only for a real break in published behavior or public API, and tell the user.',\n '`Add` releases a minor version. Use it only for new capabilities of published packages.'\n ],\n releaseWorthyChanges: [\n 'Published package runtime behavior',\n 'Public API, exports, or types',\n 'Release, changelog, or versioning behavior',\n 'Published README content that requires a package patch release'\n ],\n nonReleaseDefaults: [\n 'Agent instructions, prompts, and repository context: `Chore(Agent)`',\n 'Sites, apps, and other unpublished workspaces: `Chore(<Scope>)`, `Refactor`, `Style`, or `Test`, even for fixes and performance work',\n 'Tests that only cover existing behavior: `Test`',\n 'Benchmark harnesses, fixtures, reports, and measurement-only changes: `Benchmark` (never `Perf`)',\n 'Build tooling and dev-only configuration: `Build`; CI workflows: `CI`; formatting: `Style`',\n 'Development dependencies, lockfiles, and routine metadata: `Chore(Deps)` or `Chore`',\n 'Examples: `Example`; internal or site documentation: `Docs`',\n 'Refactors that do not change published behavior: `Refactor`'\n ],\n verification: [\n `${cli} check --from origin/main --to HEAD`,\n `${cli} explain`\n ],\n examples: [\n {\n commit: 'Add(Core): Support ESM config files',\n use: 'A new capability in a published package',\n release: getReleaseType('Add', 'Core', policy) ?? false,\n ...(explicit ? { avoid: 'Feat(Core): Support ESM config files' } : {})\n },\n {\n commit: 'Chore(Site): Fix the homepage header transition',\n use: 'A fix in an unpublished site or app workspace',\n release: false,\n avoid: 'Fix(Site): Fix the homepage header transition'\n },\n {\n commit: 'Chore(Agent): Update repository guidance for coding agents',\n use: 'Agent instructions, prompts, or repo context',\n release: false,\n avoid: 'Feat(Agent): Add agent guide'\n },\n {\n commit: 'Test(Release): Cover scoped README bump rules',\n use: 'Tests that validate existing release behavior',\n release: false\n },\n {\n commit: 'Benchmark(Benchmarks): Refresh benchmark report',\n use: 'Benchmark-only changes when the benchmark area is the useful scope',\n release: false,\n avoid: 'Perf(Benchmarks): Refresh benchmark report'\n },\n {\n commit: 'Benchmark: Refresh benchmark report',\n use: 'Benchmark-only changes when no clear scope exists',\n release: false\n },\n {\n commit: 'CI(GitHub): Update PR title check permissions',\n use: 'CI workflow, status check, and automation changes that do not change release behavior',\n release: false,\n avoid: 'Fix(CI): Update PR title check permissions'\n },\n {\n commit: 'Build(Tooling): Update Vitest config',\n use: 'Build system, bundler, local tooling, and dev-only configuration changes',\n release: false,\n avoid: 'Update(Build): Update Vitest config'\n },\n {\n commit: 'Style(Lint): Format TypeScript files',\n use: 'Formatting, lint-only, whitespace, or readability changes with no behavior change',\n release: false,\n avoid: 'Improve(Core): Format TypeScript files'\n },\n {\n commit: 'Chore(Deps): Update Vitest dev dependency',\n use: 'Development dependency, lockfile, audit report, and routine metadata changes',\n release: false,\n avoid: 'Upgrade(Deps): Update Vitest dev dependency'\n },\n {\n commit: 'Example(Release): Add a release workflow sample',\n use: 'Example-only additions or updates that do not change published package behavior',\n release: false,\n avoid: 'Add(Example): Add a release workflow sample'\n },\n {\n commit: 'Docs: Add commit type examples',\n use: 'Documentation that is not published as package README content',\n release: false\n },\n {\n commit: 'Docs(README): Clarify package installation',\n use: 'A published package README (not the repository root README)',\n release: 'patch'\n },\n {\n commit: 'Fix(Release): Preserve workspace dependency ranges',\n use: 'A release behavior bug that affects published package behavior',\n release: 'patch'\n }\n ]\n }\n}\n\n/** Agent policy for the default `explicit` mode. */\nexport const agentCommitPolicy = getAgentCommitPolicy()\n\nfunction formatRule(type: string, scope?: string) {\n return `\\`${type}${scope ? `(${scope})` : ''}\\``\n}\n\nexport function getReleaseTable(policy: ReleasePolicy = defaultReleasePolicy) {\n const rows: Record<'major' | 'minor' | 'patch' | 'none', string[]> = { major: [], minor: [], patch: [], none: [] }\n for (const { type, scope } of commits) {\n const release = getReleaseType(type, scope, policy)\n rows[release || 'none'].push(formatRule(type, scope))\n }\n if (policy.mode === 'auto') rows.major.push('`BREAKING CHANGE:` footer')\n return rows\n}\n\nexport const agentsBlockStart = '<!-- aronrepo:commit-policy:start -->'\nexport const agentsBlockEnd = '<!-- aronrepo:commit-policy:end -->'\n\nexport interface RenderAgentsBlockOptions extends AgentCommitPolicyOptions {\n /** Resolved release paths; `undefined` means every path may release. */\n releasePaths?: ReleasePathsConfig\n}\n\n/** Renders the generated commit policy block for AGENTS.md, including its markers. */\nexport function renderAgentsBlock(policy: ReleasePolicy = defaultReleasePolicy, options: RenderAgentsBlockOptions = {}) {\n const agent = getAgentCommitPolicy(policy, options)\n const paths = options.releasePaths\n const typeRows = commits.map(({ type, scope, description }) =>\n `| ${formatRule(type, scope)} | ${getReleaseType(type, scope, policy) || 'none'} | ${description} |`)\n const lines = [\n agentsBlockStart,\n '<!-- Generated by `aronrepo agents --write`. Edit aronrepo.config.js and regenerate instead of editing this block. -->',\n '',\n '## Commit and Release Policy',\n '',\n `Release mode: **${policy.mode}**. ${policy.mode === 'explicit'\n ? 'Only the repository owner decides minor and major versions, with `Bump(Minor)` and `Bump(Major)` commits.'\n : '`Add` releases minor versions, and `BREAKING CHANGE:` footers release major versions.'}`,\n '',\n 'Commit headers and PR titles use `Type(Scope): Summary` or `Type: Summary`: a PascalCase type, an optional scope for the package or area, and a sentence-case summary without a trailing period.',\n '',\n '| Type | Release | Use for |',\n '| --- | --- | --- |',\n ...typeRows,\n '',\n `Legacy types are rejected: ${legacyCommits.map(({ type, replacement }) => `\\`${type}\\` (use \\`${replacement}\\`)`).join(', ')}.`,\n '',\n '### Release decisions belong to the owner',\n '',\n ...agent.ownerDecisions.map((rule) => `- ${rule}`),\n '',\n '### Choosing a type',\n '',\n `- ${agent.releaseImpactRule}`,\n '- Pick the type that describes the change: a new capability is `Add`, a better existing capability is `Improve`, a bug fix is `Fix`, and a runtime dependency change is `Upgrade`.',\n `- A commit that changes no release path must use a non-release type (${nonReleaseAlternatives.map((type) => `\\`${type}\\``).join(', ')}), even when it fixes or speeds up something.`,\n '- Split unrelated changes so each commit carries its own release level.',\n '',\n 'Non-release defaults:',\n '',\n ...agent.nonReleaseDefaults.map((rule) => `- ${rule}`),\n '',\n '### Release paths',\n '',\n ...(paths?.include\n ? [\n 'Only changes to these files can release a version:',\n '',\n ...paths.include.map((glob) => `- \\`${glob}\\``),\n '',\n `Excluding: ${(paths.exclude ?? defaultReleasePathExcludes).map((glob) => `\\`${glob}\\``).join(', ')}.`\n ]\n : ['Every path can release a version in this repository.']),\n '',\n '### Before handing off commits',\n '',\n ...agent.verification.map((command) => `- \\`${command}\\``),\n '',\n '`aronrepo explain` prints the next release level and the reason for each commit. Tell the user when it is not what they expect.',\n agentsBlockEnd\n ]\n return lines.join('\\n')\n}\n","import semver from 'semver'\nimport type { ReleaseType } from './commits'\n\n/** Prerelease branches. Each publishes `X.Y.Z-<branch>.N` on the npm dist-tag of the same name. */\nexport const prereleaseChannels = ['alpha', 'beta', 'rc', 'canary'] as const\n\n/** Branches that release: `main` publishes on `latest`, and each prerelease branch on its own dist-tag. */\nexport const releaseBranches = ['main', ...prereleaseChannels] as const\n\nexport interface ReleaseChannel {\n branch: string\n /** npm dist-tag that the release moves to. */\n distTag: string\n /** Prerelease identifier, for prerelease branches only. */\n prerelease?: string\n}\n\n/** The release channel of a branch, or `undefined` when the branch does not release. */\nexport function getReleaseChannel(branch: string | undefined): ReleaseChannel | undefined {\n if (branch === 'main') return { branch, distTag: 'latest' }\n if (branch && (prereleaseChannels as readonly string[]).includes(branch)) return { branch, distTag: branch, prerelease: branch }\n return undefined\n}\n\n/** The first version of a repository without version tags. */\nexport const initialVersion = '1.0.0'\n\nexport function toVersionTag(version: string) {\n return `v${version}`\n}\n\n/** The version of a `vX.Y.Z` or `vX.Y.Z-pre.N` tag, or `undefined` for other tags. */\nexport function parseVersionTag(tag: string) {\n if (!tag.startsWith('v')) return undefined\n const version = tag.slice(1)\n return semver.valid(version) === version ? version : undefined\n}\n\nfunction versionsOf(tags: string[]) {\n return tags.flatMap((tag) => {\n const version = parseVersionTag(tag)\n return version ? [version] : []\n })\n}\n\nfunction highest(versions: string[]) {\n return versions.length ? semver.rsort([...versions])[0] : undefined\n}\n\nfunction stableVersions(versions: string[]) {\n return versions.filter((version) => !semver.prerelease(version))\n}\n\nfunction channelVersions(versions: string[], prerelease: string) {\n return versions.filter((version) => semver.prerelease(version)?.[0] === prerelease)\n}\n\nfunction coreVersion(version: string) {\n return `${semver.major(version)}.${semver.minor(version)}.${semver.patch(version)}`\n}\n\n/** The latest stable version among tags, if any. */\nexport function getLatestStableVersion(tags: string[]) {\n return highest(stableVersions(versionsOf(tags)))\n}\n\n/**\n * The tag a channel's release range starts from: the latest stable tag, or on a\n * prerelease branch the latest tag of that channel when it is newer.\n */\nexport function getBaseTag(channel: ReleaseChannel, reachableTags: string[]) {\n const versions = versionsOf(reachableTags)\n const stable = highest(stableVersions(versions))\n if (channel.prerelease) {\n const prerelease = highest(channelVersions(versions, channel.prerelease)\n .filter((version) => !stable || semver.gt(version, stable)))\n if (prerelease) return toVersionTag(prerelease)\n }\n return stable ? toVersionTag(stable) : undefined\n}\n\nexport interface VersionTags {\n /** Version tags reachable from the release commit. */\n reachable: string[]\n /** Every version tag in the repository, to number prereleases. */\n all: string[]\n}\n\n/**\n * The next version of a channel.\n *\n * `main` raises the latest stable version by `release`. A prerelease branch\n * targets the same version, or the version its earlier prereleases already\n * target when that is higher, and numbers the prerelease after every existing\n * tag of that version and channel.\n */\nexport function getNextVersion(channel: ReleaseChannel, release: Exclude<ReleaseType, false>, tags: VersionTags) {\n const reachable = versionsOf(tags.reachable)\n const stable = highest(stableVersions(reachable))\n const target = stable ? semver.inc(stable, release)! : initialVersion\n if (!channel.prerelease) return target\n\n const previous = highest(channelVersions(reachable, channel.prerelease)\n .filter((version) => !stable || semver.gt(version, stable)))\n const core = previous && semver.gte(coreVersion(previous), target) ? coreVersion(previous) : target\n const numbers = channelVersions(versionsOf(tags.all), channel.prerelease)\n .filter((version) => coreVersion(version) === core)\n .map((version) => Number(semver.prerelease(version)?.[1] ?? 0))\n return `${core}-${channel.prerelease}.${Math.max(0, ...numbers) + 1}`\n}\n","import { findCommitRule, releaseGroups } from './commits'\nimport type { CommitDecision } from './policy'\n\nexport interface ReleaseNotesOptions {\n version: string\n /** Tag of the previous release, for the compare link. */\n previousTag?: string\n /** Release date as `YYYY-MM-DD`. */\n date?: string\n /** Repository URL, such as `https://github.com/owner/repo`, for links. */\n repositoryUrl?: string\n commits: CommitDecision[]\n}\n\nconst breakingTitle = '⚠ Breaking Changes'\n\nfunction groupOf(decision: CommitDecision) {\n if (decision.type === 'Revert') return 'Reverts'\n return findCommitRule(decision.type, decision.scope)?.group\n}\n\nfunction formatEntry(decision: CommitDecision, repositoryUrl?: string) {\n const summary = decision.subject ?? decision.header\n const scope = decision.scope ? `**${decision.scope}:** ` : ''\n const hash = decision.hash ? decision.hash.slice(0, 7) : undefined\n const link = hash\n ? repositoryUrl ? ` ([${hash}](${repositoryUrl}/commit/${decision.hash}))` : ` (${hash})`\n : ''\n return `- ${scope}${summary}${link}`\n}\n\n/**\n * Markdown release notes. Only commits that release appear, grouped by type in\n * the order of the commit table; `BREAKING CHANGE:` footers of major releases\n * come first.\n */\nexport function renderReleaseNotes(options: ReleaseNotesOptions) {\n const { version, previousTag, repositoryUrl } = options\n const tag = `v${version}`\n const title = repositoryUrl && previousTag\n ? `[${version}](${repositoryUrl}/compare/${previousTag}...${tag})`\n : version\n const lines = [`## ${title}${options.date ? ` (${options.date})` : ''}`]\n\n const released = options.commits.filter(({ release }) => release)\n const breaking = released\n .filter(({ release }) => release === 'major')\n .flatMap(({ breakingNotes }) => breakingNotes ?? [])\n if (breaking.length) {\n lines.push('', `### ${breakingTitle}`, '', ...breaking.map((note) => `- ${note}`))\n }\n\n const groups = new Map<string, CommitDecision[]>()\n for (const decision of released) {\n const group = groupOf(decision)\n if (!group) continue\n groups.set(group, [...groups.get(group) ?? [], decision])\n }\n for (const group of releaseGroups) {\n const entries = groups.get(group)\n if (!entries) continue\n const sorted = [...entries].sort((a, b) =>\n (a.scope ?? '').localeCompare(b.scope ?? '', 'en') || (a.subject ?? a.header).localeCompare(b.subject ?? b.header, 'en'))\n lines.push('', `### ${group}`, '', ...sorted.map((decision) => formatEntry(decision, repositoryUrl)))\n }\n\n if (!breaking.length && !groups.size) lines.push('', 'No changes to published packages.')\n return `${lines.join('\\n')}\\n`\n}\n"],"mappings":"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"}
package/dist/node.d.ts ADDED
@@ -0,0 +1,226 @@
1
+ import { E as CommitInput, M as ReleasePathsConfig, N as ReleasePolicy, T as CommitDecision, X as ReleaseType, j as ReleaseMode, r as ReleaseChannel, w as AronrepoConfig } from "./index-Co5yiJXA.js";
2
+ export interface PackageJson {
3
+ name?: string;
4
+ version?: string;
5
+ private?: boolean;
6
+ workspaces?: string[] | {
7
+ packages?: string[];
8
+ };
9
+ publishConfig?: {
10
+ access?: string;
11
+ provenance?: boolean;
12
+ [key: string]: unknown;
13
+ };
14
+ [key: string]: unknown;
15
+ }
16
+ export declare const configFileNames: string[];
17
+ export declare function findConfigFile(cwd?: string): string | undefined;
18
+ /** Loads `aronrepo.config.js` from the repository root; returns `{}` when it is missing. */
19
+ export declare function loadConfig(cwd?: string): Promise<AronrepoConfig>;
20
+ export declare function readWorkspacePatterns(cwd?: string): string[];
21
+ export declare function queryWorkspaceDirs(patterns: string[], cwd?: string): string[];
22
+ export declare function readWorkspacePackage(cwd: string, workspace: string): PackageJson;
23
+ /** Workspace directories whose package is published to npm. */
24
+ export declare function queryPublicWorkspaceDirs(cwd?: string): string[];
25
+ /**
26
+ * Resolves the files whose changes can release a version.
27
+ *
28
+ * Configured paths win. Otherwise public workspace packages define them; a
29
+ * single-package repository with a non-private root package uses every path.
30
+ * Returns `undefined` when no published package is found, which turns the check off.
31
+ */
32
+ export declare function resolveReleasePaths(cwd?: string, policy?: Pick<ReleasePolicy, 'paths'>): ReleasePathsConfig | undefined;
33
+ export type PackageManager = 'bun' | 'pnpm' | 'yarn' | 'npm';
34
+ /** The package manager from `packageManager` in package.json, then from the lockfile; `npm` by default. */
35
+ export declare function detectPackageManager(cwd?: string): PackageManager;
36
+ /** How to run the aronrepo CLI with a package manager. */
37
+ export declare function getCliCommand(packageManager: PackageManager): string;
38
+ /**
39
+ * How to run the aronrepo CLI in a repository: its `aronrepo` script when it has
40
+ * one, for example a workspace that builds aronrepo itself, or the installed binary.
41
+ */
42
+ export declare function getProjectCliCommand(cwd: string, packageManager?: PackageManager): string;
43
+ export interface ProjectPolicy {
44
+ cwd: string;
45
+ packageManager: PackageManager;
46
+ /** How to run the aronrepo CLI in this repository. */
47
+ cli: string;
48
+ config: AronrepoConfig;
49
+ configFile?: string;
50
+ policy: ReleasePolicy;
51
+ releasePaths?: ReleasePathsConfig;
52
+ isReleasePath?: (file: string) => boolean;
53
+ }
54
+ /** Loads the config, release policy, and release paths of a repository. */
55
+ export declare function loadProjectPolicy(cwd?: string, overrides?: Partial<ReleasePolicy>): Promise<ProjectPolicy>;
56
+ /** Files changed by one commit. Merge commits report no files. */
57
+ export declare function getCommitFiles(cwd: string, hash: string): string[];
58
+ export declare function getStagedFiles(cwd?: string): string[];
59
+ /** Files changed between the merge base of `base` and `head`, like a pull request diff. */
60
+ export declare function getDiffFiles(cwd: string, base: string, head: string): string[];
61
+ /** Commits in `from..to`, oldest first, with their changed files. */
62
+ export declare function getRangeCommits(cwd: string, from: string | undefined, to?: string): Required<CommitInput>[];
63
+ /** Latest tag reachable from `ref`, or `undefined` when there is none. */
64
+ export declare function getLatestTag(cwd: string, ref?: string): string | undefined;
65
+ /** Resolves the release of a commit range with the repository's policy and release paths. */
66
+ export declare function explainRange(cwd: string, from: string | undefined, to?: string, overrides?: Partial<ReleasePolicy>): Promise<{
67
+ release: ReleaseType;
68
+ commits: CommitDecision[];
69
+ from: string | undefined;
70
+ to: string;
71
+ cwd: string;
72
+ packageManager: PackageManager;
73
+ /** How to run the aronrepo CLI in this repository. */
74
+ cli: string;
75
+ config: AronrepoConfig;
76
+ configFile?: string;
77
+ policy: ReleasePolicy;
78
+ releasePaths?: ReleasePathsConfig;
79
+ isReleasePath?: (file: string) => boolean;
80
+ }>;
81
+ export interface CommandResult {
82
+ code: number;
83
+ output: string;
84
+ }
85
+ export interface CommonOptions {
86
+ cwd?: string;
87
+ mode?: ReleaseMode;
88
+ json?: boolean;
89
+ }
90
+ export declare function isIgnoredMessage(message: string): boolean;
91
+ export interface CheckOptions extends CommonOptions {
92
+ /** Commit message file, as passed to a commit-msg hook. Uses staged files. */
93
+ edit?: string;
94
+ /** Commit message text. Uses staged files unless `files` is set. */
95
+ message?: string;
96
+ /** PR title, checked against the `base...head` diff. */
97
+ title?: string;
98
+ base?: string;
99
+ head?: string;
100
+ /** Commit range, checked commit by commit with each commit's own files. */
101
+ from?: string;
102
+ to?: string;
103
+ files?: string[];
104
+ }
105
+ export declare function check(options: CheckOptions): Promise<CommandResult>;
106
+ export interface ExplainOptions extends CommonOptions {
107
+ from?: string;
108
+ to?: string;
109
+ }
110
+ export declare function explain(options: ExplainOptions): Promise<CommandResult>;
111
+ export interface ReleaseCommandOptions extends CommonOptions {
112
+ dryRun?: boolean;
113
+ branch?: string;
114
+ /** Receives progress lines; defaults to stdout. JSON output stays quiet. */
115
+ log?: (message: string) => void;
116
+ }
117
+ export declare function release(options: ReleaseCommandOptions): Promise<CommandResult>;
118
+ export declare function policy(options: CommonOptions & {
119
+ markdown?: boolean;
120
+ }): Promise<CommandResult>;
121
+ export declare function replaceAgentsBlock(content: string, block: string): string;
122
+ export declare function readAgentsBlock(content: string): string | undefined;
123
+ export declare function agents(options: CommonOptions & {
124
+ file?: string;
125
+ write?: boolean;
126
+ }): Promise<CommandResult>;
127
+ export declare function doctor(options: CommonOptions): Promise<CommandResult>;
128
+ export declare const officialRegistry = "https://registry.npmjs.org/";
129
+ /** npm dist-tag that holds a release until every package of it is published. */
130
+ export declare const stagingDistTag = "aronrepo-staging";
131
+ /** GitHub rejects release bodies over 125,000 characters. */
132
+ export declare const releaseBodyLimit = 120000;
133
+ export interface RunResult {
134
+ stdout: string;
135
+ stderr: string;
136
+ }
137
+ export type Runner = (command: string, args: string[], options: {
138
+ cwd: string;
139
+ env: NodeJS.ProcessEnv;
140
+ }) => Promise<RunResult>;
141
+ export type Fetch = (input: string, init?: RequestInit) => Promise<Response>;
142
+ export interface ReleaseEnvironment {
143
+ cwd: string;
144
+ env: NodeJS.ProcessEnv;
145
+ run: Runner;
146
+ fetch: Fetch;
147
+ log: (message: string) => void;
148
+ /** Waits between registry checks. */
149
+ wait: (ms: number) => Promise<void>;
150
+ }
151
+ export declare const runCommand: Runner;
152
+ export interface ReleasePackage {
153
+ /** Directory relative to the repository root, `.` for a single-package repository. */
154
+ dir: string;
155
+ name: string;
156
+ manifest: PackageJson;
157
+ }
158
+ /** Published packages of the repository in dependency order. */
159
+ export declare function getReleasePackages(cwd: string): ReleasePackage[];
160
+ export interface ReleasePlan {
161
+ branch: string;
162
+ channel?: ReleaseChannel;
163
+ /** Full hash of the commit that releases. */
164
+ head: string;
165
+ mode: ReleasePolicy['mode'];
166
+ /** The tag the range starts from; `undefined` for the first release. */
167
+ from?: string;
168
+ release: ReleaseType;
169
+ version?: string;
170
+ tag?: string;
171
+ commits: CommitDecision[];
172
+ notes?: string;
173
+ packages: ReleasePackage[];
174
+ }
175
+ export interface PlanReleaseOptions {
176
+ /** Defaults to `GITHUB_REF_NAME`, then the checked-out branch. */
177
+ branch?: string;
178
+ mode?: ReleasePolicy['mode'];
179
+ /** Plan as if the branch were `main` when it does not release, for `aronrepo explain` on feature branches. */
180
+ fallbackToMain?: boolean;
181
+ /** Tags to ignore, to rebuild the plan of a release that is already tagged. */
182
+ ignoreTags?: string[];
183
+ date?: string;
184
+ }
185
+ /** The repository URL on GitHub, from `GITHUB_REPOSITORY` or the root package.json. */
186
+ export declare function getRepositoryUrl(cwd: string, env?: NodeJS.ProcessEnv): string | undefined;
187
+ /** Plans the next release of the checked-out commit without changing anything. */
188
+ export declare function planRelease(options?: PlanReleaseOptions, environmentOptions?: Partial<ReleaseEnvironment>): Promise<ReleasePlan>;
189
+ /** Registry of a package: its scoped registry, `publishConfig.registry`, `NPM_CONFIG_REGISTRY`, then npm. */
190
+ export declare function getRegistry(manifest: PackageJson, env?: NodeJS.ProcessEnv): string;
191
+ /** Exchanges a GitHub Actions OIDC token for a short-lived npm publish token (npm trusted publishing). */
192
+ export declare function exchangeOidcToken(environment: ReleaseEnvironment, name: string, registry: string): Promise<string | undefined>;
193
+ /** Writes the release version and git head into a package manifest. */
194
+ export declare function writeReleaseManifest(cwd: string, dir: string, version: string, gitHead: string): PackageJson;
195
+ /** Reads `package/package.json` from a packed tarball. */
196
+ export declare function readPackedManifest(tarball: string): PackageJson;
197
+ export interface GitHubRelease {
198
+ tag: string;
199
+ notes: string;
200
+ prerelease: boolean;
201
+ }
202
+ /** Creates the GitHub release of a tag unless it exists. Needs `GITHUB_TOKEN` and the repository. */
203
+ export declare function publishGitHubRelease(environment: ReleaseEnvironment, release: GitHubRelease): Promise<string | undefined>;
204
+ export interface ReleaseOptions extends PlanReleaseOptions {
205
+ /** Plans and prints the release without changing anything. */
206
+ dryRun?: boolean;
207
+ }
208
+ export interface ReleaseResult {
209
+ status: 'skipped' | 'none' | 'dry-run' | 'released' | 'resumed';
210
+ plan: ReleasePlan;
211
+ }
212
+ /**
213
+ * Releases the checked-out commit:
214
+ *
215
+ * 1. plan the version from the commits since the channel's last tag;
216
+ * 2. write the version and git head into every published package and pack it;
217
+ * 3. publish each package, in dependency order, on the `aronrepo-staging`
218
+ * dist-tag, skipping versions already published from the same commit;
219
+ * 4. wait until the registry serves every package, then move the channel's
220
+ * dist-tag to the new version;
221
+ * 5. push the version tag and create the GitHub release.
222
+ *
223
+ * Every step checks what an interrupted run already did, so rerunning the job
224
+ * finishes a release instead of skipping or duplicating it.
225
+ */
226
+ export declare function runRelease(options?: ReleaseOptions, environmentOptions?: Partial<ReleaseEnvironment>): Promise<ReleaseResult>;
package/dist/node.js ADDED
@@ -0,0 +1 @@
1
+ export { t as agents, n as check, C as configFileNames, w as detectPackageManager, r as doctor, u as exchangeOidcToken, i as explain, T as explainRange, E as findConfigFile, D as getCliCommand, O as getCommitFiles, k as getDiffFiles, A as getLatestTag, j as getProjectCliCommand, M as getRangeCommits, d as getRegistry, f as getReleasePackages, p as getRepositoryUrl, N as getStagedFiles, a as isIgnoredMessage, P as loadConfig, F as loadProjectPolicy, m as officialRegistry, h as planRelease, o as policy, g as publishGitHubRelease, I as queryPublicWorkspaceDirs, L as queryWorkspaceDirs, s as readAgentsBlock, _ as readPackedManifest, R as readWorkspacePackage, z as readWorkspacePatterns, c as release, v as releaseBodyLimit, l as replaceAgentsBlock, B as resolveReleasePaths, y as runCommand, b as runRelease, x as stagingDistTag, S as writeReleaseManifest } from "./commands-CO26JPbK.js";
package/package.json CHANGED
@@ -1,46 +1,55 @@
1
1
  {
2
- "name": "aronrepo",
3
- "version": "2.2.1",
4
- "type": "module",
5
- "license": "MIT",
6
- "description": "Facade package for the Aronrepo monorepo toolchain.",
7
- "repository": {
8
- "type": "git",
9
- "url": "https://github.com/1aron/aronrepo.git",
10
- "directory": "packages/aronrepo"
11
- },
12
- "sideEffects": false,
13
- "exports": {
14
- ".": {
15
- "types": "./dist/index.d.ts",
16
- "import": "./dist/index.js",
17
- "default": "./dist/index.js"
18
- }
19
- },
20
- "types": "./dist/index.d.ts",
21
- "files": [
22
- "dist"
23
- ],
24
- "publishConfig": {
25
- "access": "public",
26
- "provenance": true
27
- },
28
- "peerDependencies": {
29
- "@commitlint/cli": "*",
30
- "semantic-release": "*"
31
- },
32
- "dependencies": {
33
- "@aronrepo/commitlint-config": "^2.2.1",
34
- "@aronrepo/conventional-commits": "^2.2.1",
35
- "@aronrepo/conventional-changelog-config": "^2.2.1",
36
- "@aronrepo/semantic-release-config": "^2.2.1",
37
- "@aronrepo/semantic-release-pnpm": "^2.2.1"
38
- },
39
- "scripts": {
40
- "build": "tsdown",
41
- "dev": "tsdown --watch",
42
- "test": "vitest",
43
- "type-check": "tsc --noEmit",
44
- "lint": "eslint"
45
- }
46
- }
2
+ "name": "aronrepo",
3
+ "version": "3.0.0",
4
+ "type": "module",
5
+ "license": "MIT",
6
+ "description": "Aronrepo: one conventional commit and release policy for owners and coding agents, with commit checks, release decisions, and npm publishing.",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/1aron/aronrepo.git",
10
+ "directory": "packages/aronrepo"
11
+ },
12
+ "sideEffects": false,
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js",
17
+ "default": "./dist/index.js"
18
+ },
19
+ "./node": {
20
+ "types": "./dist/node.d.ts",
21
+ "import": "./dist/node.js",
22
+ "default": "./dist/node.js"
23
+ }
24
+ },
25
+ "types": "./dist/index.d.ts",
26
+ "bin": {
27
+ "aronrepo": "./dist/cli.js"
28
+ },
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "publishConfig": {
33
+ "access": "public",
34
+ "provenance": true
35
+ },
36
+ "scripts": {
37
+ "build": "tsdown",
38
+ "dev": "tsdown --watch",
39
+ "test": "vitest",
40
+ "type-check": "tsc --noEmit",
41
+ "lint": "eslint"
42
+ },
43
+ "dependencies": {
44
+ "js-yaml": "^5.5.0",
45
+ "picomatch": "^4.0.7",
46
+ "semver": "^7.8.6",
47
+ "tinyglobby": "^0.2.17"
48
+ },
49
+ "devDependencies": {
50
+ "@types/js-yaml": "^4.0.9",
51
+ "@types/picomatch": "^4.0.3",
52
+ "@types/semver": "^7.8.0"
53
+ },
54
+ "gitHead": "89de39ae4ce7128dc8101c944636a6620416c662"
55
+ }