{"version":3,"file":"src-CGc7d-5_.mjs","names":["version","VERSION","pkgVersion","declaration","SOURCE_GLOBS","WRITE_CALLS","CLI_VERSION","cancelled","toJson","PREFIX","pascal","parseFrameworkArg","CLI_VERSION","formatMapReport","FRAMEWORKS","formatMapReportView"],"sources":["../src/lib/environment.ts","../src/core/output.ts","../package.json","../src/core/brand.ts","../src/lib/agents/report.ts","../src/lib/constants.ts","../src/lib/debug-report.ts","../src/lib/errors.ts","../src/lib/debug.ts","../src/lib/init/catalog.ts","../src/lib/map/parse.ts","../src/lib/map/facts.ts","../src/lib/map/project-facts.ts","../src/lib/map/utils.ts","../src/lib/map/adapters/next.ts","../src/lib/map/adapters/nuxt.ts","../src/lib/map/adapters/tanstack-start.ts","../src/lib/map/adapters/hono.ts","../src/lib/map/adapters/index.ts","../src/lib/map/directives.ts","../src/lib/map/exemptions.ts","../src/lib/map/rules/types.ts","../src/lib/map/rules/ai-logging.ts","../src/lib/map/rules/audit.ts","../src/lib/map/rules/audit-coverage.ts","../src/lib/map/rules/auth-identity.ts","../src/lib/map/rules/context.ts","../src/lib/map/rules/error-catalog.ts","../src/lib/map/rules/error-handling.ts","../src/lib/map/rules/page-error-handling.ts","../src/lib/map/rules/structured-errors.ts","../src/lib/map/rules/wide-event.ts","../src/lib/map/rules/index.ts","../src/lib/map/sensitivity.ts","../src/lib/map/score.ts","../src/lib/map/scan.ts","../src/lib/init/insight.ts","../src/lib/init/edit.ts","../src/lib/init/frameworks.ts","../src/lib/init/prompts.ts","../src/lib/map/detect.ts","../src/lib/project.ts","../src/lib/agents/block.ts","../src/lib/agents/plan.ts","../src/lib/agents/skills.ts","../src/lib/agents/run.ts","../src/core/context.ts","../src/lib/ui.ts","../src/lib/command.ts","../src/commands/agents.ts","../src/commands/doctor.ts","../src/lib/init/pm.ts","../src/lib/init/resolve.ts","../src/lib/init/telemetry.ts","../src/lib/init/run.ts","../src/lib/init/report.ts","../src/lib/init/workspace.ts","../src/commands/init.ts","../src/lib/map/write.ts","../src/lib/map/baseline.ts","../src/lib/map/report.ts","../src/lib/map/telemetry.ts","../src/commands/map.ts","../src/commands/telemetry.ts","../src/commands/index.ts","../src/index.ts"],"sourcesContent":["/**\n * Deploy / runtime stage for the CLI itself.\n *\n * Not the user's app env — whether *this* `evlog` binary is a local workspace\n * build or a packaged install (`npx`, dependency, global).\n */\nexport type CliEnvironment = 'development' | 'preview' | 'production' | string\n\nexport type ResolveCliEnvironmentOptions = {\n  /** Process env (defaults to `process.env`). */\n  env?: NodeJS.Dict<string>\n  /**\n   * Module URL used to detect packaged vs workspace installs.\n   * Defaults to this file's `import.meta.url`.\n   */\n  moduleUrl?: string\n}\n\n/**\n * True when the CLI is running from a published / installed package\n * (`node_modules/.../@evlog/cli`), not from the monorepo `packages/cli` tree.\n */\nexport function isPackagedCli(moduleUrl: string = import.meta.url): boolean {\n  const normalized = moduleUrl.replace(/\\\\/g, '/')\n  if (normalized.includes('/node_modules/')) return true\n  if (normalized.includes('/packages/cli/')) return false\n  // Unknown install path (custom global, bundled) → treat as packaged.\n  return true\n}\n\n/**\n * Resolve the CLI's own environment for `--json`, `--debug`, and telemetry.\n *\n * Priority:\n * 1. `EVLOG_CLI_ENV` (explicit override)\n * 2. `VERCEL_ENV` (when the CLI runs on Vercel: production | preview | development)\n * 3. Packaged install → `production` (users running published `evlog`)\n * 4. Workspace / local → `NODE_ENV` or `development`\n */\nexport function resolveCliEnvironment(\n  options: ResolveCliEnvironmentOptions = {},\n): CliEnvironment {\n  const env = options.env ?? process.env\n  const moduleUrl = options.moduleUrl ?? import.meta.url\n\n  const explicit = env.EVLOG_CLI_ENV?.trim()\n  if (explicit) return explicit\n\n  const vercel = env.VERCEL_ENV?.trim()\n  if (vercel) return vercel\n\n  if (isPackagedCli(moduleUrl)) return 'production'\n\n  return env.NODE_ENV?.trim() || 'development'\n}\n","import { resolveCliEnvironment } from '../lib/environment'\nimport type { CliContext } from './context'\n\nexport const DOCS_URL = 'https://evlog.dev'\nexport const DOCS_LABEL = 'evlog.dev'\n\n/** Current CLI result schema. Bump when a `--json` payload shape changes. */\nexport const SCHEMA_VERSION = 2\n\n/** Documented exit codes: 0 ok (warns allowed), 1 any fail, 2 usage error. */\nexport const EXIT_OK = 0\nexport const EXIT_FAIL = 1\nexport const EXIT_USAGE = 2\n\nconst codes = {\n  reset: '\\x1B[0m',\n  bold: '\\x1B[1m',\n  dim: '\\x1B[2m',\n  underline: '\\x1B[4m',\n  red: '\\x1B[31m',\n  green: '\\x1B[32m',\n  yellow: '\\x1B[33m',\n  blue: '\\x1B[34m',\n  magenta: '\\x1B[35m',\n  cyan: '\\x1B[36m',\n  white: '\\x1B[37m',\n} as const\n\n/** A style name accepted by {@link Style.paint}. */\nexport type StyleCode = keyof typeof codes\n\n/**\n * Minimal ANSI kit bound to a {@link CliContext} — hand-rolled like\n * evlog's pretty printer and the telemetry notice, no color dependency.\n */\nexport interface Style {\n  paint: (code: StyleCode | StyleCode[], text: string) => string\n  link: (url: string, label: string) => string\n}\n\n/** Create the styling helpers for a context (honors `NO_COLOR` / non-TTY). */\nexport function createStyle(ctx: Pick<CliContext, 'color'>): Style {\n  const paint = (code: StyleCode | StyleCode[], text: string): string => {\n    if (!ctx.color) return text\n    const seq = (Array.isArray(code) ? code : [code]).map(k => codes[k]).join('')\n    return `${seq}${text}${codes.reset}`\n  }\n  const link = (url: string, label: string): string => {\n    if (!ctx.color) return `${label} (${url})`\n    return `\\x1B]8;;${url}\\x07${paint(['cyan', 'underline'], label)}\\x1B]8;;\\x07`\n  }\n  return { paint, link }\n}\n\n/** Status of a single diagnostic check. */\nexport type CheckStatus = 'ok' | 'warn' | 'fail'\n\n/** Shared glyphs for check / finding status (doctor report + debug case file). */\nexport const CHECK_STATUS: Record<CheckStatus, { glyph: string, color: StyleCode }> = {\n  ok: { glyph: '✓', color: 'green' },\n  warn: { glyph: '⚠', color: 'yellow' },\n  fail: { glyph: '✗', color: 'red' },\n}\n\n/** One diagnostic check result — commands return these, never print. */\nexport interface Check {\n  id: string\n  status: CheckStatus\n  message: string\n  hint?: string\n}\n\n/** Aggregate counts over a list of checks. */\nexport interface CheckSummary {\n  ok: number\n  warn: number\n  fail: number\n}\n\n/** Count check statuses. */\nexport function summarize(checks: Check[]): CheckSummary {\n  const summary: CheckSummary = { ok: 0, warn: 0, fail: 0 }\n  for (const check of checks) summary[check.status]++\n  return summary\n}\n\n/** Exit code for a set of checks: 1 when any check failed, 0 otherwise. */\nexport function exitCodeFor(summary: CheckSummary): number {\n  return summary.fail > 0 ? EXIT_FAIL : EXIT_OK\n}\n\n/**\n * Render checks as a blue-railed list with ✓ / ⚠ / ✗, cyan ids, and dim hints.\n */\nexport function formatChecks(ctx: Pick<CliContext, 'color'>, checks: Check[]): string {\n  if (checks.length === 0) return ''\n  const { paint } = createStyle(ctx)\n  const width = Math.max(...checks.map(c => c.id.length))\n  const rail = paint('blue', '│')\n  const lines: string[] = []\n\n  for (const check of checks) {\n    const { glyph, color } = CHECK_STATUS[check.status]\n    const symbol = paint(color, glyph)\n    const id = paint('cyan', check.id.padEnd(width))\n    lines.push(`${rail} ${symbol} ${id}  ${check.message}`)\n    if (check.hint && check.status !== 'ok') {\n      lines.push(`${rail}   ${paint('dim', `└ ${check.hint}`)}`)\n    }\n  }\n\n  return lines.join('\\n')\n}\n\n/** One-line footer: `3 ok · 1 warn · 0 fail`. */\nexport function formatSummary(ctx: Pick<CliContext, 'color'>, summary: CheckSummary): string {\n  const { paint } = createStyle(ctx)\n  const parts = [\n    paint(summary.ok > 0 ? 'green' : 'dim', `${summary.ok} ok`),\n    paint(summary.warn > 0 ? 'yellow' : 'dim', `${summary.warn} warn`),\n    paint(summary.fail > 0 ? 'red' : 'dim', `${summary.fail} fail`),\n  ]\n  return parts.join(paint('dim', ' · '))\n}\n\n/**\n * Write a `--json` payload — the only thing allowed on stdout in JSON mode.\n * Always includes `schemaVersion` and `environment`; breaking the shape requires a bump.\n */\nexport function writeJson(payload: Record<string, unknown>): void {\n  process.stdout.write(`${JSON.stringify({\n    schemaVersion: SCHEMA_VERSION,\n    environment: resolveCliEnvironment(),\n    ...payload,\n  })}\\n`)\n}\n\n/** Write human-readable output to stderr (stdout is reserved for `--json`). */\nexport function writeHuman(text: string): void {\n  process.stderr.write(`${text}\\n`)\n}\n","","import { version as VERSION } from '../../package.json'\nimport type { CliContext } from './context'\nimport { DOCS_LABEL, DOCS_URL, createStyle } from './output'\n\n/** Brand tagline — the evlog slogan. */\nexport const TAGLINE = 'DIGGING THROUGH LOGS IS NOT OBSERVABILITY. IT\\'S HOPE'\n\n/**\n * `evlog` wordmark — figlet \"slant\" font (UnJS-family aesthetic).\n * Trailing spaces stripped; every line padded to the same width.\n */\nexport const WORDMARK = [\n  '             __           ',\n  '  ___ _   __/ /___  ____ _',\n  ' / _ \\\\ | / / / __ \\\\/ __ `/',\n  '/  __/ |/ / / /_/ / /_/ / ',\n  '\\\\___/|___/_/\\\\____/\\\\__, /  ',\n  '                 /____/   ',\n] as const\n\nconst WORDMARK_WIDTH = WORDMARK[0].length\nconst MIN_COLUMNS = WORDMARK_WIDTH + 8\n\n/**\n * Vertical scanline glow across the wordmark rows — bright core, dim edges.\n * Six rows: dim → mid → bold → bold → mid → dim.\n */\nconst SCANLINES = [\n  ['dim', 'white'],\n  ['white'],\n  ['bold', 'white'],\n  ['bold', 'white'],\n  ['white'],\n  ['dim', 'white'],\n] as const\n\n/** Gradient stops: brand blue → near-black (site accent bar, L→R fade). */\nconst GRADIENT_FROM = [43, 90, 255] as const\nconst GRADIENT_TO = [8, 10, 40] as const\n\n/**\n * Where the accent bar sits inside its terminal row — the only sub-cell\n * (\"pixel\") control terminals give us:\n *\n * | Glyph | Position in cell      | Air above text |\n * | ----- | --------------------- | -------------- |\n * | `▀`   | top half              | none (glued)   |\n * | `━`   | optical middle        | some           |\n * | `▄`   | lower half (default)  | half cell      |\n * | `▂`   | lower quarter         | more           |\n * | `▁`   | baseline              | most           |\n */\nexport const GRADIENT_GLYPH = '▄'\n\n/** Accent bar width under command titles. */\nexport const HEADER_GRADIENT_WIDTH = 28\n\n/**\n * Horizontal rule fading blue → dark, like the site's accent bar.\n * Truecolor per-cell; plain dashes when colors are off.\n *\n * @param glyph - Override {@link GRADIENT_GLYPH} to tune vertical air above the bar.\n */\nexport function gradientRule(\n  ctx: Pick<CliContext, 'color'>,\n  width: number,\n  glyph: string = GRADIENT_GLYPH,\n): string {\n  if (!ctx.color) return '─'.repeat(width)\n  let out = ''\n  for (let i = 0; i < width; i++) {\n    const t = width === 1 ? 1 : i / (width - 1)\n    const r = Math.round(GRADIENT_FROM[0] + (GRADIENT_TO[0] - GRADIENT_FROM[0]) * t)\n    const g = Math.round(GRADIENT_FROM[1] + (GRADIENT_TO[1] - GRADIENT_FROM[1]) * t)\n    const b = Math.round(GRADIENT_FROM[2] + (GRADIENT_TO[2] - GRADIENT_FROM[2]) * t)\n    out += `\\x1B[38;2;${r};${g};${b}m${glyph}`\n  }\n  return `${out}\\x1B[0m`\n}\n\n/**\n * Whether the branded command header should print.\n *\n * Disabled when:\n * - `--json` (machine output)\n * - `--no-header` (flag on the command or anywhere on argv)\n * - `EVLOG_CLI_NO_HEADER=1` or `EVLOG_CLI_HEADER=0`\n */\nexport function wantsHeader(\n  ctx: Pick<CliContext, 'env'>,\n  args?: { json?: boolean, noHeader?: boolean },\n  argv: readonly string[] = process.argv,\n): boolean {\n  if (args?.json) return false\n  if (args?.noHeader) return false\n  if (ctx.env.EVLOG_CLI_NO_HEADER === '1') return false\n  if (ctx.env.EVLOG_CLI_HEADER === '0') return false\n  if (argv.includes('--no-header')) return false\n  return true\n}\n\n/**\n * Branded command header used by every leaf command:\n *\n * ```\n *     evlog doctor v0.0.0\n *     ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\n * ```\n *\n * Vertical air between title and bar is controlled by {@link GRADIENT_GLYPH}\n * (sub-cell), not by blank rows. Skip via {@link wantsHeader}.\n */\nexport function formatCommandHeader(\n  ctx: CliContext,\n  options: { command: string, version?: string },\n): string {\n  const { paint } = createStyle(ctx)\n  const version = options.version ?? VERSION\n  return [\n    '',\n    `${paint('bold', 'evlog')} ${paint(['cyan', 'bold'], options.command)} ${paint('dim', `v${version}`)}`,\n    `${gradientRule(ctx, HEADER_GRADIENT_WIDTH)}`,\n    '',\n  ].join('\\n')\n}\n\n/**\n * Full branded banner: figlet wordmark with scanline glow, gradient accent\n * rule, and a single dim meta line (tagline · version · docs link).\n *\n * Falls back to a compact one-liner when colors are off or the terminal is\n * too narrow for the art.\n */\nexport function formatBanner(ctx: CliContext, version: string): string {\n  const { paint, link } = createStyle(ctx)\n\n  if (!ctx.color || ctx.columns < MIN_COLUMNS) {\n    return `  ${paint('bold', 'evlog')} ${paint('dim', `v${version} — digging through logs is not observability ·`)} ${link(DOCS_URL, DOCS_LABEL)}\\n`\n  }\n\n  const art = WORDMARK.map((row, i) => `  ${paint([...SCANLINES[i]!], row)}`)\n  const rule = `  ${gradientRule(ctx, WORDMARK_WIDTH)}`\n  const slogan = `  ${paint('dim', TAGLINE)}`\n  const meta = `  ${paint('dim', `v${version} · `)}${link(DOCS_URL, DOCS_LABEL)}`\n\n  return `${art.join('\\n')}\\n\\n${rule}\\n\\n${slogan}\\n${meta}\\n`\n}\n","import { gradientRule, HEADER_GRADIENT_WIDTH } from '../../core/brand'\nimport type { CliContext } from '../../core/context'\nimport { DOCS_URL, createStyle } from '../../core/output'\nimport type { AgentsResult } from './run'\n\n/** The subset of a skills outcome the report needs — `init` reports one too. */\nexport interface SkillsLines {\n  status: 'pending' | 'already' | 'installed' | 'skipped' | 'failed'\n  command: string\n  dirs?: string[]\n  error?: string\n}\n\n/**\n * How the skills step went, as report lines.\n *\n * Shared with the `init` report rather than written twice: it is the same four\n * outcomes with the same wording, and two copies of a user-facing string are\n * two copies that drift. A command to type is a label plus the command, never a\n * sentence with the command inside it — inline, the reader never registers\n * there is something to run.\n */\nexport function skillsReportLines(ctx: CliContext, skills: SkillsLines): string[] {\n  const { paint } = createStyle(ctx)\n  const command = (label: string, line: string): string =>\n    `  ${paint('dim', label)}  ${paint('bold', line)}`\n\n  switch (skills.status) {\n    case 'already':\n      return [\n        `${paint('green', '✓')} ${paint('dim', `evlog skills already installed${skills.dirs?.length ? ` · ${skills.dirs.join(', ')}` : ''}`)}`,\n        /* The skills CLI owns their lifecycle, so the refresh command is theirs. */\n        command('refresh', 'npx skills update'),\n      ]\n    case 'installed':\n      return [\n        `${paint('green', '✓')} ${paint('dim', 'installed the evlog skills')}`,\n        /* A non-interactive run never saw the command go by, and this is the\n           only record of what was spawned on its behalf. */\n        command('ran    ', skills.command),\n      ]\n    case 'failed':\n      return [\n        `${paint('red', '✗')} ${paint('dim', 'skills not installed')}`,\n        ...(skills.error ? [`   ${paint('dim', skills.error)}`] : []),\n        command('retry  ', skills.command),\n      ]\n    default:\n      return [\n        `${paint('yellow', '·')} ${paint('dim', 'skills not installed')}`,\n        command('install', skills.command),\n      ]\n  }\n}\n\n/**\n * What `evlog agents` did, for a run that asked nothing.\n *\n * Same contract as the `init` report: every outcome gets a line, including the\n * ones where nothing changed, so \"already up to date\" is never confusable with\n * \"did not look\".\n */\nexport function formatAgentsReport(ctx: CliContext, result: AgentsResult): string {\n  const { paint } = createStyle(ctx)\n  const lines: string[] = []\n\n  if (result.cancelled) {\n    return paint('yellow', 'Cancelled — nothing was written.')\n  }\n\n  lines.push(paint('bold', result.framework ?? 'no framework detected'))\n  lines.push('')\n\n  for (const action of result.written) {\n    const verb = result.dryRun\n      ? (action.kind === 'create' ? 'would create' : 'would update')\n      : (action.kind === 'create' ? 'created' : 'updated')\n    const glyph = result.dryRun ? paint('yellow', '·') : paint('green', '✓')\n    lines.push(`${glyph} ${paint('dim', verb)} ${action.relative}`)\n  }\n\n  for (const note of result.already) {\n    lines.push(paint('dim', `· ${note}`))\n  }\n\n  lines.push(...skillsReportLines(ctx, result.skills))\n\n  lines.push('')\n  lines.push(gradientRule(ctx, HEADER_GRADIENT_WIDTH))\n  if (result.dryRun) {\n    lines.push(paint('dim', 'dry run — nothing was written. Drop --dry-run to apply.'))\n  } else {\n    lines.push(`${paint('dim', 'next:')} ${paint('bold', 'evlog map')} ${paint('dim', 'to score what is still dark')}`)\n  }\n  lines.push(`${paint('dim', 'agent skills →')} ${paint('dim', `${DOCS_URL}/reference/agent-skills`)}`)\n\n  return lines.join('\\n')\n}\n","import { version as pkgVersion } from '../../package.json'\n\n/** Telemetry tool name — user-facing in disclosure and consent strings. */\nexport const TOOL_NAME = 'evlog-cli'\n\n/** Package version — shared by the main meta and command headers. */\nexport const VERSION = pkgVersion\n\n/**\n * Default telemetry ingestion endpoint — evlog's own dashboard (`apps/telemetry`).\n * Overridable via `EVLOG_TELEMETRY_ENDPOINT` (see `resolveEndpoint()` in `@evlog/telemetry`).\n * Still gated by consent (`DO_NOT_TRACK`, `EVLOG_TELEMETRY=0`, `telemetry disable`).\n */\nexport const TELEMETRY_ENDPOINT = 'https://telemetry.evlog.cloud/api/telemetry/ingest'\n","import type { CliContext } from '../core/context'\nimport { CHECK_STATUS, createStyle } from '../core/output'\nimport type { CheckStatus } from '../core/output'\n\ntype FindingLike = {\n  id?: unknown\n  status?: unknown\n  code?: unknown\n  why?: unknown\n  fix?: unknown\n  link?: unknown\n}\n\ntype AttemptLike = {\n  base?: unknown\n  method?: unknown\n  ok?: unknown\n  error?: unknown\n}\n\nfunction asStatus(value: unknown): CheckStatus {\n  if (value === 'ok' || value === 'warn' || value === 'fail') return value\n  return 'warn'\n}\n\nfunction shortPath(path: string, max = 64): string {\n  if (path.length <= max) return path\n  return `…${path.slice(-(max - 1))}`\n}\n\n/**\n * Human-readable debug case file for a CLI wide event.\n * Keeps the terminal scannable; full dump stays on `--json --debug` (stderr).\n */\nexport function formatDebugReport(\n  event: Record<string, unknown>,\n  ctx: Pick<CliContext, 'color'>,\n): string {\n  const { paint } = createStyle(ctx)\n  const lines: string[] = ['']\n\n  lines.push(paint('dim', '── debug ────────────────────────────────'))\n\n  const command = typeof event.command === 'string' ? event.command : undefined\n  const cwd = typeof event.cwd === 'string' ? event.cwd : undefined\n  const environment = typeof event.environment === 'string' ? event.environment : undefined\n\n  if (command) {\n    lines.push(`${paint('dim', 'command')}  ${paint('cyan', command)}`)\n  }\n  if (environment) {\n    lines.push(`${paint('dim', 'env')}      ${paint('cyan', environment)}`)\n  }\n  if (cwd) {\n    lines.push(`${paint('dim', 'cwd')}      ${cwd}`)\n  }\n\n  const steps = Array.isArray(event.steps) ? event.steps.map(String) : []\n  if (steps.length > 0) {\n    lines.push(\n      `${paint('dim', 'steps')}    ${steps.map(s => paint('cyan', s)).join(paint('dim', ' → '))}`,\n    )\n  }\n\n  const { error } = event\n  if (error && typeof error === 'object') {\n    const err = error as Record<string, unknown>\n    lines.push('')\n    lines.push(paint('dim', 'error'))\n    const code = typeof err.code === 'string' ? err.code : undefined\n    const message = typeof err.message === 'string' ? err.message : undefined\n    if (code) lines.push(`  ${paint('red', '✗')} ${paint('cyan', code)}`)\n    if (message) lines.push(`    ${message}`)\n    if (typeof err.why === 'string') lines.push(`    ${paint('dim', 'why')}  ${err.why}`)\n    if (typeof err.fix === 'string') lines.push(`    ${paint('dim', 'fix')}  ${err.fix}`)\n  }\n\n  const findings = Array.isArray(event.findings) ? event.findings as FindingLike[] : []\n  if (findings.length > 0) {\n    lines.push('')\n    lines.push(paint('dim', 'findings'))\n    for (const finding of findings) {\n      const status = asStatus(finding.status)\n      const { glyph, color } = CHECK_STATUS[status]\n      const code = typeof finding.code === 'string' ? finding.code : String(finding.id ?? 'unknown')\n      lines.push(`  ${paint(color, glyph)} ${paint('cyan', code)}`)\n      if (typeof finding.why === 'string') {\n        lines.push(`    ${paint('dim', 'why')}  ${finding.why}`)\n      }\n      if (typeof finding.fix === 'string') {\n        lines.push(`    ${paint('dim', 'fix')}  ${finding.fix}`)\n      }\n      if (typeof finding.link === 'string') {\n        lines.push(`    ${paint('dim', 'link')} ${finding.link}`)\n      }\n    }\n  }\n\n  const tried = Array.isArray(event.resolveTried) ? event.resolveTried as AttemptLike[] : []\n  if (tried.length > 0) {\n    const okCount = tried.filter(t => t.ok === true).length\n    lines.push('')\n    lines.push(`${paint('dim', 'resolve')}  ${okCount}/${tried.length} probes ok`)\n\n    const failed = tried.filter(t => t.ok !== true)\n    const show = failed.slice(0, 4)\n    for (const attempt of show) {\n      const method = typeof attempt.method === 'string' ? attempt.method : '?'\n      const base = typeof attempt.base === 'string' ? shortPath(attempt.base) : '?'\n      const err = typeof attempt.error === 'string' ? paint('dim', ` · ${attempt.error}`) : ''\n      lines.push(`  ${paint('dim', '·')} ${method} ${base}${err}`)\n    }\n    if (failed.length > show.length) {\n      lines.push(paint('dim', `  · … ${failed.length - show.length} more`))\n    }\n  }\n\n  lines.push(paint('dim', '──────────────────────────────────────────'))\n  lines.push(paint('dim', 'full event → --json --debug  (stderr)'))\n  lines.push('')\n  return lines.join('\\n')\n}\n","import { defineErrorCatalog } from 'evlog'\n\n/**\n * Typed error catalog for `@evlog/cli`.\n *\n * Wire codes are `cli.<KEY>` (e.g. `cli.EVLOG_NOT_FOUND`). Used when a\n * command aborts, and attached as `findings[].code` on `--debug` wide events\n * so a failed doctor check carries why / fix / link without throwing.\n */\nexport const cliErrors = defineErrorCatalog('cli', {\n  NODE_TOO_OLD: {\n    status: 400,\n    message: ({ version, min }: { version: string, min: number }) =>\n      `Node ${version} is too old (need >= ${min})`,\n    why: 'The evlog CLI requires a modern Node runtime',\n    fix: 'Upgrade Node to the latest LTS',\n    link: 'https://nodejs.org/',\n    tags: ['doctor', 'environment'],\n  },\n  PROJECT_NO_PACKAGE: {\n    status: 404,\n    message: 'No package.json found',\n    why: 'Doctor needs a package root to diagnose the project',\n    fix: 'Run from your app directory or pass --cwd',\n    tags: ['doctor', 'project'],\n  },\n  EVLOG_NOT_FOUND: {\n    status: 404,\n    message: 'evlog is not installed in this project',\n    why: 'No resolvable evlog package in node_modules and no declaration in package.json',\n    fix: 'pnpm add evlog — see installation docs',\n    link: 'https://evlog.dev/getting-started/installation',\n    tags: ['doctor', 'evlog'],\n  },\n  EVLOG_DECLARED_NOT_INSTALLED: {\n    status: 404,\n    message: ({ range }: { range: string }) =>\n      `evlog is declared (${range}) but not installed`,\n    why: 'package.json lists evlog but node_modules resolve failed',\n    fix: 'Run your package manager install step',\n    tags: ['doctor', 'evlog'],\n  },\n  COMMAND_FAILED: {\n    status: 500,\n    message: 'CLI command failed',\n    why: 'An unexpected error aborted the command',\n    fix: 'Re-run with --debug and share the wide event',\n    tags: ['cli'],\n  },\n  MAP_NO_PACKAGE_JSON: {\n    status: 404,\n    message: 'No package.json found',\n    why: 'map needs a package root to detect the framework and scan routes',\n    fix: 'Run from your app directory or pass --cwd',\n    tags: ['map', 'project'],\n  },\n  MAP_WORKSPACE_ROOT: {\n    status: 400,\n    message: 'Monorepo root detected with no supported framework',\n    why: 'map scans one app at a time and cannot infer a framework from a bare workspace root',\n    fix: 'Run from an app directory (e.g. apps/web) or pass --cwd',\n    tags: ['map', 'project'],\n  },\n  MAP_FRAMEWORK_NOT_DETECTED: {\n    status: 400,\n    message: 'Could not detect a supported framework (nuxt, nitro, next, tanstack-start, hono)',\n    why: 'No matching dependency or config file was found in this project',\n    fix: 'Use --framework <name> to override detection',\n    tags: ['map', 'project'],\n  },\n  MAP_INVALID_FRAMEWORK: {\n    status: 400,\n    message: ({ value }: { value: string }) =>\n      `Unknown --framework \"${value}\"`,\n    why: 'map only ships adapters for nuxt, nitro, next, tanstack-start, and hono',\n    fix: 'Pass one of: nuxt, nitro, next, tanstack-start, hono',\n    tags: ['map'],\n  },\n  INIT_INVALID_FRAMEWORK: {\n    status: 400,\n    message: ({ value }: { value: string }) =>\n      `Unknown --framework \"${value}\"`,\n    why: 'init only knows how to wire nuxt, nitro, next, tanstack-start, and hono',\n    fix: 'Pass one of: nuxt, nitro, next, tanstack-start, hono — or omit it and let detection decide',\n    link: 'https://evlog.dev/cli/init',\n    tags: ['init'],\n  },\n  INIT_FRAMEWORK_UNSUPPORTED: {\n    status: 400,\n    message: ({ framework }: { framework: string }) =>\n      `evlog init cannot wire ${framework} yet`,\n    why: 'The framework has a map adapter, but init has no wiring plan for it',\n    fix: 'Wire evlog by hand following the framework guide, then run evlog map to score coverage',\n    link: 'https://evlog.dev/integrate/frameworks/overview',\n    tags: ['init'],\n  },\n  INIT_INVALID_ENRICHER: {\n    status: 400,\n    message: ({ value, known }: { value: string, known: string }) =>\n      `Unknown --enrichers entry \"${value}\" — pass a comma-separated list of: ${known}`,\n    why: 'Enrichers are a fixed set, so a typo would silently wire one fewer',\n    fix: 'Run evlog init without --enrichers to pick from the list interactively',\n    link: 'https://evlog.dev/use-cases/enrichers',\n    tags: ['init'],\n  },\n  INIT_INVALID_SAMPLING: {\n    status: 400,\n    message: ({ value, known }: { value: string, known: string }) =>\n      `Unknown --sampling \"${value}\" — pass one of: ${known}`,\n    why: 'Sampling is a fixed set of traffic tiers, not a rate',\n    fix: 'Run evlog init without --sampling to pick a tier interactively',\n    link: 'https://evlog.dev/cli/init',\n    tags: ['init'],\n  },\n  INIT_NO_APPS: {\n    status: 400,\n    message: ({ value, known }: { value: string, known: string }) =>\n      `No workspace app matches \"${value}\" — this workspace has: ${known}`,\n    why: 'Setting up nothing is never what --apps was meant to express',\n    fix: 'Name the packages by their directory (apps/web) or their package.json name',\n    link: 'https://evlog.dev/cli/init',\n    tags: ['init', 'workspace'],\n  },\n  INIT_INVALID_DRAIN: {\n    status: 400,\n    /* The known ids come from the catalog rather than being spelled out here:\n       a fixed list in an error message is a list that goes stale the first time\n       an adapter is added. */\n    message: ({ value, known }: { value: string, known: string }) =>\n      `Unknown --drain \"${value}\" — pass one of: ${known}`,\n    why: 'A destination that is not in the catalog cannot be wired, and defaulting instead would send events somewhere the author did not ask for',\n    fix: 'Run evlog init without --drain to pick from the list interactively',\n    link: 'https://evlog.dev/integrate/adapters/overview',\n    tags: ['init'],\n  },\n  INIT_INVALID_EXTRA: {\n    status: 400,\n    message: ({ value, known }: { value: string, known: string }) =>\n      `Unknown --extras entry \"${value}\" — pass a comma-separated list of: ${known}`,\n    why: 'Extras are a fixed set, so a typo would silently do nothing',\n    fix: 'Run evlog init without --extras to pick from the list interactively',\n    link: 'https://evlog.dev/cli/init',\n    tags: ['init'],\n  },\n  AGENTS_INVALID_SOURCE: {\n    status: 400,\n    message: ({ value }: { value: string }) =>\n      `Invalid --source \"${value}\" — expected an http(s) URL`,\n    why: 'The source is handed to npx, and on Windows that argument reaches a shell',\n    fix: 'Pass the origin the skills are published from, e.g. --source https://www.evlog.dev',\n    link: 'https://evlog.dev/cli/agents',\n    tags: ['agents', 'skills'],\n  },\n  AGENTS_INVALID_SKILL: {\n    status: 400,\n    message: ({ value }: { value: string }) =>\n      `Invalid --skills entry \"${value}\"`,\n    why: 'Skill names are lowercase and dashed, and the value is handed to npx',\n    fix: 'Run evlog agents without --skills to install every published skill',\n    link: 'https://evlog.dev/reference/agent-skills',\n    tags: ['agents', 'skills'],\n  },\n  AGENTS_UNREADABLE: {\n    status: 500,\n    message: ({ file }: { file: string }) => `Cannot read ${file}`,\n    why: 'The path exists but could not be read — it may be a directory, or permissions may deny it',\n    fix: 'Check the file and its permissions, then run the command again',\n    link: 'https://evlog.dev/cli/agents',\n    tags: ['agents'],\n  },\n  MAP_BASELINE_NOT_FOUND: {\n    status: 404,\n    message: ({ source }: { source: string }) =>\n      `No baseline map at ${source}`,\n    why: 'A baseline gate compares against a committed evlog.map.json, and none was readable',\n    fix: 'Run evlog map once and commit evlog.map.json, or pass --baseline <path>',\n    link: 'https://evlog.dev/cli/ci',\n    tags: ['map', 'baseline'],\n  },\n  MAP_BASELINE_REF_NOT_FOUND: {\n    status: 404,\n    message: ({ ref }: { ref: string }) =>\n      `No git ref ${ref}`,\n    why: '--baseline git:<ref> reads the committed evlog.map.json from that ref, and the ref does not exist',\n    fix: 'Point --baseline at a branch or tag that exists, e.g. git:origin/main',\n    link: 'https://evlog.dev/cli/ci',\n    tags: ['map', 'baseline'],\n  },\n  MAP_BASELINE_NOT_COMMITTED: {\n    status: 404,\n    message: ({ ref }: { ref: string }) =>\n      `No evlog.map.json in ${ref}, and the ratchet needs a committed map`,\n    why: 'The ratchet compares against a committed evlog.map.json, so a file that was never tracked cannot be read through git',\n    fix: 'Commit one from the base branch: evlog map && git add -f evlog.map.json',\n    link: 'https://evlog.dev/cli/ci',\n    tags: ['map', 'baseline'],\n  },\n  MAP_BASELINE_INVALID: {\n    status: 400,\n    message: ({ source, reason }: { source: string, reason: string }) =>\n      `Baseline ${source} is unusable — ${reason}`,\n    why: 'The baseline has to be an evlog.map.json written by this CLI to be comparable',\n    fix: 'Regenerate it with evlog map, or point --baseline at the right file',\n    link: 'https://evlog.dev/cli/ci',\n    tags: ['map', 'baseline'],\n  },\n  MAP_BASELINE_VERSION_MISMATCH: {\n    status: 400,\n    message: ({ baselineCli, runningCli, baselineRuleSet, runningRuleSet }: { baselineCli: string, runningCli: string, baselineRuleSet: number, runningRuleSet: number }) =>\n      `baseline was written by @evlog/cli ${baselineCli}, running @evlog/cli ${runningCli} (rule set ${baselineRuleSet} \\u2192 ${runningRuleSet})`,\n    why: 'The rule set changed between the two versions, so a per-check diff could blame code the PR did not touch',\n    fix: 'Regenerate the baseline: evlog map && git add evlog.map.json',\n    link: 'https://evlog.dev/cli/ci',\n    tags: ['map', 'baseline'],\n  },\n  MAP_INVALID_MIN_SCORE: {\n    status: 400,\n    message: ({ value }: { value: string }) =>\n      `Invalid --min-score \"${value}\"`,\n    why: 'A gate that cannot be read is a gate that never fails, and CI would go green on a threshold nobody applied',\n    fix: 'Pass a whole number between 0 and 100, e.g. --min-score 80',\n    tags: ['map'],\n  },\n})\n\ndeclare module 'evlog' {\n  interface RegisteredErrorCatalogs {\n    cli: typeof cliErrors\n  }\n}\n","import { createLogger, EvlogError, initLogger } from 'evlog'\nimport type { RequestLogger } from 'evlog'\nimport type { CliContext } from '../core/context'\nimport type { CheckStatus } from '../core/output'\nimport { VERSION } from './constants'\nimport { formatDebugReport } from './debug-report'\nimport { resolveCliEnvironment } from './environment'\nimport { cliErrors } from './errors'\n\nexport type DebugArgs = { debug?: boolean, json?: boolean }\n\n/** Soft finding attached to the debug wide event (catalog-backed). */\nexport interface CliFinding {\n  code: string\n  status?: CheckStatus\n  id?: string\n  why?: string\n  fix?: string\n  link?: string\n}\n\n/**\n * Catalog factory shape (`cliErrors.X`) — static `code` / `why` / `fix` / `link`\n * from {@link import('evlog').defineError}.\n */\nexport type CatalogFindingSource = {\n  code: string\n  why?: unknown\n  fix?: unknown\n  link?: unknown\n}\n\ntype StepFields<T>\n  = Record<string, unknown>\n    | ((result: T) => Record<string, unknown> | undefined)\n\n/**\n * Debug handle for one CLI command invocation.\n *\n * Always available from {@link import('./command').defineEvlogCommand}:\n * when `--debug` is off, `step` still runs the work and `finding` / `set` no-op.\n */\nexport interface CliDebug {\n  /** Underlying request logger when debug is on. */\n  readonly raw: RequestLogger | undefined\n\n  /**\n   * Run work as a named checkpoint. Appends to `steps` when debug is on.\n   * On throw, still records the step as failed, then rethrows.\n   */\n  step: <T>(\n    name: string,\n    fn: () => T | Promise<T>,\n    fields?: StepFields<T>,\n  ) => Promise<T>\n\n  /**\n   * Append a catalog-backed finding.\n   *\n   * @example\n   * ```ts\n   * log.finding(cliErrors.EVLOG_NOT_FOUND, { id: 'evlog', status: 'warn' })\n   * ```\n   */\n  finding: (\n    source: CliFinding | CatalogFindingSource,\n    extras?: Pick<CliFinding, 'status' | 'id'>,\n  ) => void\n\n  /** Merge arbitrary fields into the wide event when debug is on. */\n  set: (fields: Record<string, unknown>) => void\n}\n\nlet loggerReady = false\n\nfunction asOptionalString(value: unknown): string | undefined {\n  return typeof value === 'string' ? value : undefined\n}\n\nfunction toCliFinding(\n  source: CliFinding | CatalogFindingSource,\n  extras?: Pick<CliFinding, 'status' | 'id'>,\n): CliFinding {\n  const s = source as CliFinding\n  const status = extras?.status\n    ?? (s.status === 'ok' || s.status === 'warn' || s.status === 'fail' ? s.status : undefined)\n    ?? 'warn'\n\n  return {\n    code: source.code,\n    why: asOptionalString(source.why),\n    fix: asOptionalString(source.fix),\n    link: asOptionalString(source.link),\n    id: extras?.id ?? (typeof s.id === 'string' ? s.id : undefined),\n    status,\n  }\n}\n\nfunction resolveFields<T>(\n  fields: StepFields<T> | undefined,\n  result: T,\n): Record<string, unknown> | undefined {\n  if (!fields) return undefined\n  if (typeof fields === 'function') return fields(result) ?? undefined\n  return fields\n}\n\n/** Live debug handle backed by a request logger. */\nexport function createCliDebug(log: RequestLogger): CliDebug {\n  return {\n    raw: log,\n    async step(name, fn, fields) {\n      try {\n        const result = await fn()\n        const extra = resolveFields(fields, result)\n        log.set({ steps: [name], ...extra })\n        return result\n      } catch (error) {\n        log.set({ steps: [name], stepFailed: name })\n        throw error\n      }\n    },\n    finding(source, extras) {\n      log.set({ findings: [toCliFinding(source, extras)] })\n    },\n    set(fields) {\n      log.set(fields)\n    },\n  }\n}\n\n/** No-op debug handle — `step` still executes `fn`. */\nexport function createNoopCliDebug(): CliDebug {\n  return {\n    raw: undefined,\n    async step(_name, fn) {\n      return await fn()\n    },\n    finding() {},\n    set() {},\n  }\n}\n\n/**\n * Whether CLI debug wide events should run.\n *\n * Enabled when:\n * - `--debug` (flag on the command or anywhere on argv)\n * - `EVLOG_CLI_DEBUG=1`\n *\n * Independent of `@evlog/telemetry` / `EVLOG_TELEMETRY_DEBUG`.\n */\nexport function wantsDebug(\n  ctx: Pick<CliContext, 'env'>,\n  args?: DebugArgs,\n  argv: readonly string[] = process.argv,\n): boolean {\n  if (args?.debug) return true\n  if (ctx.env.EVLOG_CLI_DEBUG === '1') return true\n  if (argv.includes('--debug')) return true\n  return false\n}\n\n/**\n * One-time `initLogger` for CLI debug.\n *\n * - Human (`--debug`): compact case-file report on stderr\n * - JSON (`--json --debug`): raw wide event JSON on stderr\n */\nexport function ensureCliDebugLogger(options: { json?: boolean, color?: boolean } = {}): void {\n  if (loggerReady) return\n  loggerReady = true\n\n  const json = options.json === true\n  const color = options.color === true\n\n  initLogger({\n    env: {\n      service: 'evlog-cli',\n      version: VERSION,\n      environment: resolveCliEnvironment(),\n    },\n    pretty: false,\n    silent: true,\n    minLevel: 'debug',\n    _suppressDrainWarning: true,\n    drain: ({ event }) => {\n      if (json) {\n        process.stderr.write(`${JSON.stringify(event)}\\n`)\n        return\n      }\n      process.stderr.write(formatDebugReport(event as Record<string, unknown>, { color }))\n    },\n  })\n}\n\n/** Create a request logger for one CLI command invocation. */\nexport function createCliLogger(seed: Record<string, unknown> = {}): RequestLogger {\n  return createLogger(seed)\n}\n\n/**\n * Run `fn` with a {@link CliDebug} handle. Always passes a handle:\n * live when debug is on, no-op (but `step` still runs work) when off.\n *\n * Emits once in `finally` when debug is on. Unexpected throws become\n * {@link cliErrors.COMMAND_FAILED} when not already an {@link EvlogError}.\n */\nexport async function withCliDebug<T>(\n  ctx: CliContext,\n  options: { command: string } & DebugArgs,\n  fn: (log: CliDebug) => Promise<T> | T,\n): Promise<T> {\n  if (!wantsDebug(ctx, options)) {\n    return await fn(createNoopCliDebug())\n  }\n\n  ensureCliDebugLogger({ json: options.json, color: ctx.color })\n  const raw = createCliLogger({\n    command: options.command,\n    cliVersion: VERSION,\n    environment: resolveCliEnvironment(),\n  })\n  const log = createCliDebug(raw)\n\n  try {\n    return await fn(log)\n  } catch (error) {\n    if (error instanceof EvlogError) {\n      raw.error(error)\n    } else {\n      raw.error(cliErrors.COMMAND_FAILED({\n        cause: error instanceof Error ? error : undefined,\n        message: error instanceof Error ? error.message : String(error),\n      }))\n    }\n    throw error\n  } finally {\n    raw.emit()\n  }\n}\n\n/** Reset module state — tests only. */\nexport function resetCliDebugLoggerForTests(): void {\n  loggerReady = false\n}\n","import type { ProjectFacts } from '../map/project-facts'\nimport type { Framework } from '../map/types'\n\n/**\n * Everything `init` can offer, as data.\n *\n * One catalog drives both surfaces — the prompts render from it and the flags\n * validate against it — so the two cannot drift.\n */\n\nexport type DrainId =\n  | 'fs'\n  | 'axiom'\n  | 'otlp'\n  | 'posthog'\n  | 'sentry'\n  | 'better-stack'\n  | 'datadog'\n  | 'hyperdx'\n  | 'none'\n\nexport interface Destination {\n  id: DrainId\n  label: string\n  /** One line under the label in the picker — what you get, not what it is. */\n  hint: string\n  /** Import specifier, `null` for the console-only choice. */\n  specifier: string | null\n  /** Factory to call in the generated code. */\n  factory: string | null\n  /** Environment variables the adapter reads. Never prompted for — see the env note. */\n  env: { name: string, hint: string }[]\n  docs: string\n  /** The filesystem drain is not: it writes files on whatever box serves the request. */\n  productionSafe: boolean\n}\n\nexport const DESTINATIONS: readonly Destination[] = [\n  {\n    id: 'fs',\n    label: 'Local files',\n    hint: 'NDJSON under .evlog/logs — no account, works offline',\n    specifier: 'evlog/fs',\n    factory: 'createFsDrain()',\n    env: [],\n    docs: '/integrate/adapters/self-hosted/fs',\n    productionSafe: false,\n  },\n  {\n    id: 'axiom',\n    label: 'Axiom',\n    hint: 'Wide events you can query with APL',\n    specifier: 'evlog/axiom',\n    factory: 'createAxiomDrain()',\n    env: [\n      { name: 'AXIOM_DATASET', hint: 'dataset to write to' },\n      { name: 'AXIOM_API_KEY', hint: 'API token with ingest permission' },\n    ],\n    docs: '/integrate/adapters/cloud/axiom',\n    productionSafe: true,\n  },\n  {\n    id: 'otlp',\n    label: 'OpenTelemetry (OTLP)',\n    hint: 'Any OTLP collector — vendor-neutral',\n    specifier: 'evlog/otlp',\n    factory: 'createOTLPDrain()',\n    env: [\n      { name: 'OTEL_EXPORTER_OTLP_ENDPOINT', hint: 'collector URL' },\n      { name: 'OTEL_SERVICE_NAME', hint: 'defaults to your evlog service name' },\n    ],\n    docs: '/integrate/adapters/hybrid/otlp',\n    productionSafe: true,\n  },\n  {\n    id: 'posthog',\n    label: 'PostHog',\n    hint: 'Product analytics and logs in one place',\n    specifier: 'evlog/posthog',\n    factory: 'createPostHogDrain()',\n    env: [\n      { name: 'POSTHOG_API_KEY', hint: 'project API key' },\n      { name: 'POSTHOG_HOST', hint: 'defaults to PostHog cloud' },\n    ],\n    docs: '/integrate/adapters/cloud/posthog',\n    productionSafe: true,\n  },\n  {\n    id: 'sentry',\n    label: 'Sentry',\n    hint: 'Errors with the full wide event attached',\n    specifier: 'evlog/sentry',\n    factory: 'createSentryDrain()',\n    env: [{ name: 'SENTRY_DSN', hint: 'project DSN' }],\n    docs: '/integrate/adapters/cloud/sentry',\n    productionSafe: true,\n  },\n  {\n    id: 'better-stack',\n    label: 'Better Stack',\n    hint: 'Logtail ingest with live tail',\n    specifier: 'evlog/better-stack',\n    factory: 'createBetterStackDrain()',\n    env: [{ name: 'BETTER_STACK_API_KEY', hint: 'source token' }],\n    docs: '/integrate/adapters/cloud/better-stack',\n    productionSafe: true,\n  },\n  {\n    id: 'datadog',\n    label: 'Datadog',\n    hint: 'Logs intake, correlated with your APM traces',\n    specifier: 'evlog/datadog',\n    factory: 'createDatadogDrain()',\n    env: [\n      { name: 'DATADOG_API_KEY', hint: 'API key' },\n      { name: 'DATADOG_SITE', hint: 'e.g. datadoghq.eu' },\n    ],\n    docs: '/integrate/adapters/cloud/datadog',\n    productionSafe: true,\n  },\n  {\n    id: 'hyperdx',\n    label: 'HyperDX',\n    hint: 'OTLP-native, session replay alongside logs',\n    specifier: 'evlog/hyperdx',\n    factory: 'createHyperDXDrain()',\n    env: [{ name: 'HYPERDX_API_KEY', hint: 'ingestion key' }],\n    docs: '/integrate/adapters/hybrid/hyperdx',\n    productionSafe: true,\n  },\n  {\n    id: 'none',\n    label: 'Nothing yet',\n    hint: 'Pretty console output only — wire a drain when you are ready',\n    specifier: null,\n    factory: null,\n    env: [],\n    docs: '/integrate/adapters/overview',\n    productionSafe: true,\n  },\n]\n\nexport function findDestination(id: string): Destination | undefined {\n  return DESTINATIONS.find(destination => destination.id === id)\n}\n\n/** Destinations offered for local development — the file sink, or nothing. */\nexport const DEV_DESTINATIONS = DESTINATIONS.filter(d => d.id === 'fs' || d.id === 'none')\n\n/** Production destinations. The filesystem sink is deliberately absent. */\nexport const PROD_DESTINATIONS = DESTINATIONS.filter(d => d.productionSafe && d.factory !== null)\n\n/* ── enrichers ──────────────────────────────────────────────────────────── */\n\nexport type EnricherId = 'user-agent' | 'geo' | 'request-size' | 'trace-context'\n\nexport interface Enricher {\n  id: EnricherId\n  label: string\n  hint: string\n  factory: string\n}\n\nexport const ENRICHERS: readonly Enricher[] = [\n  {\n    id: 'user-agent',\n    label: 'User agent',\n    hint: 'Browser, OS and device, parsed from the header',\n    factory: 'createUserAgentEnricher()',\n  },\n  {\n    id: 'geo',\n    label: 'Geo',\n    hint: 'Country and region from CDN headers — no lookup, no cost',\n    factory: 'createGeoEnricher()',\n  },\n  {\n    id: 'request-size',\n    label: 'Request size',\n    hint: 'Bytes in and out — cheap, and it finds the payloads nobody expected',\n    factory: 'createRequestSizeEnricher()',\n  },\n  {\n    id: 'trace-context',\n    label: 'Trace context',\n    hint: 'W3C traceparent, so events line up with your traces',\n    factory: 'createTraceContextEnricher()',\n  },\n]\n\nexport const DEFAULT_ENRICHERS: readonly EnricherId[] = ['user-agent', 'geo', 'request-size', 'trace-context']\n\nexport function findEnricher(id: string): Enricher | undefined {\n  return ENRICHERS.find(enricher => enricher.id === id)\n}\n\n/* ── sampling ───────────────────────────────────────────────────────────── */\n\nexport type SamplingProfile = 'all' | 'low' | 'medium' | 'high' | 'very-high'\n\nexport interface SamplingPreset {\n  id: SamplingProfile\n  label: string\n  hint: string\n  /**\n   * Rates to write, or `null` for \"keep everything\".\n   *\n   * `debug` is absent on purpose: an unspecified level is kept at 100%, and\n   * debug events only exist because somebody turned them on to chase something.\n   */\n  rates: { info: number, warn: number } | null\n}\n\n/**\n * Named by the traffic the app takes, not by the ratio.\n *\n * Errors stay at 100% in every tier. Info is what moves across the ladder;\n * warnings only give way at the top.\n */\nexport const SAMPLING_PRESETS: readonly SamplingPreset[] = [\n  {\n    id: 'all',\n    label: 'Everything',\n    hint: 'No sampling — the right answer until volume or cost says otherwise',\n    rates: null,\n  },\n  {\n    id: 'low',\n    label: 'Low traffic',\n    hint: 'Half the info events, every warning — a small app that has started to repeat itself',\n    rates: { info: 50, warn: 100 },\n  },\n  {\n    id: 'medium',\n    label: 'Medium traffic',\n    hint: '1 info event in 4, every warning — steady traffic with a bill worth watching',\n    rates: { info: 25, warn: 100 },\n  },\n  {\n    id: 'high',\n    label: 'High traffic',\n    hint: '1 info event in 10, every warning — info is most of what you are paying for',\n    rates: { info: 10, warn: 100 },\n  },\n  {\n    id: 'very-high',\n    label: 'Very high traffic',\n    hint: '1 info event in 100 and half the warnings — trends rather than individual requests',\n    rates: { info: 1, warn: 50 },\n  },\n]\n\nexport function findSamplingPreset(id: string): SamplingPreset | undefined {\n  return SAMPLING_PRESETS.find(preset => preset.id === id)\n}\n\n/* ── extras ─────────────────────────────────────────────────────────────── */\n\nexport type ExtraId =\n  | 'enrichers'\n  | 'pipeline'\n  | 'sampling'\n  | 'vite'\n  | 'error-catalog'\n  | 'audit-catalog'\n  | 'ai'\n  | 'better-auth'\n\n/** Heading the extra is listed under in the picker. */\nexport type ExtraGroup = 'Context' | 'Delivery' | 'Catalogs' | 'Build' | 'Integrations'\n\nexport interface Extra {\n  id: ExtraId\n  group: ExtraGroup\n  label: string\n  hint: string\n  docs: string\n  /** Frameworks this makes sense for; omitted means all of them. */\n  frameworks?: readonly Framework[]\n  /** Only offered when production events actually leave the process. */\n  requiresProdDrain?: true\n}\n\nexport const EXTRAS: readonly Extra[] = [\n  {\n    id: 'enrichers',\n    group: 'Context',\n    label: 'Request enrichers',\n    hint: 'User agent, geo, size, trace context — you pick which',\n    docs: '/use-cases/enrichers',\n  },\n  {\n    id: 'pipeline',\n    group: 'Delivery',\n    label: 'Batching and retry',\n    hint: 'Buffer events and retry failed sends instead of one HTTP call per request',\n    docs: '/extend/drain-pipeline',\n    requiresProdDrain: true,\n  },\n  {\n    id: 'sampling',\n    group: 'Delivery',\n    label: 'Sampling',\n    hint: 'Keep every error, a fraction of the healthy traffic',\n    docs: '/learn/sampling',\n  },\n  {\n    id: 'error-catalog',\n    group: 'Catalogs',\n    label: 'Error catalog',\n    hint: 'Turn the errors you already repeat across files into typed entries',\n    docs: '/learn/catalogs',\n  },\n  {\n    id: 'audit-catalog',\n    group: 'Catalogs',\n    label: 'Audit actions',\n    hint: 'Typed actions for the sensitive routes that have no trail yet',\n    docs: '/use-cases/audit/overview',\n  },\n  {\n    id: 'vite',\n    group: 'Build',\n    label: 'Vite plugin',\n    hint: 'Strip log.debug() from production builds, inject source locations',\n    docs: '/reference/vite-plugin',\n    frameworks: ['tanstack-start'],\n  },\n  {\n    id: 'ai',\n    group: 'Integrations',\n    label: 'AI SDK logging',\n    hint: 'Token usage, tool calls and cost on every generation',\n    docs: '/use-cases/ai-sdk/overview',\n  },\n  {\n    id: 'better-auth',\n    group: 'Integrations',\n    label: 'Auth identity',\n    hint: 'Attach the signed-in user to every event automatically',\n    docs: '/use-cases/better-auth/overview',\n  },\n]\n\nexport function findExtra(id: string): Extra | undefined {\n  return EXTRAS.find(extra => extra.id === id)\n}\n\n/** What the project looks like, as far as deciding what to offer goes. */\nexport interface OfferContext {\n  framework: Framework\n  /** Production destinations chosen — empty means nothing leaves the process. */\n  prodDrains: DrainId[]\n  /** What the scan found, or `null` when it has not run. */\n  facts: ProjectFacts | null\n  /** Sensitive entry points with no audit trail, from the same scan. */\n  auditGaps: number\n}\n\n/**\n * The extras worth showing for this project.\n *\n * Gated on evidence: integrations need their package installed, catalogs need\n * the scan to have found something to seed them with.\n */\nexport function availableExtras(context: OfferContext): Extra[] {\n  return EXTRAS.filter((extra) => {\n    if (extra.frameworks && !extra.frameworks.includes(context.framework)) return false\n    if (extra.requiresProdDrain && context.prodDrains.length === 0) return false\n\n    switch (extra.id) {\n      case 'ai': return context.facts?.pairable.has('ai') ?? false\n      case 'better-auth': return context.facts?.pairable.has('better-auth') ?? false\n      /* One inline error is a local decision; the same one in three handlers is\n         a catalog entry nobody has written yet. */\n      case 'error-catalog': return (context.facts?.repeatedErrors.size ?? 0) > 0\n      case 'audit-catalog': return context.auditGaps > 0\n      default: return true\n    }\n  })\n}\n\n/** A count to put next to an offer, so the reason it is there is visible. */\nexport function offerEvidence(extra: Extra, context: OfferContext): string | null {\n  switch (extra.id) {\n    case 'error-catalog': {\n      const count = context.facts?.repeatedErrors.size ?? 0\n      return count > 0 ? `${count} repeated error${count === 1 ? '' : 's'} found` : null\n    }\n    case 'audit-catalog':\n      return context.auditGaps > 0 ? `${context.auditGaps} sensitive route${context.auditGaps === 1 ? '' : 's'} with no trail` : null\n    case 'ai': return 'ai is installed'\n    case 'better-auth': return 'better-auth is installed'\n    default: return null\n  }\n}\n","import { readFileSync } from 'node:fs'\nimport { parseSync } from 'oxc-parser'\nimport type { Comment, Node, Program } from 'oxc-parser'\nimport type { HandlerLocation } from './types'\n\nexport interface ParseResult {\n  program: Program\n  source: string\n  errors: string[]\n  /** Byte offset → line resolver for this source. */\n  lines: LineIndex\n  /** Comments, kept for `evlog-map-disable` directives. */\n  comments: readonly Comment[]\n}\n\n/**\n * Offset → position lookup for one source file.\n *\n * Built once per file and shared by every consumer: resolving a line by\n * counting newlines from the start of the file is O(offset), which turns\n * quadratic once you ask for thousands of node positions.\n */\nexport interface LineIndex {\n  lineAt: (offset: number) => number\n  locAt: (offset: number) => HandlerLocation\n}\n\nexport function createLineIndex(source: string): LineIndex {\n  const starts: number[] = [0]\n  for (let i = 0; i < source.length; i++) {\n    if (source[i] === '\\n') starts.push(i + 1)\n  }\n\n  /** Index of the line containing `offset`, by binary search over line starts. */\n  function indexOf(offset: number): number {\n    let low = 0\n    let high = starts.length - 1\n    while (low < high) {\n      const mid = Math.ceil((low + high) / 2)\n      if (starts[mid]! <= offset) low = mid\n      else high = mid - 1\n    }\n    return low\n  }\n\n  return {\n    lineAt: offset => indexOf(offset) + 1,\n    locAt: (offset) => {\n      const index = indexOf(offset)\n      return { line: index + 1, column: offset - starts[index]! }\n    },\n  }\n}\n\n/** Parse a route file (Vue `<script>` extracted first) into an oxc AST + source. */\nexport function parseFile(filePath: string): ParseResult | null {\n  let source: string\n  try {\n    source = readFileSync(filePath, 'utf8')\n  } catch {\n    return null\n  }\n  return parseSource(filePath, source)\n}\n\n/** Reads and parses one path. */\nexport type ParseFn = (filePath: string) => ParseResult | null\n\n/**\n * A {@link parseFile} that touches each path once, for the length of one scan.\n *\n * The adapter parses a file to find its handler and the scan parses it again to\n * derive its facts — and Next emits one entry per exported method, so a\n * `route.ts` with GET, POST and DELETE went through oxc four times.\n *\n * Scoped to a scan rather than the module: a cache that outlives the run would\n * serve stale ASTs to the next one.\n */\nexport function createParseCache(): ParseFn {\n  const seen = new Map<string, ParseResult | null>()\n  return (filePath) => {\n    if (!seen.has(filePath)) seen.set(filePath, parseFile(filePath))\n    return seen.get(filePath) ?? null\n  }\n}\n\n/**\n * Parse source that is already in memory.\n *\n * Split out from {@link parseFile} so rules can be tested against inline code\n * without touching the filesystem — `filePath` is only used to pick the\n * dialect and to label parse errors.\n */\nexport function parseSource(filePath: string, source: string): ParseResult | null {\n  const ext = filePath.split('.').pop()?.toLowerCase()\n  let code = source\n\n  if (ext === 'vue') {\n    const extracted = extractVueScript(source)\n    if (!extracted) return null\n    code = extracted\n  }\n\n  const result = parseSync(filePath, code, {\n    sourceType: 'module',\n    lang: ext === 'tsx' || ext === 'jsx' ? 'tsx' : 'ts',\n  })\n\n  return {\n    program: result.program,\n    source: code,\n    errors: result.errors.map(e => e.message),\n    lines: createLineIndex(code),\n    comments: result.comments,\n  }\n}\n\n/**\n * Extract a Vue `<script>` block, padded with the newlines that preceded it.\n *\n * The padding keeps every reported line number aligned with the `.vue` file the\n * user will open, instead of being relative to the script block.\n */\nfunction extractVueScript(source: string): string | null {\n  const block = matchVueScript(source)\n  if (!block) return null\n  const before = source.slice(0, block.index).split('\\n').length - 1\n  return '\\n'.repeat(before) + block.code\n}\n\nfunction matchVueScript(source: string): { code: string, index: number } | null {\n  const scriptSetup = source.match(/<script[^>]*setup[^>]*>([\\s\\S]*?)<\\/script>/i)\n  if (scriptSetup?.[1] !== undefined && scriptSetup.index !== undefined) {\n    return { code: scriptSetup[1], index: scriptSetup.index + scriptSetup[0].indexOf('>') + 1 }\n  }\n  const plain = source.match(/<script[^>]*>([\\s\\S]*?)<\\/script>/i)\n  if (plain?.[1] !== undefined && plain.index !== undefined) {\n    return { code: plain[1], index: plain.index + plain[0].indexOf('>') + 1 }\n  }\n  return null\n}\n\nexport type VisitorFn = (node: Node, parent: Node | null) => void\n\n/** Walk every node in an oxc AST subtree, depth-first. */\nexport function walkAst(node: Node, visitor: VisitorFn, parent: Node | null = null): void {\n  visitor(node, parent)\n  for (const key of Object.keys(node as unknown as Record<string, unknown>)) {\n    const value = (node as unknown as Record<string, unknown>)[key]\n    if (!value) continue\n    if (Array.isArray(value)) {\n      for (const child of value) {\n        if (child && typeof child === 'object' && 'type' in child) {\n          walkAst(child as Node, visitor, node)\n        }\n      }\n    } else if (typeof value === 'object' && value !== null && 'type' in value) {\n      walkAst(value as Node, visitor, node)\n    }\n  }\n}\n\n/**\n * Real source position of a node.\n *\n * `lines` is required on purpose: the previous signature made it optional and\n * fell back to `{ line: 1 }`, so every caller that forgot it silently reported\n * findings on line 1.\n */\nexport function nodeLoc(node: Node, lines: LineIndex): HandlerLocation | null {\n  if ('start' in node && typeof node.start === 'number') {\n    return lines.locAt(node.start)\n  }\n  if ('loc' in node && node.loc && typeof node.loc === 'object') {\n    const loc = node.loc as { start?: { line?: number, column?: number } }\n    if (loc.start?.line !== undefined) {\n      return { line: loc.start.line, column: loc.start.column ?? 0 }\n    }\n  }\n  return null\n}\n\nexport function isCallNamed(node: Node, names: string[]): node is Node & { type: 'CallExpression', callee: Node } {\n  if (node.type !== 'CallExpression') return false\n  const { callee } = (node as { callee: Node })\n  if (callee.type === 'Identifier') {\n    return names.includes(callee.name)\n  }\n  if (callee.type === 'MemberExpression') {\n    const prop = (callee as { property: Node }).property\n    if (prop.type === 'Identifier') {\n      return names.includes(prop.name)\n    }\n  }\n  return false\n}\n\nexport function findHandlerLocation(parsed: ParseResult, patterns: string[]): HandlerLocation | null {\n  let found: HandlerLocation | null = null\n  walkAst(parsed.program, (node) => {\n    if (found) return\n    if (isCallNamed(node, patterns)) {\n      const loc = nodeLoc(node, parsed.lines)\n      if (loc) {\n        found = loc\n      }\n    }\n    if (node.type === 'ExportDefaultDeclaration') {\n      const loc = nodeLoc(node, parsed.lines)\n      if (loc) found = loc\n    }\n  })\n  return found\n}\n\nexport function hasDirective(program: Program, directive: string): boolean {\n  let found = false\n  walkAst(program, (node) => {\n    if (node.type === 'ExpressionStatement') {\n      const expr = (node as { expression: Node }).expression\n      if (expr.type === 'Literal' && (expr as { value: unknown }).value === directive) {\n        found = true\n      }\n    }\n  })\n  return found\n}\n\nexport function findHttpMethodExports(parsed: ParseResult): Array<{ method: string, line: number }> {\n  const methods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']\n  const found: Array<{ method: string, line: number }> = []\n  walkAst(parsed.program, (node) => {\n    if (node.type === 'ExportNamedDeclaration') {\n      const decl = node as { declaration?: Node, specifiers?: Array<{ exported: Node }> }\n      if (decl.declaration?.type === 'FunctionDeclaration') {\n        const fn = decl.declaration as { id?: { name: string } }\n        if (fn.id?.name && methods.includes(fn.id.name)) {\n          const loc = nodeLoc(node, parsed.lines)\n          found.push({ method: fn.id.name, line: loc?.line ?? 1 })\n        }\n      }\n      if (decl.declaration?.type === 'VariableDeclaration') {\n        const varDecl = decl.declaration as { declarations: Array<{ id: Node, init?: Node }> }\n        for (const d of varDecl.declarations) {\n          if (d.id.type === 'Identifier' && methods.includes(d.id.name) && d.init) {\n            const loc = nodeLoc(d.init, parsed.lines)\n            found.push({ method: d.id.name, line: loc?.line ?? 1 })\n          }\n        }\n      }\n      /* `export { handler as GET }` — a legitimate way to write a route\n         handler, and the only one where the method name never appears on a\n         declaration. */\n      for (const specifier of decl.specifiers ?? []) {\n        const exported = specifier.exported as { type: string, name?: string, value?: string }\n        const name = exported.type === 'Identifier' ? exported.name : exported.value\n        if (!name || !methods.includes(name)) continue\n        const loc = nodeLoc(specifier.exported, parsed.lines)\n        found.push({ method: name, line: loc?.line ?? 1 })\n      }\n    }\n  })\n  return found\n}\n","import type { Node } from 'oxc-parser'\nimport type { ParseResult } from './parse'\nimport { walkAst } from './parse'\nimport type { HandlerLocation } from './types'\n\n/**\n * Everything the rules are allowed to know about one file.\n *\n * All AST decoding lives here, in a single pass, so that rules never walk the\n * tree themselves. That is deliberate: hand-rolled node spelunking scattered\n * across rules is what makes a static analyser fragile, because each rule ends\n * up with its own slightly different idea of what \"a call to log.set()\" means.\n * One place to get it right, one place to fix when it is wrong.\n */\nexport interface FileFacts {\n  /** Local binding → import source, e.g. `useLogger` → `evlog`. */\n  imports: Map<string, string>\n  /** Names declared in this file — used to detect shadowing of auto-imports. */\n  localDeclarations: Set<string>\n  calls: readonly CallFact[]\n  throws: readonly ThrowFact[]\n  catches: readonly CatchFact[]\n  /** Network calls (`fetch`, `$fetch`, `useFetch`, `axios.*`, …). */\n  network: readonly CallFact[]\n  /**\n   * Network calls with no error affordance around them.\n   *\n   * Guarding is resolved per call rather than per file: an unrelated `try` at\n   * the top of a page used to satisfy the whole rule, so a page could pass with\n   * its actual data fetch left unhandled.\n   */\n  unguardedNetwork: readonly CallFact[]\n  /** Where an evlog logger is created, if it is. */\n  loggerInit: HandlerLocation | null\n  /** Identifiers holding an evlog logger — `const log = useLogger(event)`. */\n  loggerBindings: ReadonlySet<string>\n  /**\n   * evlog wrappers used here, e.g. `withEvlog`, `withAudit`.\n   *\n   * These instrument the event without the handler ever naming a logger, which\n   * is exactly how evlog documents its Next.js integration — so a rule that\n   * only looks for `useLogger()` would flag evlog's own recommended code.\n   */\n  evlogWrappers: ReadonlySet<string>\n  /** evlog entrypoints imported here, e.g. `evlog`, `evlog/ai`. */\n  evlogImports: ReadonlySet<string>\n  /**\n   * evlog names this file re-exports, or `*` for `export * from 'evlog'`.\n   *\n   * Re-exporting evlog through a local module is how its own Next.js docs read\n   * (`import { useLogger } from '@/lib/evlog'`), so a scan that only trusted the\n   * literal source `evlog` scored that recommended shape as uninstrumented.\n   */\n  reexportsEvlog: ReadonlySet<string>\n  /** Object keys and member names seen anywhere — cheap PII surface. */\n  names: ReadonlySet<string>\n  /** `createError({ … })` calls with enough literal detail to compare. */\n  inlineErrors: readonly InlineErrorFact[]\n  /** Catalog names declared here — `billing` for `defineErrorCatalog('billing', …)`. */\n  catalogsDeclared: readonly string[]\n  /** Calls on a known evlog logger, e.g. `loggerCalls('audit')`. */\n  loggerCalls: (member: string) => readonly CallFact[]\n  /** Calls by normalized callee name, e.g. `callsTo('createError')`. */\n  callsTo: (name: string) => readonly CallFact[]\n}\n\nexport interface CallFact {\n  /** Normalized callee: `useLogger`, `log.set`, `console.error`. */\n  name: string\n  /** Trailing member for member calls (`set`), else the identifier. */\n  member: string\n  /** Receiver identifier for member calls (`log`), else `null`. */\n  receiver: string | null\n  /**\n   * Root identifier of the callee chain — `log` in `log.audit?.deny()`.\n   *\n   * Separate from `receiver`, which is only the immediate object: without this,\n   * a nested or optional chain loses track of who the call is really on.\n   */\n  root: string | null\n  /** Member names from the root — `['audit', 'deny']` for `log.audit?.deny()`. */\n  chain: readonly string[]\n  line: number\n  /** Byte offset of the call, used to place it inside an error guard. */\n  start: number\n  /** Keys of the first argument when it is an object literal. */\n  props: ReadonlySet<string>\n}\n\nexport interface ThrowFact {\n  kind: 'plain-error' | 'create-error' | 'other'\n  /** Keys passed to `createError({ … })`. */\n  props: ReadonlySet<string>\n  line: number\n}\n\n/**\n * One `createError({ … })` call, identified by its literal payload.\n *\n * The signature exists so the same error can be recognised in two different\n * files. That is the only honest reason to bring up error catalogs: an error\n * written once is fine where it is, whereas the same error written out in three\n * handlers is a catalog entry waiting to happen.\n */\nexport interface InlineErrorFact {\n  /** Literal status/code/message/why, normalized. Empty when nothing compares. */\n  signature: string\n  /** Short human label, e.g. `402 Card declined`. */\n  label: string\n  line: number\n}\n\nexport interface CatchFact {\n  line: number\n  isEmpty: boolean\n  /** Logs, rethrows, or returns — i.e. the error is not silently dropped. */\n  handled: boolean\n}\n\n/**\n * Factories that hand back a wide-event logger.\n *\n * evlog's `log` export is not one of them — it is the simple logging API and\n * has no `set` or `audit`.\n */\nconst LOGGER_FACTORIES = ['useLogger', 'createLogger', 'createRequestLogger', 'initLogger']\n\n/**\n * evlog wrappers that instrument a handler on the caller's behalf.\n *\n * `withEvlog` creates the request logger (evlog's documented Next.js pattern);\n * `withAudit` writes audit fields onto the ambient one.\n */\nconst EVLOG_WRAPPERS = ['withEvlog', 'withAudit']\n\n/** Network entry points worth an event when they fail. */\nconst NETWORK_CALLS = [\n  'fetch',\n  '$fetch',\n  'useFetch',\n  'useLazyFetch',\n  'useAsyncData',\n  'useLazyAsyncData',\n  'ofetch',\n]\n\nconst NETWORK_RECEIVERS = ['axios', 'http', 'https']\n\n/** Statement shapes inside a `catch` that count as handling the error. */\nconst HANDLING_MEMBERS = ['error', 'warn', 'set', 'audit', 'captureException']\n\n/** Calls that put an error affordance around whatever they wrap. */\nconst ERROR_GUARD_MEMBERS = ['catch', 'onError', 'catchError']\n\n/** Half-open `[start, end)` byte range of source that guards against a failure. */\ntype GuardRange = readonly [number, number]\n\nfunction nodeRange(node: Node): GuardRange {\n  const { start, end } = node as unknown as { start: number, end: number }\n  return [start, end]\n}\n\nfunction isEvlogSource(source: string | undefined | null): boolean {\n  return source === 'evlog' || (source?.startsWith('evlog/') ?? false)\n}\n\n/**\n * How a local module is keyed when matching an import to a re-exporting file.\n *\n * The same module is written `@/lib/evlog`, `~/lib/evlog` and `../../lib/evlog`\n * depending on where it is imported from, and resolving those properly means\n * reading `tsconfig` path aliases, Nuxt aliases and Vite aliases — three sources\n * of truth that can each be wrong. The last meaningful segment is stable across\n * all of them: `evlog` for `lib/evlog.ts`, and the directory name for an\n * `index.ts`, which is how such a module is imported anyway.\n */\nexport function moduleKey(specifier: string): string {\n  const segments = specifier\n    .replace(/\\.(?:m|c)?[jt]sx?$/, '')\n    .split('/')\n    .filter(segment => segment.length > 0 && segment !== '.' && segment !== '..')\n\n  const last = segments[segments.length - 1]\n  if (last === 'index') return segments[segments.length - 2] ?? 'index'\n  return last ?? specifier\n}\n\n/** Properties whose literal values make one error distinguishable from another. */\nconst ERROR_IDENTITY_KEYS = ['status', 'statusCode', 'code', 'message', 'why']\n\nfunction literalValue(node: Node | undefined): string | null {\n  if (!node) return null\n  if (node.type === 'Literal') {\n    const { value } = node as { value: unknown }\n    return value === null || value === undefined ? null : String(value)\n  }\n  /* A template literal with no interpolation is just a string. */\n  if (node.type === 'TemplateLiteral') {\n    const template = node as { expressions: Node[], quasis: Array<{ value: { cooked?: string | null } }> }\n    if (template.expressions.length > 0) return null\n    return template.quasis[0]?.value.cooked ?? null\n  }\n  return null\n}\n\n/** Literal properties of an object literal, by key. */\nfunction literalProps(node: Node | undefined): Map<string, string> {\n  const props = new Map<string, string>()\n  if (!node || node.type !== 'ObjectExpression') return props\n  for (const prop of (node as { properties: Node[] }).properties) {\n    if (prop.type !== 'Property') continue\n    const { key, value } = prop as { key: Node, value: Node }\n    const name = key.type === 'Identifier'\n      ? key.name\n      : key.type === 'Literal' ? String((key as { value: unknown }).value) : null\n    if (name === null) continue\n    const literal = literalValue(value)\n    if (literal !== null) props.set(name, literal)\n  }\n  return props\n}\n\n/**\n * Identity of a `createError({ … })` payload.\n *\n * Only literals count: an error built from variables cannot be compared across\n * files, and guessing would produce false matches — which in a suggestion means\n * pointing at code that has nothing in common.\n */\nfunction errorIdentity(argument: Node | undefined): InlineErrorFact | null {\n  const props = literalProps(argument)\n  const identity = ERROR_IDENTITY_KEYS\n    .filter(key => props.has(key))\n    .map(key => `${key}=${props.get(key)!}`)\n  if (identity.length === 0) return null\n\n  const status = props.get('status') ?? props.get('statusCode')\n  const text = props.get('code') ?? props.get('message') ?? props.get('why')\n  const label = [status, text].filter(Boolean).join(' ')\n\n  return { signature: identity.join('|'), label: label.length > 0 ? label : identity[0]!, line: 0 }\n}\n\nfunction objectKeys(node: Node | undefined): Set<string> {\n  const keys = new Set<string>()\n  if (!node || node.type !== 'ObjectExpression') return keys\n  for (const prop of (node as { properties: Node[] }).properties) {\n    if (prop.type !== 'Property') continue\n    const { key } = prop as { key: Node }\n    if (key.type === 'Identifier') keys.add(key.name)\n    if (key.type === 'Literal') keys.add(String((key as { value: unknown }).value))\n  }\n  return keys\n}\n\ntype CalleeShape = Pick<CallFact, 'name' | 'member' | 'receiver' | 'root' | 'chain'>\n\n/** Strip the wrapper oxc puts around an optional chain (`a?.b()`). */\n/**\n * Strip the wrappers that sit between a name and its value.\n *\n * `req.context.log as RequestLogger` is the spelling evlog's own TanStack Start\n * guide uses, and a cast that hides the member chain is enough to make the\n * handler look uninstrumented.\n */\nfunction unwrapChain(node: Node): Node {\n  let current = node\n  while (true) {\n    switch (current.type) {\n      case 'ChainExpression':\n      case 'ParenthesizedExpression':\n        current = (current as { expression: Node }).expression\n        break\n      case 'TSAsExpression':\n      case 'TSSatisfiesExpression':\n      case 'TSNonNullExpression':\n        current = (current as { expression: Node }).expression\n        break\n      default:\n        return current\n    }\n  }\n}\n\n/**\n * Where a framework parks the request logger, read as a member chain.\n *\n * Not every integration hands the logger back from a factory: evlog's Nitro\n * plugin puts it on the request context, so the documented TanStack Start and\n * h3 handlers reach it with `req.context.log` and never call `useLogger()`.\n * Reading only factories scored those handlers as dark events while they were\n * calling `log.set()` on every request.\n */\nconst CONTEXT_LOGGER_PATH = ['context', 'log'] as const\n\n/** Whether `chain` contains `context.log` as consecutive members. */\nfunction hasContextLoggerPath(chain: readonly string[]): boolean {\n  return chain.some(\n    (name, index) => name === CONTEXT_LOGGER_PATH[0] && chain[index + 1] === CONTEXT_LOGGER_PATH[1],\n  )\n}\n\n/**\n * Hono's `c.get('log')` (and the same shape on any context object).\n *\n * Not a member path: the key is a call argument. Taken at face value like\n * `context.log` — there is no import to check, and missing it would score\n * every idiomatic Hono handler as a dark event.\n */\nfunction isContextGetLog(node: Node): boolean {\n  if (node.type !== 'CallExpression') return false\n  const call = node as { callee: Node, arguments: Node[] }\n  if (call.callee.type !== 'MemberExpression') return false\n  const member = call.callee as { property: Node, computed?: boolean }\n  if (member.computed || member.property.type !== 'Identifier' || member.property.name !== 'get') {\n    return false\n  }\n  const [key] = call.arguments\n  return key?.type === 'Literal' && (key as { value: unknown }).value === 'log'\n}\n\n/** Member names of `node`, root first — `['context', 'log']` for `req.context.log`. */\nfunction memberPath(node: Node): string[] {\n  const path: string[] = []\n  let current = unwrapChain(node)\n  while (current.type === 'MemberExpression') {\n    const { property, object } = current as { property: Node, object: Node }\n    if (property.type !== 'Identifier') return []\n    path.unshift(property.name)\n    current = unwrapChain(object)\n  }\n  return path\n}\n\n/**\n * Bindings a declaration pattern introduces.\n *\n * Only the shapes that appear in evlog's own setup are handled: a plain name and\n * a flat object pattern. Anything deeper would be guesswork.\n */\nfunction patternNames(id: Node): string[] {\n  if (id.type === 'Identifier') return [id.name]\n  if (id.type !== 'ObjectPattern') return []\n\n  const names: string[] = []\n  for (const property of (id as { properties: Node[] }).properties) {\n    if (property.type !== 'Property') continue\n    const { value, key } = property as { value: Node, key: Node }\n    if (value.type === 'Identifier') names.push(value.name)\n    else if (key.type === 'Identifier') names.push(key.name)\n  }\n  return names\n}\n\n/** Local name `key` is bound to by an object pattern, honouring renames. */\nfunction destructuredAs(id: Node, key: string): string | null {\n  if (id.type !== 'ObjectPattern') return null\n  for (const property of (id as { properties: Node[] }).properties) {\n    if (property.type !== 'Property') continue\n    const { key: propertyKey, value } = property as { key: Node, value: Node }\n    if (propertyKey.type !== 'Identifier' || propertyKey.name !== key) continue\n    if (value.type === 'Identifier') return value.name\n  }\n  return null\n}\n\n/**\n * Decode a call's callee into names.\n *\n * Walks the whole member chain so `log.audit?.deny()` is still recognised as a\n * call on `log`: matching only the immediate object misses it, and an\n * unrecognised audit call means the report claims an audited route is not.\n */\nfunction describeCallee(rawCallee: Node): CalleeShape | null {\n  const callee = unwrapChain(rawCallee)\n\n  if (callee.type === 'Identifier') {\n    return { name: callee.name, member: callee.name, receiver: null, root: null, chain: [callee.name] }\n  }\n  if (callee.type !== 'MemberExpression') return null\n\n  const chain: string[] = []\n  let current = callee as Node\n  while (true) {\n    current = unwrapChain(current)\n    if (current.type !== 'MemberExpression') break\n    const { property } = (current as { property: Node })\n    if (property.type !== 'Identifier') return null\n    chain.unshift(property.name)\n    current = (current as { object: Node }).object\n  }\n\n  const member = chain.at(-1)\n  if (member === undefined) return null\n  const root = current.type === 'Identifier' ? current.name : null\n  const receiver = chain.length === 1 ? root : (chain.at(-2) ?? null)\n\n  return {\n    name: [root, ...chain].filter(Boolean).join('.'),\n    member,\n    receiver,\n    root,\n    chain,\n  }\n}\n\nfunction isNetworkCall(call: CallFact): boolean {\n  if (NETWORK_CALLS.includes(call.member)) return true\n  return call.receiver !== null && NETWORK_RECEIVERS.includes(call.receiver)\n}\n\n/**\n * Whether a statement inside a `catch` block does something with the error.\n *\n * Nested bodies count: `catch (e) { if (retryable(e)) log.warn(e); else throw e }`\n * is a handled error however deep the branch sits, and reading only the direct\n * children reported that catch as swallowing everything.\n */\nfunction statementHandlesError(statement: Node): boolean {\n  if (statement.type === 'ThrowStatement' || statement.type === 'ReturnStatement') return true\n\n  switch (statement.type) {\n    case 'BlockStatement':\n      return (statement as { body: Node[] }).body.some(statementHandlesError)\n    case 'IfStatement': {\n      const { consequent, alternate } = statement as { consequent: Node, alternate?: Node | null }\n      return statementHandlesError(consequent) || (!!alternate && statementHandlesError(alternate))\n    }\n    case 'SwitchStatement':\n      return (statement as { cases: Array<{ consequent: Node[] }> }).cases\n        .some(branch => branch.consequent.some(statementHandlesError))\n    case 'TryStatement': {\n      const { block, handler, finalizer } = statement as {\n        block: Node\n        handler?: { body: Node } | null\n        finalizer?: Node | null\n      }\n      return statementHandlesError(block)\n        || (!!handler && statementHandlesError(handler.body))\n        || (!!finalizer && statementHandlesError(finalizer))\n    }\n    default:\n      break\n  }\n\n  if (statement.type !== 'ExpressionStatement') return false\n\n  let { expression } = (statement as { expression: Node })\n  if (expression.type === 'AwaitExpression') {\n    expression = (expression as { argument: Node }).argument\n  }\n  if (expression.type !== 'CallExpression') return false\n\n  const described = describeCallee((expression as { callee: Node }).callee)\n  if (!described) return false\n  if (described.root === 'console') return true\n  return described.chain.some(name => HANDLING_MEMBERS.includes(name))\n}\n\n/**\n * Collect the facts for one parsed file in a single AST pass.\n *\n * @param options.evlogAutoImports - evlog identifiers the framework injects\n * without an import (Nuxt/Nitro). An auto-import only counts when the file does\n * not declare the same name itself, so a local `function useLogger()` stub is\n * not mistaken for evlog's.\n * @param options.evlogBarrels - local modules that re-export evlog, keyed by\n * {@link moduleKey}, with the names each one forwards. Collected once per scan so\n * that a handler importing from `@/lib/evlog` is credited without this function\n * ever touching the filesystem.\n */\nexport function buildFileFacts(\n  parsed: ParseResult,\n  options: {\n    evlogAutoImports?: readonly string[]\n    evlogBarrels?: ReadonlyMap<string, ReadonlySet<string>>\n  } = {},\n): FileFacts {\n  const { lines } = parsed\n  const imports = new Map<string, string>()\n  const localDeclarations = new Set<string>()\n  const calls: CallFact[] = []\n  const throwFacts: ThrowFact[] = []\n  const catchFacts: CatchFact[] = []\n  const inlineErrors: InlineErrorFact[] = []\n  const catalogsDeclared: string[] = []\n  const reexportsEvlog = new Set<string>()\n  const names = new Set<string>()\n  /** Resolved after the pass: needs imports and declarations to be complete. */\n  const loggerCandidates: Array<{ binding: string | null, factory: string, line: number }> = []\n  /** Loggers read off the request context — no import to resolve them against. */\n  const contextLoggers: Array<{ binding: string, line: number }> = []\n  /** Exported bindings whose value comes from a call — resolved after the pass. */\n  const exportedFromFactory: Array<{ names: readonly string[], factory: string }> = []\n  /** Source spans in which a failure is caught, handled or surfaced. */\n  const guards: GuardRange[] = []\n\n  walkAst(parsed.program, (node) => {\n    switch (node.type) {\n      case 'ImportDeclaration': {\n        const declaration = node as {\n          source: { value: string }\n          specifiers: Array<{ type: string, local?: { name: string } }>\n        }\n        for (const specifier of declaration.specifiers) {\n          if (specifier.local) imports.set(specifier.local.name, declaration.source.value)\n        }\n        break\n      }\n\n      case 'ExportNamedDeclaration': {\n        const exported = node as {\n          source?: { value: string } | null\n          specifiers?: Array<{ exported?: { name?: string } }>\n          declaration?: Node | null\n        }\n\n        if (exported.source) {\n          if (!isEvlogSource(exported.source.value)) break\n          for (const specifier of exported.specifiers ?? []) {\n            if (specifier.exported?.name) reexportsEvlog.add(specifier.exported.name)\n          }\n          break\n        }\n\n        /* `export const { useLogger, withEvlog } = createEvlog({ … })` — evlog's\n           documented Next.js setup. Whether the factory is really evlog's can\n           only be answered once the imports are known, so it waits. */\n        if (exported.declaration?.type !== 'VariableDeclaration') break\n        for (const declarator of (exported.declaration as { declarations: Node[] }).declarations) {\n          const { id, init } = declarator as { id: Node, init?: Node }\n          if (init?.type !== 'CallExpression') continue\n          const factory = describeCallee((init as { callee: Node }).callee)\n          if (!factory) continue\n          exportedFromFactory.push({ names: patternNames(id), factory: factory.member })\n        }\n        break\n      }\n\n      case 'ExportAllDeclaration': {\n        const declaration = node as { source?: { value: string } | null }\n        if (isEvlogSource(declaration.source?.value)) reexportsEvlog.add('*')\n        break\n      }\n\n      case 'FunctionDeclaration':\n      case 'ClassDeclaration': {\n        const { id } = (node as { id?: { name: string } })\n        if (id?.name) localDeclarations.add(id.name)\n        break\n      }\n\n      case 'VariableDeclarator': {\n        const declarator = node as { id: Node, init?: Node }\n        /* Destructuring binds names too: without this, `const { useLogger } =\n           createStub()` shadows the auto-import unnoticed and the file gets\n           credited with evlog's logger when it declared its own. */\n        for (const name of patternNames(declarator.id)) {\n          localDeclarations.add(name)\n        }\n        if (!declarator.init) break\n\n        let init = unwrapChain(declarator.init)\n        if (init.type === 'AwaitExpression') init = unwrapChain((init as { argument: Node }).argument)\n\n        /* `const log = req.context.log` and `const { log } = req.context`: the\n           logger comes off the request, not out of a factory. */\n        if (init.type === 'MemberExpression') {\n          const path = memberPath(init)\n          const line = lines.lineAt((init as unknown as { start: number }).start)\n          if (hasContextLoggerPath(path)) {\n            for (const name of patternNames(declarator.id)) {\n              contextLoggers.push({ binding: name, line })\n            }\n          } else if (path.at(-1) === CONTEXT_LOGGER_PATH[0]) {\n            const binding = destructuredAs(declarator.id, CONTEXT_LOGGER_PATH[1])\n            if (binding) contextLoggers.push({ binding, line })\n          }\n        }\n\n        if (init.type === 'CallExpression') {\n          const described = describeCallee((init as { callee: Node }).callee)\n          if (described && LOGGER_FACTORIES.includes(described.member)) {\n            loggerCandidates.push({\n              binding: declarator.id.type === 'Identifier' ? declarator.id.name : null,\n              factory: described.member,\n              line: lines.lineAt((init as unknown as { start: number }).start),\n            })\n          }\n          /* `const log = c.get('log')` — Hono's documented accessor. */\n          if (isContextGetLog(init)) {\n            const line = lines.lineAt((init as unknown as { start: number }).start)\n            for (const name of patternNames(declarator.id)) {\n              contextLoggers.push({ binding: name, line })\n            }\n          }\n        }\n\n        /* `const { data, error } = await useFetch(…)` — the failure is bound\n           rather than caught, which is Nuxt's shape for handling it. */\n        if (destructuredAs(declarator.id, 'error')) guards.push(nodeRange(node))\n        break\n      }\n\n      case 'TryStatement': {\n        guards.push(nodeRange((node as { block: Node }).block))\n        break\n      }\n\n      case 'CallExpression': {\n        const described = describeCallee((node as { callee: Node }).callee)\n        if (!described) break\n        const [firstArgument] = (node as { arguments: Node[] }).arguments\n        const { start } = (node as unknown as { start: number })\n        const line = lines.lineAt(start)\n        calls.push({ ...described, line, start, props: objectKeys(firstArgument) })\n\n        /* `fetch(…).catch(…)` — the guard spans the call it is chained onto. */\n        if (ERROR_GUARD_MEMBERS.includes(described.member)) guards.push(nodeRange(node))\n\n        if (described.member === 'createError') {\n          const identity = errorIdentity(firstArgument)\n          if (identity) inlineErrors.push({ ...identity, line })\n        }\n        if (described.member === 'defineErrorCatalog') {\n          const name = literalValue(firstArgument)\n          if (name !== null) catalogsDeclared.push(name)\n        }\n        break\n      }\n\n      case 'ThrowStatement': {\n        const { argument } = (node as { argument: Node | null })\n        if (!argument) break\n        const line = lines.lineAt((node as unknown as { start: number }).start)\n\n        if (argument.type === 'NewExpression') {\n          const { callee } = argument as { callee: Node }\n          const isPlain = callee.type === 'Identifier' && callee.name === 'Error'\n          throwFacts.push({ kind: isPlain ? 'plain-error' : 'other', props: new Set(), line })\n          break\n        }\n        if (argument.type === 'CallExpression') {\n          const described = describeCallee((argument as { callee: Node }).callee)\n          if (described?.member === 'createError') {\n            const [firstArgument] = (argument as { arguments: Node[] }).arguments\n            throwFacts.push({ kind: 'create-error', props: objectKeys(firstArgument), line })\n            break\n          }\n        }\n        throwFacts.push({ kind: 'other', props: new Set(), line })\n        break\n      }\n\n      case 'CatchClause': {\n        const statements = (node as { body: { body: Node[] } }).body.body\n        catchFacts.push({\n          line: lines.lineAt((node as unknown as { start: number }).start),\n          isEmpty: statements.length === 0,\n          handled: statements.some(statementHandlesError),\n        })\n        break\n      }\n\n      case 'MemberExpression': {\n        const { property } = (node as { property: Node })\n        if (property.type === 'Identifier') names.add(property.name)\n        break\n      }\n\n      case 'Property': {\n        const { key } = node as { key: Node }\n        if (key.type === 'Identifier') names.add(key.name)\n        if (key.type === 'Literal') names.add(String((key as { value: unknown }).value))\n        break\n      }\n\n      default:\n        break\n    }\n  })\n\n  /*\n   * Whether a name refers to evlog's export, now that imports and local\n   * declarations are both known.\n   *\n   * An explicit import wins: `import { useLogger } from './my-logger'` is not\n   * evlog's, even in a project where evlog auto-imports that name. A local\n   * declaration beats an auto-import for the same reason.\n   */\n  const evlogAutoImports = options.evlogAutoImports ?? []\n  const { evlogBarrels } = options\n  const resolvesToEvlog = (name: string): boolean => {\n    const source = imports.get(name)\n    if (source !== undefined) {\n      if (isEvlogSource(source)) return true\n      /* A local module counts only for the names it actually forwards, so a\n         hand-written `./my-logger` stub is still not evlog's. */\n      const forwarded = evlogBarrels?.get(moduleKey(source))\n      return forwarded !== undefined && (forwarded.has(name) || forwarded.has('*'))\n    }\n    return evlogAutoImports.includes(name) && !localDeclarations.has(name)\n  }\n\n  const loggerBindings = new Set<string>()\n  let loggerInit: HandlerLocation | null = null\n  for (const candidate of loggerCandidates) {\n    if (!resolvesToEvlog(candidate.factory)) continue\n    loggerInit ??= { line: candidate.line, column: 0 }\n    if (candidate.binding) loggerBindings.add(candidate.binding)\n  }\n  /* Taken at face value: there is no import to check a context read against, and\n     the cost of the two errors is not symmetric — crediting a rare non-evlog\n     `context.log` is harmless, while missing evlog's own documented shape tells\n     a correctly instrumented handler that it is a dark event. */\n  for (const contextLogger of contextLoggers) {\n    loggerInit ??= { line: contextLogger.line, column: 0 }\n    loggerBindings.add(contextLogger.binding)\n  }\n  /*\n   * evlog's `log` export is deliberately not treated as a request logger: it is\n   * the simple logging API (`log.info`, `log.error`) with no `set` or `audit`,\n   * so it emits standalone lines rather than contributing to the request's wide\n   * event.\n   */\n  if (!loggerInit) {\n    const bare = calls.find(call => LOGGER_FACTORIES.includes(call.member) && resolvesToEvlog(call.member))\n    if (bare) loggerInit = { line: bare.line, column: 0 }\n  }\n  /* `event.context.log.set({ … })` — used straight off the request, never bound. */\n  if (!loggerInit) {\n    const inline = calls.find(call => hasContextLoggerPath(call.chain))\n    if (inline) loggerInit = { line: inline.line, column: 0 }\n  }\n\n  for (const { names: exportedNames, factory } of exportedFromFactory) {\n    if (!resolvesToEvlog(factory)) continue\n    for (const name of exportedNames) reexportsEvlog.add(name)\n  }\n\n  const evlogImports = new Set<string>()\n  for (const source of imports.values()) {\n    if (isEvlogSource(source)) evlogImports.add(source)\n  }\n\n  const evlogWrappers = new Set<string>()\n  for (const call of calls) {\n    if (EVLOG_WRAPPERS.includes(call.member) && resolvesToEvlog(call.member)) {\n      evlogWrappers.add(call.member)\n    }\n  }\n\n  const network = calls.filter(isNetworkCall)\n  const unguardedNetwork = network.filter(\n    call => !guards.some(([start, end]) => call.start >= start && call.start < end),\n  )\n\n  return {\n    imports,\n    localDeclarations,\n    calls,\n    throws: throwFacts,\n    catches: catchFacts,\n    network,\n    unguardedNetwork,\n    loggerInit,\n    loggerBindings,\n    evlogWrappers,\n    evlogImports,\n    reexportsEvlog,\n    names,\n    inlineErrors,\n    catalogsDeclared,\n    /* Matches anywhere in the chain so `log.audit()` and `log.audit?.deny()`\n       both count as audit calls, and reads the logger straight off the request\n       context for handlers that never bind it — `req.context.log.set({ … })`. */\n    loggerCalls: member => calls.filter((call) => {\n      if (!call.chain.includes(member)) return false\n      if (call.root !== null && loggerBindings.has(call.root)) return true\n      return hasContextLoggerPath(call.chain)\n    }),\n    callsTo: name => calls.filter(call => call.member === name),\n  }\n}\n","import { readFileSync } from 'node:fs'\nimport { join, relative } from 'node:path'\nimport { globSync } from 'tinyglobby'\nimport { buildFileFacts, moduleKey } from './facts'\nimport type { FileFacts } from './facts'\nimport { parseSource } from './parse'\nimport type { ScanContext } from './types'\n\n/**\n * An evlog feature the project has already adopted somewhere.\n *\n * Adoption is the whole point: suggesting a feature nobody asked for is\n * lecturing, whereas suggesting more of a feature the team already chose is\n * useful. Nothing here ever affects the score.\n */\nexport type EvlogFeature = 'error-catalog' | 'audit' | 'ai' | 'better-auth' | 'client-logging'\n\n/** Third-party packages worth pairing with an evlog integration. */\nexport type PairablePackage = 'ai' | 'better-auth'\n\n/** The same inline error, written out in more than one file. */\nexport interface RepeatedError {\n  /** Short human label, e.g. `402 Card declined`. */\n  label: string\n  /** Project-relative files it appears in, sorted. */\n  files: readonly string[]\n}\n\nexport interface ProjectFacts {\n  /** Direct dependencies and devDependencies. */\n  dependencies: ReadonlySet<string>\n  /** evlog features with evidence of use somewhere in the project. */\n  features: ReadonlySet<EvlogFeature>\n  /** Third-party packages present that evlog has an integration for. */\n  pairable: ReadonlySet<PairablePackage>\n  /** Error catalogs already declared, by name — so a suggestion can name one. */\n  catalogs: readonly string[]\n  /**\n   * Local modules that re-export evlog, keyed by {@link moduleKey}.\n   *\n   * Collected project-wide because the module that re-exports evlog is never the\n   * handler being scored: without this, evlog's own recommended Next.js shape\n   * (`import { useLogger } from '@/lib/evlog'`) scored as uninstrumented.\n   */\n  evlogBarrels: ReadonlyMap<string, ReadonlySet<string>>\n  /**\n   * Inline errors duplicated across files, by signature.\n   *\n   * This is the only evidence that justifies bringing up error catalogs: one\n   * inline error is a local decision, the same one in three handlers is a\n   * catalog entry that has not been written yet.\n   */\n  repeatedErrors: ReadonlyMap<string, RepeatedError>\n}\n\n/**\n * Marker → feature, checked against raw source before parsing.\n *\n * The marker is only a prefilter: a file that contains the text is parsed and\n * confirmed against the AST, so a mention inside a comment or a string does not\n * count as adoption.\n */\nconst FEATURE_MARKERS: Record<EvlogFeature, string> = {\n  'error-catalog': 'defineErrorCatalog',\n  'audit': 'audit(',\n  'ai': 'evlog/ai',\n  'better-auth': 'evlog/better-auth',\n  'client-logging': 'evlog/client',\n}\n\nconst PAIRABLE_PACKAGES: readonly PairablePackage[] = ['ai', 'better-auth']\n\n/**\n * Source files worth searching for adoption evidence.\n *\n * The extension list tracks what the adapters scan — a catalog declared in a\n * `.mjs` or `.cts` barrel would otherwise be invisible here, and every handler\n * importing it would be scored as if the project had no catalog at all.\n */\nconst SOURCE_GLOBS = ['**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs,vue}']\nconst IGNORED = [\n  '**/node_modules/**',\n  '**/.git/**',\n  '**/dist/**',\n  '**/build/**',\n  '**/.turbo/**',\n  '**/.nuxt/**',\n  '**/.next/**',\n  '**/.svelte-kit/**',\n  '**/.vercel/**',\n  '**/.output/**',\n  '**/coverage/**',\n  '**/*.d.ts',\n]\n\n/** Confirm a marker against the AST rather than trusting the text match. */\nfunction confirmFeature(feature: EvlogFeature, facts: FileFacts): boolean {\n  switch (feature) {\n    case 'error-catalog':\n      return facts.callsTo('defineErrorCatalog').length > 0\n    case 'audit':\n      return facts.loggerCalls('audit').length > 0 || facts.evlogWrappers.has('withAudit')\n    case 'ai':\n      return facts.evlogImports.has('evlog/ai')\n    case 'better-auth':\n      return facts.evlogImports.has('evlog/better-auth')\n    case 'client-logging':\n      return facts.evlogImports.has('evlog/client')\n  }\n}\n\n/**\n * What the project has already adopted, collected once per scan.\n *\n * Adoption evidence has to be project-wide, not per-file: an error catalog is\n * declared in one shared module and used from many handlers, so a per-file view\n * would never see it.\n */\nexport function collectProjectFacts(\n  ctx: ScanContext,\n  options: { packageJson: unknown, evlogAutoImports?: readonly string[] },\n): ProjectFacts {\n  const dependencies = readDependencies(options.packageJson)\n  const features = new Set<EvlogFeature>()\n  const pending = new Set(Object.keys(FEATURE_MARKERS) as EvlogFeature[])\n  const catalogs = new Set<string>()\n  const errors = new Map<string, { label: string, files: Set<string> }>()\n  const evlogBarrels = new Map<string, Set<string>>()\n\n  const files = globSync(SOURCE_GLOBS, {\n    cwd: ctx.projectRoot,\n    absolute: true,\n    ignore: IGNORED,\n  })\n\n  for (const file of files) {\n    let source: string\n    try {\n      source = readFileSync(file, 'utf8')\n    } catch {\n      continue\n    }\n\n    /* Text prefilter before parsing: most files match nothing here, and parsing\n       every file in a large app to answer four questions would not be worth it. */\n    const markers = [...pending].filter(feature => source.includes(FEATURE_MARKERS[feature]))\n    const mayDeclareErrors = source.includes('createError(') || source.includes('defineErrorCatalog')\n    const mayReexport = source.includes('export') && source.includes('evlog')\n    if (markers.length === 0 && !mayDeclareErrors && !mayReexport) continue\n\n    const parsed = parseSource(file, source)\n    if (!parsed) continue\n    const facts = buildFileFacts(parsed, { evlogAutoImports: options.evlogAutoImports })\n\n    for (const feature of markers) {\n      if (!confirmFeature(feature, facts)) continue\n      features.add(feature)\n      pending.delete(feature)\n    }\n    for (const name of facts.catalogsDeclared) catalogs.add(name)\n\n    if (facts.reexportsEvlog.size > 0) {\n      const key = moduleKey(relative(ctx.projectRoot, file))\n      const forwarded = evlogBarrels.get(key) ?? new Set<string>()\n      for (const name of facts.reexportsEvlog) forwarded.add(name)\n      evlogBarrels.set(key, forwarded)\n    }\n\n    const relativePath = relative(ctx.projectRoot, file)\n    for (const error of facts.inlineErrors) {\n      const entry = errors.get(error.signature)\n      if (entry) entry.files.add(relativePath)\n      else errors.set(error.signature, { label: error.label, files: new Set([relativePath]) })\n    }\n  }\n\n  const repeatedErrors = new Map<string, RepeatedError>()\n  for (const [signature, entry] of errors) {\n    if (entry.files.size < 2) continue\n    repeatedErrors.set(signature, { label: entry.label, files: [...entry.files].sort() })\n  }\n\n  const pairable = new Set(PAIRABLE_PACKAGES.filter(pkg => dependencies.has(pkg)))\n\n  return {\n    dependencies,\n    features,\n    pairable,\n    catalogs: [...catalogs].sort(),\n    evlogBarrels,\n    repeatedErrors,\n  }\n}\n\nfunction readDependencies(packageJson: unknown): Set<string> {\n  const manifest = packageJson as {\n    dependencies?: Record<string, string>\n    devDependencies?: Record<string, string>\n  } | null\n  return new Set([\n    ...Object.keys(manifest?.dependencies ?? {}),\n    ...Object.keys(manifest?.devDependencies ?? {}),\n  ])\n}\n\n/** Read the project manifest, or `null` when it is missing or malformed. */\nexport function readPackageJson(projectRoot: string): unknown {\n  try {\n    return JSON.parse(readFileSync(join(projectRoot, 'package.json'), 'utf8'))\n  } catch {\n    return null\n  }\n}\n","import { createHash } from 'node:crypto'\nimport { isAbsolute, relative, sep } from 'node:path'\nimport type { Framework, RawRouteEntry } from './types'\n\nconst HTTP_METHODS = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'] as const\n\n/** Stable id for a route — hash of framework/kind/method/path (12 hex chars). */\nexport function routeId(entry: Pick<RawRouteEntry, 'framework' | 'kind' | 'path' | 'method'>): string {\n  const key = `${entry.framework}:${entry.kind}:${entry.method ?? '*'}:${entry.path}`\n  return createHash('sha256').update(key).digest('hex').slice(0, 12)\n}\n\n/**\n * Extension of a module, in every spelling the route globs pick up.\n *\n * `.mjs` and `.cjs` are in here because Nitro serves them as handlers just the\n * same: leaving them out kept the extension in the derived path and dropped the\n * method off `checkout.post.mjs`.\n */\nconst MODULE_EXTENSION = /\\.(?:[mc]?[jt]s)$/\n\n/** Extract an HTTP method from a filename like `checkout.post.ts` (Nuxt/Nitro convention). */\nexport function extractMethodFromFilename(filename: string): string | null {\n  const base = filename.replace(MODULE_EXTENSION, '')\n  const dot = base.lastIndexOf('.')\n  if (dot === -1) return null\n  const suffix = base.slice(dot + 1).toLowerCase()\n  if ((HTTP_METHODS as readonly string[]).includes(suffix)) {\n    return suffix.toUpperCase()\n  }\n  return null\n}\n\n/** Drop a source file extension, keeping the rest of the name intact. */\nexport function stripExtension(filename: string): string {\n  return filename.replace(/\\.(?:vue|[mc]?[jt]sx?)$/, '')\n}\n\n/** Remove HTTP method suffix and file extension from a route filename. */\nexport function stripRouteFilename(filename: string): string {\n  const withoutExt = stripExtension(filename)\n  const dot = withoutExt.lastIndexOf('.')\n  if (dot === -1) return withoutExt\n  const suffix = withoutExt.slice(dot + 1).toLowerCase()\n  if ((HTTP_METHODS as readonly string[]).includes(suffix)) {\n    return withoutExt.slice(0, dot)\n  }\n  return withoutExt\n}\n\n/** Convert file-based route segments to a URL pattern. */\nexport function segmentsToPath(segments: string[], prefix = ''): string {\n  const parts: string[] = []\n  for (const seg of segments) {\n    if (!seg || seg === 'index') continue\n    if (seg.startsWith('(') && seg.endsWith(')')) continue\n    if (seg.startsWith('[[...') && seg.endsWith(']]')) {\n      const name = seg.slice(5, -2)\n      parts.push(`:${name}*?`)\n      continue\n    }\n    if (seg.startsWith('[...') && seg.endsWith(']')) {\n      const name = seg.slice(4, -1)\n      parts.push(`:${name}*`)\n      continue\n    }\n    if (seg.startsWith('[') && seg.endsWith(']')) {\n      parts.push(`:${seg.slice(1, -1)}`)\n      continue\n    }\n    if (seg.startsWith('$')) {\n      if (seg.startsWith('$...')) {\n        parts.push(`:${seg.slice(4)}*`)\n      } else {\n        parts.push(`:${seg.slice(1)}`)\n      }\n      continue\n    }\n    parts.push(seg)\n  }\n  const path = `/${parts.join('/')}`.replace(/\\/+/g, '/')\n  return prefix ? `${prefix}${path === '/' ? '' : path}` : (path || '/')\n}\n\n/**\n * Path of `file` relative to `root`, always with `/` separators.\n *\n * Globs return posix paths while the root comes from the OS, so comparing the\n * two by prefix drops routes on Windows and eats a character when the root\n * carries a trailing separator. A file outside the root is returned untouched.\n */\nexport function relativeFromRoot(root: string, file: string): string {\n  const rel = relative(root, file)\n  if (rel.length === 0 || rel.startsWith('..') || isAbsolute(rel)) return file\n  return sep === '/' ? rel : rel.split(sep).join('/')\n}\n\n/** One line of `source`, with `radius` lines of context around it, trimmed. */\nexport function lineSnippet(source: string, line: number, radius = 0): string {\n  const lines = source.split('\\n')\n  const idx = line - 1\n  const start = Math.max(0, idx - radius)\n  const end = Math.min(lines.length, idx + radius + 1)\n  return lines.slice(start, end).join('\\n').trim()\n}\n\n/** Human-readable name of a framework, for report headers. */\nexport function frameworkLabel(framework: Framework): string {\n  switch (framework) {\n    case 'nuxt': return 'Nuxt'\n    case 'nitro': return 'Nitro'\n    case 'next': return 'Next.js'\n    case 'tanstack-start': return 'TanStack Start'\n    case 'hono': return 'Hono'\n  }\n}\n","import { readFileSync } from 'node:fs'\nimport type { Node } from 'oxc-parser'\nimport { globSync } from 'tinyglobby'\nimport type { ParseResult } from '../parse'\nimport {\n  findHandlerLocation,\n  findHttpMethodExports,\n  hasDirective,\n  nodeLoc,\n  parseFile,\n  walkAst,\n} from '../parse'\nimport type { FrameworkAdapter, RawRouteEntry, ScanContext } from '../types'\nimport { relativeFromRoot, segmentsToPath } from '../utils'\n\n/**\n * Where the App Router lives, `app/` or `src/app/`.\n *\n * Both page and route files count: an API-only project has no `page.*` at all,\n * and picking the wrong directory there makes every later glob come back empty.\n */\nfunction resolveAppDir(root: string): string {\n  for (const candidate of ['app', 'src/app']) {\n    if (globSync(`${candidate}/**/{page,route}.{tsx,jsx,ts,js}`, { cwd: root }).length > 0) {\n      return candidate\n    }\n  }\n  return 'app'\n}\n\nfunction routeDirFromFile(rel: string, appDir: string): string {\n  const inner = rel.slice(`${appDir}/`.length)\n  /* The leading separator is optional: `app/route.ts` has none, and leaving the\n     filename in place would turn the root handler into `/route.ts`. */\n  return inner.replace(/(?:^|\\/)route\\.(?:tsx?|jsx?)$/, '')\n}\n\n/**\n * Next.js App Router: `route.ts` handlers, `page.tsx`, middleware, `\"use server\"`\n * actions. No auto-imports — every evlog helper is imported explicitly, and\n * nothing is emitted until a handler opts in with `useLogger()` or `withEvlog()`.\n */\nexport const nextAdapter: FrameworkAdapter = {\n  framework: 'next',\n  requestLogger: 'explicit',\n  // eslint-disable-next-line require-await -- satisfies the async FrameworkAdapter contract\n  async extractRoutes(ctx: ScanContext): Promise<RawRouteEntry[]> {\n    const routes: RawRouteEntry[] = []\n    const root = ctx.projectRoot\n    const appDir = resolveAppDir(root)\n    const parse = ctx.parse ?? parseFile\n\n    for (const file of globSync(`${appDir}/**/route.{ts,js,tsx,jsx}`, { cwd: root, absolute: true })) {\n      const rel = relativeFromRoot(root, file)\n      const dir = routeDirFromFile(rel, appDir)\n      const apiPath = segmentsToPath(dir.split('/')) || '/'\n\n      const parsed = parse(file)\n      if (!parsed) {\n        routes.push({\n          framework: 'next',\n          kind: 'api',\n          method: null,\n          path: apiPath,\n          file: rel,\n          handler: null,\n        })\n        continue\n      }\n\n      const methods = findHttpMethodExports(parsed)\n      if (methods.length === 0) {\n        routes.push({\n          framework: 'next',\n          kind: 'api',\n          method: null,\n          path: apiPath,\n          file: rel,\n          handler: findHandlerLocation(parsed, []),\n        })\n      } else {\n        for (const { method, line } of methods) {\n          routes.push({\n            framework: 'next',\n            kind: 'api',\n            method,\n            path: apiPath,\n            file: rel,\n            handler: { line, column: 0 },\n          })\n        }\n      }\n    }\n\n    for (const file of globSync(`${appDir}/**/page.{tsx,jsx,ts,js}`, { cwd: root, absolute: true })) {\n      const rel = relativeFromRoot(root, file)\n      const inner = rel.slice(`${appDir}/`.length)\n      const dir = inner.replace(/^(.*\\/)?page\\.(tsx?|jsx?)$/, (_m, parent) => parent ?? '')\n      const path = segmentsToPath(dir ? dir.split('/') : []) || '/'\n      routes.push({\n        framework: 'next',\n        kind: 'page',\n        method: null,\n        path,\n        file: rel,\n        handler: null,\n      })\n    }\n\n    for (const file of globSync(['middleware.{ts,js}', 'src/middleware.{ts,js}'], { cwd: root, absolute: true })) {\n      const rel = relativeFromRoot(root, file)\n      const parsed = parse(file)\n      routes.push({\n        framework: 'next',\n        kind: 'middleware',\n        method: null,\n        path: '*',\n        file: rel,\n        handler: parsed\n          ? findHandlerLocation(parsed, [])\n          : null,\n      })\n    }\n\n    for (const file of globSync([`${appDir}/**/*.{ts,tsx,js,jsx}`, 'src/**/*.{ts,tsx,js,jsx}'], { cwd: root, absolute: true })) {\n      /* This glob covers the whole source tree, and almost none of it declares\n         an action. The directive has to appear literally for Next to treat the\n         module as one, so a substring test rules most files out before oxc. */\n      if (!mentionsServerDirective(file)) continue\n      const parsed = parse(file)\n      if (!parsed || !hasDirective(parsed.program, 'use server')) continue\n      const rel = relativeFromRoot(root, file)\n      const exports = findServerActionExports(parsed)\n      for (const exp of exports) {\n        routes.push({\n          framework: 'next',\n          kind: 'server-action',\n          method: 'POST',\n          path: `action:${exp.name}`,\n          file: rel,\n          handler: { line: exp.line, column: 0 },\n        })\n      }\n    }\n\n    return routes\n  },\n}\n\n/** Whether a file so much as mentions `use server`, read without parsing. */\nfunction mentionsServerDirective(file: string): boolean {\n  try {\n    return readFileSync(file, 'utf8').includes('use server')\n  } catch {\n    return false\n  }\n}\n\n/**\n * Every action a `'use server'` module exposes.\n *\n * All four export spellings count, because Next treats every export of such a\n * module as a public endpoint: a missed one is an unscanned POST handler, not a\n * cosmetic gap.\n */\nfunction findServerActionExports(parsed: ParseResult): Array<{ name: string, line: number }> {\n  const exports: Array<{ name: string, line: number }> = []\n  const lineOf = (node: Node | undefined): number => (node ? nodeLoc(node, parsed.lines)?.line ?? 1 : 1)\n\n  walkAst(parsed.program, (node) => {\n    if (node.type === 'ExportDefaultDeclaration') {\n      const { declaration } = node as { declaration?: Node & { id?: { name: string } } }\n      if (declaration?.type !== 'FunctionDeclaration' && declaration?.type !== 'ArrowFunctionExpression') return\n      exports.push({ name: declaration.id?.name ?? 'default', line: lineOf(node) })\n      return\n    }\n\n    if (node.type !== 'ExportNamedDeclaration') return\n    const decl = node as {\n      source?: { value: string } | null\n      specifiers?: Array<{ exported?: { type: string, name?: string, value?: string } }>\n      declaration?: {\n        type: string\n        id?: { name: string }\n        declarations?: Array<{ id: { type: string, name: string }, init?: { type: string } }>\n      }\n    }\n\n    /* `export { createOrder }` and `export { handler as createOrder }`, but not\n       `export { x } from './elsewhere'` — a re-export is another module's. */\n    if (!decl.declaration && !decl.source) {\n      for (const specifier of decl.specifiers ?? []) {\n        const name = specifier.exported?.name ?? specifier.exported?.value\n        if (name) exports.push({ name, line: lineOf(node) })\n      }\n      return\n    }\n\n    if (decl.declaration?.type === 'FunctionDeclaration' && decl.declaration.id?.name) {\n      exports.push({ name: decl.declaration.id.name, line: lineOf(node) })\n    }\n    if (decl.declaration?.type === 'VariableDeclaration') {\n      for (const d of decl.declaration.declarations ?? []) {\n        if (d.id.type === 'Identifier' && d.init && (d.init.type === 'ArrowFunctionExpression' || d.init.type === 'FunctionExpression')) {\n          exports.push({ name: d.id.name, line: lineOf(d.init as Node) })\n        }\n      }\n    }\n  })\n  return exports\n}\n","import { basename } from 'node:path'\nimport { globSync } from 'tinyglobby'\nimport type { ParseFn } from '../parse'\nimport { findHandlerLocation, parseFile } from '../parse'\nimport type { FrameworkAdapter, RawRouteEntry, ScanContext } from '../types'\nimport { extractMethodFromFilename, relativeFromRoot, segmentsToPath, stripRouteFilename } from '../utils'\n\n/**\n * Extensions Nitro serves a handler from.\n *\n * `.mjs` and `.cjs` are in the list because Nitro runs them exactly like a\n * `.ts` handler: a route written in either was invisible to the whole scan.\n */\nconst HANDLER_EXT = '{ts,js,mts,cts,mjs,cjs}'\n\n/** A directory of file-based handlers, and the URL prefix its routes get. */\ninterface RouteRoot {\n  dir: string\n  prefix: string\n}\n\n/**\n * Where each framework keeps its handlers.\n *\n * Nuxt and raw Nitro differ by these paths and nothing else, so they share the\n * extraction below rather than each carrying a copy of it — the copies had\n * already started to drift.\n */\nconst API_ROOTS: Record<'nuxt' | 'nitro', readonly RouteRoot[]> = {\n  nuxt: [{ dir: 'server/api', prefix: '/api' }, { dir: 'server/routes', prefix: '' }],\n  nitro: [{ dir: 'api', prefix: '/api' }, { dir: 'routes', prefix: '' }],\n}\n\nconst MIDDLEWARE_DIR: Record<'nuxt' | 'nitro', string> = {\n  nuxt: 'server/middleware',\n  nitro: 'middleware',\n}\n\n/**\n * Where Nuxt keeps file-based pages.\n *\n * Nuxt 4 defaults to `app/pages`; older layouts use `pages/` or `src/pages`.\n * Several can coexist in odd projects — scan every root that actually has\n * `.vue` files rather than picking one and leaving the others invisible.\n */\nconst PAGE_DIRS = ['app/pages', 'pages', 'src/pages'] as const\n\nconst CRON_GLOBS = [`server/tasks/**/*.${HANDLER_EXT}`]\n\n/** What both Nitro-based adapters need to turn a file into an entry point. */\ninterface ExtractContext {\n  root: string\n  parse: ParseFn\n  framework: 'nuxt' | 'nitro'\n}\n\n/** One page root and the `.vue` files already discovered under it. */\ninterface PageRoot {\n  dir: string\n  files: readonly string[]\n}\n\n/**\n * Page directories under `root` that contain at least one `.vue` file.\n * Returns the matched files with each directory so extractors do not glob twice.\n * Falls back to an empty `pages` root when nothing is present.\n */\nfunction resolvePageRoots(root: string): readonly PageRoot[] {\n  const found: PageRoot[] = []\n  for (const dir of PAGE_DIRS) {\n    const files = globSync(`${dir}/**/*.vue`, { cwd: root, absolute: true })\n    if (files.length > 0) found.push({ dir, files })\n  }\n  return found.length > 0 ? found : [{ dir: 'pages', files: [] }]\n}\n\nfunction fileToApiRoute(file: string, apiRoot: RouteRoot, { root, parse, framework }: ExtractContext): RawRouteEntry {\n  const rel = relativeFromRoot(root, file)\n  const method = extractMethodFromFilename(basename(file))\n\n  const parts = rel.slice(`${apiRoot.dir}/`.length).split('/')\n  parts[parts.length - 1] = stripRouteFilename(parts.at(-1) ?? '')\n\n  const parsed = parse(file)\n\n  return {\n    framework,\n    kind: 'api',\n    method,\n    path: segmentsToPath(parts, apiRoot.prefix) || '/',\n    file: rel,\n    handler: parsed ? findHandlerLocation(parsed, ['defineEventHandler', 'eventHandler']) : null,\n  }\n}\n\nfunction fileToPageRoute(file: string, root: string, pageDir: string): RawRouteEntry {\n  const rel = relativeFromRoot(root, file)\n  const prefix = `${pageDir}/`\n  const segments = rel.startsWith(prefix)\n    ? rel.slice(prefix.length).split('/')\n    : rel.split('/')\n  const last = segments.length - 1\n  segments[last] = stripRouteFilename(segments[last] ?? '')\n  const path = segmentsToPath(segments) || '/'\n\n  return {\n    framework: 'nuxt',\n    kind: 'page',\n    method: null,\n    path,\n    file: rel,\n    handler: null,\n  }\n}\n\nfunction fileToMiddlewareRoute(file: string, { root, parse, framework }: ExtractContext): RawRouteEntry {\n  const rel = relativeFromRoot(root, file)\n  const parsed = parse(file)\n  const handler = parsed\n    ? findHandlerLocation(parsed, ['defineEventHandler'])\n    : null\n\n  return {\n    framework,\n    kind: 'middleware',\n    method: null,\n    path: '*',\n    file: rel,\n    handler,\n  }\n}\n\n/** A Nitro scheduled task — no request, but the same wide-event expectations. */\nfunction fileToCronRoute(file: string, root: string, parse: ParseFn): RawRouteEntry {\n  const rel = relativeFromRoot(root, file)\n  const name = stripRouteFilename(basename(file))\n  const parsed = parse(file)\n  const handler = parsed\n    ? findHandlerLocation(parsed, ['defineTask', 'defineEventHandler'])\n    : null\n\n  return {\n    framework: 'nuxt',\n    kind: 'cron',\n    method: null,\n    path: `/tasks/${name}`,\n    file: rel,\n    handler,\n  }\n}\n\n/**\n * What evlog's Nuxt module auto-imports (`addImports` / `addServerImports`).\n *\n * An un-imported `useLogger()` or `log` is evlog's here, as long as the file\n * does not declare one itself.\n */\nconst NUXT_EVLOG_AUTO_IMPORTS = [\n  'useLogger',\n  'log',\n  'createEvlogError',\n] as const\n\n/** Handlers and middleware, in whichever directories this framework serves them from. */\nfunction extractServerRoutes(ctx: ScanContext, framework: 'nuxt' | 'nitro'): RawRouteEntry[] {\n  const routes: RawRouteEntry[] = []\n  const root = ctx.projectRoot\n  const extract: ExtractContext = { root, parse: ctx.parse ?? parseFile, framework }\n\n  for (const apiRoot of API_ROOTS[framework]) {\n    for (const file of globSync(`${apiRoot.dir}/**/*.${HANDLER_EXT}`, { cwd: root, absolute: true })) {\n      routes.push(fileToApiRoute(file, apiRoot, extract))\n    }\n  }\n\n  for (const file of globSync(`${MIDDLEWARE_DIR[framework]}/**/*.${HANDLER_EXT}`, { cwd: root, absolute: true })) {\n    routes.push(fileToMiddlewareRoute(file, extract))\n  }\n\n  return routes\n}\n\n/** Nuxt project: `server/api`, `server/routes`, `server/middleware`, `server/tasks` and pages. */\nexport const nuxtAdapter: FrameworkAdapter = {\n  framework: 'nuxt',\n  evlogAutoImports: NUXT_EVLOG_AUTO_IMPORTS,\n  requestLogger: 'ambient',\n  // eslint-disable-next-line require-await -- satisfies the async FrameworkAdapter contract\n  async extractRoutes(ctx: ScanContext): Promise<RawRouteEntry[]> {\n    const routes = extractServerRoutes(ctx, 'nuxt')\n    const root = ctx.projectRoot\n    const parse = ctx.parse ?? parseFile\n\n    for (const { dir, files } of resolvePageRoots(root)) {\n      for (const file of files) {\n        routes.push(fileToPageRoute(file, root, dir))\n      }\n    }\n\n    for (const pattern of CRON_GLOBS) {\n      for (const file of globSync(pattern, { cwd: root, absolute: true })) {\n        routes.push(fileToCronRoute(file, root, parse))\n      }\n    }\n\n    return routes\n  },\n}\n\n/** Raw Nitro project (no Nuxt): the same handlers, one directory level up. */\nexport const nitroAdapter: FrameworkAdapter = {\n  framework: 'nitro',\n  evlogAutoImports: NUXT_EVLOG_AUTO_IMPORTS,\n  requestLogger: 'ambient',\n  // eslint-disable-next-line require-await -- satisfies the async FrameworkAdapter contract\n  async extractRoutes(ctx: ScanContext): Promise<RawRouteEntry[]> {\n    return extractServerRoutes(ctx, 'nitro')\n  },\n}\n\n/** The adapter for whichever of the two Nitro-based frameworks was detected. */\nexport function getNuxtOrNitroAdapter(framework: 'nuxt' | 'nitro'): FrameworkAdapter {\n  return framework === 'nitro' ? nitroAdapter : nuxtAdapter\n}\n","import { basename } from 'node:path'\nimport type { Node } from 'oxc-parser'\nimport { globSync } from 'tinyglobby'\nimport type { ParseFn, ParseResult } from '../parse'\nimport { findHandlerLocation, nodeLoc, parseFile, walkAst } from '../parse'\nimport type { FrameworkAdapter, RawRouteEntry, ScanContext } from '../types'\nimport { relativeFromRoot, segmentsToPath, stripExtension } from '../utils'\n\nfunction extractTanstackRoutes(file: string, root: string, parse: ParseFn): RawRouteEntry[] {\n  const rel = relativeFromRoot(root, file)\n  if (rel.includes('__root')) return []\n\n  const segments = stripExtension(rel.replace(/^src\\/routes\\//, '')).split('/')\n  const path = segmentsToPath(segments) || '/'\n  const parsed = parse(file)\n  const routes: RawRouteEntry[] = []\n\n  if (!parsed) {\n    routes.push({\n      framework: 'tanstack-start',\n      kind: 'page',\n      method: null,\n      path,\n      file: rel,\n      handler: null,\n    })\n    return routes\n  }\n\n  const hasServerHandlers = detectServerHandlers(parsed)\n  if (hasServerHandlers.length > 0) {\n    for (const { method, line } of hasServerHandlers) {\n      routes.push({\n        framework: 'tanstack-start',\n        kind: 'api',\n        method,\n        path,\n        file: rel,\n        handler: { line, column: 0 },\n      })\n    }\n  } else if (path.startsWith('/api/') || isApiStem(file)) {\n    routes.push({\n      framework: 'tanstack-start',\n      kind: 'api',\n      method: null,\n      path,\n      file: rel,\n      handler: findHandlerLocation(parsed, ['createServerFn']),\n    })\n  } else {\n    routes.push({\n      framework: 'tanstack-start',\n      kind: 'page',\n      method: null,\n      path,\n      file: rel,\n      handler: null,\n    })\n  }\n\n  return routes\n}\n\n/**\n * Whether the filename itself says \"API\", as a whole word.\n *\n * A substring test reads `capital.tsx` and `rapid-list.tsx` as API routes, and\n * every check that follows is then asked of a page.\n */\nfunction isApiStem(file: string): boolean {\n  return stripExtension(basename(file)).split(/[.\\-_]/).includes('api')\n}\n\n/**\n * HTTP methods TanStack Start recognises on a route's `methods` object.\n *\n * Case matters: the framework only honours the uppercase form, so folding the\n * key would turn any `{ get: … }` or `{ delete: … }` in the module — a form\n * config, an options object — into a fabricated API entry point.\n */\nconst METHOD_KEYS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']\n\nfunction detectServerHandlers(parsed: ParseResult): Array<{ method: string, line: number }> {\n  const handlers: Array<{ method: string, line: number }> = []\n  walkAst(parsed.program, (node) => {\n    if (node.type !== 'Property') return\n    const prop = node as { key: { type: string, name?: string }, value: { type: string } }\n    if (prop.key.type === 'Identifier') {\n      const key = prop.key.name\n      if (key && METHOD_KEYS.includes(key)) {\n        if (prop.value.type === 'ArrowFunctionExpression' || prop.value.type === 'FunctionExpression') {\n          const loc = nodeLoc(prop.value as Node, parsed.lines)\n          handlers.push({ method: key, line: loc?.line ?? 1 })\n        }\n      }\n    }\n  })\n  return handlers\n}\n\n/**\n * TanStack Start: `src/routes/**` file-based routes, API vs page via HTTP method\n * props / `createServerFn`. No auto-imports — evlog helpers must be imported.\n */\nexport const tanstackStartAdapter: FrameworkAdapter = {\n  framework: 'tanstack-start',\n  requestLogger: 'explicit',\n  // eslint-disable-next-line require-await -- satisfies the async FrameworkAdapter contract\n  async extractRoutes(ctx: ScanContext): Promise<RawRouteEntry[]> {\n    const routes: RawRouteEntry[] = []\n    const root = ctx.projectRoot\n    const parse = ctx.parse ?? parseFile\n\n    for (const file of globSync('src/routes/**/*.{ts,tsx}', { cwd: root, absolute: true })) {\n      routes.push(...extractTanstackRoutes(file, root, parse))\n    }\n\n    return routes\n  },\n}\n","import type { Node } from 'oxc-parser'\nimport { globSync } from 'tinyglobby'\nimport type { ParseFn, ParseResult } from '../parse'\nimport { nodeLoc, parseFile, walkAst } from '../parse'\nimport type { FrameworkAdapter, RawRouteEntry, ScanContext } from '../types'\nimport { relativeFromRoot } from '../utils'\n\n/**\n * Hono route methods → HTTP verb.\n *\n * `all` has no single verb (matches every method), so it lands as `method: null`.\n * `use` / `route` / `onError` are not entry points and are ignored.\n */\nconst ROUTE_METHODS: ReadonlyMap<string, string | null> = new Map([\n  ['get', 'GET'],\n  ['post', 'POST'],\n  ['put', 'PUT'],\n  ['patch', 'PATCH'],\n  ['delete', 'DELETE'],\n  ['options', 'OPTIONS'],\n  ['all', null],\n])\n\n/** Verbs with an `app.<verb>()` shorthand — anything else registers via `app.on()`. */\nexport const HONO_SHORTHAND_VERBS: ReadonlySet<string> = new Set(\n  [...ROUTE_METHODS.values()].filter((verb): verb is string => verb !== null),\n)\n\n/**\n * Source roots to scan for `app.get('/path', …)`-style registrations.\n *\n * Hono has no file-based router: routes live in ordinary modules. Cover the\n * common layouts without walking `node_modules`.\n */\nconst SOURCE_GLOBS = [\n  'src/**/*.{ts,tsx,js,jsx}',\n  'app/**/*.{ts,tsx,js,jsx}',\n  'routes/**/*.{ts,tsx,js,jsx}',\n  '*.{ts,tsx,js,jsx}',\n] as const\n\n/** Every file the adapter reads — the globs overlap, so deduplicate. */\nfunction sourceFiles(root: string): string[] {\n  return [...new Set(globSync([...SOURCE_GLOBS], { cwd: root, absolute: true }))]\n}\n\ninterface FoundRoute {\n  method: string | null\n  path: string\n  line: number\n}\n\n/**\n * Pull a string path out of the first (or second, for `app.on`) call argument.\n *\n * Only string literals count: a computed path (`\\`/users/${id}\\``) is invisible\n * to the static scan, the same way Next skips dynamic segments it cannot name.\n */\nfunction stringLiteral(node: Node | undefined): string | null {\n  if (!node) return null\n  if (node.type === 'Literal' && typeof (node as { value: unknown }).value === 'string') {\n    return (node as { value: string }).value\n  }\n  return null\n}\n\n/**\n * The same, accepting `app.on`'s array spelling: `'GET'` and `['GET', 'POST']`\n * both come back as a list, anything else as an empty one.\n */\nfunction stringLiterals(node: Node | undefined): string[] {\n  if (!node) return []\n  if (node.type === 'ArrayExpression') {\n    const { elements } = node as { elements: (Node | null)[] }\n    return elements.map(element => stringLiteral(element ?? undefined)).filter((value): value is string => value !== null)\n  }\n  const single = stringLiteral(node)\n  return single === null ? [] : [single]\n}\n\n/**\n * Whether a string looks like a Hono route path.\n *\n * Used to tell `api.get('/users', …)` apart from `c.get('log')`: the receiver\n * name is useless (`app`, `api`, `routes`, `c`…), but a real route path starts\n * with `/` (or is the catch-all `*`), and a context key never does.\n */\nfunction isRoutePath(path: string): boolean {\n  return path.startsWith('/') || path === '*'\n}\n\n/** Function-like node types that can be Hono route handlers. */\nconst HANDLER_TYPES = new Set([\n  'ArrowFunctionExpression',\n  'FunctionExpression',\n  'Identifier',\n])\n\n/**\n * Whether the node looks like a route handler (function) rather than an options\n * object. This tells `app.get('/users', handler)` apart from HTTP client calls\n * like `axios.get('/users', { headers })`.\n */\nfunction looksLikeHandler(node: Node | undefined): boolean {\n  if (!node) return false\n  return HANDLER_TYPES.has(node.type)\n}\n\n/**\n * Find every `*.get('/path', handler)` / `*.post(…)` call in a parsed file.\n *\n * The receiver name does not matter (`app`, `api`, `routes`): Hono sub-apps are\n * registered the same way. Two cheap shape checks keep `c.get('log')` out:\n * the first argument must look like a path, and there must be a handler after it.\n * `app.on(…)` is the one spelling where the method is an argument rather than\n * the callee, and it takes arrays on both sides: `app.on(['PUT', 'DELETE'],\n * ['/a', '/b'], …)` registers every combination.\n */\nfunction findHonoRoutes(parsed: ParseResult): FoundRoute[] {\n  const found: FoundRoute[] = []\n\n  walkAst(parsed.program, (node) => {\n    if (node.type !== 'CallExpression') return\n    const call = node as { callee: Node, arguments: Node[] }\n    const { callee } = call\n    if (callee.type !== 'MemberExpression') return\n\n    const { property, computed } = callee as { property: Node, computed?: boolean }\n    if (computed) return\n    if (property.type !== 'Identifier') return\n\n    const { name } = property\n\n    if (name === 'on') {\n      const methods = stringLiterals(call.arguments[0]).map(method => method.toUpperCase())\n      const paths = stringLiterals(call.arguments[1]).filter(isRoutePath)\n      if (methods.length === 0 || paths.length === 0 || call.arguments.length < 3) return\n      const loc = nodeLoc(node, parsed.lines)\n      for (const method of methods) {\n        for (const path of paths) {\n          found.push({ method, path, line: loc?.line ?? 1 })\n        }\n      }\n      return\n    }\n\n    if (!ROUTE_METHODS.has(name)) return\n    const path = stringLiteral(call.arguments[0])\n    /* Path + handler function: `c.get('log')` has neither a `/…` path nor a\n       second argument, and `axios.get('/users', { headers })` passes an object\n       rather than a function, so both are filtered without tracking bindings. */\n    if (!path || !isRoutePath(path) || !looksLikeHandler(call.arguments[1])) return\n\n    const loc = nodeLoc(node, parsed.lines)\n    found.push({\n      method: ROUTE_METHODS.get(name) ?? null,\n      path,\n      line: loc?.line ?? 1,\n    })\n  })\n\n  return found\n}\n\nfunction extractFromFile(file: string, root: string, parse: ParseFn): RawRouteEntry[] {\n  const rel = relativeFromRoot(root, file)\n  const parsed = parse(file)\n  if (!parsed) return []\n\n  return findHonoRoutes(parsed).map(route => ({\n    framework: 'hono' as const,\n    kind: 'api' as const,\n    method: route.method,\n    path: route.path,\n    file: rel,\n    handler: { line: route.line, column: 0 },\n  }))\n}\n\n/** Local names bound to `evlog` from `evlog/hono`, alias included. */\nfunction evlogMiddlewareNames(parsed: ParseResult): Set<string> {\n  const names = new Set<string>()\n  walkAst(parsed.program, (node) => {\n    if (node.type !== 'ImportDeclaration') return\n    const declaration = node as {\n      source: { value: string }\n      specifiers: Array<{ type: string, imported?: { name?: string }, local?: { name: string } }>\n    }\n    if (declaration.source.value !== 'evlog/hono') return\n    for (const specifier of declaration.specifiers) {\n      if (specifier.imported?.name === 'evlog' && specifier.local) names.add(specifier.local.name)\n    }\n  })\n  return names\n}\n\n/** Whether the file registers evlog's middleware: `app.use(evlog())`. */\nfunction registersEvlogMiddleware(parsed: ParseResult): boolean {\n  const names = evlogMiddlewareNames(parsed)\n  if (names.size === 0) return false\n\n  let found = false\n  walkAst(parsed.program, (node) => {\n    if (found || node.type !== 'CallExpression') return\n    const call = node as { callee: Node, arguments: Node[] }\n    if (call.callee.type !== 'MemberExpression') return\n    const { property, computed } = call.callee as { property: Node, computed?: boolean }\n    if (computed || property.type !== 'Identifier' || property.name !== 'use') return\n    found = call.arguments.some((argument) => {\n      if (argument.type !== 'CallExpression') return false\n      const { callee } = argument as { callee: Node }\n      return callee.type === 'Identifier' && names.has((callee as unknown as { name: string }).name)\n    })\n  })\n  return found\n}\n\n/**\n * Hono: scan source for `app.get/post/…('/path', …)` registrations.\n *\n * No auto-imports — `useLogger` / `c.get('log')` come from `evlog/hono`. Unlike\n * Nuxt or Nitro, the per-request event only exists once the app itself calls\n * `app.use(evlog())`, so the ambient/explicit capability is resolved per\n * project: ambient when the middleware is registered somewhere in the scanned\n * sources, explicit (nothing is emitted at all) when it is not.\n */\nexport const honoAdapter: FrameworkAdapter = {\n  framework: 'hono',\n  requestLogger: 'explicit',\n  resolveRequestLogger(ctx: ScanContext): 'ambient' | 'explicit' {\n    const parse = ctx.parse ?? parseFile\n    for (const file of sourceFiles(ctx.projectRoot)) {\n      const parsed = parse(file)\n      if (parsed && registersEvlogMiddleware(parsed)) return 'ambient'\n    }\n    return 'explicit'\n  },\n  // eslint-disable-next-line require-await -- satisfies the async FrameworkAdapter contract\n  async extractRoutes(ctx: ScanContext): Promise<RawRouteEntry[]> {\n    const parse = ctx.parse ?? parseFile\n    const routes: RawRouteEntry[] = []\n\n    for (const file of sourceFiles(ctx.projectRoot)) {\n      routes.push(...extractFromFile(file, ctx.projectRoot, parse))\n    }\n\n    return routes\n  },\n}\n","import type { Framework, FrameworkAdapter } from '../types'\nimport { nextAdapter } from './next'\nimport { getNuxtOrNitroAdapter } from './nuxt'\nimport { tanstackStartAdapter } from './tanstack-start'\nimport { honoAdapter } from './hono'\n\n/** Resolve the route-extraction adapter for a detected framework. */\nexport function getAdapter(framework: Framework): FrameworkAdapter {\n  switch (framework) {\n    case 'nuxt':\n    case 'nitro':\n      return getNuxtOrNitroAdapter(framework)\n    case 'next':\n      return nextAdapter\n    case 'tanstack-start':\n      return tanstackStartAdapter\n    case 'hono':\n      return honoAdapter\n  }\n}\n","import type { Comment } from 'oxc-parser'\nimport type { LineIndex } from './parse'\nimport type { RouteEntry } from './types'\n\n/**\n * Comment directives that turn a check off.\n *\n * Every static analyser needs an escape hatch, and it has to live next to the\n * code rather than in a config file: the reason a check does not apply is a\n * property of that handler, and it should be reviewable in the same diff.\n *\n * ```ts\n * // evlog-map-disable-next-line audit -- internal tool, no audit trail wanted\n * export default defineEventHandler(async (event) => {\n * ```\n *\n * A disabled check is reported as `n/a` with the reason attached, exactly like\n * evlog's own infrastructure exemptions, so it costs no score — and it stays\n * visible in the report rather than disappearing.\n */\nconst DIRECTIVE = 'evlog-map-disable'\n\n/** Directive forms, longest first so `-next-line` is not read as bare. */\nconst FORMS = [\n  { suffix: '-next-line', offset: 1 },\n  { suffix: '-line', offset: 0 },\n  { suffix: '', offset: null },\n] as const\n\nexport interface Suppression {\n  /** Rule ids the directive names, or `null` when it covers every rule. */\n  rules: readonly string[] | null\n  /** Line the directive covers, or `null` when it covers the whole file. */\n  line: number | null\n  /** Text after `--`, or `null` when the author gave no reason. */\n  reason: string | null\n  /** Line the comment itself sits on, for the message and for evidence. */\n  declaredAt: number\n}\n\n/** A rule id named by a directive that no registered rule answers to. */\nexport interface UnknownDirectiveId {\n  id: string\n  declaredAt: number\n}\n\nexport interface SuppressionSet {\n  /** Every directive found, in source order. */\n  all: readonly Suppression[]\n  /** File-wide directive covering `ruleId`, if any. */\n  file: (ruleId: string) => Suppression | null\n  /** Directive covering `ruleId` on `line`, if any. */\n  at: (ruleId: string, line: number) => Suppression | null\n  /**\n   * Ids named in a directive that are not in `known`.\n   *\n   * A typo has to be loud: silently ignoring `// evlog-map-disable-next-line\n   * audti` leaves the author believing a check is off while it still fails.\n   */\n  unknown: (known: readonly string[]) => readonly UnknownDirectiveId[]\n}\n\nconst EMPTY: SuppressionSet = {\n  all: [],\n  file: () => null,\n  at: () => null,\n  unknown: () => [],\n}\n\n/** Parse one comment body into a directive, or `null` when it is not one. */\nexport function parseDirective(value: string, commentLine: number): Suppression | null {\n  const text = value.trim()\n  if (!text.startsWith(DIRECTIVE)) return null\n\n  const form = FORMS.find(candidate => text.startsWith(`${DIRECTIVE}${candidate.suffix}`))\n  if (!form) return null\n\n  /* Only the directive's own line matters: a block comment may span several,\n     and the rest of it is prose rather than part of the reason. */\n  const rest = text.slice(DIRECTIVE.length + form.suffix.length).split('\\n')[0] ?? ''\n  /* Anything but a separator right after the directive means this is a longer\n     word — `evlog-map-disabled`, say — and not a directive at all. */\n  if (rest.length > 0 && !/^[\\s,]/.test(rest)) return null\n\n  const [head = '', ...reasonParts] = rest.split('--')\n  const rules = head.split(/[\\s,]+/).filter(id => id.length > 0)\n  const reason = reasonParts.join('--').trim()\n\n  return {\n    rules: rules.length > 0 ? rules : null,\n    line: form.offset === null ? null : commentLine + form.offset,\n    reason: reason.length > 0 ? reason : null,\n    declaredAt: commentLine,\n  }\n}\n\n/** Collect every `evlog-map-disable` directive in one parsed file. */\nexport function collectSuppressions(comments: readonly Comment[], lines: LineIndex): SuppressionSet {\n  const all: Suppression[] = []\n\n  for (const comment of comments) {\n    const directive = parseDirective(comment.value, lines.lineAt(comment.start))\n    if (directive) all.push(directive)\n  }\n\n  if (all.length === 0) return EMPTY\n\n  const covers = (suppression: Suppression, ruleId: string): boolean =>\n    suppression.rules === null || suppression.rules.includes(ruleId)\n\n  return {\n    all,\n    file: ruleId => all.find(s => s.line === null && covers(s, ruleId)) ?? null,\n    at: (ruleId, line) => all.find(s => s.line === line && covers(s, ruleId)) ?? null,\n    unknown: (known) => {\n      const seen = new Set<string>()\n      const unknown: UnknownDirectiveId[] = []\n      for (const suppression of all) {\n        for (const id of suppression.rules ?? []) {\n          if (known.includes(id) || seen.has(id)) continue\n          seen.add(id)\n          unknown.push({ id, declaredAt: suppression.declaredAt })\n        }\n      }\n      return unknown\n    },\n  }\n}\n\n/** Checks this entry point turned off with an `evlog-map-disable` comment. */\nexport function countSuppressed(route: RouteEntry): number {\n  return Object.values(route.checks).filter(check => check?.suppressed).length\n}\n\n/** How a disabled check reads in the report. */\nexport function suppressionMessage(suppression: Suppression): string {\n  const scope = suppression.line === null\n    ? 'disabled for this file'\n    : `disabled at line ${suppression.declaredAt}`\n  return suppression.reason ? `${scope} — ${suppression.reason}` : scope\n}\n","import type { CheckId, RawRouteEntry, RouteEntry } from './types'\n\n/** Why an entry point is not held to some of the rules, and to which ones. */\nexport interface RouteExemption {\n  /** Shown in the report in place of the check's verdict. */\n  reason: string\n  /**\n   * Rules that do not apply to this route.\n   *\n   * `'all'` rather than a list of ids on purpose: an exemption that enumerates\n   * rule ids has to be revisited every time a rule is added, and forgetting is\n   * silent — the new rule simply starts failing on exempt routes.\n   */\n  skip: 'all' | readonly CheckId[]\n}\n\n/**\n * evlog's own ingest endpoint, as consecutive path segments.\n *\n * Matched segment by segment rather than as a substring: an exemption skips\n * every rule, so a loose match is the worst kind of bug this tool can have —\n * it silently drops a real handler out of the score instead of reporting a\n * gap. `lib/evlog/ingestable.ts` and `/api/evlog/ingestion-report` both contain\n * `evlog/ingest` and neither is evlog's endpoint.\n */\nconst INFRA_SEGMENTS = [\n  ['evlog', 'ingest'],\n  ['_evlog', 'ingest'],\n]\n\nconst INFRA_EXEMPTION: RouteExemption = {\n  reason: 'evlog infrastructure — client log ingest endpoint',\n  skip: 'all',\n}\n\n/**\n * Segments of a route path or file, lowercased, with the extension and any\n * method suffix dropped so `_evlog/ingest.post.ts` still reads as `ingest`.\n */\nfunction segmentsOf(value: string): string[] {\n  return value\n    .toLowerCase()\n    .split('/')\n    .filter(segment => segment.length > 0)\n    .map(segment => segment.split('.')[0] ?? segment)\n}\n\n/** Whether `segments` contains `pattern` as a consecutive run. */\nfunction containsRun(segments: readonly string[], pattern: readonly string[]): boolean {\n  return segments.some((_, index) => pattern.every((name, offset) => segments[index + offset] === name))\n}\n\n/**\n * Routes that are evlog plumbing (client ingest, internal handlers) — not app\n * handlers. Observability rules are n/a, not failures.\n */\nexport function getRouteExemption(route: Pick<RawRouteEntry, 'path' | 'file'>): RouteExemption | null {\n  const path = segmentsOf(route.path)\n  const file = segmentsOf(route.file)\n\n  for (const pattern of INFRA_SEGMENTS) {\n    if (containsRun(path, pattern) || containsRun(file, pattern)) return INFRA_EXEMPTION\n  }\n\n  return null\n}\n\n/** Whether an exemption covers a given rule. */\nexport function isSkipped(exemption: RouteExemption, id: CheckId): boolean {\n  return exemption.skip === 'all' || exemption.skip.includes(id)\n}\n\n/** Whether this entry point is evlog's own plumbing rather than app code. */\nexport function isInfrastructureRoute(route: Pick<RawRouteEntry, 'path' | 'file'>): boolean {\n  return getRouteExemption(route) !== null\n}\n\n/** The `infra` tag for the report, or an empty string for app entry points. */\nexport function infrastructureLabel(route: RouteEntry): string {\n  return getRouteExemption(route) ? 'infra' : ''\n}\n","import type { Node } from 'oxc-parser'\nimport type { FileFacts } from '../facts'\nimport type { ProjectFacts } from '../project-facts'\nimport type { CheckId, Framework, RawRouteEntry, RouteKind, Sensitivity } from '../types'\n\n/** Entry-point kinds that own a server-side wide event. */\nexport const HANDLER_KINDS: readonly RouteKind[] = ['api', 'server-action', 'middleware', 'cron']\n\n/** The entry point a rule is looking at, with its sensitivity already resolved. */\nexport interface RuleTarget extends RawRouteEntry {\n  sensitivity: Sensitivity\n}\n\n/** A gap a rule found. Reporting nothing means the rule passed. */\nexport interface RuleReport {\n  message: string\n  /** Defaults to the handler's line. */\n  line?: number\n  /** Attach the source line as evidence. */\n  snippet?: boolean\n}\n\nexport interface RuleContext {\n  target: RuleTarget\n  facts: FileFacts\n  /** What the project has already adopted — the gate for every opportunity. */\n  project: ProjectFacts\n  framework: Framework\n  /** What the framework integration does on its own, declared by its adapter. */\n  capabilities: FrameworkCapabilities\n  /** Whether evlog is installed at all — some rules phrase themselves differently. */\n  hasEvlog: boolean\n  source: string\n  report: (report: RuleReport) => void\n}\n\n/** The parts of a {@link FrameworkAdapter} a rule is allowed to depend on. */\nexport interface FrameworkCapabilities {\n  requestLogger: 'ambient' | 'explicit'\n  evlogAutoImports: readonly string[]\n}\n\n/**\n * Node-type listeners dispatched during the shared AST pass, plus `onEnd` for\n * verdicts that depend on the whole file (\"nothing anywhere in this handler\").\n *\n * Most rules only need `onEnd` because {@link FileFacts} already answers their\n * question; listeners are the escape hatch for anything the facts do not cover.\n */\nexport type RuleListeners = Partial<Record<Node['type'], (node: Node) => void>> & {\n  onEnd?: () => void\n}\n\n/**\n * Which entry points a rule looks at.\n *\n * Declarative on purpose: rules used to guard themselves with an early\n * `return n/a`, which meant the same routing logic was written once per rule\n * and again in the runner. Here the runner is the only place that decides.\n */\nexport interface RuleApplicability {\n  /**\n   * Entry-point kinds. A rule that does not apply to a kind is left out of the\n   * report entirely, rather than reported as not-applicable.\n   */\n  kinds: readonly RouteKind[]\n  /** Restrict to specific frameworks. Omit for all of them. */\n  frameworks?: readonly Framework[]\n  /**\n   * Last word before the rule runs, for conditions only known after parsing\n   * (sensitivity, presence of a fetch, …). Returning `false` reports the rule\n   * as not-applicable, which is visible in the map — unlike `kinds`.\n   */\n  when?: (context: Omit<RuleContext, 'report'>) => boolean\n}\n\n/**\n * Where a rule's fix belongs inside an entry point.\n *\n * The report composes the suggested shape from these slots, so a rule added\n * later lands in the snippet without anyone editing the renderer. `body` is the\n * default because most fixes are simply one more call among the work.\n *\n * - `setup` — before the work, e.g. acquiring the logger.\n * - `body` — among the work, e.g. an audit record.\n * - `guard` — wraps the work: the rule opens a `catch` and the report closes it.\n * - `exit` — how the entry point fails, e.g. the shape of a thrown error.\n */\nexport type FixSlot = 'setup' | 'body' | 'guard' | 'exit'\n\n/**\n * What every rule declares about itself.\n *\n * A rule owns its column title, its documentation link, and the fix it\n * suggests, so that adding a rule means adding one file and one registry entry,\n * instead of editing six tables that have no way of telling you they went out\n * of sync.\n */\ninterface BaseRule {\n  id: CheckId\n  /** Column header in `--all`, kept to ~8 characters. */\n  title: string\n  /** The concrete thing the rule wants to see, e.g. `log.audit`. */\n  expects: string\n  /** The question this rule answers, as a sentence, for `--inspect`. */\n  question: string\n  /** Docs path, e.g. `/learn/lifecycle`. */\n  docs: string\n  appliesTo: RuleApplicability\n  /** Code suggestion shown by `evlog map <file>`, aware of framework and project. */\n  suggest?: (context: SuggestContext) => readonly string[]\n  /** Where {@link BaseRule.suggest} belongs in the composed shape. Defaults to `body`. */\n  fixSlot?: FixSlot\n  create: (context: RuleContext) => RuleListeners\n}\n\n/** What a rule may use to shape its suggested code. */\nexport interface SuggestContext {\n  target: RuleTarget\n  framework: Framework\n  /** Lets a suggestion name what the project already has, e.g. its catalog. */\n  project: ProjectFacts\n}\n\n/** A rule whose failure is a real gap, and costs score points. */\nexport interface RequirementRule extends BaseRule {\n  category: 'requirement'\n  /** Points removed from an entry point's score when this rule fails. */\n  weight: number\n}\n\n/**\n * A rule that suggests going further with a feature the project already uses.\n *\n * Opportunities carry no weight — the type makes it impossible to give one, so\n * a suggestion can never quietly turn into a penalty. Nobody is scored down for\n * not adopting a feature they never asked for; they are only pointed at more of\n * what they already chose.\n */\nexport interface OpportunityRule extends BaseRule {\n  category: 'opportunity'\n  /**\n   * Where the work actually is.\n   *\n   * `entry-point` (the default) means each hit is its own edit. `project` means\n   * the whole suggestion is one installation, done once — reporting it per entry\n   * point would claim there are five things to do when there is one.\n   */\n  scope?: 'entry-point' | 'project'\n}\n\nexport type MapRule = RequirementRule | OpportunityRule\n","import { HANDLER_KINDS } from './types'\nimport type { MapRule } from './types'\n\n/** AI SDK entry points whose cost and latency belong on the event. */\nconst AI_CALLS = ['generateText', 'streamText', 'generateObject', 'streamObject', 'embed', 'embedMany']\n\n/**\n * This handler calls the AI SDK — is the model call on the event?\n *\n * Gated on the `ai` package being a dependency, so this only ever appears for\n * teams already building with it. Without `evlog/ai` the event records that the\n * request happened but not what the model cost, which is usually the most\n * expensive and most variable part of the request.\n */\nexport const aiLoggingRule = {\n  id: 'ai-logging',\n  category: 'opportunity',\n  /* One wrapped model, shared by every handler that calls it. */\n  scope: 'project',\n  title: 'ai',\n  expects: 'evlog/ai',\n  question: 'Are model calls, tokens and latency on the event?',\n  docs: '/use-cases/ai-sdk/overview',\n  appliesTo: {\n    kinds: HANDLER_KINDS,\n    when: ({ project, facts }) => {\n      if (!project.pairable.has('ai')) return false\n      /* Project-wide, like `auth-identity`: the middleware is installed once on\n         a shared model, and reading only this file would keep nagging every\n         handler that calls that model. */\n      if (project.features.has('ai')) return false\n      return AI_CALLS.some(name => facts.callsTo(name).length > 0)\n    },\n  },\n\n  suggest() {\n    return [\n      'import { createAIMiddleware } from \\'evlog/ai\\'',\n      '',\n      'const model = wrapLanguageModel({',\n      '  model: openai(\\'gpt-4o\\'),',\n      '  middleware: createAIMiddleware(log),',\n      '})',\n    ]\n  },\n\n  create(context) {\n    const { facts } = context\n    return {\n      onEnd() {\n        /* Source order, not the order of `AI_CALLS`: grouping by name first\n           points the evidence at whichever helper happens to be listed first,\n           which can sit well below the call the reader should look at. */\n        const call = facts.calls.find(fact => AI_CALLS.includes(fact.member))\n        context.report({\n          message: 'AI SDK call without evlog/ai — tokens, cost and model latency are missing from the event',\n          line: call?.line,\n        })\n      },\n    }\n  },\n} satisfies MapRule\n","import { HANDLER_KINDS } from './types'\nimport type { MapRule, RuleTarget } from './types'\n\n/** Route segments that name nothing: prefixes, indexes, and dynamic params. */\nfunction isAnonymousSegment(segment: string): boolean {\n  if (segment.length === 0) return true\n  if (segment === 'api' || segment === 'index') return true\n  return segment.startsWith('[') || segment.startsWith(':') || segment.startsWith('*')\n}\n\n/** Verb implied by the HTTP method, used only when the path is a single word. */\nconst METHOD_VERBS: Record<string, string> = {\n  POST: 'created',\n  PUT: 'updated',\n  PATCH: 'updated',\n  DELETE: 'deleted',\n  GET: 'read',\n}\n\n/**\n * A plausible audit action for an entry point, read off its route path.\n *\n * The suggested action used to be the literal `payment.captured` everywhere,\n * which read as nonsense on `/api/auth/login` and made the whole snippet look\n * like filler. `/api/auth/login` now suggests `auth.login`.\n */\nexport function auditAction(target: Pick<RuleTarget, 'path' | 'method'>): string {\n  const named = target.path.split('/').filter(segment => !isAnonymousSegment(segment))\n  if (named.length === 0) return 'resource.action'\n  if (named.length === 1) {\n    const verb = METHOD_VERBS[target.method?.toUpperCase() ?? ''] ?? 'action'\n    return `${named[0]}.${verb}`\n  }\n  return named.join('.')\n}\n\n\n/**\n * Does a sensitive entry point leave an audit trail?\n *\n * Only runs where the sensitivity classifier found money or auth — everywhere\n * else an audit record would be noise, so the rule reports itself as\n * not-applicable rather than passing for free.\n */\nexport const auditRule = {\n  id: 'audit',\n  category: 'requirement',\n  title: 'audit',\n  expects: 'log.audit',\n  question: 'Does this sensitive entry point leave an audit trail?',\n  weight: 25,\n  docs: '/use-cases/audit/overview',\n  appliesTo: {\n    kinds: HANDLER_KINDS,\n    when: ({ target }) => target.sensitivity.level === 'high',\n  },\n\n  suggest({ target }) {\n    return [\n      'log.audit({',\n      `  action: '${auditAction(target)}',`,\n      '  actor: { type: \\'user\\', id: user.id },',\n      '})',\n    ]\n  },\n\n  create(context) {\n    return {\n      onEnd() {\n        if (context.facts.loggerCalls('audit').length > 0) return\n        context.report({\n          message: context.hasEvlog\n            ? 'has logger + context but no log.audit() — sensitive route needs audit trail'\n            : 'sensitive route without log.audit()',\n        })\n      },\n    }\n  },\n} satisfies MapRule\n","import { HANDLER_KINDS } from './types'\nimport type { MapRule } from './types'\n\n/** Calls that change state, and are therefore worth an audit record. */\nconst WRITE_CALLS = ['create', 'update', 'insert', 'upsert', 'delete', 'destroy']\n\n/**\n * The project records audit events — is this write covered?\n *\n * Complements the `audit` requirement, which only fires on entry points the\n * sensitivity classifier flagged as money or auth. This one is softer and wider:\n * once a team has an audit trail, every state change is a candidate, and they\n * are the ones who know which ones matter.\n */\nexport const auditCoverageRule = {\n  id: 'audit-coverage',\n  category: 'opportunity',\n  title: 'audit+',\n  expects: 'log.audit',\n  question: 'Should this state change be on the audit trail too?',\n  docs: '/use-cases/audit/recording',\n  appliesTo: {\n    kinds: HANDLER_KINDS,\n    when: ({ project, target, facts }) => {\n      /* High sensitivity is already the `audit` requirement's job — no double\n         reporting for the same gap. */\n      if (target.sensitivity.level === 'high') return false\n      if (!project.features.has('audit')) return false\n      return facts.loggerCalls('audit').length === 0 && hasWrite(facts)\n    },\n  },\n\n  suggest() {\n    return [\n      'log.audit({',\n      '  action: \\'order.updated\\',',\n      '  actor: { type: \\'user\\', id: user.id },',\n      '  resource: { type: \\'order\\', id: order.id },',\n      '})',\n    ]\n  },\n\n  create(context) {\n    const { facts } = context\n    return {\n      onEnd() {\n        const write = facts.calls.find(call => WRITE_CALLS.includes(call.member.toLowerCase()))\n        context.report({\n          message: 'changes state with no audit record — the project records audit events elsewhere',\n          line: write?.line,\n        })\n      },\n    }\n  },\n} satisfies MapRule\n\nfunction hasWrite(facts: { calls: readonly { member: string }[] }): boolean {\n  return facts.calls.some(call => WRITE_CALLS.includes(call.member.toLowerCase()))\n}\n","import { HANDLER_KINDS } from './types'\nimport type { MapRule } from './types'\n\n/**\n * This project uses Better Auth — do its events know who the user is?\n *\n * Gated on `better-auth` being a dependency. `evlog/better-auth` attaches the\n * user and session to every event, which is what turns \"a request failed\" into\n * \"this user's request failed\" when someone reports a problem.\n */\nexport const authIdentityRule = {\n  id: 'auth-identity',\n  category: 'opportunity',\n  /* One Nitro plugin, installed once — not a per-handler edit. */\n  scope: 'project',\n  title: 'identity',\n  expects: 'evlog/better-auth',\n  question: 'Do events carry the authenticated user?',\n  docs: '/use-cases/better-auth/overview',\n  appliesTo: {\n    kinds: HANDLER_KINDS,\n    when: ({ project, facts, target }) => {\n      if (!project.pairable.has('better-auth')) return false\n      if (project.features.has('better-auth')) return false\n      /* Only where auth is actually in play: the auth routes themselves, or a\n         handler that reads the session. */\n      const touchesAuth = target.sensitivity.reasons.some(reason => reason.startsWith('auth:'))\n      const readsSession = facts.callsTo('getSession').length > 0\n        || facts.imports.has('auth')\n        || facts.names.has('session')\n      return touchesAuth || readsSession\n    },\n  },\n\n  suggest() {\n    return [\n      'import { createAuthMiddleware } from \\'evlog/better-auth\\'',\n      '',\n      'export default defineNitroPlugin(createAuthMiddleware(auth))',\n    ]\n  },\n\n  create(context) {\n    return {\n      onEnd() {\n        context.report({\n          message: 'Better Auth is installed but evlog/better-auth is not — events carry no user identity',\n        })\n      },\n    }\n  },\n} satisfies MapRule\n","import { HANDLER_KINDS } from './types'\nimport type { MapRule } from './types'\n\n/**\n * Does the handler attach anything to its event?\n *\n * A logger with no `log.set()` produces a technically-valid event that says\n * nothing about the request it describes, which is the most common way a wide\n * event ends up useless in production.\n *\n * Only `set()` calls on a resolved evlog logger count. The previous\n * implementation matched any `.set()` in the file, so a `Map.set()` was enough\n * to pass this rule.\n */\nexport const contextRule = {\n  id: 'context',\n  category: 'requirement',\n  title: 'context',\n  expects: 'log.set',\n  question: 'Is request context attached to the event?',\n  weight: 15,\n  docs: '/learn/wide-events',\n  appliesTo: { kinds: HANDLER_KINDS },\n\n  fixSlot: 'setup',\n  suggest() {\n    return ['log.set({ user: { id }, order: { id, total } })']\n  },\n\n  create(context) {\n    return {\n      onEnd() {\n        if (context.facts.loggerCalls('set').length > 0) return\n        context.report({\n          message: context.hasEvlog\n            ? 'no log.set() context accumulation'\n            : 'no log.set() — adopt evlog for request context',\n        })\n      },\n    }\n  },\n} satisfies MapRule\n","import type { FileFacts } from '../facts'\nimport type { ProjectFacts, RepeatedError } from '../project-facts'\nimport { HANDLER_KINDS } from './types'\nimport type { MapRule } from './types'\n\n/**\n * The same error is written out in several handlers — should it be a catalog entry?\n *\n * Deliberately narrow. An earlier version fired on any inline `createError()`,\n * which meant five of six handlers got a suggestion for writing perfectly good\n * errors — that is policing, not helping. Duplication is the one signal that\n * makes the case on its own: the same status and message maintained in three\n * places will drift, and a catalog is exactly the fix for that.\n *\n * Also gated on the project already declaring a catalog, so the suggestion can\n * point at something that exists instead of pitching a feature.\n */\nexport const errorCatalogRule = {\n  id: 'error-catalog',\n  category: 'opportunity',\n  title: 'catalog',\n  expects: 'catalog error',\n  question: 'Should these duplicated errors become catalog entries?',\n  docs: '/learn/catalogs',\n  appliesTo: {\n    kinds: HANDLER_KINDS,\n    when: ({ project, facts }) =>\n      project.features.has('error-catalog') && findDuplicate(facts, project) !== null,\n  },\n\n  suggest({ project }) {\n    const [catalog] = project.catalogs\n    const name = catalog ?? 'billing'\n    const constant = `${name}Errors`\n    return [\n      `// add the entry to your ${name} catalog`,\n      `export const ${constant} = defineErrorCatalog('${name}', {`,\n      '  PAYMENT_DECLINED: { status: 402, message: \\'Card declined\\' },',\n      '})',\n      '',\n      '// then, in every handler that used to spell it out',\n      `throw ${constant}.PAYMENT_DECLINED()`,\n    ]\n  },\n\n  create(context) {\n    const { facts, project } = context\n    return {\n      onEnd() {\n        const duplicate = findDuplicate(facts, project)\n        if (!duplicate) return\n        const { repeated, line } = duplicate\n        const elsewhere = repeated.files.length - 1\n        const others = elsewhere === 1 ? '1 other file' : `${elsewhere} other files`\n        context.report({\n          message: `\"${repeated.label}\" is spelled out here and in ${others} — one catalog entry would cover them`,\n          line,\n        })\n      },\n    }\n  },\n} satisfies MapRule\n\n/** The first inline error in this file that also exists somewhere else. */\nfunction findDuplicate(\n  facts: FileFacts,\n  project: ProjectFacts,\n): { repeated: RepeatedError, line: number } | null {\n  for (const error of facts.inlineErrors) {\n    const repeated = project.repeatedErrors.get(error.signature)\n    if (repeated) return { repeated, line: error.line }\n  }\n  return null\n}\n","import { HANDLER_KINDS } from './types'\nimport type { MapRule } from './types'\n\n/**\n * Does every `catch` do something with the error?\n *\n * A swallowed error is worse than an unhandled one: the request looks\n * successful, the event says nothing, and the failure is invisible until a user\n * reports it.\n *\n * A handler with no `catch` at all is not a gap and is reported as\n * not-applicable: evlog's framework integrations hook the runtime's error\n * channel (`nitroApp.hooks.hook('error')` in Nitro, `withEvlog` in Next), so an\n * exception that escapes is still recorded on the event with its status. The\n * rule used to pass for free in that case, which made the report claim\n * \"failures are caught and logged\" about a handler that catches nothing.\n */\nexport const errorHandlingRule = {\n  id: 'error-handling',\n  category: 'requirement',\n  title: 'catch',\n  expects: 'log.error in catch',\n  question: 'Is every caught error logged or rethrown?',\n  weight: 15,\n  docs: '/learn/structured-errors',\n  appliesTo: {\n    kinds: HANDLER_KINDS,\n    when: ({ facts }) => facts.catches.length > 0,\n  },\n\n  /* Opens the catch and logs; the report closes it with however the handler\n     leaves, which is the `exit` slot's business and not this rule's. */\n  fixSlot: 'guard',\n  suggest() {\n    return ['catch (error) {', '  log.error(error)']\n  },\n\n  create(context) {\n    return {\n      onEnd() {\n        for (const clause of context.facts.catches) {\n          if (clause.isEmpty) {\n            context.report({\n              message: 'empty catch block swallows errors',\n              line: clause.line,\n              snippet: true,\n            })\n            return\n          }\n          if (!clause.handled) {\n            context.report({\n              message: 'catch block swallows error without logging or rethrow',\n              line: clause.line,\n              snippet: true,\n            })\n            return\n          }\n        }\n      },\n    }\n  },\n} satisfies MapRule\n","import type { MapRule } from './types'\n\n/**\n * When a page fetches data server-side, can it survive that fetch failing?\n *\n * Applies only to pages that actually fetch — a purely presentational page has\n * nothing to fail, so the rule reports itself as not-applicable.\n *\n * The error affordance is read from the AST and tied to the request it covers:\n * a `try` the call sits inside, a `.catch()` chained onto it, or an `error`\n * binding destructured from it. Checking the file for any of those instead let\n * an unrelated `try` elsewhere on the page vouch for a fetch nobody guarded.\n */\nexport const pageErrorHandlingRule = {\n  id: 'page-error-handling',\n  category: 'requirement',\n  title: 'fetch',\n  expects: 'fetch error handling',\n  question: 'Does this page handle its data fetch failing?',\n  weight: 20,\n  docs: '/learn/lifecycle',\n  appliesTo: {\n    kinds: ['page'],\n    when: ({ facts }) => facts.network.length > 0,\n  },\n\n  suggest({ framework }) {\n    if (framework === 'nuxt') {\n      return [\n        'const { data, error } = await useFetch(\\'/api/orders\\')',\n        'if (error.value) log.error(error.value)',\n      ]\n    }\n    return [\n      'try {',\n      '  const orders = await getOrders()',\n      '} catch (error) {',\n      '  log.error(error)',\n      '}',\n    ]\n  },\n\n  create(context) {\n    const { facts } = context\n    return {\n      onEnd() {\n        const [unguarded] = facts.unguardedNetwork\n        if (!unguarded) return\n        context.report({\n          message: `${unguarded.name}() without error handling — the page breaks when it fails`,\n          line: unguarded.line,\n        })\n      },\n    }\n  },\n} satisfies MapRule\n","import { HANDLER_KINDS } from './types'\nimport type { MapRule } from './types'\n\n/** The message depends on which half of `{ why, fix }` is missing. */\nfunction createErrorMessage(props: ReadonlySet<string>): string | null {\n  const hasWhy = props.has('why')\n  const hasFix = props.has('fix')\n  if (hasWhy && hasFix) return null\n  if (hasWhy) return 'createError() has why but missing fix'\n  if (hasFix) return 'createError() has fix but missing why'\n  return 'createError() missing why and fix'\n}\n\n/**\n * Are thrown errors explainable?\n *\n * `throw new Error('failed')` reaches the client as a string with no cause and\n * no remedy. `createError({ why, fix })` is what makes an error actionable for\n * whoever reads it at 3am.\n *\n * A handler that raises nothing is reported as not-applicable rather than\n * passing: there is no error to give a shape to, and a free pass made the report\n * claim \"errors carry why and fix\" about a file with no errors in it.\n */\nexport const structuredErrorsRule = {\n  id: 'structured-errors',\n  category: 'requirement',\n  title: 'errors',\n  expects: 'createError({ why, fix })',\n  question: 'Do thrown errors carry why and fix?',\n  weight: 20,\n  docs: '/learn/structured-errors',\n  appliesTo: {\n    kinds: HANDLER_KINDS,\n    when: ({ facts }) => facts.throws.length > 0 || facts.callsTo('createError').length > 0,\n  },\n\n  fixSlot: 'exit',\n  suggest() {\n    return [\n      'throw createError({',\n      '  status: 400,',\n      '  message: \\'what the caller sees\\',',\n      '  why: \\'what actually went wrong\\',',\n      '  fix: \\'what to do about it\\',',\n      '})',\n    ]\n  },\n\n  create(context) {\n    return {\n      onEnd() {\n        for (const thrown of context.facts.throws) {\n          if (thrown.kind === 'plain-error') {\n            context.report({\n              message: 'throw new Error() — use createError({ why, fix })',\n              line: thrown.line,\n              snippet: true,\n            })\n            return\n          }\n          if (thrown.kind === 'create-error') {\n            const message = createErrorMessage(thrown.props)\n            if (message) {\n              context.report({ message, line: thrown.line, snippet: true })\n              return\n            }\n          }\n        }\n\n        /* `createError()` returned rather than thrown still shapes the response. */\n        for (const call of context.facts.callsTo('createError')) {\n          const message = createErrorMessage(call.props)\n          if (message) {\n            context.report({ message, line: call.line, snippet: true })\n            return\n          }\n        }\n      },\n    }\n  },\n} satisfies MapRule\n","import { HANDLER_KINDS } from './types'\nimport type { MapRule } from './types'\n\n/**\n * Does this entry point contribute a wide event?\n *\n * The wording depends on what the framework integration already does. With\n * evlog's Nitro plugin an event is emitted for every request whether the\n * handler asks or not, so \"this handler is invisible\" would be false there —\n * the event exists, it just carries nothing but method, path and status.\n */\nexport const wideEventRule = {\n  id: 'wide-event',\n  category: 'requirement',\n  title: 'logger',\n  expects: 'useLogger',\n  question: 'Does this entry point emit a wide event?',\n  weight: 40,\n  docs: '/learn/wide-events',\n  appliesTo: { kinds: HANDLER_KINDS },\n\n  fixSlot: 'setup',\n  suggest({ framework }) {\n    const ambient = framework === 'nuxt' || framework === 'nitro'\n    return [ambient ? 'const log = useLogger(event)' : 'const log = useLogger()']\n  },\n\n  create(context) {\n    const { facts, capabilities } = context\n    return {\n      onEnd() {\n        /* An evlog wrapper instruments the handler without naming a logger —\n           `withEvlog` is how evlog documents its own Next.js integration. */\n        if (facts.loggerInit || facts.evlogWrappers.size > 0) return\n\n        if (!context.hasEvlog) {\n          context.report({ message: 'evlog not installed — adopt evlog for wide events' })\n          return\n        }\n        context.report({\n          message: capabilities.requestLogger === 'ambient'\n            ? 'handler adds nothing to its request event — only method, path and status are recorded'\n            : 'no useLogger() — handler is a dark event',\n        })\n      },\n    }\n  },\n} satisfies MapRule\n","import type { FileFacts } from '../facts'\nimport type { ParseResult } from '../parse'\nimport { walkAst } from '../parse'\nimport type { Suppression } from '../directives'\nimport { collectSuppressions, suppressionMessage } from '../directives'\nimport { getRouteExemption, isSkipped } from '../exemptions'\nimport type { ProjectFacts } from '../project-facts'\nimport type { CheckId, CheckResult, Framework, ScanContext } from '../types'\nimport { lineSnippet } from '../utils'\nimport { aiLoggingRule } from './ai-logging'\nimport { auditRule } from './audit'\nimport { auditCoverageRule } from './audit-coverage'\nimport { authIdentityRule } from './auth-identity'\nimport { contextRule } from './context'\nimport { errorCatalogRule } from './error-catalog'\nimport { errorHandlingRule } from './error-handling'\nimport { pageErrorHandlingRule } from './page-error-handling'\nimport { structuredErrorsRule } from './structured-errors'\nimport { wideEventRule } from './wide-event'\nimport type {\n  FrameworkCapabilities,\n  MapRule,\n  OpportunityRule,\n  RequirementRule,\n  RuleContext,\n  RuleListeners,\n  RuleReport,\n  RuleTarget,\n} from './types'\n\n/** Literal-typed registry, so the ids can be checked against {@link CheckId}. */\nconst REGISTRY = [\n  wideEventRule,\n  contextRule,\n  structuredErrorsRule,\n  auditRule,\n  errorHandlingRule,\n  pageErrorHandlingRule,\n  errorCatalogRule,\n  auditCoverageRule,\n  aiLoggingRule,\n  authIdentityRule,\n] as const\n\n/**\n * The registry and the published {@link CheckId} union must describe the same\n * set of rules, in both directions. `evlog.map.json` is a public contract, so\n * drift here would silently change what consumers receive — this fails the\n * build instead of the next release.\n */\ntype RegisteredId = typeof REGISTRY[number]['id']\ntype AssertIdsMatch = [RegisteredId] extends [CheckId]\n  ? [CheckId] extends [RegisteredId] ? true : never\n  : never\nconst idsMatch: AssertIdsMatch = true\nvoid idsMatch\n\n/**\n * Every observability rule, in report order.\n *\n * Adding a rule is one new file plus one line in {@link REGISTRY}. Nothing else\n * needs to change: weight, column title, docs link, and applicability all\n * travel with the rule.\n */\nexport const RULES: readonly MapRule[] = REGISTRY\n\n/**\n * Version of the rule set as written into `evlog.map.json`.\n *\n * Bump this only when a rule's semantics change in a way that could flip a\n * verdict for code a PR did not touch: a tightened check, a new requirement, a\n * reweighting. A release that adds a map feature without moving any verdict\n * must leave it alone, or every project would be forced to regenerate its\n * baseline for nothing. Written beside the CLI version so `--baseline` can\n * tell a stale committed map apart from a merely older one.\n */\nexport const RULE_SET_VERSION = 1\n\nconst RULES_BY_ID = new Map<CheckId, MapRule>(RULES.map(rule => [rule.id, rule]))\n\n/** Look up a rule's metadata — weight, title, docs link, suggested fix. */\nexport function getRule(id: CheckId): MapRule | undefined {\n  return RULES_BY_ID.get(id)\n}\n\n/** Whether a rule's question makes any sense for this target at all. */\nfunction isRelevant(rule: MapRule, target: RuleTarget, framework: Framework): boolean {\n  if (!rule.appliesTo.kinds.includes(target.kind)) return false\n  if (rule.appliesTo.frameworks && !rule.appliesTo.frameworks.includes(framework)) return false\n  return true\n}\n\nfunction toCheckResult(report: RuleReport, target: RuleTarget, source: string): CheckResult {\n  const line = reportLine(report, target)\n  return {\n    status: 'fail',\n    message: report.message,\n    evidence: {\n      file: target.file,\n      line,\n      snippet: report.snippet ? lineSnippet(source, line) : undefined,\n    },\n  }\n}\n\n/** The line a finding points at — what a `-next-line` directive has to cover. */\nfunction reportLine(report: RuleReport, target: RuleTarget): number {\n  return report.line ?? target.handler?.line ?? 1\n}\n\n/**\n * A finding the author waived with a comment.\n *\n * `n/a` rather than `pass`: the rule did find something, and calling that a pass\n * would read as coverage the entry point does not have. The evidence points at\n * the comment, so a reader can find the decision and the reason behind it.\n */\nfunction toSuppressedResult(suppression: Suppression, target: RuleTarget): CheckResult {\n  return {\n    status: 'n/a',\n    suppressed: true,\n    message: suppressionMessage(suppression),\n    evidence: { file: target.file, line: suppression.declaredAt },\n  }\n}\n\n/** One entry point, parsed and reduced to facts, ready for the rules. */\nexport interface RuleRun {\n  ctx: ScanContext\n  target: RuleTarget\n  parsed: ParseResult | null\n  facts: FileFacts | null\n  project: ProjectFacts\n  capabilities: FrameworkCapabilities\n}\n\n/** Requirement results and opportunity results, kept apart. */\nexport interface RuleResults {\n  checks: Partial<Record<CheckId, CheckResult>>\n  suggestions: Partial<Record<CheckId, CheckResult>>\n  /** Problems with the file's own `evlog-map-disable` comments, e.g. a typo'd id. */\n  warnings: string[]\n}\n\n/**\n * Run every applicable rule against one entry point in a single AST pass.\n *\n * Rules that are irrelevant by kind or framework are left out of the result\n * entirely; rules that are relevant but gated by `when` (sensitivity, presence\n * of a fetch, whether the project uses a feature) are reported as `n/a`, so the\n * map distinguishes \"this question makes no sense here\" from \"this question does\n * not apply right now\".\n */\nexport function runRules(run: RuleRun): RuleResults {\n  return runRuleSet(RULES, run)\n}\n\n/**\n * {@link runRules} against an explicit set of rules.\n *\n * Exposed so a single rule can be exercised in isolation — the equivalent of\n * ESLint's `RuleTester`, which is what makes a false positive a local fix\n * rather than an archaeology session.\n */\nexport function runRuleSet(rules: readonly MapRule[], run: RuleRun): RuleResults {\n  const { ctx, target, parsed, facts } = run\n  const results: RuleResults = { checks: {}, suggestions: {}, warnings: [] }\n  const bucket = (rule: MapRule): Partial<Record<CheckId, CheckResult>> =>\n    rule.category === 'requirement' ? results.checks : results.suggestions\n  const relevant = rules.filter(rule => isRelevant(rule, target, ctx.framework))\n  /* Depends only on the route's path and file, so it holds even for a file we\n     cannot read — an exempt health check stays exempt when it fails to parse. */\n  const exemption = getRouteExemption(target)\n\n  if (!parsed || !facts) {\n    /* A file that will not parse is a real failure, but only of requirements —\n       we have no basis to suggest anything about code we could not read. */\n    for (const rule of relevant) {\n      if (rule.category !== 'requirement') continue\n      if (exemption && isSkipped(exemption, rule.id)) {\n        results.checks[rule.id] = { status: 'n/a', message: exemption.reason }\n        continue\n      }\n      results.checks[rule.id] = {\n        status: 'fail',\n        message: 'file failed to parse',\n        evidence: { file: target.file, line: 1, snippet: undefined },\n      }\n    }\n    return results\n  }\n\n  /* Validated against the whole registry rather than `rules`, so exercising one\n     rule in isolation never turns a valid id into a warning. */\n  const suppressions = collectSuppressions(parsed.comments, parsed.lines)\n  for (const { id, declaredAt } of suppressions.unknown(RULES.map(rule => rule.id))) {\n    results.warnings.push(`${target.file}:${declaredAt} disables \"${id}\", which is not a check evlog map runs`)\n  }\n  const active: Array<{ rule: MapRule, listeners: RuleListeners, reports: RuleReport[] }> = []\n\n  for (const rule of relevant) {\n    if (exemption && isSkipped(exemption, rule.id)) {\n      bucket(rule)[rule.id] = { status: 'n/a', message: exemption.reason }\n      continue\n    }\n\n    const base = {\n      target,\n      facts,\n      project: run.project,\n      framework: ctx.framework,\n      capabilities: run.capabilities,\n      hasEvlog: ctx.hasEvlog,\n      source: parsed.source,\n    }\n    if (rule.appliesTo.when && !rule.appliesTo.when(base)) {\n      /* An opportunity that does not apply is silence, not a row in the report:\n         \"you could use a feature you don't use\" is noise. */\n      if (rule.category === 'requirement') results.checks[rule.id] = { status: 'n/a' }\n      continue\n    }\n\n    const reports: RuleReport[] = []\n    const context: RuleContext = { ...base, report: report => reports.push(report) }\n    active.push({ rule, listeners: rule.create(context), reports })\n  }\n\n  /* One walk shared by every rule, dispatched by node type. Skipped entirely\n     when no rule asked for nodes, which is the common case now that the facts\n     already answer most questions. */\n  const withNodeListeners = active.filter(entry => hasNodeListeners(entry.listeners))\n  if (withNodeListeners.length > 0) {\n    walkAst(parsed.program, (node) => {\n      for (const entry of withNodeListeners) {\n        entry.listeners[node.type]?.(node)\n      }\n    })\n  }\n\n  for (const entry of active) {\n    entry.listeners.onEnd?.()\n    const [first] = entry.reports\n    /* An opportunity with nothing to say is left out entirely. */\n    if (entry.rule.category === 'opportunity' && !first) continue\n\n    if (first) {\n      /* Directives are resolved once a rule has something to say, rather than\n         before it runs: a disabled check is a failure the author chose not to\n         see, so a rule that would have passed is still reported as passing, and\n         one that never applied stays a plain `n/a`. That keeps the count of\n         disabled checks equal to the number of findings actually waived. */\n      const disabled = suppressions.file(entry.rule.id)\n        ?? suppressions.at(entry.rule.id, reportLine(first, target))\n      if (disabled) {\n        if (entry.rule.category === 'requirement') {\n          results.checks[entry.rule.id] = toSuppressedResult(disabled, target)\n        }\n        continue\n      }\n    }\n\n    bucket(entry.rule)[entry.rule.id] = first\n      ? toCheckResult(first, target, parsed.source)\n      : { status: 'pass' as const }\n  }\n\n  return results\n}\n\n/** Rules that move the score, in report order. */\nexport const REQUIREMENTS: readonly RequirementRule[] = RULES.filter(\n  (rule): rule is RequirementRule => rule.category === 'requirement',\n)\n\n/** Rules that suggest going further, in report order. */\nexport const OPPORTUNITIES: readonly OpportunityRule[] = RULES.filter(\n  (rule): rule is OpportunityRule => rule.category === 'opportunity',\n)\n\n/** Whether a rule registered anything beyond the end-of-pass hook. */\nfunction hasNodeListeners(listeners: RuleListeners): boolean {\n  return Object.keys(listeners).some(key => key !== 'onEnd')\n}\n\nexport { HANDLER_KINDS } from './types'\nexport type {\n  FixSlot,\n  FrameworkCapabilities,\n  MapRule,\n  OpportunityRule,\n  RequirementRule,\n  RuleContext,\n  RuleListeners,\n  RuleTarget,\n  SuggestContext,\n} from './types'\n","import type { FileFacts } from './facts'\nimport type { RawRouteEntry, Sensitivity } from './types'\n\nconst MONEY_IMPORTS = ['stripe', '@stripe/stripe-js', 'paddle-sdk', '@lemonsqueezy/lemonsqueezy.js']\nconst AUTH_IMPORTS = ['better-auth', 'next-auth', 'lucia', '@auth/core', '@auth/nextjs']\n\nconst MONEY_TERMS = ['checkout', 'payment', 'billing', 'invoice', 'refund', 'subscription', 'charge', 'payout']\nconst AUTH_TERMS = ['auth', 'oauth', 'login', 'logout', 'signin', 'signup', 'register', 'password', 'token', 'session', 'mfa', 'otp']\n\n/**\n * Whole-word matcher per term, allowing a plural.\n *\n * Anchoring matters more than it looks: the previous patterns were plain\n * substrings, so `/api/authors` was classified as authentication and `/api/blog`\n * escaped only by luck. A route wrongly marked sensitive is handed a 25-point\n * audit requirement it has no reason to satisfy, and counts double in the global\n * score — the fastest way to make the whole number untrustworthy.\n *\n * Compiled once at load: the term lists are constants, so rebuilding twenty\n * expressions for every entry point buys nothing.\n */\nfunction compileTerms(terms: readonly string[]): ReadonlyArray<readonly [string, RegExp]> {\n  return terms.map(term => [term, new RegExp(`(?:^|[^a-z0-9])${term}s?(?:[^a-z0-9]|$)`, 'i')] as const)\n}\n\nconst MONEY_PATTERNS = compileTerms(MONEY_TERMS)\nconst AUTH_PATTERNS = compileTerms(AUTH_TERMS)\n\nfunction matchTerm(path: string, patterns: ReadonlyArray<readonly [string, RegExp]>): string | null {\n  for (const [term, pattern] of patterns) {\n    if (pattern.test(path)) return term\n  }\n  return null\n}\n\nconst PII_FIELDS = /email|phone|address|ssn|iban/i\nconst WRITE_CALLS = ['create', 'update', 'insert', 'upsert']\n\n/** Whether a package is imported, allowing for subpath imports. */\nfunction importsPackage(facts: FileFacts, pkg: string): boolean {\n  for (const source of facts.imports.values()) {\n    if (source === pkg || source.startsWith(`${pkg}/`)) return true\n  }\n  return false\n}\n\n/**\n * Sensitivity classification (money / auth / PII) for one entry point.\n *\n * Reads resolved imports and the identifiers actually present in the AST rather\n * than searching the raw source text. Substring matching on source could not\n * tell an import apart from a comment, so a `// TODO: drop stripe` was enough\n * to mark a route as handling money.\n */\nexport function classifySensitivity(route: RawRouteEntry, facts: FileFacts): Sensitivity {\n  const reasons: string[] = []\n  const path = route.path.toLowerCase()\n\n  for (const pkg of MONEY_IMPORTS) {\n    if (importsPackage(facts, pkg)) reasons.push(`money: imports ${pkg}`)\n  }\n  const moneyTerm = matchTerm(path, MONEY_PATTERNS)\n  if (moneyTerm) reasons.push(`money: path says \"${moneyTerm}\"`)\n\n  for (const pkg of AUTH_IMPORTS) {\n    if (importsPackage(facts, pkg)) reasons.push(`auth: imports ${pkg}`)\n  }\n  const authTerm = matchTerm(path, AUTH_PATTERNS)\n  if (authTerm) reasons.push(`auth: path says \"${authTerm}\"`)\n\n  const touchesPii = [...facts.names].some(name => PII_FIELDS.test(name))\n  const writes = facts.calls.some(call => WRITE_CALLS.includes(call.member.toLowerCase()))\n  if (touchesPii && writes) {\n    reasons.push('pii: write operation with sensitive fields')\n  }\n\n  const hasMoney = reasons.some(reason => reason.startsWith('money:'))\n  const hasAuth = reasons.some(reason => reason.startsWith('auth:'))\n  const hasPii = reasons.some(reason => reason.startsWith('pii:'))\n\n  if (hasMoney || hasAuth) return { level: 'high', reasons }\n  if (hasPii) return { level: 'medium', reasons }\n  return { level: 'none', reasons: [] }\n}\n\n/** One-character marker for the report's route lines, empty when not sensitive. */\nexport function sensitivityBadge(sensitivity: Sensitivity): string {\n  return BADGES[sensitivityLabel(sensitivity)] ?? ''\n}\n\nconst BADGES: Record<string, string> = { money: '$', auth: 'A', pii: 'o' }\n\n/** What makes this entry point sensitive — `money`, `auth`, `pii`, or nothing. */\nexport function sensitivityLabel(sensitivity: Sensitivity): 'money' | 'auth' | 'pii' | '' {\n  if (sensitivity.reasons.some(reason => reason.startsWith('money:'))) return 'money'\n  if (sensitivity.reasons.some(reason => reason.startsWith('auth:'))) return 'auth'\n  if (sensitivity.level === 'medium') return 'pii'\n  return ''\n}\n","import type { CheckId, CheckResult, RouteEntry } from './types'\nimport { isInfrastructureRoute } from './exemptions'\nimport { REQUIREMENTS, getRule } from './rules/index'\n\n/** Fallback weight for a rule id that is not in the registry. */\nconst UNKNOWN_WEIGHT = 10\n\n/**\n * Score one entry point from its requirement results.\n *\n * Opportunities are deliberately unreachable from here: they live in\n * `route.suggestions`, and their type carries no weight to subtract.\n */\nexport function scoreRoute(checks: Partial<Record<CheckId, CheckResult>>): number {\n  let score = 100\n  for (const [id, result] of Object.entries(checks) as [CheckId, CheckResult][]) {\n    if (result.status !== 'fail') continue\n    const rule = getRule(id)\n    if (rule && rule.category !== 'requirement') continue\n    score -= rule?.category === 'requirement' ? rule.weight : UNKNOWN_WEIGHT\n  }\n  return Math.max(0, score)\n}\n\n/**\n * Weighted average of the per-entry scores.\n *\n * The weights say which entry points the number should follow: a sensitive\n * handler counts double, a page counts half. Page wins when both apply — a page\n * that touches money is still a page, and its own rule set is thinner, so\n * letting it weigh double would drag the project score on the strength of one\n * check.\n *\n * Exempt entries are left out entirely. Every rule is `n/a` for them, so they\n * score a free 100, and averaging those in would let a project of static pages\n * report a high score while its handlers are dark — the report already counts\n * them apart from real coverage, and the number has to agree with it.\n */\nexport function scoreGlobal(routes: RouteEntry[]): number {\n  const scored = routes.filter(route => classifyRouteObservability(route) !== 'exempt')\n  if (scored.length === 0) return 100\n\n  let totalWeight = 0\n  let weightedSum = 0\n\n  for (const route of scored) {\n    let weight = 1\n    if (route.sensitivity.level === 'high') weight = 2\n    if (route.kind === 'page') weight = 0.5\n\n    totalWeight += weight\n    weightedSum += route.score * weight\n  }\n\n  return Math.round(weightedSum / totalWeight)\n}\n\n/** Grade band a score falls into, at 90 / 70 / 50. */\nexport function gradeFromScore(score: number): 'excellent' | 'good' | 'needs-work' | 'at-risk' {\n  if (score >= 90) return 'excellent'\n  if (score >= 70) return 'good'\n  if (score >= 50) return 'needs-work'\n  return 'at-risk'\n}\n\n/**\n * How much of an entry point the map can actually see.\n *\n * `exempt` covers both evlog's own plumbing and entry points with nothing to\n * instrument; neither belongs in the unobserved tally, because neither is a gap\n * anyone should close.\n */\nexport function classifyRouteObservability(route: RouteEntry): 'instrumented' | 'partial' | 'dark' | 'exempt' {\n  if (isInfrastructureRoute(route)) return 'exempt'\n\n  const { 'wide-event': wide, context } = route.checks\n\n  if (route.kind === 'page') {\n    const pageErr = route.checks['page-error-handling']\n    if (pageErr?.status === 'pass') return 'instrumented'\n    /* A page that fetches nothing has nothing to log: its rule reports `n/a`,\n       and calling that dark would show a static page as an observability gap. */\n    if (!pageErr || pageErr.status === 'n/a') return 'exempt'\n    return 'dark'\n  }\n\n  if (wide?.status === 'pass' && context?.status === 'pass') return 'instrumented'\n  if (wide?.status === 'pass' || context?.status === 'pass') return 'partial'\n  return 'dark'\n}\n\n/** Compact per-rule status for terminal display, e.g. \"logger ✓  context ✓  audit ✗\". */\nexport function routeCheckChips(route: RouteEntry): string | null {\n  const relevant = Object.entries(route.checks).filter(([, r]) => r?.status !== 'n/a') as [CheckId, CheckResult][]\n  if (relevant.length === 0) return null\n\n  const parts = relevant.map(([id, result]) => {\n    const label = getRule(id)?.title ?? id\n    const mark = result.status === 'pass' ? '✓' : '✗'\n    return `${label} ${mark}`\n  })\n\n  return parts.join('  ')\n}\n\n/** The one line to show next to an entry point: its heaviest unmet requirement. */\nexport function topIssue(route: RouteEntry): string {\n  const chips = routeCheckChips(route)\n  const observability = classifyRouteObservability(route)\n\n  if (observability === 'instrumented') {\n    const failed = (Object.entries(route.checks) as [CheckId, CheckResult | undefined][])\n      .filter(([, c]) => c?.status === 'fail')\n    if (failed.length === 0) return 'ok'\n    const [id, check] = failed[0]!\n    if (id === 'audit') {\n      return `gap: ${check?.message ?? 'missing audit'}`\n    }\n    return check?.message ?? id\n  }\n\n  if (observability === 'partial') {\n    return chips ?? 'partial instrumentation'\n  }\n\n  /* Registry order is report order: the heaviest gap is named first. */\n  for (const rule of REQUIREMENTS) {\n    const check = route.checks[rule.id]\n    if (check?.status === 'fail') {\n      return check.message ?? rule.id\n    }\n  }\n  return chips ?? 'ok'\n}\n","import { join } from 'node:path'\nimport { version as CLI_VERSION } from '../../../package.json'\nimport { getAdapter } from './adapters/index'\nimport { countSuppressed } from './directives'\nimport { buildFileFacts } from './facts'\nimport { createParseCache, parseFile } from './parse'\nimport { collectProjectFacts, readPackageJson } from './project-facts'\nimport type { ProjectFacts } from './project-facts'\nimport { RULE_SET_VERSION, getRule, runRules } from './rules/index'\nimport type { FrameworkCapabilities } from './rules/index'\nimport { classifySensitivity } from './sensitivity'\nimport { classifyRouteObservability, gradeFromScore, scoreGlobal, scoreRoute } from './score'\nimport type {\n  CheckId,\n  CheckResult,\n  MapFile,\n  ProjectSuggestion,\n  RawRouteEntry,\n  RouteEntry,\n  ScanContext,\n  ScanResult,\n} from './types'\nimport { routeId } from './utils'\n\ninterface AnalyseInput {\n  ctx: ScanContext\n  raw: RawRouteEntry\n  project: ProjectFacts\n  capabilities: FrameworkCapabilities\n}\n\n/**\n * Analyse one entry point: read it once, derive the facts, classify\n * sensitivity from those facts, then run the rules against them.\n *\n * Sensitivity has to come before the rules because `audit` is gated on it.\n */\nfunction analyseRoute(input: AnalyseInput): { route: RouteEntry, warnings: string[] } {\n  const { ctx, raw, project, capabilities } = input\n  const parsed = (ctx.parse ?? parseFile)(join(ctx.projectRoot, raw.file))\n  const facts = parsed\n    ? buildFileFacts(parsed, {\n      evlogAutoImports: capabilities.evlogAutoImports,\n      evlogBarrels: project.evlogBarrels,\n    })\n    : null\n\n  if (parsed && parsed.errors.length > 0 && ctx.verbose) {\n    console.warn(`Parse warnings in ${raw.file}: ${parsed.errors.join(', ')}`)\n  }\n\n  const sensitivity = facts\n    ? classifySensitivity(raw, facts)\n    : { level: 'none' as const, reasons: [] }\n  const { checks, suggestions, warnings } = runRules({\n    ctx,\n    target: { ...raw, sensitivity },\n    parsed,\n    facts,\n    project,\n    capabilities,\n  })\n\n  return {\n    route: {\n      ...raw,\n      id: routeId(raw),\n      checks,\n      suggestions,\n      sensitivity,\n      score: scoreRoute(checks),\n    },\n    warnings,\n  }\n}\n\n/** Extract entry points for `ctx.framework`, run the rules, and score them. */\nexport async function scan(input: ScanContext): Promise<ScanResult> {\n  /* One parser for the whole run: the adapter and the analysis below read the\n     same files, and Next emits one entry per exported method. */\n  const ctx: ScanContext = { ...input, parse: input.parse ?? createParseCache() }\n  const adapter = getAdapter(ctx.framework)\n  const capabilities: FrameworkCapabilities = {\n    requestLogger: adapter.resolveRequestLogger?.(ctx) ?? adapter.requestLogger,\n    evlogAutoImports: adapter.evlogAutoImports ?? [],\n  }\n\n  const project = collectProjectFacts(ctx, {\n    packageJson: readPackageJson(ctx.projectRoot),\n    evlogAutoImports: capabilities.evlogAutoImports,\n  })\n\n  const rawRoutes = await adapter.extractRoutes(ctx)\n  const analysed = rawRoutes.map(raw => analyseRoute({ ctx, raw, project, capabilities }))\n  const routes = analysed.map(entry => entry.route)\n  const warnings = analysed.flatMap(entry => entry.warnings)\n  const suggestions = hoistProjectSuggestions(routes)\n\n  const globalScore = scoreGlobal(routes)\n\n  const tally = { instrumented: 0, partial: 0, dark: 0, exempt: 0, suppressedChecks: 0 }\n  for (const route of routes) {\n    tally[classifyRouteObservability(route)]++\n    tally.suppressedChecks += countSuppressed(route)\n  }\n\n  const map: MapFile = {\n    version: 1,\n    generatedAt: new Date().toISOString(),\n    cliVersion: CLI_VERSION,\n    ruleSetVersion: RULE_SET_VERSION,\n    framework: ctx.framework,\n    projectName: ctx.projectName,\n    score: globalScore,\n    routes,\n  }\n\n  return {\n    map,\n    grade: gradeFromScore(globalScore),\n    summary: tally,\n    project,\n    suggestions,\n    warnings,\n  }\n}\n\n/**\n * Move project-scoped suggestions off the routes and into one list.\n *\n * Installing `evlog/better-auth` is a single edit, so leaving a copy on every\n * entry point where auth is in play would make the report claim there are five\n * things to do. The first entry point that raised it keeps the evidence, which\n * is where the reader should look first.\n */\nfunction hoistProjectSuggestions(routes: RouteEntry[]): ProjectSuggestion[] {\n  const hoisted = new Map<CheckId, ProjectSuggestion>()\n\n  for (const route of routes) {\n    for (const [id, result] of Object.entries(route.suggestions) as [CheckId, CheckResult][]) {\n      const rule = getRule(id)\n      if (rule?.category !== 'opportunity' || rule.scope !== 'project') continue\n      delete route.suggestions[id]\n      if (hoisted.has(id) || result.status !== 'fail') continue\n      hoisted.set(id, {\n        id,\n        message: result.message ?? rule.question,\n        evidence: result.evidence,\n      })\n    }\n  }\n\n  return [...hoisted.values()]\n}\n","import { collectProjectFacts, readPackageJson } from '../map/project-facts'\nimport type { ProjectFacts } from '../map/project-facts'\nimport { createParseCache } from '../map/parse'\nimport { scan } from '../map/scan'\nimport type { Framework, RouteEntry, ScanContext } from '../map/types'\n\n/** What `init` learned by reading the project, before it offers anything. */\nexport interface ProjectInsight {\n  facts: ProjectFacts\n  /** Sensitive entry points whose audit check failed — the audit catalog seeds. */\n  auditGaps: AuditGap[]\n  /** Errors written out identically in more than one file. */\n  repeatedErrors: RepeatedErrorSeed[]\n}\n\nexport interface AuditGap {\n  /** Route path as scanned, e.g. `/api/payments/refund`. */\n  path: string\n  method: string | null\n  file: string\n  /** Why the classifier flagged it — `money`, `auth`, `pii`. */\n  reasons: string[]\n}\n\nexport interface RepeatedErrorSeed {\n  /** Catalog key, derived from the error's own words: `CARD_DECLINED`. */\n  key: string\n  status?: number\n  message: string\n  /** The `why` the code already wrote, when it wrote one. */\n  why?: string\n  files: readonly string[]\n}\n\n/**\n * Run the `map` analysis for `init`'s benefit.\n *\n * The same code path rather than an approximation: two analyses that disagree\n * would have `init` offering to fix something `map` does not report. Returns\n * `null` when the scan cannot run — a project too broken to parse should still\n * be able to install evlog.\n */\nexport async function readProject(projectRoot: string, framework: Framework, projectName: string): Promise<ProjectInsight | null> {\n  const context: ScanContext = {\n    projectRoot,\n    framework,\n    projectName,\n    hasEvlog: true,\n    verbose: false,\n    parse: createParseCache(),\n  }\n\n  try {\n    const result = await scan(context)\n    const facts = collectProjectFacts(context, { packageJson: readPackageJson(projectRoot) })\n\n    return {\n      facts,\n      auditGaps: result.map.routes.filter(isAuditGap).map(toAuditGap),\n      repeatedErrors: toErrorSeeds(facts),\n    }\n  } catch {\n    return null\n  }\n}\n\nfunction isAuditGap(route: RouteEntry): boolean {\n  return route.checks.audit?.status === 'fail'\n}\n\nfunction toAuditGap(route: RouteEntry): AuditGap {\n  return {\n    path: route.path,\n    method: route.method,\n    file: route.file,\n    // `money: path says \"checkout\"` → `money`.\n    reasons: [...new Set(route.sensitivity.reasons.map(reason => reason.split(':')[0]!.trim()))],\n  }\n}\n\n/**\n * Turn the scan's repeated-error signatures into catalog entries.\n *\n * The signature is `status=402|message=Card declined`, built from the literal\n * fields of the calls themselves — so the catalog holds the project's own errors.\n */\nfunction toErrorSeeds(facts: ProjectFacts): RepeatedErrorSeed[] {\n  const seeds: RepeatedErrorSeed[] = []\n  const used = new Set<string>()\n\n  for (const [signature, repeated] of facts.repeatedErrors) {\n    const fields = parseSignature(signature)\n    const message = fields.message ?? fields.why ?? repeated.label\n    const key = uniqueKey(catalogKey(fields.code ?? message), used)\n    used.add(key)\n\n    const status = Number(fields.status ?? fields.statusCode)\n    // Carry over the prose the code already has rather than a TODO.\n    seeds.push({\n      key,\n      status: Number.isInteger(status) ? status : undefined,\n      message,\n      why: fields.why,\n      files: repeated.files,\n    })\n  }\n\n  return seeds.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : 0))\n}\n\nfunction parseSignature(signature: string): Record<string, string> {\n  const fields: Record<string, string> = {}\n  for (const part of signature.split('|')) {\n    const separator = part.indexOf('=')\n    if (separator === -1) continue\n    fields[part.slice(0, separator)] = part.slice(separator + 1)\n  }\n  return fields\n}\n\n/** `Card declined` → `CARD_DECLINED`, shaped to be a valid identifier. */\nfunction catalogKey(source: string): string {\n  const key = source\n    .replace(/[^a-z0-9]+/gi, '_')\n    .replace(/^_+|_+$/g, '')\n    .toUpperCase()\n    .split('_')\n    .filter(Boolean)\n    .slice(0, 4)\n    .join('_')\n  if (key.length === 0) return 'UNNAMED_ERROR'\n  return /^[0-9]/.test(key) ? `E_${key}` : key\n}\n\nfunction uniqueKey(key: string, used: Set<string>): string {\n  if (!used.has(key)) return key\n  let suffix = 2\n  while (used.has(`${key}_${suffix}`)) suffix++\n  return `${key}_${suffix}`\n}\n\n/** `/api/payments/refund` + POST → `payments.refund.created`, an audit action name. */\nexport function auditActionName(gap: AuditGap): string {\n  const segments = gap.path\n    .split('/')\n    .filter(segment => segment.length > 0 && segment !== 'api' && !segment.startsWith(':') && !segment.startsWith('['))\n  const resource = segments.slice(-2).join('.') || 'resource'\n  const verb = VERBS[gap.method ?? ''] ?? 'accessed'\n  return `${resource}.${verb}`\n}\n\nconst VERBS: Record<string, string> = {\n  POST: 'created',\n  PUT: 'updated',\n  PATCH: 'updated',\n  DELETE: 'deleted',\n  GET: 'accessed',\n  HEAD: 'accessed',\n}\n","import { readFileSync } from 'node:fs'\nimport type { Node, Program } from 'oxc-parser'\nimport { parseSource } from '../map/parse'\n\n/**\n * Offset-based edits to an existing config file.\n *\n * Locate the node with oxc, splice text at its offsets, leave every other byte\n * alone. Nothing here reprints the AST — a config that comes back reformatted\n * is a worse outcome than a step the user finishes by hand.\n */\nexport interface ConfigFile {\n  path: string\n  source: string\n  program: Program\n}\n\ntype ObjectNode = Node & { type: 'ObjectExpression', properties: Node[] }\ntype ArrayNode = Node & { type: 'ArrayExpression', elements: (Node | null)[] }\n\nfunction offsets(node: Node): { start: number, end: number } {\n  const anyNode = node as unknown as { start: number, end: number }\n  return { start: anyNode.start, end: anyNode.end }\n}\n\n/** Parse a config file for editing; `null` when unreadable or unparseable. */\nexport function readConfig(path: string): ConfigFile | null {\n  let source: string\n  try {\n    source = readFileSync(path, 'utf8')\n  } catch {\n    return null\n  }\n  const parsed = parseSource(path, source)\n  if (!parsed || parsed.errors.length > 0) return null\n  return { path, source, program: parsed.program }\n}\n\nfunction propertyName(prop: Node): string | null {\n  if (prop.type !== 'Property') return null\n  const { key } = prop as unknown as { key: Node }\n  if (key.type === 'Identifier') return (key as unknown as { name: string }).name\n  if (key.type === 'Literal') return String((key as unknown as { value: unknown }).value)\n  return null\n}\n\n/** The exported object literal, wrapped (`defineNuxtConfig({…})`) or bare. */\nexport function findConfigObject(program: Program): ObjectNode | null {\n  for (const statement of program.body as Node[]) {\n    if (statement.type !== 'ExportDefaultDeclaration') continue\n    const { declaration } = (statement as unknown as { declaration: Node })\n    if (declaration.type === 'ObjectExpression') return declaration as ObjectNode\n    if (declaration.type === 'CallExpression') {\n      const [argument] = (declaration as unknown as { arguments: Node[] }).arguments\n      if (argument?.type === 'ObjectExpression') return argument as ObjectNode\n    }\n  }\n  return null\n}\n\n/** Property value on an object literal, by key. */\nexport function getProperty(object: ObjectNode, name: string): Node | null {\n  for (const prop of object.properties) {\n    if (propertyName(prop) === name) return (prop as unknown as { value: Node }).value\n  }\n  return null\n}\n\n/** Whether an object literal already declares `name`. */\nexport function hasProperty(object: ObjectNode, name: string): boolean {\n  return object.properties.some(prop => propertyName(prop) === name)\n}\n\n/** Whether the file already imports anything from `specifier`. */\nexport function hasImportFrom(program: Program, specifier: string): boolean {\n  return (program.body as Node[]).some((statement) => {\n    if (statement.type !== 'ImportDeclaration') return false\n    const { source } = (statement as unknown as { source: { value: string } })\n    return source.value === specifier\n  })\n}\n\n/** Textual on purpose: `'evlog/nuxt'` and `evlog({…})` are both \"already wired\". */\nexport function arrayMentions(source: string, array: ArrayNode, needle: string): boolean {\n  return array.elements.some((element) => {\n    if (!element) return false\n    const { start, end } = offsets(element)\n    return source.slice(start, end).includes(needle)\n  })\n}\n\n/** Indentation of the line containing `offset`. */\nfunction indentAt(source: string, offset: number): string {\n  const lineStart = source.lastIndexOf('\\n', offset - 1) + 1\n  const match = source.slice(lineStart, offset).match(/^[\\t ]*/)\n  return match?.[0] ?? ''\n}\n\n/** One unit of indentation, as this file spells it (tabs vs. spaces). */\nfunction indentUnit(source: string): string {\n  const match = source.match(/\\n([\\t ]+)\\S/)\n  const found = match?.[1] ?? '  '\n  return found.startsWith('\\t') ? '\\t' : ' '.repeat(Math.min(found.length, 4))\n}\n\n/** Text to insert at a byte offset — the only edit this module ever makes. */\nexport interface Splice {\n  /** Byte offset in the original source. */\n  at: number\n  text: string\n}\n\n/**\n * Where a new sibling goes after `lastEnd`, and whether a comma is owed.\n *\n * Inserting at the end of the last element puts the new text *before* an\n * existing `,`, which produces `}, ,` — the point has to move past it.\n */\nfunction afterLast(source: string, lastEnd: number, containerEnd: number): { at: number, needsComma: boolean } {\n  const between = source.slice(lastEnd, containerEnd - 1)\n  const comma = between.indexOf(',')\n  const onlyWhitespaceBefore = comma !== -1 && between.slice(0, comma).trim().length === 0\n  return onlyWhitespaceBefore\n    ? { at: lastEnd + comma + 1, needsComma: false }\n    : { at: lastEnd, needsComma: true }\n}\n\n/** Apply splices to a source string, right to left so offsets stay valid. */\nexport function applySplices(source: string, splices: Splice[]): string {\n  return [...splices]\n    .sort((a, b) => b.at - a.at)\n    .reduce((text, splice) => text.slice(0, splice.at) + splice.text + text.slice(splice.at), source)\n}\n\n/** Splice that appends `entry` as the last element of `array`. */\nexport function appendToArray(source: string, array: ArrayNode, entry: string): Splice {\n  const { start, end } = offsets(array)\n  const last = array.elements.filter(Boolean).at(-1)\n\n  if (!last) {\n    const inner = source.slice(start + 1, end - 1)\n    // An array written on one line stays on one line.\n    if (!inner.includes('\\n')) return { at: end - 1, text: entry }\n    const indent = indentAt(source, start) + indentUnit(source)\n    return { at: end - 1, text: `${indent}${entry},\\n${indentAt(source, start)}` }\n  }\n\n  const { at, needsComma } = afterLast(source, offsets(last).end, end)\n  const multiline = source.slice(start, end).includes('\\n')\n\n  if (!multiline) return { at, text: `${needsComma ? ', ' : ' '}${entry}` }\n\n  const indent = indentAt(source, offsets(last).start)\n  return { at, text: `${needsComma ? ',' : ''}\\n${indent}${entry}` }\n}\n\n/** Splice that appends `key: value` as the last property of `object`. */\nexport function appendProperty(source: string, object: ObjectNode, text: string): Splice {\n  const { start, end } = offsets(object)\n  const last = object.properties.at(-1)\n  const indent = last ? indentAt(source, offsets(last).start) : indentAt(source, start) + indentUnit(source)\n\n  if (!last) {\n    const inner = source.slice(start + 1, end - 1)\n    if (inner.trim().length === 0 && !inner.includes('\\n')) {\n      return { at: end - 1, text: `\\n${indent}${text},\\n${indentAt(source, start)}` }\n    }\n    return { at: end - 1, text: `${indent}${text},\\n` }\n  }\n\n  const { at, needsComma } = afterLast(source, offsets(last).end, end)\n  return { at, text: `${needsComma ? ',' : ''}\\n${indent}${text},` }\n}\n\n/** Splice that adds an import statement after the last existing one. */\nexport function addImport(source: string, program: Program, statement: string): Splice {\n  const imports = (program.body as Node[]).filter(node => node.type === 'ImportDeclaration')\n  const last = imports.at(-1)\n  if (last) return { at: offsets(last).end, text: `\\n${statement}` }\n  return { at: 0, text: `${statement}\\n` }\n}\n\nexport type { ArrayNode, ObjectNode }\n\n/** The `createEvlog({ … })` options object — {@link findConfigObject} does not reach it. */\nexport function findCreateEvlogCall(program: Program): ObjectNode | null {\n  let found: ObjectNode | null = null\n\n  const visit = (node: Node): void => {\n    if (found || !node || typeof node !== 'object') return\n\n    if (node.type === 'CallExpression') {\n      const call = node as unknown as { callee: Node, arguments: Node[] }\n      const callee = call.callee as unknown as { type: string, name?: string }\n      if (callee.type === 'Identifier' && callee.name === 'createEvlog') {\n        const [argument] = call.arguments\n        if (argument?.type === 'ObjectExpression') {\n          found = argument as ObjectNode\n          return\n        }\n      }\n    }\n\n    for (const value of Object.values(node as unknown as Record<string, unknown>)) {\n      if (Array.isArray(value)) value.forEach(entry => visit(entry as Node))\n      else if (value && typeof value === 'object' && 'type' in value) visit(value as Node)\n    }\n  }\n\n  visit(program as unknown as Node)\n  return found\n}\n\n/** Offset just past the last import statement — where a preamble belongs. */\nexport function importsEnd(source: string, program: Program): number {\n  const imports = (program.body as Node[]).filter(node => node.type === 'ImportDeclaration')\n  const last = imports.at(-1)\n  return last ? offsets(last).end : 0\n}\n","import { existsSync, readFileSync } from 'node:fs'\nimport { join, relative } from 'node:path'\nimport type { Framework } from '../map/types'\nimport { findDestination, findEnricher, findSamplingPreset } from './catalog'\nimport type { DrainId, EnricherId, ExtraId, SamplingProfile } from './catalog'\nimport { auditActionName } from './insight'\nimport type { AuditGap, RepeatedErrorSeed } from './insight'\nimport {\n  addImport,\n  appendProperty,\n  appendToArray,\n  applySplices,\n  arrayMentions,\n  findConfigObject,\n  findCreateEvlogCall,\n  getProperty,\n  importsEnd,\n  hasImportFrom,\n  hasProperty,\n  readConfig,\n} from './edit'\nimport type { ArrayNode, ObjectNode, Splice } from './edit'\n\n/** A file `init` will write — always the full new contents, never a patch. */\nexport interface FileAction {\n  path: string\n  relative: string\n  kind: 'create' | 'patch'\n  contents: string\n}\n\n/** A step `init` will not do for you, with the code to paste and why. */\nexport interface ManualStep {\n  title: string\n  file: string\n  snippet: string\n  reason: string\n}\n\nexport interface WiringPlan {\n  actions: FileAction[]\n  manual: ManualStep[]\n  /** Wiring that is already in place — printed so the run is never silent. */\n  already: string[]\n}\n\n/**\n * Frameworks `init` can wire — the ones with a `frameworkPlan` case.\n *\n * `map` adapters can land ahead of init wiring: every init surface (flag\n * parsing, prompt, workspace targets, telemetry) reads this list so a map-only\n * framework is refused cleanly instead of reaching the planner.\n */\nexport const INIT_FRAMEWORKS = ['nuxt', 'nitro', 'next', 'tanstack-start', 'hono'] as const satisfies readonly Framework[]\n\nexport function isInitFramework(framework: Framework): boolean {\n  return (INIT_FRAMEWORKS as readonly Framework[]).includes(framework)\n}\n\nexport interface WiringInput {\n  /** Package root — where configs live and files are written. */\n  root: string\n  framework: Framework\n  service: string\n  /** Local sink: `fs` or `none`. */\n  devDrain: DrainId\n  /** Where production events go. Empty means nothing leaves the process. */\n  prodDrains: DrainId[]\n  /** Opt-in additions layered onto the drain and the config. */\n  extras: ExtraId[]\n  /** Which enrichers to wire, when the `enrichers` extra was selected. */\n  enrichers: EnricherId[]\n  /** Sampling preset, when the `sampling` extra was selected. */\n  sampling: SamplingProfile\n  /** Nitro major, when the framework is Nitro (`tanstack-start` is always v3). */\n  nitroMajor: 2 | 3\n  /** Seeds from the scan, when the catalog extras were selected. */\n  repeatedErrors: readonly RepeatedErrorSeed[]\n  auditGaps: readonly AuditGap[]\n}\n\n/** Every destination this run wires, dev and prod alike. */\nfunction allDrains(input: WiringInput): DrainId[] {\n  return [...new Set([input.devDrain, ...input.prodDrains])].filter(id => id !== 'none')\n}\n\n/** Whether a file already calls every drain factory this run would wire. */\nfunction wiresEveryDrain(path: string, input: WiringInput): boolean {\n  let source: string\n  try {\n    source = readFileSync(path, 'utf8')\n  } catch {\n    return false\n  }\n\n  return allDrains(input).every((id) => {\n    const factory = findDestination(id)?.factory\n    return factory ? source.includes(factory.replace('()', '')) : true\n  })\n}\n\n/** The same destination chosen for dev and production is one import, not two. */\nfunction dedupeDestinations<T extends { id: DrainId }>(destinations: T[]): T[] {\n  const seen = new Set<DrainId>()\n  return destinations.filter((destination) => {\n    if (seen.has(destination.id)) return false\n    seen.add(destination.id)\n    return true\n  })\n}\n\nfunction describeDrains(input: WiringInput): string {\n  const labels = allDrains(input).map(id => findDestination(id)?.label ?? id)\n  return labels.length > 0 ? labels.join(' and ') : 'the console'\n}\n\nfunction firstExisting(root: string, names: string[]): string | null {\n  for (const name of names) {\n    if (existsSync(join(root, name))) return join(root, name)\n  }\n  return null\n}\n\nconst CONFIG_EXTENSIONS = ['ts', 'mts', 'js', 'mjs']\n\nfunction configCandidates(base: string): string[] {\n  return CONFIG_EXTENSIONS.map(ext => `${base}.${ext}`)\n}\n\n/* ── nuxt ───────────────────────────────────────────────────────────────── */\n\nfunction nuxtConfigTemplate(input: WiringInput): string {\n  const sampling = samplingProperty(input)\n  return `export default defineNuxtConfig({\n  modules: ['evlog/nuxt'],\n  evlog: {\n    env: { service: '${input.service}' },${sampling ? `\\n    ${sampling},` : ''}\n  },\n})\n`\n}\n\nfunction planNuxt(input: WiringInput): WiringPlan {\n  const plan: WiringPlan = { actions: [], manual: [], already: [] }\n  const configPath = firstExisting(input.root, configCandidates('nuxt.config'))\n\n  if (!configPath) {\n    const path = join(input.root, 'nuxt.config.ts')\n    plan.actions.push({ path, relative: 'nuxt.config.ts', kind: 'create', contents: nuxtConfigTemplate(input) })\n    return withNitroPlugins(plan, input)\n  }\n\n  const relativePath = relative(input.root, configPath)\n  const config = readConfig(configPath)\n  const object = config ? findConfigObject(config.program) : null\n\n  if (!config || !object) {\n    plan.manual.push({\n      title: 'Register the Nuxt module',\n      file: relativePath,\n      snippet: `modules: ['evlog/nuxt'],\\nevlog: {\\n  env: { service: '${input.service}' },\\n},`,\n      reason: config ? 'the config does not export a plain object literal' : 'the config could not be parsed',\n    })\n    return withNitroPlugins(plan, input)\n  }\n\n  const splices: Splice[] = []\n  const modules = getProperty(object, 'modules')\n\n  if (modules?.type === 'ArrayExpression') {\n    if (arrayMentions(config.source, modules as ArrayNode, 'evlog/nuxt')) plan.already.push(`${relativePath} already registers evlog/nuxt`)\n    else splices.push(appendToArray(config.source, modules as ArrayNode, `'evlog/nuxt'`))\n  } else if (modules) {\n    plan.manual.push({\n      title: 'Register the Nuxt module',\n      file: relativePath,\n      snippet: `'evlog/nuxt'`,\n      reason: '`modules` is computed rather than an array literal',\n    })\n  } else {\n    splices.push(appendProperty(config.source, object, `modules: ['evlog/nuxt']`))\n  }\n\n  if (hasProperty(object, 'evlog')) {\n    plan.already.push(`${relativePath} already has an evlog block`)\n    const sampling = samplingProperty(input)\n    const block = getProperty(object, 'evlog')\n    if (sampling && block?.type === 'ObjectExpression') {\n      if (hasProperty(block as ObjectNode, 'sampling')) {\n        plan.manual.push({\n          title: 'Reconcile the sampling rates',\n          file: relativePath,\n          snippet: `${sampling},`,\n          reason: 'the evlog block already sets sampling — replacing rates you chose is not init\\'s call',\n        })\n      } else {\n        splices.push(appendProperty(config.source, block as ObjectNode, sampling))\n      }\n    } else if (sampling) {\n      plan.manual.push({\n        title: 'Add sampling to the evlog block',\n        file: relativePath,\n        snippet: `${sampling},`,\n        reason: 'the evlog block is not a plain object literal',\n      })\n    }\n  } else {\n    const sampling = samplingProperty(input)\n    splices.push(appendProperty(\n      config.source,\n      object,\n      `evlog: {\\n    env: { service: '${input.service}' },${sampling ? `\\n    ${sampling},` : ''}\\n  }`,\n    ))\n  }\n\n  if (splices.length > 0) {\n    plan.actions.push({\n      path: configPath,\n      relative: relativePath,\n      kind: 'patch',\n      contents: applySplices(config.source, splices),\n    })\n  }\n\n  return withNitroPlugins(plan, input)\n}\n\n/* ── nitro / tanstack start ─────────────────────────────────────────────── */\n\nfunction nitroModuleSpecifier(major: 2 | 3): string {\n  return major === 3 ? 'evlog/nitro/v3' : 'evlog/nitro'\n}\n\nfunction nitroConfigTemplate(input: WiringInput): string {\n  const sampling = samplingProperty(input)\n  const asyncContext = input.framework === 'tanstack-start'\n    ? '  experimental: {\\n    asyncContext: true,\\n  },\\n'\n    : ''\n\n  if (input.nitroMajor === 3) {\n    return `import { defineConfig } from 'nitro'\nimport evlog from 'evlog/nitro/v3'\n\nexport default defineConfig({\n${asyncContext}  modules: [\n    evlog({\n      env: { service: '${input.service}' },${sampling ? `\\n      ${sampling},` : ''}\n    }),\n  ],\n})\n`\n  }\n\n  return `import { defineNitroConfig } from 'nitropack/config'\nimport evlog from 'evlog/nitro'\n\nexport default defineNitroConfig({\n  modules: [\n    evlog({\n      env: { service: '${input.service}' },${sampling ? `\\n      ${sampling},` : ''}\n    }),\n  ],\n})\n`\n}\n\nfunction planNitro(input: WiringInput): WiringPlan {\n  const plan: WiringPlan = { actions: [], manual: [], already: [] }\n  const specifier = nitroModuleSpecifier(input.nitroMajor)\n  const configPath = firstExisting(input.root, configCandidates('nitro.config'))\n\n  if (!configPath) {\n    const path = join(input.root, 'nitro.config.ts')\n    plan.actions.push({ path, relative: 'nitro.config.ts', kind: 'create', contents: nitroConfigTemplate(input) })\n    return withTanstackNotes(withNitroPlugins(plan, input), input)\n  }\n\n  const relativePath = relative(input.root, configPath)\n  const config = readConfig(configPath)\n  const object = config ? findConfigObject(config.program) : null\n  const sampling = samplingProperty(input)\n  const moduleCall = `evlog({\\n      env: { service: '${input.service}' },${sampling ? `\\n      ${sampling},` : ''}\\n    })`\n\n  if (!config || !object) {\n    plan.manual.push({\n      title: 'Register the Nitro module',\n      file: relativePath,\n      snippet: `import evlog from '${specifier}'\\n\\n// inside the config:\\nmodules: [\\n  ${moduleCall},\\n],`,\n      reason: config ? 'the config does not export a plain object literal' : 'the config could not be parsed',\n    })\n    return withTanstackNotes(withNitroPlugins(plan, input), input)\n  }\n\n  const splices: Splice[] = []\n  const modules = getProperty(object, 'modules')\n  let needsImport = false\n\n  if (modules?.type === 'ArrayExpression') {\n    if (arrayMentions(config.source, modules as ArrayNode, 'evlog')) {\n      plan.already.push(`${relativePath} already registers the evlog module`)\n    } else {\n      splices.push(appendToArray(config.source, modules as ArrayNode, moduleCall))\n      needsImport = true\n    }\n  } else if (modules) {\n    plan.manual.push({\n      title: 'Register the Nitro module',\n      file: relativePath,\n      snippet: moduleCall,\n      reason: '`modules` is computed rather than an array literal',\n    })\n  } else {\n    splices.push(appendProperty(config.source, object, `modules: [\\n    ${moduleCall},\\n  ]`))\n    needsImport = true\n  }\n\n  if (needsImport && !hasImportFrom(config.program, specifier)) {\n    splices.push(addImport(config.source, config.program, `import evlog from '${specifier}'`))\n  }\n\n  if (input.framework === 'tanstack-start') {\n    /* `useRequest()` is how TanStack Start route handlers reach the logger, and\n       it returns nothing without async context — wiring the module without this\n       flag produces an install that looks complete and logs no business\n       context. */\n    const experimental = getProperty(object, 'experimental')\n    if (!experimental) {\n      splices.push(appendProperty(config.source, object, `experimental: {\\n    asyncContext: true,\\n  }`))\n    } else if (experimental.type === 'ObjectExpression' && !hasProperty(experimental as ObjectNode, 'asyncContext')) {\n      splices.push(appendProperty(config.source, experimental as ObjectNode, 'asyncContext: true'))\n    }\n  }\n\n  if (splices.length > 0) {\n    plan.actions.push({\n      path: configPath,\n      relative: relativePath,\n      kind: 'patch',\n      contents: applySplices(config.source, splices),\n    })\n  }\n\n  return withTanstackNotes(withNitroPlugins(plan, input), input)\n}\n\n/** The root route is a component file — splicing a middleware into it is guesswork. */\nfunction withTanstackNotes(plan: WiringPlan, input: WiringInput): WiringPlan {\n  if (input.framework !== 'tanstack-start') return plan\n\n  if (input.extras.includes('vite')) {\n    // The plugin order in vite.config.ts varies per template — cheaper to paste than to guess.\n    const viteConfig = firstExisting(input.root, configCandidates('vite.config'))\n    plan.manual.push({\n      title: 'Add the evlog Vite plugin',\n      file: viteConfig ? relative(input.root, viteConfig) : 'vite.config.ts',\n      snippet: `import evlog from 'evlog/vite'\n\nexport default defineConfig({\n  plugins: [\n    evlog(),\n    // …your existing plugins\n  ],\n})`,\n      reason: 'strips log.debug() from production builds and injects source locations',\n    })\n  }\n\n  const rootRoute = firstExisting(input.root, ['src/routes/__root.tsx', 'app/routes/__root.tsx'])\n  plan.manual.push({\n    title: 'Return structured errors from the root route',\n    file: rootRoute ? relative(input.root, rootRoute) : 'src/routes/__root.tsx',\n    snippet: `import { createMiddleware } from '@tanstack/react-start'\nimport { evlogErrorHandler } from 'evlog/nitro/v3'\n\nexport const Route = createRootRoute({\n  server: {\n    middleware: [createMiddleware().server(evlogErrorHandler)],\n  },\n})`,\n    reason: 'TanStack Start handles errors before Nitro, so createError() needs this middleware to keep why / fix / link',\n  })\n  return plan\n}\n\n/**\n * The Nitro drain plugin for the chosen destinations.\n *\n * Only the filesystem drain is gated on `import.meta.dev` — it writes files on\n * whatever box serves the request.\n */\nfunction nitroDrainTemplate(input: WiringInput): string | null {\n  const dev = input.devDrain === 'none' ? null : findDestination(input.devDrain) ?? null\n  const prod = input.prodDrains.map(id => findDestination(id)).filter(Boolean) as NonNullable<ReturnType<typeof findDestination>>[]\n  if (!dev && prod.length === 0) return null\n\n  const batched = input.extras.includes('pipeline') && prod.length > 0\n  const imports: string[] = []\n  if (batched) imports.push(`import type { DrainContext } from 'evlog'`)\n  /* Deduped by id: nothing stops the same destination being the local sink and\n     a production one, and importing its factory twice is a file that does not\n     compile. */\n  for (const destination of dedupeDestinations([...(dev ? [dev] : []), ...prod])) {\n    imports.push(`import { ${destination.factory!.replace('()', '')} } from '${destination.specifier}'`)\n  }\n  if (batched) imports.push(`import { createDrainPipeline } from 'evlog/pipeline'`)\n\n  const body: string[] = []\n  if (batched) {\n    body.push(`const pipeline = createDrainPipeline<DrainContext>({\n  batch: { size: 50, intervalMs: 5000 },\n  retry: { maxAttempts: 3 },\n})\n`)\n  }\n\n  // Batching wraps the network sends only, never the local write.\n  const wrap = (factory: string) => batched ? `pipeline(${factory})` : factory\n  const prodList = prod.map(destination => wrap(destination.factory!)).join(', ')\n\n  // One plugin branched on the environment, so the whole delivery story is in one place.\n  if (dev && prod.length > 0) {\n    body.push(`/**\n * Development writes to ${dev.label}; production sends to ${prod.map(d => d.label).join(' and ')}.\n${envComment(prod)} */\nconst drains = import.meta.dev\n  ? [${dev.factory}]\n  : [${prodList}]\n\nexport default defineNitroPlugin((nitroApp) => {\n  nitroApp.hooks.hook('evlog:drain', async (ctx) => {\n    await Promise.all(drains.map(drain => drain(ctx)))\n  })\n})\n`)\n  } else if (prod.length > 0) {\n    body.push(`/**\n * Wide events land in ${prod.map(d => d.label).join(' and ')}.\n${envComment(prod)} */\nconst drains = [${prodList}]\n\nexport default defineNitroPlugin((nitroApp) => {\n  nitroApp.hooks.hook('evlog:drain', async (ctx) => {\n    await Promise.all(drains.map(drain => drain(ctx)))\n  })\n})\n`)\n  } else {\n    body.push(`/**\n * Local wide-event sink — NDJSON under .evlog/logs.\n */\nconst drain = ${dev!.factory}\n\nexport default defineNitroPlugin((nitroApp) => {\n  // Local files are a development convenience — never a production sink.\n  if (!import.meta.dev) return\n  nitroApp.hooks.hook('evlog:drain', drain)\n})\n`)\n  }\n\n  return `${imports.join('\\n')}\\n\\n${body.join('\\n')}`\n}\n\nfunction envComment(destinations: { env: { name: string }[] }[]): string {\n  const names = [...new Set(destinations.flatMap(d => d.env.map(v => v.name)))]\n  return names.length > 0 ? ` * Reads ${names.join(', ')} from the environment.\\n` : ''\n}\n\nfunction nitroEnricherTemplate(input: WiringInput): string {\n  const chosen = input.enrichers.map(id => findEnricher(id)).filter(Boolean)\n  const factories = chosen.map(enricher => enricher!.factory)\n  const names = [...factories].map(factory => factory.replace('()', '')).sort()\n\n  return `import {\n${names.map(name => `  ${name},`).join('\\n')}\n} from 'evlog/enrichers'\n\nconst enrichers = [\n${factories.map(factory => `  ${factory},`).join('\\n')}\n]\n\nexport default defineNitroPlugin((nitroApp) => {\n  nitroApp.hooks.hook('evlog:enrich', async (ctx) => {\n    for (const enrich of enrichers) await enrich(ctx)\n  })\n})\n`\n}\n\n/**\n * Add the Nitro-side plugins.\n *\n * An existing drain file is never rewritten; a destination it does not already\n * wire goes beside it under a name of its own.\n */\nfunction withNitroPlugins(plan: WiringPlan, input: WiringInput): WiringPlan {\n  const drain = nitroDrainTemplate(input)\n  if (drain) {\n    const preferred = join('server', 'plugins', 'evlog-drain.ts')\n    const path = join(input.root, preferred)\n\n    if (!existsSync(path)) {\n      plan.actions.push({ path, relative: preferred, kind: 'create', contents: drain })\n    } else if (wiresEveryDrain(path, input)) {\n      // Including the file this command wrote last time — this is what keeps it idempotent.\n      plan.already.push(`${preferred} already wires ${describeDrains(input)}`)\n    } else {\n      const suffix = allDrains(input).join('-') || 'extra'\n      const alternate = join('server', 'plugins', `evlog-drain-${suffix}.ts`)\n      const alternatePath = join(input.root, alternate)\n      if (existsSync(alternatePath)) {\n        plan.already.push(`${alternate} already exists`)\n      } else {\n        plan.actions.push({ path: alternatePath, relative: alternate, kind: 'create', contents: drain })\n        plan.already.push(`${preferred} left as it is — the new drain went to ${alternate}`)\n      }\n    }\n  }\n\n  if (input.extras.includes('enrichers') && input.enrichers.length > 0) {\n    const relativePath = join('server', 'plugins', 'evlog-enrich.ts')\n    const path = join(input.root, relativePath)\n    if (existsSync(path)) plan.already.push(`${relativePath} already exists`)\n    else plan.actions.push({ path, relative: relativePath, kind: 'create', contents: nitroEnricherTemplate(input) })\n  }\n\n  return plan\n}\n\n/** The `sampling` block for a module config, when the extra was selected. */\nfunction samplingProperty(input: WiringInput): string | null {\n  if (!input.extras.includes('sampling')) return null\n  const preset = findSamplingPreset(input.sampling)\n  if (!preset?.rates) return null\n  const { info, warn } = preset.rates\n  /* `error: 100` is stated rather than chosen, and `debug` is left out: an\n     unspecified level is kept in full. */\n  return `sampling: {\n      rates: { info: ${info}, warn: ${warn}, error: 100 },\n    }`\n}\n\n/* ── next ───────────────────────────────────────────────────────────────── */\n\nfunction nextInstrumentationTemplate(service: string): string {\n  return `import { defineNodeInstrumentation } from 'evlog/next/instrumentation'\n\nexport const { register, onRequestError } = defineNodeInstrumentation({\n  service: '${service}',\n  captureOutput: true,\n})\n`\n}\n\n/**\n * The pieces of a generated evlog config file — shared by Next's `lib/evlog.ts`\n * (create and patch paths) and Hono's `src/evlog.ts`, which are both plain\n * TypeScript rather than a framework config.\n */\ninterface FactoryParts {\n  imports: string[]\n  /** Statements that go above `createEvlog`. */\n  preamble: string\n  /** Option keys, each already indented and comma-terminated. */\n  options: string[]\n}\n\nfunction factoryParts(input: WiringInput): FactoryParts {\n  const dev = input.devDrain === 'none' ? null : findDestination(input.devDrain) ?? null\n  const prod = input.prodDrains.map(id => findDestination(id)).filter(Boolean) as NonNullable<ReturnType<typeof findDestination>>[]\n  const batched = input.extras.includes('pipeline') && prod.length > 0\n\n  const imports: string[] = []\n  if (batched) imports.push(`import type { DrainContext } from 'evlog'`)\n  /* Deduped by id: nothing stops the same destination being the local sink and\n     a production one, and importing its factory twice is a file that does not\n     compile. */\n  for (const destination of dedupeDestinations([...(dev ? [dev] : []), ...prod])) {\n    imports.push(`import { ${destination.factory!.replace('()', '')} } from '${destination.specifier}'`)\n  }\n  if (batched) imports.push(`import { createDrainPipeline } from 'evlog/pipeline'`)\n\n  const enrichers = input.extras.includes('enrichers')\n    ? input.enrichers.map(id => findEnricher(id)).filter(Boolean)\n    : []\n  if (enrichers.length > 0) {\n    const names = enrichers.map(enricher => enricher!.factory.replace('()', '')).sort()\n    imports.push(`import {\\n${names.map(name => `  ${name},`).join('\\n')}\\n} from 'evlog/enrichers'`)\n  }\n\n  const blocks: string[] = []\n  if (batched) {\n    blocks.push(`const pipeline = createDrainPipeline<DrainContext>({\\n  batch: { size: 50, intervalMs: 5000 },\\n  retry: { maxAttempts: 3 },\\n})`)\n  }\n\n  const wrap = (factory: string) => batched ? `pipeline(${factory})` : factory\n  const options: string[] = []\n\n  // Neither Next nor Hono has `import.meta.dev`, so the split is on NODE_ENV.\n  if (dev && prod.length > 0) {\n    blocks.push(`const drains = process.env.NODE_ENV === 'production'\\n  ? [${prod.map(d => wrap(d.factory!)).join(', ')}]\\n  : [${dev.factory}]`)\n    options.push('  drain: async ctx => void await Promise.all(drains.map(drain => drain(ctx))),')\n  } else if (prod.length > 0) {\n    blocks.push(`const drains = [${prod.map(d => wrap(d.factory!)).join(', ')}]`)\n    options.push('  drain: async ctx => void await Promise.all(drains.map(drain => drain(ctx))),')\n  } else if (dev) {\n    options.push('  // Local NDJSON under .evlog/logs — development only.')\n    options.push(`  drain: process.env.NODE_ENV === 'production' ? undefined : ${dev.factory},`)\n  }\n\n  if (enrichers.length > 0) {\n    blocks.push(`const enrichers = [\\n${enrichers.map(enricher => `  ${enricher!.factory},`).join('\\n')}\\n]`)\n    options.push('  enrich: async (ctx) => {\\n    for (const enrich of enrichers) await enrich(ctx)\\n  },')\n  }\n\n  const preset = input.extras.includes('sampling') ? findSamplingPreset(input.sampling) : undefined\n  if (preset?.rates) {\n    const { info, warn } = preset.rates\n    options.push(`  sampling: {\\n    rates: { info: ${info}, warn: ${warn}, error: 100 },\\n  },`)\n  }\n\n  return { imports, preamble: blocks.length > 0 ? `\\n${blocks.join('\\n\\n')}\\n` : '', options }\n}\n\nfunction nextLibTemplate(input: WiringInput): string {\n  const { imports, preamble, options } = factoryParts(input)\n  const all = [`import { createEvlog } from 'evlog/next'`, ...imports]\n\n  return `${all.join('\\n')}\n${preamble}\nexport const { withEvlog, useLogger, log, createError } = createEvlog({\n  service: '${input.service}',\n${options.join('\\n')}${options.length > 0 ? '\\n' : ''}})\n`\n}\n\n/**\n * Splice the chosen options into a `lib/evlog.ts` that is already there.\n *\n * Only works when the file actually calls `createEvlog({ … })`; a re-export\n * barrel or a computed config gets the snippet to paste instead.\n */\nfunction patchNextLib(plan: WiringPlan, input: WiringInput, path: string, relativePath: string): void {\n  const { imports, preamble, options } = factoryParts(input)\n  if (options.length === 0) {\n    plan.already.push(`${relativePath} already exists`)\n    return\n  }\n\n  const config = readConfig(path)\n  const call = config ? findCreateEvlogCall(config.program) : null\n\n  if (!config || !call) {\n    plan.manual.push({\n      title: 'Wire the destinations into your evlog factory',\n      file: relativePath,\n      snippet: `${imports.join('\\n')}\\n${preamble}\\ncreateEvlog({\\n${options.join('\\n')}\\n})`,\n      reason: `${relativePath} exists but does not call createEvlog({ … }) here — splicing into it would be guesswork`,\n    })\n    return\n  }\n\n  const present = ['drain', 'enrich', 'sampling'].filter(key => hasProperty(call, key))\n  if (present.length > 0) {\n    plan.manual.push({\n      title: 'Reconcile your evlog factory options',\n      file: relativePath,\n      snippet: options.join('\\n'),\n      reason: `${relativePath} already sets ${present.join(', ')} — replacing what you wrote is not init's call`,\n    })\n    return\n  }\n\n  const splices: Splice[] = [appendProperty(config.source, call, options.map(line => line.trim()).join('\\n  ').replace(/,$/, ''))]\n\n  /* One splice, not two: at the same offset the order between them is whatever\n     the sort happens to do. */\n  const missing = imports.filter((statement) => {\n    const specifier = statement.match(/from '([^']+)'/)?.[1]\n    return specifier && !hasImportFrom(config.program, specifier)\n  })\n\n  const head = [\n    missing.length > 0 ? `\\n${missing.join('\\n')}` : '',\n    preamble.trim().length > 0 ? `\\n\\n${preamble.trim()}` : '',\n  ].join('')\n\n  if (head.length > 0) {\n    splices.push({ at: importsEnd(config.source, config.program), text: head })\n  }\n\n  plan.actions.push({\n    path,\n    relative: relativePath,\n    kind: 'patch',\n    contents: applySplices(config.source, splices),\n  })\n}\n\n/* ── catalogs, seeded from the scan ─────────────────────────────────────── */\n\n/** An error catalog built from the project's own repeated errors. */\nfunction errorCatalogTemplate(input: WiringInput): string {\n  /* Keep the dashes in the wire prefix — `shop-api.CARD_DECLINED` reads, where\n     stripping them gives `shopapi`. The variable gets the camelCase spelling\n     because that is what an identifier has to be. */\n  const prefix = input.service.replace(/[^a-z0-9-]/gi, '-').replace(/-+/g, '-').replace(/^-|-$/g, '').toLowerCase() || 'app'\n  const identifier = `${prefix.replace(/-(.)/g, (_, char) => char.toUpperCase())}Errors`\n  const entries = input.repeatedErrors.map((seed) => {\n    const files = seed.files.slice(0, 3).join(', ')\n    const status = seed.status ? `\\n    status: ${seed.status},` : ''\n    const why = seed.why ? quote(seed.why) : `'TODO: what went wrong, in the reader\\\\'s terms'`\n    return `  /** Currently written inline in ${files}${seed.files.length > 3 ? ', …' : ''} */\n  ${objectKey(seed.key)}: {${status}\n    message: ${quote(seed.message)},\n    why: ${why},\n    fix: 'TODO: what they should do about it',\n  },`\n  })\n\n  return `import { defineErrorCatalog } from 'evlog'\n\n/**\n * Typed errors for ${input.service}.\n *\n * Seeded by \\`evlog init\\` from errors this project already repeats across\n * files. Fill in \\`why\\` and \\`fix\\` — they are what turn a stack trace into\n * something a reader, or an agent, can act on — then replace the inline\n * \\`createError\\` calls with \\`${identifier}.<KEY>()\\`.\n */\nexport const ${identifier} = defineErrorCatalog('${prefix}', {\n${entries.join('\\n')}\n})\n\ndeclare module 'evlog' {\n  interface RegisteredErrorCatalogs {\n    '${prefix}': typeof ${identifier}\n  }\n}\n`\n}\n\n/** Audit actions named after the sensitive routes the scan found without a trail. */\nfunction auditCatalogTemplate(input: WiringInput): string {\n  const seen = new Set<string>()\n  const entries = input.auditGaps.map((gap) => {\n    let name = auditActionName(gap)\n    while (seen.has(name)) name = `${name}2`\n    seen.add(name)\n\n    const constant = name.replace(/[^a-z0-9]+/gi, '_').toUpperCase()\n    const target = gap.path.split('/').filter(Boolean).at(-1)?.replace(/[^a-z0-9]/gi, '') || 'resource'\n    const why = gap.reasons.length > 0 ? ` — flagged for ${gap.reasons.join(', ')}` : ''\n\n    return `/** ${gap.method ?? 'ANY'} ${gap.path}${why} */\nexport const ${constant} = defineAuditAction('${name}', {\n  target: '${target}',\n  description: 'TODO: what this records, in one line',\n})`\n  })\n\n  return `import { defineAuditAction } from 'evlog'\n\n/**\n * Audit actions for ${input.service}.\n *\n * Seeded by \\`evlog init\\` from the entry points \\`evlog map\\` flagged as\n * sensitive with no audit trail. Call them from the handlers listed above each\n * one:\n *\n *   log.audit(${entries.length > 0 ? [...seen][0]!.replace(/[^a-z0-9]+/gi, '_').toUpperCase() : 'ACTION'}({ actor: { type: 'user', id: user.id }, outcome: 'success' }))\n */\n${entries.join('\\n\\n')}\n`\n}\n\n/** Single-quoted, since generated files go through the reader's linter. */\nfunction quote(value: string): string {\n  /* Newlines are escaped rather than dropped: a message spanning two lines is\n     unusual but legal, and emitting it raw ends the string literal mid-file. */\n  return `'${value\n    .replace(/\\\\/g, '\\\\\\\\')\n    .replace(/'/g, '\\\\\\'')\n    .replace(/\\n/g, '\\\\n')\n    .replace(/\\r/g, '\\\\r')}'`\n}\n\n/** Quotes a key that is not a valid identifier, so the generated file parses. */\nfunction objectKey(key: string): string {\n  return /^[A-Z_$][\\w$]*$/i.test(key) ? key : quote(key)\n}\n\n/** Where a catalog file goes, per framework convention. */\nfunction catalogDir(input: WiringInput): string {\n  if (input.framework === 'next') {\n    const useSrc = existsSync(join(input.root, 'src', 'app')) || existsSync(join(input.root, 'src', 'pages'))\n    return useSrc ? join('src', 'lib') : 'lib'\n  }\n  if (input.framework === 'tanstack-start') return join('src', 'lib')\n  if (input.framework === 'hono') {\n    return existsSync(join(input.root, 'src')) ? join('src', 'lib') : 'lib'\n  }\n  return join('server', 'utils')\n}\n\nfunction withCatalogs(plan: WiringPlan, input: WiringInput): WiringPlan {\n  const dir = catalogDir(input)\n\n  if (input.extras.includes('error-catalog') && input.repeatedErrors.length > 0) {\n    addFile(plan, input, join(dir, 'errors.ts'), errorCatalogTemplate(input))\n  }\n  if (input.extras.includes('audit-catalog') && input.auditGaps.length > 0) {\n    addFile(plan, input, join(dir, 'audit.ts'), auditCatalogTemplate(input))\n  }\n\n  return plan\n}\n\n/** Queue a file, or report it as already present. Never overwrites. */\nfunction addFile(plan: WiringPlan, input: WiringInput, relativePath: string, contents: string): void {\n  const path = join(input.root, relativePath)\n  if (existsSync(path)) {\n    plan.already.push(`${relativePath} already exists`)\n    return\n  }\n  plan.actions.push({ path, relative: relativePath, kind: 'create', contents })\n}\n\n/* ── environment ────────────────────────────────────────────────────────── */\n\n/** Append the adapters' variables to `.env.example` — never `.env`, which holds secrets. */\nfunction withEnvExample(plan: WiringPlan, input: WiringInput): WiringPlan {\n  const variables = input.prodDrains\n    .map(id => findDestination(id))\n    .flatMap(destination => destination?.env ?? [])\n  if (variables.length === 0) return plan\n\n  const path = join(input.root, '.env.example')\n  const existing = existsSync(path) ? readFileSync(path, 'utf8') : ''\n  const missing = variables.filter(variable => !new RegExp(`^\\\\s*${variable.name}\\\\s*=`, 'm').test(existing))\n\n  if (missing.length === 0) {\n    plan.already.push('.env.example already lists the adapter keys')\n    return plan\n  }\n\n  const width = Math.max(...missing.map(variable => variable.name.length))\n  const block = [\n    '# evlog — wide event delivery',\n    ...missing.map(variable => `${`${variable.name}=`.padEnd(width + 2)}# ${variable.hint}`),\n    '',\n  ].join('\\n')\n  const contents = existing.length > 0\n    ? `${existing.replace(/\\n*$/, '\\n')}\\n${block}`\n    : block\n\n  plan.actions.push({\n    path,\n    relative: '.env.example',\n    kind: existing.length > 0 ? 'patch' : 'create',\n    contents,\n  })\n  return plan\n}\n\nfunction planNext(input: WiringInput): WiringPlan {\n  const plan: WiringPlan = { actions: [], manual: [], already: [] }\n  /* Next resolves both `instrumentation.ts` and `src/instrumentation.ts`, but\n     only the one that matches the app directory — putting it at the root of a\n     `src/` project makes a file that is never loaded. */\n  const useSrc = existsSync(join(input.root, 'src', 'app')) || existsSync(join(input.root, 'src', 'pages'))\n  const base = useSrc ? join(input.root, 'src') : input.root\n\n  const instrumentation = firstExisting(base, configCandidates('instrumentation'))\n  if (instrumentation) {\n    plan.already.push(`${relative(input.root, instrumentation)} already exists`)\n  } else {\n    const path = join(base, 'instrumentation.ts')\n    plan.actions.push({\n      path,\n      relative: relative(input.root, path),\n      kind: 'create',\n      contents: nextInstrumentationTemplate(input.service),\n    })\n  }\n\n  const lib = firstExisting(base, ['lib/evlog.ts', 'lib/evlog.tsx', 'app/lib/evlog.ts'])\n  if (lib) {\n    patchNextLib(plan, input, lib, relative(input.root, lib))\n  } else {\n    const path = join(base, 'lib', 'evlog.ts')\n    plan.actions.push({\n      path,\n      relative: relative(input.root, path),\n      kind: 'create',\n      contents: nextLibTemplate(input),\n    })\n  }\n\n  plan.manual.push({\n    title: 'Wrap a route handler',\n    file: relative(input.root, join(base, 'app', 'api', '<route>', 'route.ts')),\n    snippet: `import { withEvlog, useLogger } from '@/lib/evlog'\n\nexport const GET = withEvlog(async () => {\n  const log = useLogger()\n  log.set({ action: 'hello' })\n  return Response.json({ ok: true })\n})`,\n    reason: 'Next has no ambient request logger — each handler opts in with withEvlog()',\n  })\n\n  return plan\n}\n\n/* ── hono ───────────────────────────────────────────────────────────────── */\n\nfunction honoEvlogTemplate(input: WiringInput): string {\n  const { imports, preamble, options } = factoryParts(input)\n  /* Hono splits the surface: sampling belongs to `initLogger`, drains and\n     enrichers are middleware options. */\n  const sampling = options.filter(option => option.trimStart().startsWith('sampling:'))\n  const middleware = options.filter(option => !sampling.includes(option))\n  const head = [`import { initLogger } from 'evlog'`, `import { evlog } from 'evlog/hono'`, ...imports]\n\n  return `${head.join('\\n')}\n\ninitLogger({\n  env: { service: '${input.service}' },\n${sampling.join('\\n')}${sampling.length > 0 ? '\\n' : ''}})\n${preamble}\n/** Register once, before your routes: \\`app.use(evlogMiddleware)\\`. */\nexport const evlogMiddleware = evlog(${middleware.length > 0 ? `{\\n${middleware.join('\\n')}\\n}` : ''})\n`\n}\n\nfunction planHono(input: WiringInput): WiringPlan {\n  const plan: WiringPlan = { actions: [], manual: [], already: [] }\n  const useSrc = existsSync(join(input.root, 'src'))\n  const relativePath = useSrc ? join('src', 'evlog.ts') : 'evlog.ts'\n  addFile(plan, input, relativePath, honoEvlogTemplate(input))\n\n  const entry = useSrc ? join('src', 'index.ts') : 'index.ts'\n  plan.manual.push({\n    title: 'Register the middleware on your app',\n    file: entry,\n    snippet: `import { Hono } from 'hono'\nimport type { EvlogVariables } from 'evlog/hono'\nimport { evlogMiddleware } from './evlog'\n\nconst app = new Hono<EvlogVariables>()\napp.use(evlogMiddleware)`,\n    reason: `${entry} is your application file, and splicing a middleware into it is guesswork`,\n  })\n\n  return plan\n}\n\n/** Build the file plan for a framework. Pure: reads the project, writes nothing. */\nexport function planWiring(input: WiringInput): WiringPlan {\n  // Applied once here rather than in each planner, where one would be forgotten.\n  return withEnvExample(withCatalogs(frameworkPlan(input), input), input)\n}\n\nfunction frameworkPlan(input: WiringInput): WiringPlan {\n  switch (input.framework) {\n    case 'nuxt': return planNuxt(input)\n    case 'nitro':\n    case 'tanstack-start': return planNitro(input)\n    case 'next': return planNext(input)\n    case 'hono': return planHono(input)\n  }\n  /* A new Framework member fails to compile here until init decides on a plan. */\n  return input.framework satisfies never\n}\n","import {\n  autocomplete,\n  autocompleteMultiselect,\n  cancel,\n  confirm,\n  groupMultiselect,\n  intro,\n  isCancel,\n  log as clackLog,\n  multiselect,\n  note,\n  outro,\n  select,\n  tasks,\n  text,\n} from '@clack/prompts'\nimport type { CliContext } from '../../core/context'\nimport { DOCS_URL, createStyle } from '../../core/output'\nimport type { Framework } from '../map/types'\nimport {\n  availableExtras,\n  DEFAULT_ENRICHERS,\n  DEV_DESTINATIONS,\n  ENRICHERS,\n  findDestination,\n  offerEvidence,\n  PROD_DESTINATIONS,\n  SAMPLING_PRESETS,\n} from './catalog'\nimport type { DrainId, EnricherId, ExtraGroup, ExtraId, OfferContext, SamplingProfile } from './catalog'\nimport { INIT_FRAMEWORKS } from './frameworks'\nimport type { FileAction, ManualStep } from './frameworks'\n\n/** Every answer `init` needs, however it was obtained. */\nexport interface InitAnswers {\n  framework: Framework\n  service: string\n  /** Local sink: `fs` or `none`. */\n  devDrain: DrainId\n  /** Production destinations — more than one fans the same event out to each. */\n  prodDrains: DrainId[]\n  extras: ExtraId[]\n  enrichers: EnricherId[]\n  sampling: SamplingProfile\n  /** Run the package manager for a missing `evlog`. */\n  install: boolean\n  /** Write the `AGENTS.md` block and install the published skills. */\n  agentGuide: boolean\n}\n\n/** Thrown when the user aborts a prompt — the command exits quietly, writing nothing. */\nexport class InitCancelled extends Error {\n  constructor() {\n    super('cancelled')\n    this.name = 'InitCancelled'\n  }\n}\n\n/** Unwrap a clack answer, turning a cancel into a throw. */\nfunction required<T>(value: T | symbol): T {\n  if (isCancel(value)) throw new InitCancelled()\n  return value as T\n}\n\nconst FRAMEWORK_LABELS: Record<Framework, string> = {\n  'nuxt': 'Nuxt',\n  'nitro': 'Nitro',\n  'next': 'Next.js',\n  'tanstack-start': 'TanStack Start',\n  'hono': 'Hono',\n}\n\nexport interface PromptContext {\n  ctx: CliContext\n  detected: Framework\n  /** Detection was a guess rather than a match — ask instead of announcing. */\n  uncertain: boolean\n  defaultService: string\n  evlogInstalled: boolean\n  /** Whether `--install` is still on — `--no-install` is an answer, not a prompt. */\n  installRequested: boolean\n  /** Whether `--agents` is still on — `--no-agents` is an answer, not a prompt. */\n  agentGuideRequested: boolean\n  /** Builds the offer list once the destinations are known. */\n  offers: (prodDrains: DrainId[], framework: Framework) => OfferContext\n}\n\nexport function openInteractive(ctx: CliContext, command: string, projectLabel: string): void {\n  const { paint } = createStyle(ctx)\n  intro(`${paint(['bold', 'cyan'], ` ${command} `)} ${paint('dim', projectLabel)}`)\n}\n\n/**\n * Ask everything, in the order a person thinks about it: what am I, what am I\n * called, where do events go here, where do they go in production, what else.\n */\nexport async function askAnswers(input: PromptContext): Promise<InitAnswers> {\n  const framework = input.uncertain\n    ? required(await select<Framework>({\n      message: 'Which framework is this?',\n      /* Only the frameworks init can wire — map-only ones would crash the planner. */\n      options: INIT_FRAMEWORKS.map(id => ({\n        value: id,\n        label: FRAMEWORK_LABELS[id],\n      })),\n      initialValue: input.detected,\n    }))\n    : input.detected\n\n  if (!input.uncertain) {\n    clackLog.step(`Detected ${FRAMEWORK_LABELS[framework]}`)\n  }\n\n  const service = required(await text({\n    message: 'Service name on every wide event',\n    placeholder: input.defaultService,\n    defaultValue: input.defaultService,\n    validate(value) {\n      /* Empty means \"take the default\", which clack fills in afterwards. */\n      if (value !== undefined && value.length > 0 && !/^[\\w.-]+$/.test(value)) {\n        return 'Letters, numbers, dot, dash and underscore only — it ends up in a log field'\n      }\n      return undefined\n    },\n  }))\n\n  /* Two questions: nobody sends local traffic to Axiom, and nobody reads\n     production logs off the box's filesystem. */\n  const devDrain = required(await select<DrainId>({\n    message: 'In development, where should events go?',\n    options: DEV_DESTINATIONS.map(destination => ({\n      value: destination.id,\n      label: destination.label,\n      hint: destination.hint,\n    })),\n    initialValue: 'fs' as DrainId,\n  }))\n\n  const prodDrains = required(await autocompleteMultiselect<DrainId>({\n    message: 'And in production?',\n    placeholder: 'Type to search — leave empty to decide later',\n    options: PROD_DESTINATIONS.map(destination => ({\n      value: destination.id,\n      label: destination.label,\n      hint: destination.hint,\n    })),\n    initialValues: [],\n    required: false,\n  }))\n\n  const context = input.offers(prodDrains, framework)\n  const offered = availableExtras(context)\n\n  let extras: ExtraId[] = []\n  if (offered.length > 0) {\n    // Grouped: eight options under one heading is a list, under four it is a decision.\n    const groups: Record<string, { value: ExtraId, label: string, hint?: string }[]> = {}\n    for (const extra of offered) {\n      const evidence = offerEvidence(extra, context)\n      const { group } = extra\n      groups[group] ??= []\n      groups[group]!.push({\n        value: extra.id,\n        // In the label, not the hint: only the focused row renders its hint.\n        label: evidence ? `${extra.label} · ${evidence}` : extra.label,\n        hint: extra.hint,\n      })\n    }\n\n    extras = required(await groupMultiselect<ExtraId>({\n      message: 'Anything else?',\n      options: groups,\n      initialValues: [],\n      required: false,\n      selectableGroups: false,\n    }))\n  }\n\n  const enrichers = extras.includes('enrichers')\n    ? required(await multiselect<EnricherId>({\n      message: 'Which enrichers?',\n      options: ENRICHERS.map(enricher => ({\n        value: enricher.id,\n        label: enricher.label,\n        hint: enricher.hint,\n      })),\n      initialValues: [...DEFAULT_ENRICHERS],\n      required: false,\n    }))\n    : []\n\n  const sampling = extras.includes('sampling')\n    ? required(await select<SamplingProfile>({\n      message: 'How much healthy traffic should reach the drain?',\n      options: SAMPLING_PRESETS.map(preset => ({\n        value: preset.id,\n        label: preset.label,\n        hint: preset.hint,\n      })),\n      initialValue: 'medium' as SamplingProfile,\n    }))\n    : 'all'\n\n  /* Wiring evlog in and leaving the agent that writes the handlers unaware of\n     it is most of the way to nothing. */\n  const agentGuide = input.agentGuideRequested\n    ? required(await confirm({\n      message: 'Teach AI agents the evlog conventions? (AGENTS.md + skills)',\n      initialValue: true,\n    }))\n    : false\n\n  // Not a question of its own: the plan lists the install and asks once.\n  return {\n    framework,\n    service: service || input.defaultService,\n    devDrain,\n    prodDrains,\n    extras: extras.filter(id => id !== 'enrichers' || enrichers.length > 0),\n    enrichers,\n    sampling,\n    install: !input.evlogInstalled && input.installRequested,\n    agentGuide,\n  }\n}\n\n/**\n * Nothing lands until the user has read what is about to land.\n *\n * @param runs - Commands this run will shell out to, listed before the writes.\n */\nexport function showPlan(\n  actions: FileAction[],\n  already: string[],\n  runs: string[] = [],\n): boolean {\n  const lines: string[] = []\n\n  for (const run of runs) lines.push(`run  ${run}`)\n  for (const action of actions) {\n    lines.push(`${action.kind === 'create' ? 'create' : 'update'}  ${action.relative}`)\n  }\n  for (const entry of already) lines.push(`skip  ${entry}`)\n\n  if (lines.length === 0) {\n    note('Everything is already wired.', 'Nothing to do')\n    return false\n  }\n\n  note(lines.join('\\n'), 'Plan')\n  return true\n}\n\nexport async function confirmPlan(\n  actions: FileAction[],\n  already: string[],\n  runs: string[] = [],\n): Promise<boolean> {\n  if (!showPlan(actions, already, runs)) return false\n\n  return required(await confirm({ message: 'Apply?', initialValue: true }))\n}\n\n/** Environment variables the chosen destinations read, printed once at the end. */\nexport function noteEnvironment(prodDrains: DrainId[]): void {\n  const variables = prodDrains\n    .map(id => findDestination(id))\n    .flatMap(destination => destination?.env.map(variable => ({ ...variable, label: destination.label })) ?? [])\n  if (variables.length === 0) return\n\n  // Never prompted for: a token typed here lands in a file we chose and in shell history.\n  const width = Math.max(...variables.map(variable => variable.name.length))\n  note(\n    variables.map(variable => `${variable.name.padEnd(width)}  ${variable.hint}`).join('\\n'),\n    'Set these before anything is received',\n  )\n}\n\n/** How the agent skills ended up, for a run that is drawing its own frame. */\nexport interface SkillsNote {\n  status: 'pending' | 'already' | 'installed' | 'skipped' | 'failed'\n  /** `npx skills add …`, as the user would type it. */\n  command: string\n  /** Agent directories they were found in, when they were already there. */\n  dirs?: string[]\n  error?: string\n}\n\n/**\n * A command the reader is meant to type.\n *\n * Label on the left, command on the right — the shape the outro already uses\n * for `score  evlog map`. Inline in a sentence it reads as prose and the reader\n * never registers there is something for them to run.\n */\nfunction command(ctx: CliContext, label: string, line: string): string {\n  const { paint } = createStyle(ctx)\n  return `${paint('dim', label)}  ${paint('bold', line)}`\n}\n\n/**\n * Say what happened to the skills.\n *\n * The interactive flow suppresses the written report, so without this the whole\n * step is invisible — and \"already installed\" looks exactly like \"did nothing\"\n * to somebody watching the terminal.\n */\nexport function noteSkills(ctx: CliContext, note: SkillsNote): void {\n  const { paint } = createStyle(ctx)\n\n  switch (note.status) {\n    case 'already':\n      clackLog.success(`evlog skills already installed${note.dirs?.length ? ` · ${paint('dim', note.dirs.join(', '))}` : ''}`)\n      clackLog.message(command(ctx, 'refresh', 'npx skills update'))\n      return\n    case 'installed':\n      clackLog.success('Installed the evlog skills')\n      return\n    case 'failed':\n      clackLog.error('Skills not installed')\n      if (note.error) clackLog.message(paint('dim', note.error))\n      clackLog.message(command(ctx, 'retry  ', note.command))\n      return\n    default:\n      clackLog.warn('Skills not installed')\n      clackLog.message(command(ctx, 'install', note.command))\n  }\n}\n\n/** Said before handing the terminal to the skills CLI, so it is not a surprise. */\nexport function noteSkillsStarting(ctx: CliContext, line: string): void {\n  const { paint } = createStyle(ctx)\n  clackLog.step(\n    `${command(ctx, 'running', line)}\\n${paint('dim', 'the skills CLI takes over from here')}`,\n  )\n}\n\nexport function noteManual(steps: ManualStep[]): void {\n  for (const step of steps) {\n    note(`${step.snippet}\\n\\n${step.reason}`, `${step.title} — ${step.file}`)\n  }\n}\n\n/** The question after a setup is \"did it work\" — answer it here. */\nexport async function runVerification(verify: () => Promise<string>): Promise<void> {\n  await tasks([\n    {\n      title: 'Verifying the install',\n      task: async () => await verify(),\n    },\n  ])\n}\n\nexport function closeInteractive(\n  ctx: CliContext,\n  framework: Framework,\n  docsPath: string,\n  dryRun = false,\n): void {\n  const { paint } = createStyle(ctx)\n  if (dryRun) {\n    /* \"Nitro wired\" after a run that wrote nothing is the command claiming\n       credit for work it did not do. */\n    outro(`${paint('yellow', 'Dry run')} — nothing was written. Drop --dry-run to apply.`)\n    return\n  }\n  clackLog.message(`${paint('dim', 'score')}  evlog map`)\n  outro(`${FRAMEWORK_LABELS[framework]} wired · ${DOCS_URL}${docsPath}`)\n}\n\n/** Closes the `evlog agents` session — without it the run just stops mid-frame. */\nexport function closeAgents(ctx: CliContext, dryRun = false): void {\n  const { paint } = createStyle(ctx)\n  if (dryRun) {\n    outro(`${paint('yellow', 'Dry run')} — nothing was written. Drop --dry-run to apply.`)\n    return\n  }\n  outro(`Your agents know evlog · ${DOCS_URL}/cli/agents`)\n}\n\nexport function closeCancelled(): void {\n  cancel('Cancelled — nothing was written.')\n}\n\n/** Ask which workspace packages to set up. */\nexport async function askWorkspaceTargets(\n  candidates: { name: string, dir: string, framework: Framework }[],\n): Promise<string[]> {\n  return required(await multiselect<string>({\n    message: 'Which apps should be set up?',\n    options: candidates.map(candidate => ({\n      value: candidate.dir,\n      label: candidate.name,\n      hint: FRAMEWORK_LABELS[candidate.framework],\n    })),\n    initialValues: candidates.map(candidate => candidate.dir),\n    required: true,\n  }))\n}\n\n/**\n * Whether prompting is possible and wanted.\n *\n * Non-interactive is the default whenever anything suggests nobody is watching:\n * no TTY, a CI environment, `--json`, or an explicit `--yes`. An agent running\n * this command must never end up waiting on a keystroke that is not coming.\n */\nexport function canPrompt(ctx: CliContext): boolean {\n  /* Both halves matter and they are not the same question: without a terminal\n     on stdin there is nobody to answer, and without one on stdout there is\n     nowhere to draw. */\n  if (!ctx.stdinTty || !ctx.tty) return false\n  if (ctx.env.CI !== undefined && ctx.env.CI !== 'false' && ctx.env.CI !== '0') return false\n  return true\n}\n","import { globSync } from 'tinyglobby'\nimport { cliErrors } from '../errors'\nimport type { ProjectInfo } from '../project'\nimport type { Framework } from './types'\n\ninterface DetectionMatch {\n  framework: Framework\n  specificity: number\n  reason: string\n}\n\nexport interface DetectionResult {\n  framework: Framework\n  warnings: string[]\n}\n\nfunction hasDep(pkg: ProjectInfo['packageJson'], names: string[]): boolean {\n  if (!pkg) return false\n  const deps = { ...pkg.dependencies, ...pkg.devDependencies }\n  return names.some(n => n in deps)\n}\n\nfunction hasConfig(root: string, patterns: string[]): boolean {\n  return globSync(patterns, { cwd: root, absolute: false }).length > 0\n}\n\n/**\n * Pick a {@link Framework} for `map`'s adapter dispatch — dependency + config\n * probes, most specific match wins. Throws a catalog {@link cliErrors} error\n * (`--framework` to override) when nothing matches, distinguishing a bare\n * monorepo root (via {@link ProjectInfo}) from a genuinely unsupported stack.\n */\nexport function detectFramework(project: ProjectInfo, override?: Framework): DetectionResult {\n  if (override) {\n    return { framework: override, warnings: [] }\n  }\n\n  if (!project.packageJson) {\n    throw cliErrors.MAP_NO_PACKAGE_JSON()\n  }\n\n  const root = project.packageDir\n  const pkg = project.packageJson\n  const matches: DetectionMatch[] = []\n\n  if (hasDep(pkg, ['nuxt']) || hasConfig(root, ['nuxt.config.{ts,js,mjs}'])) {\n    matches.push({ framework: 'nuxt', specificity: 10, reason: 'nuxt dependency or nuxt.config' })\n  }\n\n  if (\n    (hasDep(pkg, ['nitropack', 'nitro']) || hasConfig(root, ['nitro.config.{ts,js,mjs}']))\n    && !hasDep(pkg, ['nuxt'])\n  ) {\n    matches.push({ framework: 'nitro', specificity: 8, reason: 'nitro dependency or nitro.config' })\n  }\n\n  if (hasDep(pkg, ['next']) || hasConfig(root, ['next.config.{ts,js,mjs}'])) {\n    matches.push({ framework: 'next', specificity: 10, reason: 'next dependency or next.config' })\n  }\n\n  if (hasDep(pkg, ['@tanstack/react-start', '@tanstack/start'])) {\n    matches.push({ framework: 'tanstack-start', specificity: 10, reason: '@tanstack/react-start dependency' })\n  }\n\n  if (hasDep(pkg, ['hono'])) {\n    matches.push({ framework: 'hono', specificity: 10, reason: 'hono dependency' })\n  }\n\n  if (matches.length === 0) {\n    const isBareWorkspaceRoot = project.kind !== 'single' && project.packageDir === project.root\n    if (isBareWorkspaceRoot) {\n      throw cliErrors.MAP_WORKSPACE_ROOT()\n    }\n    throw cliErrors.MAP_FRAMEWORK_NOT_DETECTED()\n  }\n\n  matches.sort((a, b) => b.specificity - a.specificity)\n  const best = matches[0]!\n  const warnings: string[] = []\n\n  if (matches.length > 1) {\n    const others = matches.slice(1).map(m => m.framework).join(', ')\n    warnings.push(`Multiple frameworks detected; using ${best.framework} (${others} also matched)`)\n  }\n\n  return { framework: best.framework, warnings }\n}\n","import { access, readFile, readdir, stat } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport { dirname, join, relative, resolve, sep } from 'node:path'\n\n/** Minimal `package.json` fields used for project / workspace discovery. */\nexport interface PackageJson {\n  name?: string\n  dependencies?: Record<string, string>\n  devDependencies?: Record<string, string>\n  peerDependencies?: Record<string, string>\n  workspaces?: string[] | { packages?: string[] }\n}\n\n/** How the project is laid out — plain package or a detected workspace tool. */\nexport type WorkspaceKind = 'single' | 'pnpm' | 'npm' | 'yarn' | 'bun'\n\n/** Resolved project layout for the directory the user ran from. */\nexport interface ProjectInfo {\n  /** Directory the user ran from (or `--cwd`). */\n  cwd: string\n  /** Nearest package.json directory (may equal cwd). */\n  packageDir: string\n  /** Workspace / project root (pnpm-workspace, workspaces field, or packageDir). */\n  root: string\n  kind: WorkspaceKind\n  packageName: string | null\n  packageJson: PackageJson | null\n}\n\n/** Resolved `evlog` install discovered under the project (version + paths). */\nexport interface EvlogInstall {\n  version: string\n  /** Absolute path to the resolved `evlog` package root. */\n  path: string\n  /** Where it was declared, if found (`dependencies` / `devDependencies`). */\n  declaredIn: string | null\n  declaredRange: string | null\n}\n\n/** One probe while resolving `evlog` from the filesystem / require graph. */\nexport interface ResolveAttempt {\n  base: string\n  method: 'require' | 'fs'\n  ok: boolean\n  path?: string\n  error?: string\n}\n\nasync function exists(path: string): Promise<boolean> {\n  try {\n    await access(path)\n    return true\n  } catch {\n    return false\n  }\n}\n\n/** Deduplicate path list while preserving order. */\nfunction uniquePaths(paths: string[]): string[] {\n  return [...new Set(paths)]\n}\n\n/** Read and parse a JSON file; `null` on missing / invalid. */\nexport async function readJson<T>(path: string): Promise<T | null> {\n  try {\n    return JSON.parse(await readFile(path, 'utf-8')) as T\n  } catch {\n    return null\n  }\n}\n\nasync function detectWorkspaceKind(dir: string, pkg: PackageJson | null): Promise<WorkspaceKind | null> {\n  if (await exists(join(dir, 'pnpm-workspace.yaml'))) return 'pnpm'\n  if (!pkg?.workspaces) return null\n  // Bun uses the npm `workspaces` field; distinguish via lockfile.\n  if (await exists(join(dir, 'bun.lock')) || await exists(join(dir, 'bun.lockb'))) return 'bun'\n  if (await exists(join(dir, 'yarn.lock'))) return 'yarn'\n  return 'npm'\n}\n\n/**\n * Walk up from `start` to locate the nearest package and the workspace root.\n * Handles pnpm / bun / npm / yarn workspaces and plain single packages.\n */\nexport async function resolveProject(start: string): Promise<ProjectInfo> {\n  const cwd = resolve(start)\n  let packageDir: string | null = null\n  let packageJson: PackageJson | null = null\n  let root = cwd\n  let kind: WorkspaceKind = 'single'\n\n  let dir = cwd\n  for (;;) {\n    const pkgPath = join(dir, 'package.json')\n    if (await exists(pkgPath)) {\n      const pkg = await readJson<PackageJson>(pkgPath)\n      if (!packageDir) {\n        packageDir = dir\n        packageJson = pkg\n        // Single-package default: root is the nearest package, not a parent.\n        root = dir\n      }\n      const detected = await detectWorkspaceKind(dir, pkg)\n      if (detected) {\n        root = dir\n        kind = detected\n        break\n      }\n      // Keep walking — a parent may still be a workspace root.\n    }\n\n    const parent = dirname(dir)\n    if (parent === dir) break\n    dir = parent\n  }\n\n  if (!packageDir) {\n    return {\n      cwd,\n      packageDir: cwd,\n      root: cwd,\n      kind: 'single',\n      packageName: null,\n      packageJson: null,\n    }\n  }\n\n  return {\n    cwd,\n    packageDir,\n    root,\n    kind,\n    packageName: packageJson?.name ?? null,\n    packageJson,\n  }\n}\n\nfunction declaredEvlog(pkg: PackageJson | null): { range: string, field: string } | null {\n  if (!pkg) return null\n  for (const field of ['dependencies', 'devDependencies', 'peerDependencies'] as const) {\n    const range = pkg[field]?.evlog\n    if (range) return { range, field }\n  }\n  return null\n}\n\n/**\n * Resolve an installed `evlog` package by walking `node_modules` (hoist-aware)\n * via `createRequire`, then fall back to declared ranges in the local package.json.\n *\n * `tried` lists every probe (for `--debug` decision trails).\n */\nexport async function resolveEvlog(project: ProjectInfo): Promise<{\n  install: EvlogInstall | null\n  declared: { range: string, field: string } | null\n  tried: ResolveAttempt[]\n}> {\n  const declared = declaredEvlog(project.packageJson)\n  const tried: ResolveAttempt[] = []\n\n  // packageDir / root / cwd often collapse to the same path (e.g. bare /tmp)\n  const candidates = uniquePaths([project.packageDir, project.root, project.cwd])\n  for (const base of candidates) {\n    const pkgJsonPath = join(base, 'package.json')\n    if (!(await exists(pkgJsonPath))) {\n      tried.push({ base, method: 'require', ok: false, error: 'no package.json' })\n      continue\n    }\n    try {\n      const require = createRequire(pkgJsonPath)\n      const resolved = require.resolve('evlog/package.json')\n      const meta = await readJson<{ version?: string }>(resolved)\n      if (meta?.version) {\n        const path = dirname(resolved)\n        tried.push({ base, method: 'require', ok: true, path })\n        return {\n          install: {\n            version: meta.version,\n            path,\n            declaredIn: declared ? project.packageDir : null,\n            declaredRange: declared?.range ?? null,\n          },\n          declared,\n          tried,\n        }\n      }\n      tried.push({ base, method: 'require', ok: false, error: 'package.json missing version' })\n    } catch (error) {\n      tried.push({\n        base,\n        method: 'require',\n        ok: false,\n        error: error instanceof Error ? error.message : String(error),\n      })\n    }\n  }\n\n  // Direct filesystem probe (no package.json at base, or createRequire failed)\n  for (const base of candidates) {\n    const direct = join(base, 'node_modules', 'evlog', 'package.json')\n    const meta = await readJson<{ version?: string }>(direct)\n    if (meta?.version) {\n      const path = dirname(direct)\n      tried.push({ base, method: 'fs', ok: true, path })\n      return {\n        install: {\n          version: meta.version,\n          path,\n          declaredIn: declared ? project.packageDir : null,\n          declaredRange: declared?.range ?? null,\n        },\n        declared,\n        tried,\n      }\n    }\n    tried.push({ base, method: 'fs', ok: false, error: 'not found' })\n  }\n\n  return { install: null, declared, tried }\n}\n\n/** Relative path for display; `.` when identical. */\nexport function prettyPath(from: string, to: string): string {\n  const rel = relative(from, to)\n  if (!rel) return '.'\n  return rel.split(sep).join('/')\n}\n\n/**\n * Locate a readable `.evlog/logs` sink — prefers cwd, then package dir, then root.\n */\nexport async function findLogsSink(project: ProjectInfo): Promise<{\n  dir: string\n  files: number\n} | null> {\n  for (const base of uniquePaths([project.cwd, project.packageDir, project.root])) {\n    const dir = join(base, '.evlog', 'logs')\n    try {\n      await stat(dir)\n      const entries = await readdir(dir)\n      return { dir, files: entries.filter(f => f.endsWith('.jsonl')).length }\n    } catch {\n      // try next\n    }\n  }\n  return null\n}\n\n/** The fs drain's default directory, used when no env override names another. */\nconst DEFAULT_FS_DIR = '.evlog/logs'\n\n/**\n * Whether the project declares an fs drain. The drain creates its directory\n * lazily on first write, so a declared drain is a sink even before any event,\n * and a project without one is not expected to have a local sink at all.\n */\nexport async function findConfiguredFsDrain(\n  project: ProjectInfo,\n  env: Record<string, string | undefined>,\n): Promise<{ dir: string } | null> {\n  const envDir = env.EVLOG_FS_DIR ?? env.NUXT_EVLOG_FS_DIR\n  if (envDir) return { dir: envDir }\n\n  for (const base of uniquePaths([project.cwd, project.packageDir, project.root])) {\n    if (await dirWiresFsDrain(join(base, 'server', 'plugins'))) return { dir: DEFAULT_FS_DIR }\n    if (await fileWiresFsDrain(join(base, 'lib', 'evlog.ts'))) return { dir: DEFAULT_FS_DIR }\n    if (await fileWiresFsDrain(join(base, 'src', 'lib', 'evlog.ts'))) return { dir: DEFAULT_FS_DIR }\n  }\n  return null\n}\n\nasync function dirWiresFsDrain(dir: string): Promise<boolean> {\n  let entries: string[]\n  try {\n    entries = await readdir(dir)\n  } catch {\n    return false\n  }\n  for (const entry of entries) {\n    if (!/\\.(ts|mts|js|mjs)$/.test(entry)) continue\n    if (await fileWiresFsDrain(join(dir, entry))) return true\n  }\n  return false\n}\n\nasync function fileWiresFsDrain(path: string): Promise<boolean> {\n  try {\n    return (await readFile(path, 'utf8')).includes('createFsDrain')\n  } catch {\n    return false\n  }\n}\n\n/** Framework / integration hints based on package.json dependencies. */\nexport function detectStack(pkg: PackageJson | null): string[] {\n  if (!pkg) return []\n  const all = {\n    ...pkg.dependencies,\n    ...pkg.devDependencies,\n  }\n  const hits: string[] = []\n  const probes: [string, string][] = [\n    ['nuxt', 'nuxt'],\n    ['next', 'next'],\n    ['nitro', 'nitropack'],\n    ['hono', 'hono'],\n    ['express', 'express'],\n    ['fastify', 'fastify'],\n    ['@sveltejs/kit', 'sveltekit'],\n    ['@evlog/nuxthub', 'nuxthub'],\n    ['@evlog/telemetry', 'telemetry'],\n  ]\n  for (const [dep, label] of probes) {\n    if (all[dep]) hits.push(label)\n  }\n  return hits\n}\n","import type { Framework } from '../map/types'\n\n/**\n * The evlog section of a project's `AGENTS.md`.\n *\n * Everything between the markers is ours to rewrite; everything outside them is\n * the author's and is never touched. That split is the whole reason this command\n * can be re-run — the block tracks the CLI, the file tracks the project.\n */\n\nexport const MARKER_START = '<!-- evlog:start -->'\nexport const MARKER_END = '<!-- evlog:end -->'\n\nexport interface BlockInput {\n  /** `null` when detection found nothing — the block is still worth writing. */\n  framework: Framework | null\n  /** Whether the evlog skills are installed, for the closing pointer. */\n  hasSkills: boolean\n}\n\n/** How a request-scoped logger is obtained, per framework. */\nconst ACCESSOR: Record<Framework, string> = {\n  'nuxt': '`useLogger(event)` (auto-imported) inside a `server/api` handler',\n  'nitro': '`useLogger(event)` from `evlog/nitro` inside a route handler',\n  'next': '`useLogger()` from your `lib/evlog.ts` inside a route handler',\n  'tanstack-start': '`req.context.log` inside a server route',\n  'hono': '`c.get(\\'log\\')` or `useLogger()` from `evlog/hono` inside a route handler',\n}\n\nconst DEFAULT_ACCESSOR = '`useLogger()` inside a request handler'\n\n/**\n * Render the block.\n *\n * Deliberately short: this lands in a file every agent reads on every turn, so\n * it carries the rules and points at the skills for the depth. Prose that would\n * only restate an example is left out.\n */\nexport function renderBlock(input: BlockInput): string {\n  const accessor = input.framework ? ACCESSOR[input.framework] : DEFAULT_ACCESSOR\n\n  /* Which directory the skills landed in is the agent's business, not ours —\n     naming one would be wrong for every agent that reads a different path. */\n  const closing = input.hasSkills\n    ? 'Deeper guidance is in the `review-logging-patterns` skill — read it before a logging change.'\n    : 'Deeper guidance: https://evlog.dev/learn/wide-events'\n\n  return [\n    MARKER_START,\n    '## Logging with evlog',\n    '',\n    'This project uses [evlog](https://evlog.dev). Follow these rules when you add or change logging.',\n    '',\n    '**One wide event per operation.** A request, a job, a user action — each produces exactly one',\n    'event carrying everything about it. Not one log line per step.',\n    '',\n    `- Get the request logger with ${accessor}.`,\n    '- Add context as you learn it: `log.set({ user: { id, plan }, cart: { items, total } })`.',\n    '- Group related fields into objects. Never flat abbreviations like `{ uid, n, t }`.',\n    '- Never pass a raw body — `log.set({ user: body })` leaks passwords. List fields explicitly.',\n    '- Do not time anything by hand; the duration is computed when the event emits.',\n    '- `log.debug()` is for step detail and is stripped from production builds.',\n    '',\n    '**Errors are structured, never bare.**',\n    '',\n    '```ts',\n    'throw createError({',\n    '  message: \\'Payment failed\\',',\n    '  status: 402,',\n    '  why: \\'Card declined by the issuer\\',',\n    '  fix: \\'Use a different payment method\\',',\n    '  internal: { correlationId },   // drains only — never reaches the client',\n    '})',\n    '```',\n    '',\n    'Never `throw new Error(...)`. Never `console.error(e); throw e` — use `log.error(e)`.',\n    'When the same error appears in three or more places, promote it to `defineErrorCatalog()`.',\n    '',\n    '**Sensitive actions get an audit trail.** Call `log.audit({ action, actor, target, outcome })`',\n    'on anything that changes permissions, money, or personal data. Audit entries are never sampled.',\n    '',\n    '**Never log** passwords, tokens, API keys, full card numbers, or session JWTs. Redaction is on',\n    'in production, but it is a safety net — not a substitute for choosing the fields yourself.',\n    '',\n    'Check coverage with `npx @evlog/cli map --no-write`. Diagnose setup with `npx @evlog/cli doctor`.',\n    closing,\n    MARKER_END,\n    '',\n  ].join('\\n')\n}\n\n/**\n * Put `block` into `source`, replacing an existing one.\n *\n * Returns `null` when the file already says exactly this, which is what makes a\n * second run a no-op rather than a no-op-shaped rewrite.\n */\nexport function upsertBlock(source: string, block: string): string | null {\n  const start = source.indexOf(MARKER_START)\n  const end = source.indexOf(MARKER_END)\n\n  if (start === -1 || end === -1 || end < start) {\n    const separator = source.length === 0 || source.endsWith('\\n\\n') ? '' : source.endsWith('\\n') ? '\\n' : '\\n\\n'\n    return `${source}${separator}${block}`\n  }\n\n  const next = `${source.slice(0, start)}${block.trimEnd()}${source.slice(end + MARKER_END.length)}`\n  return next === source ? null : next\n}\n\n/** A fresh `AGENTS.md` for a project that has none. */\nexport function renderAgentsFile(projectName: string, block: string): string {\n  return `# ${projectName}\\n\\nInstructions for AI coding agents working in this repository.\\n\\n${block}`\n}\n\n/** The line that points Claude Code at `AGENTS.md` instead of duplicating it. */\nexport const CLAUDE_POINTER = '@AGENTS.md'\n\n/**\n * Add the pointer to a `CLAUDE.md`, or `null` when it already refers to AGENTS.md.\n *\n * Matches any mention rather than the exact line: a file that already says\n * \"see AGENTS.md\" in prose does not need a second instruction.\n */\nexport function upsertClaudePointer(source: string | null): string | null {\n  if (source === null) return `${CLAUDE_POINTER}\\n`\n  if (source.includes('AGENTS.md')) return null\n  return `${source.endsWith('\\n') ? source : `${source}\\n`}\\n${CLAUDE_POINTER}\\n`\n}\n","import { existsSync, readFileSync } from 'node:fs'\nimport { basename, join, relative } from 'node:path'\nimport { cliErrors } from '../errors'\nimport type { FileAction } from '../init/frameworks'\nimport type { Framework } from '../map/types'\nimport { renderAgentsFile, renderBlock, upsertBlock, upsertClaudePointer } from './block'\n\nexport interface AgentsPlanInput {\n  /** Package root — where `AGENTS.md` belongs. */\n  root: string\n  projectName: string\n  framework: Framework | null\n  /** Whether the block should point at the skills for the deeper guidance. */\n  hasSkills: boolean\n}\n\nexport interface AgentsPlan {\n  actions: FileAction[]\n  /** Files that already say exactly this — printed so a run is never silent. */\n  already: string[]\n}\n\nfunction action(root: string, path: string, contents: string): FileAction {\n  const full = join(root, path)\n  return {\n    path: full,\n    relative: relative(root, full) || path,\n    kind: existsSync(full) ? 'patch' : 'create',\n    contents,\n  }\n}\n\n/**\n * Read a file we may be about to rewrite, or `null` when it is not there.\n *\n * An existing path that cannot be read — a directory named `AGENTS.md`, or one\n * the user has no permission on — would otherwise surface as a raw stack trace,\n * since only catalog errors get a `why` and a `fix`.\n */\nfunction read(path: string): string | null {\n  if (!existsSync(path)) return null\n  try {\n    return readFileSync(path, 'utf8')\n  } catch {\n    throw cliErrors.AGENTS_UNREADABLE({ file: basename(path) })\n  }\n}\n\n/**\n * What `evlog agents` will write, given the project on disk.\n *\n * Pure and synchronous — the whole idempotency story is testable without a\n * filesystem write. Skill files are not ours to plan; see `./skills`.\n */\nexport function planAgents(input: AgentsPlanInput): AgentsPlan {\n  const actions: FileAction[] = []\n  const already: string[] = []\n\n  const block = renderBlock({ framework: input.framework, hasSkills: input.hasSkills })\n\n  const agentsPath = join(input.root, 'AGENTS.md')\n  const agentsSource = read(agentsPath)\n\n  if (agentsSource === null) {\n    actions.push(action(input.root, 'AGENTS.md', renderAgentsFile(input.projectName, block)))\n  } else {\n    const next = upsertBlock(agentsSource, block)\n    if (next === null) already.push('AGENTS.md is up to date')\n    else actions.push(action(input.root, 'AGENTS.md', next))\n  }\n\n  const claudePath = join(input.root, 'CLAUDE.md')\n  const claude = upsertClaudePointer(read(claudePath))\n  if (claude === null) already.push('CLAUDE.md already points at AGENTS.md')\n  else actions.push(action(input.root, 'CLAUDE.md', claude))\n\n  return { actions, already }\n}\n","import { spawn } from 'node:child_process'\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { cliErrors } from '../errors'\n\n/**\n * The published evlog skills, installed by delegating to `npx skills`.\n *\n * We do not copy skill files ourselves. Every agent reads a different directory\n * (`.claude/skills`, `.agents/skills`, `.codex/skills`, …), the skills CLI\n * already resolves that per agent, symlinks a canonical copy, and owns\n * `update` / `remove` / `list` — and it keeps no manifest, so anything we wrote\n * behind its back would be a second copy it could never update.\n *\n * So this module does two things: notice when the skills are already there, and\n * shell out when they are not. Same shape as `init` running the package manager\n * rather than unpacking a tarball itself.\n */\n\n/** Where the skills are published. Overridable so forks can point elsewhere. */\nexport const DEFAULT_SOURCE = 'https://www.evlog.dev'\n\n/**\n * Skill directories published from the docs site.\n *\n * Used only to notice an existing install. A name that goes stale here costs\n * one redundant `npx skills add`, which is why it is not worth a network call.\n */\nexport const EVLOG_SKILLS = ['review-logging-patterns', 'build-audit-logs', 'analyze-logs'] as const\n\n/** Per-agent skill directories, relative to a project root or to `$HOME`. */\nconst AGENT_DIRS = [\n  '.claude/skills',\n  '.agents/skills',\n  '.cursor/skills',\n  '.codex/skills',\n  '.opencode/skills',\n]\n\nexport interface InstalledSkills {\n  /** Skill names found on disk, in any agent's directory. */\n  names: string[]\n  /** The directories they were found in, relative to the project or `~`. */\n  dirs: string[]\n}\n\n/**\n * Look for evlog skills already installed, project-local and global.\n *\n * Deliberately generous: any agent, either scope. Somebody who ran\n * `npx skills add` last month should not be told to run it again.\n *\n * @param home - The global scope to search, from {@link CliContext.home}.\n */\nexport function findInstalledSkills(root: string, home: string): InstalledSkills {\n  const names = new Set<string>()\n  const dirs = new Set<string>()\n\n  for (const [base, label] of [[root, ''], [home, '~/']] as const) {\n    for (const dir of AGENT_DIRS) {\n      for (const skill of EVLOG_SKILLS) {\n        if (!existsSync(join(base, dir, skill))) continue\n        names.add(skill)\n        dirs.add(`${label}${dir}`)\n      }\n    }\n  }\n\n  return { names: [...names].sort(), dirs: [...dirs].sort() }\n}\n\nexport interface SkillsCommand {\n  /** The command line, as the user would type it. */\n  display: string\n  bin: string\n  args: string[]\n}\n\n/** Skill directory names, per the Agent Skills spec. */\nconst SKILL_NAME = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/\n\n/**\n * Characters an origin never needs, and `cmd.exe` reads as syntax.\n *\n * Being an http(s) URL is not enough on its own: `https://evlog.dev?q=1&calc`\n * parses, and `&` still separates commands. Node does not escape array\n * arguments under `shell: true`, so the allowlist is the guard.\n */\nconst SAFE_SOURCE = /^[A-Za-z0-9._~:/-]+$/\n\n/**\n * Reject anything that is not a plain http(s) origin.\n *\n * On Windows {@link runSkills} needs a shell to find `npx` — Node refuses to\n * spawn a `.cmd` without one — which means this value reaches a `cmd.exe`\n * command line. Nobody types `&` against themselves, but a `--source` fed from\n * CI config or an interpolated variable is a different question, so the shape\n * is checked once here rather than trusted all the way down.\n */\nfunction checkSource(value: string): string {\n  let url: URL\n  try {\n    url = new URL(value)\n  } catch {\n    throw cliErrors.AGENTS_INVALID_SOURCE({ value })\n  }\n  if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n    throw cliErrors.AGENTS_INVALID_SOURCE({ value })\n  }\n  if (!SAFE_SOURCE.test(value)) {\n    throw cliErrors.AGENTS_INVALID_SOURCE({ value })\n  }\n  return value\n}\n\n/**\n * Build the `npx skills add` invocation.\n *\n * `--yes` only when nobody is watching: interactively, the skills CLI asks\n * which agents to install for, and that question is its to ask.\n */\nexport function skillsCommand(options: {\n  source?: string\n  skills?: readonly string[]\n  global?: boolean\n  interactive: boolean\n}): SkillsCommand {\n  const args = ['--yes', 'skills', 'add', checkSource(options.source ?? DEFAULT_SOURCE)]\n  if (options.skills?.length) {\n    for (const skill of options.skills) {\n      if (!SKILL_NAME.test(skill)) throw cliErrors.AGENTS_INVALID_SKILL({ value: skill })\n    }\n    args.push('--skill', ...options.skills)\n  }\n  if (options.global) args.push('--global')\n  if (!options.interactive) args.push('--yes')\n\n  /* Every argument, including npx's own `--yes`: this string is what the plan\n     shows and what the report tells you to re-run, so it has to be the command\n     that actually runs rather than a tidied version of it. */\n  return { display: `npx ${args.join(' ')}`, bin: 'npx', args }\n}\n\n/**\n * Run it, returning the failure rather than throwing.\n *\n * The `AGENTS.md` block is already on disk by this point and stands on its own;\n * losing it because a subprocess could not reach the network would be the wrong\n * trade. Interactive runs inherit the terminal so the skills CLI can ask its\n * own questions.\n */\nexport function runSkills(\n  command: SkillsCommand,\n  cwd: string,\n  interactive: boolean,\n): Promise<{ ok: true } | { ok: false, error: string }> {\n  return new Promise((resolve) => {\n    const child = spawn(command.bin, command.args, {\n      cwd,\n      stdio: interactive ? 'inherit' : ['ignore', 'pipe', 'pipe'],\n      shell: process.platform === 'win32',\n      timeout: 5 * 60_000,\n    })\n\n    let stderr = ''\n    child.stderr?.on('data', (chunk: Buffer) => {\n      stderr += chunk.toString()\n    })\n\n    child.on('error', (error) => {\n      resolve({ ok: false, error: error.message })\n    })\n\n    child.on('close', (code) => {\n      if (code === 0) {\n        resolve({ ok: true })\n        return\n      }\n      const line = stderr.trim().split('\\n').filter(Boolean).at(-1)\n      resolve({ ok: false, error: line ?? `npx skills add exited ${code}` })\n    })\n  })\n}\n","import { mkdir, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport { telemetry } from '@evlog/telemetry'\nimport type { CliContext } from '../../core/context'\nimport type { CliDebug } from '../debug'\nimport { createNoopCliDebug } from '../debug'\nimport type { FileAction } from '../init/frameworks'\nimport {\n  canPrompt,\n  closeAgents,\n  closeCancelled,\n  confirmPlan,\n  InitCancelled,\n  noteSkills,\n  noteSkillsStarting,\n  openInteractive,\n  showPlan,\n} from '../init/prompts'\nimport { detectFramework } from '../map/detect'\nimport type { Framework } from '../map/types'\nimport { resolveProject } from '../project'\nimport type { ProjectInfo } from '../project'\nimport { planAgents } from './plan'\nimport { findInstalledSkills, runSkills, skillsCommand } from './skills'\n\nexport interface AgentsOptions {\n  /** Pass through to `npx skills add --skill`; empty means every published one. */\n  skills?: string[]\n  /** Do not touch the skills at all — write the block and stop. */\n  noSkills?: boolean\n  /** Install the skills for every project rather than this one. */\n  global?: boolean\n  /** Where the skills are published. */\n  source?: string\n  /** Plan everything, write nothing, run nothing. */\n  dryRun?: boolean\n  /** Force non-interactive regardless of the terminal (set by `--json`). */\n  nonInteractive?: boolean\n  /** Skip the confirm step and apply. */\n  yes?: boolean\n}\n\n/** What became of the skills step. Mirrors `init`'s install outcome. */\nexport interface SkillsOutcome {\n  status: 'already' | 'installed' | 'skipped' | 'failed'\n  /** The command as the user would type it — printed whatever the outcome. */\n  command: string\n  /** Skill names already on disk when the run started. */\n  found: string[]\n  /** Agent directories they were found in. */\n  dirs: string[]\n  error?: string\n}\n\nexport interface AgentsResult {\n  project: Pick<ProjectInfo, 'cwd' | 'root' | 'packageDir' | 'packageName'>\n  /** `null` when detection found nothing — the block is written regardless. */\n  framework: Framework | null\n  skills: SkillsOutcome\n  written: FileAction[]\n  already: string[]\n  dryRun: boolean\n  interactive: boolean\n  cancelled: boolean\n}\n\n/**\n * Framework detection, downgraded to a hint.\n *\n * `init` writes framework-specific wiring and must refuse when it cannot tell\n * what it is looking at. This command writes prose, and prose about wide events\n * is worth having in an Express app the detector does not cover.\n */\nfunction detectSoftly(project: ProjectInfo): Framework | null {\n  try {\n    return detectFramework(project).framework\n  } catch {\n    return null\n  }\n}\n\n/**\n * Teach the agents working in this project how to use evlog.\n *\n * Writes a marker-delimited block into `AGENTS.md`, points `CLAUDE.md` at it,\n * and hands the skills to `npx skills add`. Safe to re-run: anything already\n * saying exactly this is reported rather than rewritten, and skills already on\n * disk are left for `npx skills update`.\n */\nexport async function runAgents(\n  ctx: CliContext,\n  log: CliDebug = createNoopCliDebug(),\n  options: AgentsOptions = {},\n): Promise<AgentsResult> {\n  const project = await log.step(\n    'resolveProject',\n    () => resolveProject(ctx.cwd),\n    p => ({ cwd: ctx.cwd, project: { kind: p.kind, root: p.root, name: p.packageName } }),\n  )\n\n  const framework = await log.step('detectFramework', () => detectSoftly(project), f => ({ framework: f ?? 'none' }))\n\n  const dryRun = options.dryRun === true\n  const interactive = !options.nonInteractive && !options.yes && canPrompt(ctx)\n\n  const installed = await log.step(\n    'findSkills',\n    () => findInstalledSkills(project.packageDir, ctx.home),\n    r => ({ skills: r.names.length }),\n  )\n\n  const command = skillsCommand({\n    source: options.source,\n    skills: options.skills,\n    global: options.global,\n    interactive,\n  })\n\n  /* Already there is the common case on a second run, and re-adding would only\n     ask the skills CLI to redo work it tracks better than we do. */\n  const installing = !options.noSkills && installed.names.length === 0\n\n  const plan = await log.step(\n    'planAgents',\n    () => planAgents({\n      root: project.packageDir,\n      projectName: project.packageName ?? 'This project',\n      framework,\n      hasSkills: installed.names.length > 0 || installing,\n    }),\n    p => ({ writes: p.actions.length, already: p.already.length }),\n  )\n\n  /* In the plan as well as the report: a step nobody sees considered is a step\n     the reader assumes was forgotten. */\n  if (installed.names.length > 0) {\n    plan.already.push(`evlog skills already installed · ${installed.dirs.join(', ')}`)\n  }\n\n  if (interactive) {\n    openInteractive(ctx, 'evlog agents', project.packageName ?? project.packageDir)\n\n    if (dryRun) {\n      showPlan(plan.actions, plan.already, installing ? [command.display] : [])\n    } else {\n      let confirmed: boolean\n      try {\n        confirmed = await confirmPlan(plan.actions, plan.already, installing ? [command.display] : [])\n      } catch (error) {\n        if (error instanceof InitCancelled) {\n          closeCancelled()\n          return cancelled({ project, framework, command: command.display, installed })\n        }\n        throw error\n      }\n      if (!confirmed) {\n        closeCancelled()\n        return cancelled({ project, framework, command: command.display, installed })\n      }\n    }\n  }\n\n  if (!dryRun) {\n    await log.step('write', async () => {\n      for (const action of plan.actions) {\n        await mkdir(dirname(action.path), { recursive: true })\n        await writeFile(action.path, action.contents, 'utf8')\n      }\n      return plan.actions.length\n    })\n  }\n\n  let skills: SkillsOutcome\n  if (installed.names.length > 0) {\n    skills = { status: 'already', command: command.display, found: installed.names, dirs: installed.dirs }\n  } else if (options.noSkills || dryRun) {\n    skills = { status: 'skipped', command: command.display, found: [], dirs: [] }\n  } else {\n    if (interactive) noteSkillsStarting(ctx, command.display)\n    const outcome = await log.step(\n      'runSkills',\n      () => runSkills(command, project.packageDir, interactive),\n      r => ({ installed: r.ok }),\n    )\n    skills = outcome.ok\n      ? { status: 'installed', command: command.display, found: [], dirs: findInstalledSkills(project.packageDir, ctx.home).dirs }\n      : { status: 'failed', command: command.display, found: [], dirs: [], error: outcome.error }\n  }\n\n  /* The block was written before the install, so it could stand whatever the\n     subprocess did — which means it promises a skill that is now known not to\n     exist. Rewrite it rather than leave an agent chasing a missing file. */\n  if (skills.status === 'failed' && !dryRun) {\n    const corrected = planAgents({\n      root: project.packageDir,\n      projectName: project.packageName ?? 'This project',\n      framework,\n      hasSkills: false,\n    })\n    await log.step('rewriteBlock', async () => {\n      for (const action of corrected.actions) {\n        await writeFile(action.path, action.contents, 'utf8')\n      }\n      return corrected.actions.length\n    })\n  }\n\n  if (interactive) {\n    noteSkills(ctx, skills)\n    closeAgents(ctx, dryRun)\n  }\n\n  const result: AgentsResult = {\n    project,\n    framework,\n    skills,\n    written: plan.actions,\n    already: plan.already,\n    dryRun,\n    interactive,\n    cancelled: false,\n  }\n\n  recordAgentsRun(result)\n  return result\n}\n\nfunction cancelled(input: {\n  project: ProjectInfo\n  framework: Framework | null\n  command: string\n  installed: { names: string[], dirs: string[] }\n}): AgentsResult {\n  const result: AgentsResult = {\n    project: input.project,\n    framework: input.framework,\n    skills: {\n      status: 'skipped',\n      command: input.command,\n      found: input.installed.names,\n      dirs: input.installed.dirs,\n    },\n    written: [],\n    already: [],\n    dryRun: false,\n    interactive: true,\n    cancelled: true,\n  }\n  recordAgentsRun(result)\n  return result\n}\n\n/**\n * Counts and booleans only.\n *\n * Which skills exist is already public; how many files a given project rewrote\n * is not interesting enough to justify sending anything shaped like a path.\n */\nfunction agentsTelemetryFields(result: AgentsResult): Record<string, boolean | number> {\n  return {\n    agentsSkillsFound: result.skills.found.length,\n    agentsSkillsInstalled: result.skills.status === 'installed',\n    agentsSkillsFailed: result.skills.status === 'failed',\n    agentsFilesWritten: result.written.length,\n    agentsAlready: result.already.length,\n    agentsDetected: result.framework !== null,\n    agentsDryRun: result.dryRun,\n    agentsInteractive: result.interactive,\n    agentsCancelled: result.cancelled,\n  }\n}\n\nfunction recordAgentsRun(result: AgentsResult): void {\n  telemetry.set(agentsTelemetryFields(result))\n}\n\n/**\n * Every field {@link recordAgentsRun} can emit — used to document the disclosure.\n *\n * Read off the payload rather than listed again: a field added to one and not\n * the other would leave the disclosure quietly incomplete, and what this CLI\n * transmits is exactly the thing that must not drift.\n */\nexport function agentsTelemetryFieldNames(): string[] {\n  return Object.keys(agentsTelemetryFields({\n    project: { cwd: '', root: '', packageDir: '', packageName: null },\n    framework: null,\n    skills: { status: 'skipped', command: '', found: [], dirs: [] },\n    written: [],\n    already: [],\n    dryRun: false,\n    interactive: false,\n    cancelled: false,\n  }))\n}\n","import { homedir } from 'node:os'\n\n/**\n * Execution context passed to every command.\n * The only place allowed to read `process.*` — commands stay pure and testable.\n *\n * Debug instrumentation uses {@link import('../lib/debug').CliDebug} from\n * {@link import('../lib/command').defineEvlogCommand}, not this object.\n */\nexport interface CliContext {\n  /** Working directory used to resolve the host project. */\n  cwd: string\n  /** Home directory — where agents keep their global, cross-project files. */\n  home: string\n  /** Environment snapshot — commands never touch `process.env` directly. */\n  env: Record<string, string | undefined>\n  /** Running Node.js version, e.g. `v22.1.0`. */\n  nodeVersion: string\n  /** Whether the terminal is interactive (stdout or stderr is a TTY). */\n  tty: boolean\n  /**\n   * Whether stdin is a terminal.\n   *\n   * Separate from {@link tty} because they answer different questions: `tty`\n   * says output can be styled, this says a prompt has somebody to answer it.\n   * A run with piped stdin and a terminal stdout has one and not the other.\n   */\n  stdinTty: boolean\n  /** Whether ANSI styling should be emitted. */\n  color: boolean\n  /** Terminal width in columns (80 when unknown). */\n  columns: number\n}\n\nfunction isInteractive(): boolean {\n  return process.stdout.isTTY === true || process.stderr.isTTY === true\n}\n\nfunction useColors(env: Record<string, string | undefined>, tty: boolean): boolean {\n  if (env.NO_COLOR !== undefined) return false\n  if (env.FORCE_COLOR === '1' || env.FORCE_COLOR === '2' || env.FORCE_COLOR === '3') return true\n  return tty\n}\n\n/**\n * Build the {@link CliContext} for the current process.\n * Pass `overrides` in tests to fake cwd, env, or terminal capabilities.\n */\nexport function createContext(overrides: Partial<CliContext> = {}): CliContext {\n  const env = overrides.env ?? { ...process.env }\n  const tty = overrides.tty ?? isInteractive()\n  return {\n    cwd: overrides.cwd ?? process.cwd(),\n    home: overrides.home ?? homedir(),\n    env,\n    nodeVersion: overrides.nodeVersion ?? process.version,\n    tty,\n    stdinTty: overrides.stdinTty ?? process.stdin.isTTY === true,\n    color: overrides.color ?? useColors(env, tty),\n    columns: overrides.columns ?? process.stdout.columns ?? process.stderr.columns ?? 80,\n  }\n}\n","import type { CheckSummary } from '../core/output'\nimport { exitCodeFor, writeHuman, writeJson } from '../core/output'\n\n/**\n * Output helpers for a command run — the only place commands should write\n * to the terminal or set an exit code.\n *\n * - {@link CliUi.human} → stderr\n * - {@link CliUi.json} → stdout (+ `schemaVersion`)\n * - {@link CliUi.exit} → `process.exitCode` from a check summary (or raw code)\n * - {@link CliUi.done} → human **or** json + exit in one call\n */\nexport interface CliUi {\n  /** Human report on stderr. */\n  human: (text: string) => void\n  /** Machine payload on stdout (adds `schemaVersion`). */\n  json: (payload: Record<string, unknown>) => void\n  /** Set exit code from a check summary (`fail > 0` → 1) or a raw code. */\n  exit: (summaryOrCode: CheckSummary | number) => void\n  /**\n   * Emit the command result: JSON when `jsonMode` (or constructor `json`) is\n   * on, otherwise the human string; then set the exit code from `summary`.\n   */\n  done: (options: {\n    human?: string\n    json?: Record<string, unknown>\n    summary?: CheckSummary\n    jsonMode?: boolean\n  }) => void\n}\n\n/** Build a {@link CliUi} bound to the current process streams. */\nexport function createUi(options: { json?: boolean } = {}): CliUi {\n  const ui: CliUi = {\n    human: writeHuman,\n    json: writeJson,\n    exit(summaryOrCode) {\n      process.exitCode = typeof summaryOrCode === 'number'\n        ? summaryOrCode\n        : exitCodeFor(summaryOrCode)\n    },\n    done({ human, json, summary, jsonMode }) {\n      const useJson = jsonMode ?? options.json === true\n      if (useJson) {\n        if (json) writeJson(json)\n      } else if (human !== undefined) {\n        writeHuman(human)\n      }\n      if (summary) ui.exit(summary)\n    },\n  }\n  return ui\n}\n","import type { ArgsDef, CommandDef, CommandContext, CommandMeta, ParsedArgs } from 'citty'\nimport { defineCommand } from 'citty'\nimport { EvlogError } from 'evlog'\nimport { createContext } from '../core/context'\nimport type { CliContext } from '../core/context'\nimport { formatCommandHeader, wantsHeader } from '../core/brand'\nimport { EXIT_FAIL, writeHuman } from '../core/output'\nimport { withCliDebug } from './debug'\nimport type { CliDebug, DebugArgs } from './debug'\nimport { createUi } from './ui'\nimport type { CliUi } from './ui'\n\ntype AnyCommand = CommandDef<ArgsDef>\n\n/**\n * Args injected on every {@link defineEvlogCommand} leaf.\n * Commands may still declare their own; these are merged in (command wins on clash).\n */\nexport const COMMON_ARGS = {\n  json: { type: 'boolean', description: 'Machine-readable JSON on stdout' },\n  debug: { type: 'boolean', description: 'Emit a debug case file via evlog' },\n  noHeader: { type: 'boolean', description: 'Skip the branded command header' },\n} as const satisfies ArgsDef\n\n/** Citty context plus CLI helpers injected by {@link defineEvlogCommand}. */\nexport type EvlogRunContext<T extends ArgsDef = ArgsDef> = CommandContext<T> & {\n  /** Process / terminal context (cwd, env, color, …). */\n  cli: CliContext\n  /**\n   * Debug handle — always present. No-ops when `--debug` is off;\n   * `log.step` still executes the work.\n   */\n  log: CliDebug\n  /**\n   * Terminal output — `human` (stderr), `json` (stdout), `exit`, `done`.\n   * Prefer this over touching `process.stdout` / `exitCode` in commands.\n   */\n  ui: CliUi\n}\n\nexport type EvlogCommandDef<T extends ArgsDef = ArgsDef> = Omit<CommandDef<T>, 'run' | 'args'> & {\n  args?: T\n  /**\n   * Suppress the branded header for this run.\n   *\n   * For commands that draw their own frame — `init` opens a clack session with\n   * its own intro, and stacking the ASCII header on top of it reads as two\n   * programs starting. Global flags (`--no-header`, `--json`) still win.\n   */\n  skipHeader?: (ctx: CliContext, args: ParsedArgs<T & typeof COMMON_ARGS>) => boolean\n  run?: (ctx: EvlogRunContext<T & typeof COMMON_ARGS>) => ReturnType<NonNullable<CommandDef<T>['run']>>\n}\n\nfunction runArgs(args: unknown): DebugArgs & { noHeader?: boolean } {\n  const a = args as DebugArgs & { noHeader?: boolean }\n  return { json: a?.json, noHeader: a?.noHeader, debug: a?.debug }\n}\n\nfunction syncMeta(meta: CommandDef['meta']): CommandMeta {\n  if (meta && typeof meta === 'object' && !('then' in meta)) {\n    return meta\n  }\n  return {}\n}\n\n/**\n * Define a citty command with branded header, shared flags, debug filet, and `ui`.\n *\n * `run` receives `{ …citty, cli, log, ui }`.\n *\n * @example\n * ```ts\n * export default defineEvlogCommand('audit', {\n *   meta: { description: '…' },\n *   args: { since: { type: 'string' } },\n *   async run({ args, cli, log, ui }) {\n *     const data = await log.step('load', () => load(cli.cwd))\n *     ui.done({\n *       jsonMode: args.json,\n *       json: { data },\n *       human: format(data),\n *       summary: { ok: 1, warn: 0, fail: 0 },\n *     })\n *   },\n * })\n * ```\n */\nexport function defineEvlogCommand<T extends ArgsDef = ArgsDef>(\n  command: string,\n  def: EvlogCommandDef<T>,\n): CommandDef<T & typeof COMMON_ARGS> {\n  const baseMeta = syncMeta(def.meta)\n  const args = {\n    ...COMMON_ARGS,\n    ...def.args,\n  } as T & typeof COMMON_ARGS\n\n  return defineCommand({\n    ...def,\n    args,\n    meta: {\n      ...baseMeta,\n      name: baseMeta.name ?? command.split(' ').at(-1),\n    },\n    async run(ctx: CommandContext<T & typeof COMMON_ARGS>) {\n      const flags = runArgs(ctx.args)\n      const cli = createContext()\n      if (wantsHeader(cli, flags) && !def.skipHeader?.(cli, ctx.args)) {\n        writeHuman(formatCommandHeader(cli, { command }))\n      }\n      const ui = createUi({ json: flags.json })\n      return await withCliDebug(cli, { command, ...flags }, async (log) => {\n        return await def.run?.({ ...ctx, cli, log, ui })\n      })\n    },\n  } as CommandDef<T & typeof COMMON_ARGS>)\n}\n\n/**\n * Render a catalog error and exit 1; rethrow anything unexpected.\n *\n * Shared because every command that writes needs the same three things from a\n * failure — the finding on the debug event, the `why` / `fix` for the reader,\n * and a non-zero exit — and three copies of that would drift.\n */\nexport function failWith(\n  error: unknown,\n  io: { args: { json?: boolean }, log: CliDebug, ui: CliUi },\n): void {\n  if (!(error instanceof EvlogError)) throw error\n  io.log.finding(\n    { code: error.code ?? 'cli.COMMAND_FAILED', why: error.why, fix: error.fix, link: error.link },\n    { status: 'fail' },\n  )\n  io.ui.done({\n    jsonMode: io.args.json,\n    json: { error: { code: error.code, message: error.message, why: error.why, fix: error.fix } },\n    human: error.fix ? `${error.message}\\n→ ${error.fix}` : error.message,\n  })\n  io.ui.exit(EXIT_FAIL)\n}\n\n/**\n * Recursively wrap every leaf `run` handler in a command tree with the\n * branded header (and optional debug wide event). Useful for third-party\n * trees (e.g. `@evlog/telemetry`).\n *\n * @param path - Command path segments already walked, e.g. `['telemetry']`.\n */\nexport function withCommandHeaders(cmd: AnyCommand, path: string[] = []): AnyCommand {\n  const wrappedSubs = cmd.subCommands\n    ? Object.fromEntries(\n      Object.entries(cmd.subCommands).map(([key, sub]) => [\n        key,\n        withCommandHeaders(sub as AnyCommand, [...path, key]),\n      ]),\n    )\n    : undefined\n\n  if (!cmd.run) {\n    return { ...cmd, subCommands: wrappedSubs }\n  }\n\n  const label = path.join(' ') || 'evlog'\n  const originalRun = cmd.run\n\n  return {\n    ...cmd,\n    subCommands: wrappedSubs,\n    async run(ctx) {\n      const flags = runArgs(ctx.args)\n      const cli = createContext()\n      if (wantsHeader(cli, flags)) {\n        writeHuman(formatCommandHeader(cli, { command: label }))\n      }\n      return await withCliDebug(cli, { command: label, ...flags }, () => originalRun(ctx))\n    },\n  }\n}\n","import { EXIT_FAIL } from '../core/output'\nimport { formatAgentsReport } from '../lib/agents/report'\nimport { runAgents } from '../lib/agents/run'\nimport type { AgentsOptions, AgentsResult } from '../lib/agents/run'\nimport { defineEvlogCommand, failWith } from '../lib/command'\nimport { canPrompt } from '../lib/init/prompts'\n\nfunction parseSkillsArg(value: unknown): { skills: string[], noSkills: boolean } {\n  if (value === false) return { skills: [], noSkills: true }\n  if (typeof value !== 'string' || value.length === 0) return { skills: [], noSkills: false }\n  return { skills: value.split(',').map(entry => entry.trim()).filter(Boolean), noSkills: false }\n}\n\n/**\n * `evlog agents` — teach the agents working in this project how to use evlog.\n *\n * Wiring evlog in is half the job: the other half is the assistant writing the\n * handlers, which will keep reaching for `console.log` until something in the\n * repository tells it not to. This writes that something — a marker-delimited\n * block in `AGENTS.md`, and a `CLAUDE.md` that points at it.\n *\n * The skills themselves are handed to `npx skills add`. Every agent reads a\n * different directory and that CLI already resolves them, so copying the files\n * ourselves would produce a second set nothing could update.\n */\nexport default defineEvlogCommand('agents', {\n  meta: { name: 'agents', description: 'Write evlog conventions into AGENTS.md and install the agent skills' },\n  /* The clack session draws its own intro; two banners read as two programs. */\n  skipHeader: (ctx, args) => args.json !== true && args.yes !== true && canPrompt(ctx),\n  args: {\n    cwd: { type: 'string', description: 'Project directory (default: current)' },\n    // citty negations: declared positive so `--no-skills` works.\n    skills: { type: 'string', default: '', description: 'Skills to install, comma-separated (--no-skills for the AGENTS.md block alone)' },\n    global: { type: 'boolean', alias: 'g', description: 'Install the skills for every project instead of this one' },\n    source: { type: 'string', description: 'Where the skills are published (default: https://www.evlog.dev)' },\n    yes: { type: 'boolean', alias: 'y', description: 'Apply without confirming' },\n    dryRun: { type: 'boolean', description: 'Show what would change without writing anything' },\n  },\n  async run({ args, cli, log, ui }) {\n    const cwd = typeof args.cwd === 'string' && args.cwd.length > 0 ? args.cwd : undefined\n    const ctx = cwd ? { ...cli, cwd } : cli\n    const { skills, noSkills } = parseSkillsArg(args.skills)\n\n    const options: AgentsOptions = {\n      skills,\n      noSkills,\n      global: args.global,\n      source: typeof args.source === 'string' && args.source.length > 0 ? args.source : undefined,\n      dryRun: args.dryRun,\n      yes: args.yes,\n      /* JSON output and a prompt cannot share a terminal: the payload is the\n         contract, and half a TUI on stderr in front of it helps nobody. */\n      nonInteractive: args.json === true,\n    }\n\n    let result: AgentsResult\n    try {\n      result = await runAgents(ctx, log, options)\n    } catch (error) {\n      return failWith(error, { args, log, ui })\n    }\n\n    ui.done({\n      jsonMode: args.json,\n      json: toJson(result),\n      /* The interactive flow already narrated itself through clack. */\n      human: result.interactive ? undefined : formatAgentsReport(ctx, result),\n    })\n\n    if (result.skills.status === 'failed') {\n      ui.exit(EXIT_FAIL)\n    }\n  },\n})\n\nfunction toJson(result: AgentsResult): Record<string, unknown> {\n  return {\n    framework: result.framework,\n    skills: result.skills,\n    written: result.written.map(action => ({ file: action.relative, kind: action.kind })),\n    already: result.already,\n    dryRun: result.dryRun,\n    cancelled: result.cancelled,\n  }\n}\n","import { telemetry } from '@evlog/telemetry'\nimport type { CliContext } from '../core/context'\nimport {\n  DOCS_LABEL,\n  DOCS_URL,\n  createStyle,\n  formatChecks,\n  formatSummary,\n  summarize,\n} from '../core/output'\nimport type { Check, CheckSummary } from '../core/output'\nimport { defineEvlogCommand } from '../lib/command'\nimport type { CatalogFindingSource, CliDebug } from '../lib/debug'\nimport { createNoopCliDebug } from '../lib/debug'\nimport { cliErrors } from '../lib/errors'\nimport {\n  detectStack,\n  findConfiguredFsDrain,\n  findLogsSink,\n  prettyPath,\n  resolveEvlog,\n  resolveProject,\n} from '../lib/project'\nimport type { ProjectInfo } from '../lib/project'\n\n/** Typed result of `evlog doctor` — rendered by {@link formatDoctorReport}. */\nexport interface DoctorResult {\n  project: {\n    cwd: string\n    root: string\n    packageDir: string\n    kind: string\n    name: string | null\n    stack: string[]\n  }\n  checks: Check[]\n  sections: { title: string, checks: Check[] }[]\n  summary: CheckSummary\n}\n\nconst MIN_NODE_MAJOR = 20\n\nfunction checkNode(ctx: CliContext): Check {\n  const major = Number.parseInt(ctx.nodeVersion.replace(/^v/, ''), 10)\n  if (Number.isNaN(major)) {\n    return { id: 'node', status: 'warn', message: `unrecognized Node version ${ctx.nodeVersion}` }\n  }\n  if (major < MIN_NODE_MAJOR) {\n    return {\n      id: 'node',\n      status: 'fail',\n      message: `Node ${ctx.nodeVersion} is too old`,\n      hint: `evlog CLI requires Node >= ${MIN_NODE_MAJOR}`,\n    }\n  }\n  return { id: 'node', status: 'ok', message: ctx.nodeVersion }\n}\n\nfunction checkProject(project: ProjectInfo): Check {\n  if (!project.packageJson) {\n    return {\n      id: 'project',\n      status: 'warn',\n      message: 'no package.json found',\n      hint: 'run from your app or package directory',\n    }\n  }\n\n  const name = project.packageName ?? prettyPath(project.root, project.packageDir)\n  if (project.kind === 'single') {\n    return { id: 'project', status: 'ok', message: name }\n  }\n\n  const where = prettyPath(project.root, project.packageDir)\n  const scope = where === '.' ? 'workspace root' : where\n  return {\n    id: 'project',\n    status: 'ok',\n    message: `${name} · ${project.kind} · ${scope}`,\n  }\n}\n\nfunction checkEvlog(\n  project: ProjectInfo,\n  resolved: Awaited<ReturnType<typeof resolveEvlog>>,\n): Check {\n  const { install, declared } = resolved\n\n  if (install) {\n    const loc = prettyPath(project.root, install.path)\n    const range = install.declaredRange ? ` (${install.declaredRange})` : ''\n    return {\n      id: 'evlog',\n      status: 'ok',\n      message: `v${install.version}${range}`,\n      hint: loc !== '.' ? `resolved from ${loc}` : undefined,\n    }\n  }\n\n  if (declared) {\n    return {\n      id: 'evlog',\n      status: 'warn',\n      message: `declared ${declared.range} but not installed`,\n      hint: 'run your package manager install step',\n    }\n  }\n\n  return {\n    id: 'evlog',\n    status: 'warn',\n    message: 'not found in this project',\n    hint: 'pnpm add evlog — https://evlog.dev/getting-started/installation',\n  }\n}\n\nfunction checkStack(stack: string[], hasEvlog: boolean): Check | null {\n  if (stack.length === 0) return null\n  const labels = stack.join(', ')\n  if (hasEvlog) {\n    return { id: 'stack', status: 'ok', message: labels }\n  }\n  return {\n    id: 'stack',\n    status: 'warn',\n    message: labels,\n    hint: 'framework detected — add evlog and wire the matching integration',\n  }\n}\n\n/**\n * The fs drain is optional: it writes lazily, so a wired drain is a sink even\n * before the first event, and a project without one needs no local sink.\n * Returns `null` when the check has nothing to say.\n */\nasync function checkLogs(project: ProjectInfo, env: Record<string, string | undefined>): Promise<Check | null> {\n  const sink = await findLogsSink(project)\n  if (sink) {\n    const loc = prettyPath(project.cwd, sink.dir)\n    if (sink.files === 0) return { id: 'logs', status: 'ok', message: `empty sink · ${loc}` }\n    return {\n      id: 'logs',\n      status: 'ok',\n      message: `${sink.files} file${sink.files === 1 ? '' : 's'} · ${loc}`,\n    }\n  }\n\n  const declared = await findConfiguredFsDrain(project, env)\n  if (declared) {\n    const loc = prettyPath(project.cwd, declared.dir)\n    return {\n      id: 'logs',\n      status: 'ok',\n      message: `empty sink · ${loc}`,\n      hint: 'created on first write by the fs drain (evlog/fs)',\n    }\n  }\n  return null\n}\n\nfunction findingsForChecks(\n  checks: Check[],\n  resolved: Awaited<ReturnType<typeof resolveEvlog>>,\n): Array<{ source: CatalogFindingSource, id: string, status: Check['status'] }> {\n  const findings: Array<{ source: CatalogFindingSource, id: string, status: Check['status'] }> = []\n\n  for (const check of checks) {\n    if (check.status === 'ok') continue\n\n    if (check.id === 'node' && check.status === 'fail') {\n      findings.push({ source: cliErrors.NODE_TOO_OLD, id: check.id, status: check.status })\n      continue\n    }\n\n    if (check.id === 'project') {\n      findings.push({ source: cliErrors.PROJECT_NO_PACKAGE, id: check.id, status: check.status })\n      continue\n    }\n\n    if (check.id === 'evlog') {\n      findings.push({\n        source: resolved.declared\n          ? cliErrors.EVLOG_DECLARED_NOT_INSTALLED\n          : cliErrors.EVLOG_NOT_FOUND,\n        id: check.id,\n        status: check.status,\n      })\n      continue\n    }\n  }\n\n  return findings\n}\n\n/**\n * Diagnose the evlog setup for `ctx.cwd` (monorepo-aware).\n * Pure with respect to the context: no printing, no `process.*` access.\n */\nexport async function runDoctor(\n  ctx: CliContext,\n  log: CliDebug = createNoopCliDebug(),\n): Promise<DoctorResult> {\n  const project = await log.step(\n    'resolveProject',\n    () => resolveProject(ctx.cwd),\n    p => ({\n      cwd: ctx.cwd,\n      project: {\n        kind: p.kind,\n        root: p.root,\n        packageDir: p.packageDir,\n        name: p.packageName,\n      },\n    }),\n  )\n\n  const resolved = await log.step(\n    'resolveEvlog',\n    () => resolveEvlog(project),\n    r => ({\n      evlog: r.install\n        ? { version: r.install.version, path: r.install.path }\n        : { missing: true, declared: r.declared },\n      resolveTried: r.tried,\n    }),\n  )\n\n  const stack = await log.step(\n    'detectStack',\n    () => detectStack(project.packageJson),\n    s => ({ stack: s }),\n  )\n\n  const checks = await log.step('checks', async () => {\n    const environment: Check[] = [\n      checkNode(ctx),\n      checkProject(project),\n    ]\n    const stackCheck = checkStack(stack, !!resolved.install)\n    if (stackCheck) environment.push(stackCheck)\n\n    const logsCheck = await checkLogs(project, ctx.env)\n    return [\n      ...environment,\n      checkEvlog(project, resolved),\n      ...(logsCheck ? [logsCheck] : []),\n    ]\n  })\n\n  const sections = [\n    {\n      title: 'ENVIRONMENT',\n      checks: checks.filter(c => c.id === 'node' || c.id === 'project' || c.id === 'stack'),\n    },\n    {\n      title: 'EVLOG',\n      checks: checks.filter(c => c.id === 'evlog' || c.id === 'logs'),\n    },\n  ]\n\n  const summary = summarize(checks)\n\n  for (const { source, id, status } of findingsForChecks(checks, resolved)) {\n    log.finding(source, { id, status })\n  }\n\n  log.set({\n    steps: ['done'],\n    summary,\n    checks: checks.map(c => ({ id: c.id, status: c.status })),\n  })\n\n  return {\n    project: {\n      cwd: project.cwd,\n      root: project.root,\n      packageDir: project.packageDir,\n      kind: project.kind,\n      name: project.packageName,\n      stack,\n    },\n    checks,\n    sections,\n    summary,\n  }\n}\n\n/**\n * On-brand doctor report: sectioned checks + summary.\n * Command header is owned by {@link defineEvlogCommand}.\n */\nexport function formatDoctorReport(ctx: CliContext, result: DoctorResult): string {\n  const { paint, link } = createStyle(ctx)\n  const lines: string[] = []\n\n  const where = result.project.kind === 'single'\n    ? paint('dim', result.project.name ?? result.project.cwd)\n    : paint('dim', `${result.project.kind} workspace`)\n  lines.push(where, '')\n\n  for (const section of result.sections) {\n    lines.push(paint('dim', section.title))\n    lines.push(formatChecks(ctx, section.checks), '')\n  }\n\n  lines.push(formatSummary(ctx, result.summary))\n  lines.push(`${paint('dim', 'docs')} ${link(DOCS_URL, DOCS_LABEL)}`)\n  lines.push('')\n\n  return lines.join('\\n')\n}\n\n/**\n * What `evlog doctor` reports.\n *\n * Check ids are this CLI's own closed set; their statuses say which part of a\n * setup people get stuck on, which is the thing worth fixing in the docs.\n * Counts and booleans only — never the project name, the path, or the version.\n */\nfunction doctorTelemetryFields(result: DoctorResult): Record<string, boolean | number> {\n  const statusOf = (id: string) => result.checks.find(check => check.id === id)?.status\n\n  return {\n    checksFailed: result.summary.fail,\n    checksWarned: result.summary.warn,\n    checksPassed: result.summary.ok,\n    workspace: result.project.kind !== 'single',\n    doctorEvlogFound: statusOf('evlog') === 'ok',\n    doctorLogsSink: statusOf('logs') === 'ok',\n    doctorStackDetected: result.project.stack.length,\n  }\n}\n\n/** Every field {@link doctorTelemetryFields} can emit — used to document the disclosure. */\nexport function doctorTelemetryFieldNames(): string[] {\n  return Object.keys(doctorTelemetryFields({\n    project: { cwd: '', root: '', packageDir: '', kind: 'single', name: null, stack: [] },\n    checks: [],\n    sections: [],\n    summary: { ok: 0, warn: 0, fail: 0 },\n  }))\n}\n\n/**\n * `evlog doctor` — diagnose the local evlog setup.\n * Logic lives in {@link runDoctor}; this file owns the citty surface.\n */\nexport default defineEvlogCommand('doctor', {\n  meta: { name: 'doctor', description: 'Diagnose your evlog setup' },\n  args: {\n    cwd: { type: 'string', description: 'Project directory (default: current)' },\n  },\n  async run({ args, cli, log, ui }) {\n    const cwd = typeof args.cwd === 'string' && args.cwd.length > 0 ? args.cwd : undefined\n    const ctx = cwd ? { ...cli, cwd } : cli\n    const result = await runDoctor(ctx, log)\n\n    telemetry.set(doctorTelemetryFields(result))\n\n    ui.done({\n      jsonMode: args.json,\n      json: {\n        project: result.project,\n        checks: result.checks,\n        summary: result.summary,\n      },\n      human: formatDoctorReport(ctx, result),\n      summary: result.summary,\n    })\n  },\n})\n","import { execFile } from 'node:child_process'\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { promisify } from 'node:util'\n\nconst exec = promisify(execFile)\n\n/** Package managers `init` knows how to add a dependency with. */\nexport type PackageManager = 'pnpm' | 'bun' | 'yarn' | 'npm'\n\nconst LOCKFILES: Record<PackageManager, string[]> = {\n  pnpm: ['pnpm-lock.yaml'],\n  bun: ['bun.lock', 'bun.lockb'],\n  yarn: ['yarn.lock'],\n  npm: ['package-lock.json'],\n}\n\n/** Pick the package manager from lockfiles, nearest directory first. */\nexport function detectPackageManager(dirs: string[]): PackageManager {\n  for (const dir of dirs) {\n    for (const [manager, files] of Object.entries(LOCKFILES) as [PackageManager, string[]][]) {\n      if (files.some(file => existsSync(join(dir, file)))) return manager\n    }\n  }\n  return 'npm'\n}\n\n/** The command line that adds `evlog`, as the user would type it. */\nexport function installCommand(manager: PackageManager, pkg = 'evlog'): string {\n  return manager === 'npm' ? `npm install ${pkg}` : `${manager} add ${pkg}`\n}\n\n/** Returns the failure rather than throwing — the wiring already on disk stands. */\nexport async function runInstall(\n  manager: PackageManager,\n  cwd: string,\n  pkg = 'evlog',\n): Promise<{ ok: true } | { ok: false, error: string }> {\n  const args = manager === 'npm' ? ['install', pkg] : ['add', pkg]\n  try {\n    await exec(manager, args, { cwd, timeout: 5 * 60_000 })\n    return { ok: true }\n  } catch (error) {\n    const message = error instanceof Error ? error.message : String(error)\n    return { ok: false, error: message.split('\\n')[0] ?? message }\n  }\n}\n","import { cliErrors } from '../errors'\nimport type { Framework } from '../map/types'\nimport {\n  availableExtras,\n  DEFAULT_ENRICHERS,\n  DESTINATIONS,\n  ENRICHERS,\n  EXTRAS,\n  findDestination,\n  findEnricher,\n  findExtra,\n  findSamplingPreset,\n  PROD_DESTINATIONS,\n  SAMPLING_PRESETS,\n} from './catalog'\nimport type { DrainId, EnricherId, ExtraId, OfferContext, SamplingProfile } from './catalog'\nimport type { InitAnswers } from './prompts'\n\nconst DRAIN_IDS = DESTINATIONS.map(destination => destination.id).join(', ')\nconst PROD_IDS = PROD_DESTINATIONS.map(destination => destination.id).join(', ')\nconst EXTRA_IDS = EXTRAS.map(extra => extra.id).join(', ')\nconst ENRICHER_IDS = ENRICHERS.map(enricher => enricher.id).join(', ')\nconst SAMPLING_IDS = SAMPLING_PRESETS.map(preset => preset.id).join(', ')\n\n/**\n * Read a destination id, rejecting one the catalog does not know.\n *\n * Falling back to the default would wire local files into an app whose author\n * asked for Axiom, and they would find out when production told them nothing.\n */\nexport function parseDrainArg(value: unknown): DrainId | undefined {\n  if (typeof value !== 'string' || value.length === 0) return undefined\n  const destination = findDestination(value)\n  if (!destination) throw cliErrors.INIT_INVALID_DRAIN({ value, known: DRAIN_IDS })\n  return destination.id\n}\n\n/** Read `--prod-drain a,b`, which may name several destinations. */\nexport function parseProdDrainsArg(value: unknown): DrainId[] | undefined {\n  if (value === false) return []\n  if (typeof value !== 'string' || value.length === 0) return undefined\n\n  const parsed: DrainId[] = []\n  for (const id of splitList(value)) {\n    // Membership in PROD_DESTINATIONS is the rule, not a re-derivation of it.\n    const destination = PROD_DESTINATIONS.find(candidate => candidate.id === id)\n    if (!destination) throw cliErrors.INIT_INVALID_DRAIN({ value: id, known: PROD_IDS })\n    if (!parsed.includes(destination.id)) parsed.push(destination.id)\n  }\n  return parsed\n}\n\n/** Read `--extras a,b`, rejecting unknown ids the same way. */\nexport function parseExtrasArg(value: unknown): ExtraId[] | undefined {\n  if (value === false) return []\n  if (typeof value !== 'string' || value.length === 0) return undefined\n\n  const parsed: ExtraId[] = []\n  for (const id of splitList(value)) {\n    const extra = findExtra(id)\n    if (!extra) throw cliErrors.INIT_INVALID_EXTRA({ value: id, known: EXTRA_IDS })\n    if (!parsed.includes(extra.id)) parsed.push(extra.id)\n  }\n  return parsed\n}\n\n/** Read `--enrichers a,b`; absent means every enricher when the extra is on. */\nexport function parseEnrichersArg(value: unknown): EnricherId[] | undefined {\n  if (typeof value !== 'string' || value.length === 0) return undefined\n\n  const parsed: EnricherId[] = []\n  for (const id of splitList(value)) {\n    const enricher = findEnricher(id)\n    if (!enricher) throw cliErrors.INIT_INVALID_ENRICHER({ value: id, known: ENRICHER_IDS })\n    if (!parsed.includes(enricher.id)) parsed.push(enricher.id)\n  }\n  return parsed\n}\n\nexport function parseSamplingArg(value: unknown): SamplingProfile | undefined {\n  if (typeof value !== 'string' || value.length === 0) return undefined\n  const preset = findSamplingPreset(value)\n  if (!preset) throw cliErrors.INIT_INVALID_SAMPLING({ value, known: SAMPLING_IDS })\n  return preset.id\n}\n\nfunction splitList(value: string): string[] {\n  return value.split(',').map(entry => entry.trim()).filter(Boolean)\n}\n\nexport interface ResolveInput {\n  framework: Framework\n  defaultService: string\n  evlogInstalled: boolean\n  /** `--install` (default true); irrelevant when evlog is already there. */\n  install: boolean\n  /** `--agents` (default true) — write the AGENTS.md block and install the skills. */\n  agentGuide: boolean\n  devDrain?: DrainId\n  prodDrains?: DrainId[]\n  extras?: ExtraId[]\n  enrichers?: EnricherId[]\n  sampling?: SamplingProfile\n  service?: string\n  /** What the scan found, for gating the same offers the prompts gate on. */\n  offers: (prodDrains: DrainId[], framework: Framework) => OfferContext\n}\n\n/**\n * The answers a non-interactive run uses: flags first, then defaults.\n *\n * Same shape the prompts produce, so `--drain fs` and picking \"Local files\" in\n * the picker are the same run downstream.\n */\nexport function resolveAnswers(input: ResolveInput): InitAnswers {\n  const devDrain = input.devDrain ?? 'fs'\n  const prodDrains = input.prodDrains ?? []\n  const extras = (input.extras ?? []).filter(id => applicableExtras(input).has(id))\n\n  return {\n    framework: input.framework,\n    service: input.service ?? input.defaultService,\n    devDrain,\n    prodDrains,\n    extras,\n    enrichers: extras.includes('enrichers') ? input.enrichers ?? [...DEFAULT_ENRICHERS] : [],\n    sampling: extras.includes('sampling') ? input.sampling ?? 'medium' : 'all',\n    install: input.evlogInstalled ? false : input.install,\n    agentGuide: input.agentGuide,\n  }\n}\n\n/** Shared by {@link resolveAnswers} and {@link droppedExtras} — two views of one decision. */\nfunction applicableExtras(input: ResolveInput): Set<ExtraId> {\n  return new Set(\n    availableExtras(input.offers(input.prodDrains ?? [], input.framework)).map(extra => extra.id),\n  )\n}\n\n/** Extras asked for that this project cannot use — reported, not applied. */\nexport function droppedExtras(input: ResolveInput): ExtraId[] {\n  const applicable = applicableExtras(input)\n  return (input.extras ?? []).filter(id => !applicable.has(id))\n}\n","import { telemetry } from '@evlog/telemetry'\nimport { DESTINATIONS, ENRICHERS, EXTRAS, SAMPLING_PRESETS } from './catalog'\nimport { INIT_FRAMEWORKS } from './frameworks'\nimport type { InitResult } from './run'\n\n/**\n * Which choices `init` records, to learn which options people actually pick.\n *\n * Only ids from this CLI's own catalog, counts and booleans. The service name,\n * package names, paths and anything read out of the user's source never leave.\n */\nconst PREFIX = 'init'\n\n/** String fields, with the exact set of values each may take. */\nexport const INIT_TELEMETRY_FIELDS = {\n  initFramework: INIT_FRAMEWORKS,\n  initDevDrain: DESTINATIONS.map(destination => destination.id),\n  initSampling: SAMPLING_PRESETS.map(preset => preset.id),\n} as const satisfies Record<string, readonly string[]>\n\nfunction pascal(id: string): string {\n  return id.split('-').map(part => part[0]!.toUpperCase() + part.slice(1)).join('')\n}\n\n/** Field name for a multi-select member: `axiom` → `initProdAxiom`. */\nexport function memberField(group: 'Prod' | 'Extra' | 'Enricher', id: string): string {\n  return `${PREFIX}${group}${pascal(id)}`\n}\n\n/**\n * Record the answers on the active telemetry run.\n *\n * Multi-selects become one boolean per chosen option, so \"how many runs picked\n * Axiom\" is a count rather than a substring match.\n */\nexport function recordInitAnswers(result: InitResult): void {\n  const { answers } = result\n\n  const fields: Record<string, boolean | number | string> = {\n    initFramework: answers.framework,\n    initDevDrain: answers.devDrain,\n    initInteractive: result.interactive,\n    initCancelled: result.cancelled,\n    initProdDrainCount: answers.prodDrains.length,\n  }\n\n  if (answers.extras.includes('sampling')) fields.initSampling = answers.sampling\n  for (const id of answers.prodDrains) fields[memberField('Prod', id)] = true\n  for (const id of answers.extras) fields[memberField('Extra', id)] = true\n  for (const id of answers.enrichers) fields[memberField('Enricher', id)] = true\n\n  if (!result.cancelled) {\n    fields.initFilesWritten = result.written.length\n    fields.initManualSteps = result.manual.length\n    fields.initDryRun = result.dryRun\n    if (result.verified) fields.initDoctorFail = result.verified.fail\n  }\n\n  fields.initAgentGuide = answers.agentGuide\n  if (result.agentGuide) {\n    fields.initAgentSkillsFound = result.agentGuide.found.length\n    fields.initAgentSkillsFailed = result.agentGuide.status === 'failed'\n  }\n\n  /* The gap between \"offered\" and \"taken\" is what says whether an offer earns\n     its place. Whether the scan found something, never what it found. */\n  if (result.insight) {\n    fields.initHadRepeatedErrors = result.insight.repeatedErrors > 0\n    fields.initHadAuditGaps = result.insight.auditGaps > 0\n  }\n\n  /* Typed for numbers and booleans because strings need an allowlisted key —\n     ours are, on the wrapper. The cast cannot get an unlisted value past\n     `sanitizeCustom`. */\n  telemetry.set(fields as Record<string, boolean | number>)\n}\n\n/** Every field name this module can emit — used to document the disclosure. */\nexport function initTelemetryFieldNames(): string[] {\n  return [\n    ...Object.keys(INIT_TELEMETRY_FIELDS),\n    'initInteractive',\n    'initCancelled',\n    'initProdDrainCount',\n    'initFilesWritten',\n    'initManualSteps',\n    'initDryRun',\n    'initDoctorFail',\n    'initHadRepeatedErrors',\n    'initHadAuditGaps',\n    'initAgentGuide',\n    'initAgentSkillsFound',\n    'initAgentSkillsFailed',\n    ...DESTINATIONS.map(destination => memberField('Prod', destination.id)),\n    ...EXTRAS.map(extra => memberField('Extra', extra.id)),\n    ...ENRICHERS.map(enricher => memberField('Enricher', enricher.id)),\n  ]\n}\n","import { mkdir, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport { runDoctor } from '../../commands/doctor'\nimport type { CliContext } from '../../core/context'\nimport { planAgents } from '../agents/plan'\nimport { findInstalledSkills, runSkills, skillsCommand } from '../agents/skills'\nimport type { CliDebug } from '../debug'\nimport { createNoopCliDebug } from '../debug'\nimport { cliErrors } from '../errors'\nimport { detectFramework } from '../map/detect'\nimport type { Framework } from '../map/types'\nimport { resolveEvlog, resolveProject } from '../project'\nimport type { PackageJson, ProjectInfo } from '../project'\nimport type { DrainId, EnricherId, ExtraId, OfferContext, SamplingProfile } from './catalog'\nimport { isInitFramework, planWiring } from './frameworks'\nimport type { FileAction, ManualStep } from './frameworks'\nimport { readProject } from './insight'\nimport type { ProjectInsight } from './insight'\nimport { detectPackageManager, installCommand, runInstall } from './pm'\nimport type { PackageManager } from './pm'\nimport {\n  askAnswers,\n  canPrompt,\n  closeCancelled,\n  closeInteractive,\n  confirmPlan,\n  showPlan,\n  InitCancelled,\n  noteEnvironment,\n  noteManual,\n  noteSkills,\n  noteSkillsStarting,\n  openInteractive,\n  runVerification,\n} from './prompts'\nimport type { InitAnswers } from './prompts'\nimport { droppedExtras, resolveAnswers } from './resolve'\nimport { recordInitAnswers } from './telemetry'\n\nexport interface InstallOutcome {\n  status: 'already' | 'installed' | 'skipped' | 'failed'\n  /** The command as the user would type it — printed whatever the outcome. */\n  command: string\n  version?: string\n  error?: string\n}\n\nexport interface InitResult {\n  project: Pick<ProjectInfo, 'cwd' | 'root' | 'packageDir' | 'kind' | 'packageName'>\n  answers: InitAnswers\n  packageManager: PackageManager\n  install: InstallOutcome\n  /** Files written (or that would be, under `--dry-run`). */\n  written: FileAction[]\n  already: string[]\n  manual: ManualStep[]\n  /** Extras asked for that this project cannot use. */\n  dropped: ExtraId[]\n  /** What the scan found — why the offers were what they were. */\n  insight: InsightSummary | null\n  /** `evlog doctor` after the writes, when it ran. */\n  verified: VerifySummary | null\n  /** The agent guidelines step, when it was asked for. */\n  agentGuide: AgentGuideSummary | null\n  dryRun: boolean\n  /** True when the run asked questions — the report stays quiet if so. */\n  interactive: boolean\n  /** True when the user answered \"no\" at the plan, or hit Ctrl-C. */\n  cancelled: boolean\n}\n\n/** What the scan found, summarised for the report and the telemetry event. */\nexport interface InsightSummary {\n  repeatedErrors: number\n  auditGaps: number\n  pairable: string[]\n}\n\n/** The `evlog doctor` tally taken straight after the writes. */\nexport interface VerifySummary {\n  ok: number\n  warn: number\n  fail: number\n}\n\nexport type SkillsStatus = 'pending' | 'already' | 'installed' | 'failed'\n\n/** What the agent guidelines step managed to do. */\nexport interface AgentGuideSummary {\n  /** Skills already on disk when the run started, in any agent's directory. */\n  found: string[]\n  /** The agent directories they were found in. */\n  dirs: string[]\n  /** `npx skills add …`, as the user would type it. */\n  command: string\n  status: SkillsStatus\n  /** Why the skills CLI did not finish, when it did not. */\n  error?: string\n}\n\nexport interface InitOptions {\n  framework?: Framework\n  service?: string\n  devDrain?: DrainId\n  prodDrains?: DrainId[]\n  extras?: ExtraId[]\n  enrichers?: EnricherId[]\n  sampling?: SamplingProfile\n  /** Plan everything, write nothing. */\n  dryRun?: boolean\n  /** Run the package manager when evlog is missing. Default: true. */\n  install?: boolean\n  /** Skip every question and take the defaults. */\n  yes?: boolean\n  /** Write the AGENTS.md block and install the skills. Default: true. */\n  agentGuide?: boolean\n  /** Force non-interactive regardless of the terminal (set by `--json`). */\n  nonInteractive?: boolean\n}\n\n/** The package name without its scope: `@acme/checkout` → `checkout`. */\nfunction defaultService(project: ProjectInfo): string {\n  const name = project.packageName\n  if (!name) return 'app'\n  const unscoped = name.startsWith('@') ? name.split('/').at(-1) ?? name : name\n  return unscoped.replace(/[^a-z0-9-_]/gi, '-') || 'app'\n}\n\n/** The module subpath and config factory differ per major. */\nfunction detectNitroMajor(pkg: PackageJson | null, framework: Framework): 2 | 3 {\n  if (framework === 'tanstack-start') return 3\n  const deps = { ...pkg?.dependencies, ...pkg?.devDependencies }\n  if ('nitropack' in deps) return 2\n  return 3\n}\n\n/**\n * Wire evlog into the project: read it, ask, plan, confirm, write, verify.\n *\n * Interactive when there is somebody to answer; flags and defaults fill in\n * everything when there is not. Both paths produce the same {@link InitAnswers}.\n * Nothing here overwrites a file that already exists.\n */\nexport async function runInit(\n  ctx: CliContext,\n  log: CliDebug = createNoopCliDebug(),\n  options: InitOptions = {},\n): Promise<InitResult> {\n  const project = await log.step(\n    'resolveProject',\n    () => resolveProject(ctx.cwd),\n    p => ({ cwd: ctx.cwd, project: { kind: p.kind, root: p.root, name: p.packageName } }),\n  )\n\n  const detection = await log.step(\n    'detectFramework',\n    () => detectFramework(project, options.framework),\n    r => ({ framework: r.framework }),\n  )\n\n  /* `map` scans more frameworks than `init` can wire: refuse the map-only ones\n     here, before any prompt, instead of crashing in the planner. */\n  if (!isInitFramework(detection.framework)) {\n    throw cliErrors.INIT_FRAMEWORK_UNSUPPORTED({ framework: detection.framework })\n  }\n\n  const resolved = await log.step(\n    'resolveEvlog',\n    () => resolveEvlog(project),\n    r => ({ hasEvlog: !!r.install }),\n  )\n\n  // The same analysis `map` runs, so an offer can carry its evidence.\n  const insight = await log.step(\n    'readProject',\n    () => readProject(project.packageDir, detection.framework, project.packageName ?? 'app'),\n    r => ({ repeatedErrors: r?.repeatedErrors.length ?? 0, auditGaps: r?.auditGaps.length ?? 0 }),\n  )\n\n  const packageManager = detectPackageManager([project.packageDir, project.root])\n  const command = installCommand(packageManager)\n  const dryRun = options.dryRun === true\n  const evlogInstalled = !!resolved.install\n  const interactive = !options.nonInteractive && !options.yes && canPrompt(ctx)\n\n  const offers = (prodDrains: DrainId[], framework: Framework): OfferContext => ({\n    framework,\n    prodDrains,\n    facts: insight?.facts ?? null,\n    auditGaps: insight?.auditGaps.length ?? 0,\n  })\n\n  const base = {\n    framework: detection.framework,\n    defaultService: defaultService(project),\n    evlogInstalled,\n    install: options.install !== false,\n    agentGuide: options.agentGuide !== false,\n    devDrain: options.devDrain,\n    prodDrains: options.prodDrains,\n    extras: options.extras,\n    enrichers: options.enrichers,\n    sampling: options.sampling,\n    service: options.service,\n    offers,\n  }\n\n  let answers: InitAnswers\n\n  if (interactive) {\n    openInteractive(ctx, 'evlog init', project.packageName ?? project.packageDir)\n    try {\n      answers = await askAnswers({\n        ctx,\n        detected: detection.framework,\n        /* An explicit --framework is an answer, not a guess: do not ask again. */\n        uncertain: options.framework === undefined && detection.warnings.length > 0,\n        defaultService: base.defaultService,\n        evlogInstalled,\n        installRequested: base.install,\n        agentGuideRequested: base.agentGuide,\n        offers,\n      })\n    } catch (error) {\n      if (error instanceof InitCancelled) {\n        closeCancelled()\n        return cancelled(cancelledResult({ project, answers: resolveAnswers(base), packageManager, command, dryRun }))\n      }\n      throw error\n    }\n  } else {\n    answers = resolveAnswers(base)\n  }\n\n  log.set({\n    devDrain: answers.devDrain,\n    prodDrains: answers.prodDrains.join(',') || 'none',\n    extras: answers.extras.join(',') || 'none',\n  })\n\n  const plan = await log.step(\n    'planWiring',\n    () => planWiring({\n      root: project.packageDir,\n      framework: answers.framework,\n      service: answers.service,\n      devDrain: answers.devDrain,\n      prodDrains: answers.prodDrains,\n      extras: answers.extras,\n      enrichers: answers.enrichers,\n      sampling: answers.sampling,\n      nitroMajor: detectNitroMajor(project.packageJson, answers.framework),\n      repeatedErrors: insight?.repeatedErrors ?? [],\n      auditGaps: insight?.auditGaps ?? [],\n    }),\n    r => ({ writes: r.actions.length, manual: r.manual.length }),\n  )\n\n  /* Merged into the same plan rather than run afterwards, so the user reads one\n     list and confirms once. The skills are a separate step: `npx skills add`\n     owns them, and it runs alongside the package-manager install below. */\n  let agentGuide: AgentGuideSummary | null = null\n  if (answers.agentGuide) {\n    agentGuide = await log.step('agentGuide', () => {\n      const found = findInstalledSkills(project.packageDir, ctx.home)\n      const guide = planAgents({\n        root: project.packageDir,\n        projectName: project.packageName ?? 'This project',\n        framework: answers.framework,\n        hasSkills: true,\n      })\n      plan.actions.push(...guide.actions)\n      plan.already.push(...guide.already)\n      /* In the plan as well as the report: a step nobody sees considered is a\n         step the reader assumes was forgotten. */\n      if (found.names.length > 0) {\n        plan.already.push(`evlog skills already installed · ${found.dirs.join(', ')}`)\n      }\n\n      return {\n        found: found.names,\n        dirs: found.dirs,\n        command: skillsCommand({ interactive }).display,\n        status: 'pending' as SkillsStatus,\n      }\n    }, r => ({ found: r.found.length }))\n  }\n\n  /* What the run would shell out to, `--dry-run` included: a preview that hides\n     the commands is the one thing a preview exists to show. Execution stays\n     gated on `dryRun` separately, further down. */\n  const wouldInstall = !evlogInstalled && answers.install\n  /* Already-installed skills belong to `npx skills update`, not to us. */\n  const wouldAddSkills = agentGuide !== null && agentGuide.found.length === 0\n  const installing = wouldInstall && !dryRun\n  const runs = [\n    ...(wouldInstall ? [command] : []),\n    ...(wouldAddSkills ? [agentGuide!.command] : []),\n  ]\n\n  if (interactive && dryRun) {\n    /* `--dry-run` promises the plan. The confirm step is the only thing that\n       renders it, and interactive runs suppress the written report — so\n       without this the terminal shows the questions and then nothing. */\n    showPlan(plan.actions, plan.already, runs)\n  }\n\n  if (interactive && !dryRun) {\n    let confirmed: boolean\n    try {\n      confirmed = await confirmPlan(plan.actions, plan.already, runs)\n    } catch (error) {\n      if (error instanceof InitCancelled) {\n        closeCancelled()\n        return cancelled(cancelledResult({ project, answers, packageManager, command, dryRun }))\n      }\n      throw error\n    }\n    if (!confirmed) {\n      closeCancelled()\n      return cancelled(cancelledResult({ project, answers, packageManager, command, dryRun }))\n    }\n  }\n\n  let install: InstallOutcome\n  if (evlogInstalled) {\n    install = { status: 'already', command, version: resolved.install!.version }\n  } else if (!answers.install || dryRun) {\n    install = { status: 'skipped', command }\n  } else {\n    const outcome = await log.step(\n      'install',\n      () => runInstall(packageManager, project.packageDir),\n      r => ({ installed: r.ok }),\n    )\n    install = outcome.ok ? { status: 'installed', command } : { status: 'failed', command, error: outcome.error }\n  }\n\n  if (!dryRun) {\n    await log.step('write', async () => {\n      for (const action of plan.actions) {\n        await mkdir(dirname(action.path), { recursive: true })\n        await writeFile(action.path, action.contents, 'utf8')\n      }\n      return plan.actions.length\n    })\n  }\n\n  if (agentGuide) {\n    if (agentGuide.found.length > 0) {\n      agentGuide.status = 'already'\n    } else if (dryRun) {\n      agentGuide.status = 'pending'\n    } else {\n      /* Runs after the writes: the block is the part we own, and it should be\n         on disk whatever a subprocess we do not control decides to do. */\n      if (interactive) noteSkillsStarting(ctx, agentGuide.command)\n      const outcome = await log.step(\n        'skills',\n        () => runSkills(skillsCommand({ interactive }), project.packageDir, interactive),\n        r => ({ installed: r.ok }),\n      )\n      agentGuide.status = outcome.ok ? 'installed' : 'failed'\n      if (!outcome.ok) agentGuide.error = outcome.error\n    }\n  }\n\n  let verified: VerifySummary | null = null\n  if (!dryRun) {\n    const verify = async (): Promise<VerifySummary> => {\n      const doctor = await runDoctor({ ...ctx, cwd: project.packageDir })\n      return doctor.summary\n    }\n    if (interactive) {\n      await runVerification(async () => {\n        verified = await verify()\n        return `${verified.ok} ok · ${verified.warn} warn · ${verified.fail} fail`\n      })\n    } else {\n      verified = await log.step('verify', verify)\n    }\n  }\n\n  if (interactive) {\n    if (agentGuide) noteSkills(ctx, agentGuide)\n    noteEnvironment(answers.prodDrains)\n    noteManual(plan.manual)\n    closeInteractive(ctx, answers.framework, frameworkDocs(answers.framework), dryRun)\n  }\n\n  log.set({ steps: ['done'] })\n\n  const result: InitResult = {\n    project,\n    answers,\n    packageManager,\n    install,\n    written: plan.actions,\n    already: plan.already,\n    manual: plan.manual,\n    dropped: droppedExtras(base),\n    insight: insight\n      ? {\n        repeatedErrors: insight.repeatedErrors.length,\n        auditGaps: insight.auditGaps.length,\n        pairable: [...insight.facts.pairable],\n      }\n      : null,\n    verified,\n    agentGuide,\n    dryRun,\n    interactive,\n    cancelled: false,\n  }\n\n  recordInitAnswers(result)\n  return result\n}\n\n/** The result of a run the user walked away from: answers kept, nothing done. */\nfunction cancelledResult(input: {\n  project: ProjectInfo\n  answers: InitAnswers\n  packageManager: PackageManager\n  command: string\n  dryRun: boolean\n}): InitResult {\n  return {\n    project: input.project,\n    answers: input.answers,\n    packageManager: input.packageManager,\n    install: { status: 'skipped', command: input.command },\n    written: [],\n    already: [],\n    manual: [],\n    dropped: [],\n    insight: null,\n    verified: null,\n    agentGuide: null,\n    dryRun: input.dryRun,\n    /* Only an interactive run can be cancelled — there is nothing to answer\n       when nobody was asked. */\n    interactive: true,\n    cancelled: true,\n  }\n}\n\n/** A cancelled run still reports its answers: what people back out of matters. */\nfunction cancelled(result: InitResult): InitResult {\n  recordInitAnswers(result)\n  return result\n}\n\n/** Documentation path for a framework's setup guide. */\nexport function frameworkDocs(framework: Framework): string {\n  switch (framework) {\n    case 'nuxt': return '/integrate/frameworks/nuxt'\n    case 'nitro': return '/integrate/frameworks/nitro'\n    case 'next': return '/integrate/frameworks/nextjs'\n    case 'tanstack-start': return '/integrate/frameworks/tanstack-start'\n    case 'hono': return '/integrate/frameworks/hono'\n  }\n}\n","import type { CliContext } from '../../core/context'\nimport { gradientRule, HEADER_GRADIENT_WIDTH } from '../../core/brand'\nimport { DOCS_URL, createStyle } from '../../core/output'\nimport { skillsReportLines } from '../agents/report'\nimport { findDestination, findEnricher, findExtra, findSamplingPreset } from './catalog'\nimport { frameworkDocs } from './run'\nimport type { InitResult } from './run'\n\nfunction docLink(ctx: CliContext, path: string): string {\n  const style = createStyle(ctx)\n  return ctx.color ? style.link(`${DOCS_URL}${path}`, `evlog.dev${path}`) : `evlog.dev${path}`\n}\n\n/**\n * What `init` did, for a run that asked nothing.\n *\n * The interactive flow narrates itself through clack, so this renders only when\n * prompts were skipped — which is the mode an agent or a CI job runs in, and the\n * one whose output somebody will read in a log days later. Every outcome gets a\n * line, including the ones where nothing happened: a setup command that prints\n * only its writes leaves the reader unable to tell \"already wired\" from \"did\n * not look\".\n */\nexport function formatInitReport(ctx: CliContext, result: InitResult): string {\n  const { paint } = createStyle(ctx)\n  const { answers } = result\n  const lines: string[] = []\n\n  if (result.cancelled) {\n    return paint('yellow', 'Cancelled — nothing was written.')\n  }\n\n  const dev = findDestination(answers.devDrain)?.label ?? answers.devDrain\n  const prod = answers.prodDrains.map(id => findDestination(id)?.label ?? id)\n  lines.push([\n    paint('bold', answers.framework),\n    paint('dim', `service ${answers.service}`),\n    paint('dim', `dev → ${dev}`),\n    paint('dim', `prod → ${prod.length > 0 ? prod.join(' + ') : 'not set'}`),\n  ].join(paint('dim', ' · ')))\n\n  if (answers.extras.length > 0) {\n    const labels = answers.extras.map((id) => {\n      if (id === 'enrichers') {\n        const names = answers.enrichers.map(enricher => findEnricher(enricher)?.label ?? enricher)\n        return `enrichers (${names.join(', ')})`\n      }\n      if (id === 'sampling') {\n        return `sampling (${findSamplingPreset(answers.sampling)?.label ?? answers.sampling})`\n      }\n      return findExtra(id)?.label ?? id\n    })\n    lines.push(paint('dim', `extras: ${labels.join(' · ')}`))\n  }\n  lines.push('')\n\n  const { install } = result\n  if (install.status === 'already') {\n    lines.push(`${paint('green', '✓')} evlog ${paint('dim', `already installed${install.version ? ` (${install.version})` : ''}`)}`)\n  } else if (install.status === 'installed') {\n    lines.push(`${paint('green', '✓')} ${paint('dim', `installed evlog · ${install.command}`)}`)\n  } else if (install.status === 'skipped') {\n    lines.push(`${paint('yellow', '·')} ${paint('dim', `evlog is not installed — run ${install.command}`)}`)\n  } else {\n    lines.push(`${paint('red', '✗')} ${paint('dim', `install failed — run ${install.command}`)}`)\n    if (install.error) lines.push(`   ${paint('dim', install.error)}`)\n  }\n\n  for (const action of result.written) {\n    const verb = result.dryRun\n      ? (action.kind === 'create' ? 'would create' : 'would update')\n      : (action.kind === 'create' ? 'created' : 'updated')\n    const glyph = result.dryRun ? paint('yellow', '·') : paint('green', '✓')\n    lines.push(`${glyph} ${paint('dim', verb)} ${action.relative}`)\n  }\n\n  for (const note of result.already) {\n    lines.push(paint('dim', `· ${note}`))\n  }\n\n  for (const id of result.dropped) {\n    /* Silently dropping an extra would leave the author believing they wired\n       something they did not. */\n    lines.push(`${paint('yellow', '·')} ${paint('dim', `${id} does not apply here — skipped`)}`)\n  }\n\n  /* The block lands whatever happens here; saying nothing would leave the\n     author believing their agent has guidance it never received. */\n  if (result.agentGuide) {\n    lines.push(...skillsReportLines(ctx, result.agentGuide))\n  }\n\n  if (result.verified) {\n    const { ok, warn, fail } = result.verified\n    const glyph = fail > 0 ? paint('red', '✗') : warn > 0 ? paint('yellow', '⚠') : paint('green', '✓')\n    lines.push(`${glyph} ${paint('dim', `doctor: ${ok} ok · ${warn} warn · ${fail} fail`)}`)\n  }\n\n  const envVariables = answers.prodDrains\n    .map(id => findDestination(id))\n    .flatMap(destination => destination?.env ?? [])\n  if (envVariables.length > 0) {\n    lines.push('')\n    lines.push(paint('dim', 'SET BEFORE ANYTHING IS RECEIVED'))\n    const width = Math.max(...envVariables.map(variable => variable.name.length))\n    for (const variable of envVariables) {\n      lines.push(`${paint('cyan', variable.name.padEnd(width))} ${paint('dim', `— ${variable.hint}`)}`)\n    }\n  }\n\n  if (result.manual.length > 0) {\n    lines.push('')\n    lines.push(paint('dim', 'YOUR TURN'))\n    for (const step of result.manual) {\n      lines.push(`${paint('yellow', '→')} ${paint('bold', step.title)} ${paint('dim', `· ${step.file}`)}`)\n      lines.push(`   ${paint('dim', step.reason)}`)\n      for (const line of step.snippet.split('\\n')) {\n        lines.push(`   ${paint('cyan', line)}`)\n      }\n      lines.push('')\n    }\n  } else {\n    lines.push('')\n  }\n\n  lines.push(gradientRule(ctx, HEADER_GRADIENT_WIDTH))\n  if (result.dryRun) {\n    lines.push(paint('dim', 'dry run — nothing was written. Drop --dry-run to apply.'))\n  } else {\n    lines.push(`${paint('dim', 'next:')} ${paint('bold', 'evlog map')} ${paint('dim', 'to score what is still dark')}`)\n  }\n  lines.push(`${paint('dim', 'setup guide →')} ${docLink(ctx, frameworkDocs(answers.framework))}`)\n\n  return lines.join('\\n')\n}\n\n/** Header for a workspace run, above each app's own report. */\nexport function formatWorkspaceHeading(ctx: CliContext, label: string): string {\n  const { paint } = createStyle(ctx)\n  return `\\n${paint(['bold', 'cyan'], `── ${label} `)}${paint('dim', '─'.repeat(Math.max(0, 40 - label.length)))}`\n}\n","import { readFileSync } from 'node:fs'\nimport { dirname, join, relative } from 'node:path'\nimport { globSync } from 'tinyglobby'\nimport { detectFramework } from '../map/detect'\nimport type { Framework } from '../map/types'\nimport type { PackageJson, ProjectInfo } from '../project'\nimport { isInitFramework } from './frameworks'\n\n/** A workspace package `init` could set up. */\nexport interface WorkspaceApp {\n  name: string\n  /** Absolute package directory. */\n  dir: string\n  /** Path as the user would type it — `apps/web`. */\n  label: string\n  framework: Framework\n}\n\n/** Whether this looks like a workspace root rather than an app. */\nexport function isWorkspaceRoot(project: ProjectInfo): boolean {\n  return project.kind !== 'single' && project.packageDir === project.root\n}\n\n/**\n * Find the apps in a workspace that `init` knows how to wire.\n *\n * Packages with no detectable framework are left out — a shared `utils`\n * package has no entry points to instrument. So are map-only frameworks,\n * which init has no wiring plan for.\n */\nexport function findWorkspaceApps(project: ProjectInfo): WorkspaceApp[] {\n  const patterns = workspaceGlobs(project)\n  if (patterns.length === 0) return []\n\n  const manifests = globSync(patterns.map(pattern => `${pattern}/package.json`), {\n    cwd: project.root,\n    absolute: true,\n    ignore: ['**/node_modules/**'],\n  })\n\n  const apps: WorkspaceApp[] = []\n  for (const manifest of manifests) {\n    const dir = dirname(manifest)\n    if (dir === project.root) continue\n\n    let packageJson: PackageJson | null\n    try {\n      packageJson = JSON.parse(readFileSync(manifest, 'utf8')) as PackageJson\n    } catch {\n      continue\n    }\n\n    const candidate: ProjectInfo = {\n      cwd: dir,\n      packageDir: dir,\n      root: project.root,\n      kind: project.kind,\n      packageName: packageJson.name ?? null,\n      packageJson,\n    }\n\n    try {\n      const { framework } = detectFramework(candidate)\n      if (!isInitFramework(framework)) continue\n      apps.push({\n        name: packageJson.name ?? relative(project.root, dir),\n        dir,\n        label: relative(project.root, dir),\n        framework,\n      })\n    } catch {\n      // No framework, nothing to instrument.\n    }\n  }\n\n  return apps.sort((a, b) => (a.label < b.label ? -1 : a.label > b.label ? 1 : 0))\n}\n\nfunction workspaceGlobs(project: ProjectInfo): string[] {\n  if (project.kind === 'pnpm') {\n    try {\n      const yaml = readFileSync(join(project.root, 'pnpm-workspace.yaml'), 'utf8')\n      return parsePnpmPackages(yaml)\n    } catch {\n      return []\n    }\n  }\n\n  const workspaces = project.packageJson?.workspaces\n  if (Array.isArray(workspaces)) return workspaces\n  if (workspaces?.packages) return workspaces.packages\n  return []\n}\n\n/**\n * Read the `packages:` list out of `pnpm-workspace.yaml`.\n *\n * Negated globs are dropped: tinyglobby takes them as patterns rather than\n * exclusions, so keeping them would search for a directory named `!docs`.\n */\nexport function parsePnpmPackages(yaml: string): string[] {\n  const patterns: string[] = []\n  let inside = false\n\n  for (const raw of yaml.split('\\n')) {\n    const line = raw.replace(/#.*$/, '').trimEnd()\n    if (/^packages:\\s*$/.test(line)) {\n      inside = true\n      continue\n    }\n    if (inside) {\n      const entry = line.match(/^\\s*-\\s*['\"]?([^'\"\\s]+)['\"]?\\s*$/)\n      if (entry?.[1]) {\n        if (!entry[1].startsWith('!')) patterns.push(entry[1])\n        continue\n      }\n      if (line.trim().length > 0) break\n    }\n  }\n\n  return patterns\n}\n","import { EXIT_FAIL } from '../core/output'\nimport { defineEvlogCommand, failWith } from '../lib/command'\nimport { cliErrors } from '../lib/errors'\nimport { askWorkspaceTargets, canPrompt, closeCancelled, InitCancelled } from '../lib/init/prompts'\nimport { formatInitReport, formatWorkspaceHeading } from '../lib/init/report'\nimport {\n  parseDrainArg,\n  parseEnrichersArg,\n  parseExtrasArg,\n  parseProdDrainsArg,\n  parseSamplingArg,\n} from '../lib/init/resolve'\nimport { runInit } from '../lib/init/run'\nimport type { InitOptions, InitResult } from '../lib/init/run'\nimport { findWorkspaceApps, isWorkspaceRoot } from '../lib/init/workspace'\nimport { INIT_FRAMEWORKS } from '../lib/init/frameworks'\nimport { resolveProject } from '../lib/project'\nimport type { Framework } from '../lib/map/types'\n\nfunction parseFrameworkArg(value: unknown): Framework | undefined {\n  if (typeof value !== 'string' || value.length === 0) return undefined\n  if (!(INIT_FRAMEWORKS as readonly string[]).includes(value)) {\n    throw cliErrors.INIT_INVALID_FRAMEWORK({ value })\n  }\n  return value as Framework\n}\n\nfunction parseServiceArg(value: unknown): string | undefined {\n  if (typeof value !== 'string' || value.trim().length === 0) return undefined\n  return value.trim()\n}\n\n/**\n * `evlog init` — wire evlog into the project it is run in.\n *\n * Interactive by default and fully driveable by flags, because both callers are\n * real: a person picking destinations from a list, and an agent that must never\n * be left waiting on a keystroke. `--json`, `--yes`, a non-TTY stdin, or `CI`\n * all select the second path.\n *\n * The other commands score and diagnose; this one writes application code, so\n * it is deliberately conservative: it appends to configs, never rewrites them,\n * skips any file that already exists, and shows the plan before applying it.\n */\nexport default defineEvlogCommand('init', {\n  meta: { name: 'init', description: 'Wire evlog into this project — install, config, drains' },\n  /* The clack session draws its own intro; two banners read as two programs. */\n  skipHeader: (ctx, args) => args.json !== true && args.yes !== true && canPrompt(ctx),\n  args: {\n    cwd: { type: 'string', description: 'Project directory (default: current)' },\n    framework: { type: 'string', description: 'Override framework detection (nuxt, nitro, next, tanstack-start, hono)' },\n    service: { type: 'string', description: 'Service name on every wide event (default: package name)' },\n    drain: { type: 'string', description: 'Development sink: fs (default) or none' },\n    prodDrain: { type: 'string', description: 'Production destinations, comma-separated: axiom, otlp, posthog, sentry, better-stack, datadog, hyperdx' },\n    extras: { type: 'string', description: 'Comma-separated: enrichers, pipeline, sampling, vite, error-catalog, audit-catalog, ai, better-auth' },\n    enrichers: { type: 'string', description: 'Comma-separated: user-agent, geo, request-size, trace-context (default: all)' },\n    sampling: { type: 'string', description: 'Traffic tier: all, low, medium (default), high, very-high' },\n    apps: { type: 'string', description: 'Workspace packages to set up, comma-separated (monorepo root only)' },\n    yes: { type: 'boolean', alias: 'y', description: 'Skip every question and take the defaults' },\n    dryRun: { type: 'boolean', description: 'Show what would change without writing anything' },\n    // citty negations: declared positive so `--no-install` works.\n    install: { type: 'boolean', default: true, description: 'Install evlog when missing (--no-install to skip)' },\n    agents: { type: 'boolean', default: true, description: 'Write the AGENTS.md block and install the skills (--no-agents to skip)' },\n  },\n  async run({ args, cli, log, ui }) {\n    const cwd = typeof args.cwd === 'string' && args.cwd.length > 0 ? args.cwd : undefined\n    const ctx = cwd ? { ...cli, cwd } : cli\n\n    let options: InitOptions\n    try {\n      options = {\n        framework: parseFrameworkArg(args.framework),\n        service: parseServiceArg(args.service),\n        devDrain: parseDrainArg(args.drain),\n        prodDrains: parseProdDrainsArg(args.prodDrain),\n        extras: parseExtrasArg(args.extras),\n        enrichers: parseEnrichersArg(args.enrichers),\n        sampling: parseSamplingArg(args.sampling),\n        dryRun: args.dryRun,\n        install: args.install,\n        agentGuide: args.agents,\n        yes: args.yes,\n        /* JSON output and a prompt cannot share a terminal: the payload is the\n           contract, and half a TUI on stderr in front of it helps nobody. */\n        nonInteractive: args.json === true,\n      }\n    } catch (error) {\n      return failWith(error, { args, log, ui })\n    }\n\n    /* A monorepo root has no entry points of its own, so `init` there means\n       \"set up the apps\", not \"wire this package\". */\n    const project = await resolveProject(ctx.cwd)\n    const targets = isWorkspaceRoot(project) ? findWorkspaceApps(project) : []\n\n    if (targets.length > 0) {\n      const requested = typeof args.apps === 'string' && args.apps.length > 0\n        ? args.apps.split(',').map(entry => entry.trim()).filter(Boolean)\n        : null\n\n      if (requested) {\n        /* A name that matches nothing has to stop the run even when its\n           neighbours matched. `--apps web,shopp` setting up `web` and saying\n           nothing about `shopp` is the silent-default behaviour every other\n           flag here refuses. */\n        const unknown = requested.filter(\n          entry => !targets.some(app => app.label === entry || app.name === entry),\n        )\n        if (unknown.length > 0) {\n          return failWith(\n            cliErrors.INIT_NO_APPS({ value: unknown.join(', '), known: targets.map(app => app.label).join(', ') }),\n            { args, log, ui },\n          )\n        }\n      }\n\n      let selected = requested\n        ? targets.filter(app => requested.includes(app.label) || requested.includes(app.name))\n        : targets\n\n      /* Without `--apps`, a terminal gets to choose. Setting up every package in\n         a monorepo because the command was run from the root is the kind of\n         helpfulness that produces a revert. */\n      if (!requested && args.json !== true && args.yes !== true && canPrompt(ctx)) {\n        try {\n          const chosen = await askWorkspaceTargets(targets)\n          selected = targets.filter(app => chosen.includes(app.dir))\n        } catch (error) {\n          if (error instanceof InitCancelled) {\n            closeCancelled()\n            return\n          }\n          throw error\n        }\n      }\n\n      if (selected.length === 0) {\n        return failWith(\n          cliErrors.INIT_NO_APPS({ value: 'nothing', known: targets.map(app => app.label).join(', ') }),\n          { args, log, ui },\n        )\n      }\n\n      const results: InitResult[] = []\n      for (const app of selected) {\n        if (!args.json) ui.human(formatWorkspaceHeading(ctx, app.label))\n        try {\n          const result = await runInit({ ...ctx, cwd: app.dir }, log, { ...options, framework: app.framework })\n          results.push(result)\n          if (!args.json && !result.interactive) ui.human(formatInitReport(ctx, result))\n        } catch (error) {\n          /* Ctrl-C in the middle of a workspace run stops the loop rather than\n             throwing past it: the apps already set up keep what they got, and\n             the ones after are simply not touched. */\n          if (error instanceof InitCancelled) {\n            closeCancelled()\n            break\n          }\n          return failWith(error, { args, log, ui })\n        }\n      }\n\n      ui.done({\n        jsonMode: args.json,\n        json: { workspace: true, apps: results.map((result, index) => ({ app: selected[index]!.label, ...toJson(result) })) },\n      })\n      if (results.some(result => result.install.status === 'failed')) ui.exit(EXIT_FAIL)\n      return\n    }\n\n    let result: InitResult\n    try {\n      result = await runInit(ctx, log, options)\n    } catch (error) {\n      return failWith(error, { args, log, ui })\n    }\n\n    ui.done({\n      jsonMode: args.json,\n      json: toJson(result),\n      /* The interactive flow already narrated itself; printing the report after\n         it would repeat the whole run under the outro. */\n      human: result.interactive ? undefined : formatInitReport(ctx, result),\n    })\n\n    if (result.install.status === 'failed') {\n      ui.exit(EXIT_FAIL)\n    }\n  },\n})\n\nfunction toJson(result: InitResult): Record<string, unknown> {\n  return {\n    framework: result.answers.framework,\n    service: result.answers.service,\n    devDrain: result.answers.devDrain,\n    prodDrains: result.answers.prodDrains,\n    extras: result.answers.extras,\n    enrichers: result.answers.enrichers,\n    sampling: result.answers.sampling,\n    packageManager: result.packageManager,\n    install: result.install,\n    written: result.written.map(action => ({ file: action.relative, kind: action.kind })),\n    already: result.already,\n    manual: result.manual.map(step => ({ title: step.title, file: step.file, reason: step.reason })),\n    dropped: result.dropped,\n    insight: result.insight,\n    verified: result.verified,\n    agentGuide: result.agentGuide,\n    dryRun: result.dryRun,\n    cancelled: result.cancelled,\n  }\n}\n","import { writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport type { MapFile } from './types'\n\n/** Name of the map file at the project root — written here, read by `--baseline`. */\nexport const MAP_FILE_NAME = 'evlog.map.json'\n\n/**\n * Code-point order, not collation.\n *\n * `localeCompare` reads the machine's locale, so the same map serializes in a\n * different route order on a different laptop — which shows up as a phantom\n * diff in a committed `evlog.map.json` and as a flaky snapshot in CI.\n */\nfunction compare(a: string, b: string): number {\n  return a < b ? -1 : a > b ? 1 : 0\n}\n\nfunction sortedRoutes(map: MapFile): MapFile {\n  return {\n    ...map,\n    routes: [...map.routes].sort((a, b) => compare(a.path, b.path) || compare(a.method ?? '', b.method ?? '')),\n  }\n}\n\n/** Write `evlog.map.json` to `projectRoot` (routes sorted for a stable diff). Returns the path written. */\nexport function writeMapFile(projectRoot: string, map: MapFile): string {\n  const outPath = join(projectRoot, MAP_FILE_NAME)\n  writeFileSync(outPath, `${JSON.stringify(sortedRoutes(map), null, 2)}\\n`, 'utf8')\n  return outPath\n}\n\n/** The map as it would be written, routes sorted, without touching the disk. */\nexport function serializeMapFile(map: MapFile): string {\n  return JSON.stringify(sortedRoutes(map), null, 2)\n}\n\n/** {@link MapFile} with `generatedAt` and `cliVersion` redacted — stable across test runs for snapshotting. Both churn on every release, while `ruleSetVersion` stays, so a snapshot only moves when the rule set actually changes. */\nexport function mapForSnapshot(map: MapFile): Omit<MapFile, 'generatedAt' | 'cliVersion'> & { generatedAt: '[REDACTED]', cliVersion: '[REDACTED]' } {\n  return {\n    ...sortedRoutes(map),\n    generatedAt: '[REDACTED]',\n    cliVersion: '[REDACTED]',\n  }\n}\n","import { execFileSync } from 'node:child_process'\nimport { readFileSync } from 'node:fs'\nimport { isAbsolute, resolve } from 'node:path'\nimport { cliErrors } from '../errors'\nimport { version as CLI_VERSION } from '../../../package.json'\nimport { classifyRouteObservability, scoreGlobal } from './score'\nimport { RULE_SET_VERSION } from './rules/index'\nimport type { CheckId, MapFile, RouteEntry } from './types'\nimport { MAP_FILE_NAME } from './write'\n\n/** Where a baseline map was read from — the label keeps the spelling the user typed. */\nexport interface BaselineSource {\n  kind: 'file' | 'git'\n  label: string\n}\n\n/** A requirement that used to pass on this entry point and no longer does. */\nexport interface CheckRegression {\n  routeId: string\n  path: string\n  method: string | null\n  file: string\n  check: CheckId\n  /** Both gate; the distinction is printed because the fix differs. */\n  to: 'fail' | 'suppressed'\n}\n\n/** A requirement that was failing in the baseline and now passes. */\nexport interface CheckFix {\n  routeId: string\n  path: string\n  method: string | null\n  file: string\n  check: CheckId\n}\n\n/** An entry point that exists now and did not exist in the baseline. */\nexport interface AddedRoute {\n  path: string\n  method: string | null\n  file: string\n  /** No requirement passes on it — the case a baseline gate is meant to surface. */\n  dark: boolean\n}\n\n/** Result of scoring the current scan against a committed map. */\nexport interface BaselineComparison {\n  source: BaselineSource\n  baselineScore: number\n  score: number\n  /**\n   * Score movement across the entry points that existed in the baseline.\n   *\n   * Not `current.score - baseline.score`: that is a weighted average over every\n   * route, so a new dark endpoint drags it down and would fail the pull\n   * requests this comparison promises not to fail.\n   */\n  delta: number\n  /** `current.score - baseline.score`, for the report. Never gates. */\n  totalDelta: number\n  /** Requirements that went from pass to fail or suppressed. These gate. */\n  regressions: CheckRegression[]\n  /** Requirements that went from fail to pass — the report's good news. */\n  fixed: CheckFix[]\n  added: AddedRoute[]\n  /** Ids present in the baseline and gone from the scan (deleted routes). */\n  removed: { path: string, method: string | null }[]\n}\n\n/** Whether a git ref resolves to a commit in this repository. */\nfunction refExists(cwd: string, ref: string): boolean {\n  try {\n    execFileSync('git', ['-C', cwd, 'rev-parse', '--verify', '--quiet', ref], {\n      stdio: ['ignore', 'ignore', 'ignore'],\n    })\n    return true\n  } catch {\n    return false\n  }\n}\n\nfunction readGitBaseline(cwd: string, ref: string): string | null {\n  try {\n    const prefix = execFileSync('git', ['-C', cwd, 'rev-parse', '--show-prefix'], {\n      encoding: 'utf8',\n      stdio: ['ignore', 'pipe', 'ignore'],\n    }).trim()\n    return execFileSync('git', ['-C', cwd, 'show', `${ref}:${prefix}${MAP_FILE_NAME}`], {\n      encoding: 'utf8',\n      stdio: ['ignore', 'pipe', 'ignore'],\n      maxBuffer: 64 * 1024 * 1024,\n    })\n  } catch {\n    return null\n  }\n}\n\nfunction parseMapFile(raw: string, label: string): MapFile {\n  let parsed: unknown\n  try {\n    parsed = JSON.parse(raw)\n  } catch {\n    throw cliErrors.MAP_BASELINE_INVALID({ source: label, reason: 'not valid JSON' })\n  }\n  const map = parsed as Partial<MapFile>\n  if (map?.version !== 1 || !Array.isArray(map.routes) || typeof map.score !== 'number') {\n    throw cliErrors.MAP_BASELINE_INVALID({ source: label, reason: 'not an evlog.map.json (version 1)' })\n  }\n  return map as MapFile\n}\n\n/**\n * Read the map to compare against. Local-only: no network, no token, no\n * repository access, so a private repo gates like a public one.\n *\n * @param spec - `git:<ref>` to read the committed copy through git, otherwise a\n * path. Defaults to `evlog.map.json`, falling back to `git:HEAD`.\n */\nexport function loadBaseline(projectRoot: string, spec?: string): { map: MapFile, source: BaselineSource } {\n  if (spec?.startsWith('git:')) {\n    const ref = spec.slice(4) || 'HEAD'\n    if (!refExists(projectRoot, ref)) throw cliErrors.MAP_BASELINE_REF_NOT_FOUND({ ref })\n    const raw = readGitBaseline(projectRoot, ref)\n    if (raw === null) throw cliErrors.MAP_BASELINE_NOT_COMMITTED({ ref })\n    return { map: parseMapFile(raw, spec), source: { kind: 'git', label: spec } }\n  }\n\n  if (spec) {\n    const path = isAbsolute(spec) ? spec : resolve(projectRoot, spec)\n    let raw: string\n    try {\n      raw = readFileSync(path, 'utf8')\n    } catch {\n      throw cliErrors.MAP_BASELINE_NOT_FOUND({ source: spec })\n    }\n    return { map: parseMapFile(raw, spec), source: { kind: 'file', label: spec } }\n  }\n\n  try {\n    const raw = readFileSync(resolve(projectRoot, MAP_FILE_NAME), 'utf8')\n    return { map: parseMapFile(raw, MAP_FILE_NAME), source: { kind: 'file', label: MAP_FILE_NAME } }\n  } catch {\n    /* Run twice in a row, the second scan would otherwise compare against the\n       first one's output. */\n    const raw = readGitBaseline(projectRoot, 'HEAD')\n    if (raw === null) throw cliErrors.MAP_BASELINE_NOT_FOUND({ source: MAP_FILE_NAME })\n    return { map: parseMapFile(raw, 'git:HEAD'), source: { kind: 'git', label: 'git:HEAD' } }\n  }\n}\n\nfunction checkIds(route: RouteEntry): CheckId[] {\n  return Object.keys(route.checks) as CheckId[]\n}\n\n/**\n * Compare a fresh scan against a baseline, per entry point and per check.\n *\n * The unit is the requirement, not the score: a refactor that instruments one\n * route and breaks another leaves the number untouched. A deleted route is not\n * a regression, and a new dark one is reported but does not gate — that bar is\n * `--min-score`'s job.\n */\nexport function compareToBaseline(baseline: MapFile, current: MapFile, source: BaselineSource): BaselineComparison {\n  const currentById = new Map(current.routes.map(route => [route.id, route]))\n  const baselineById = new Map(baseline.routes.map(route => [route.id, route]))\n\n  const regressions: CheckRegression[] = []\n  const fixed: CheckFix[] = []\n  const removed: { path: string, method: string | null }[] = []\n\n  for (const before of baseline.routes) {\n    const after = currentById.get(before.id)\n    if (!after) {\n      removed.push({ path: before.path, method: before.method })\n      continue\n    }\n\n    for (const id of checkIds(before)) {\n      const was = before.checks[id]\n      const now = after.checks[id]\n      if (!was || !now) continue\n\n      const entry = { routeId: after.id, path: after.path, method: after.method, file: after.file, check: id }\n\n      if (was.status === 'pass' && now.status === 'fail') {\n        regressions.push({ ...entry, to: 'fail' })\n      } else if (was.status === 'pass' && now.status === 'n/a' && now.suppressed) {\n        regressions.push({ ...entry, to: 'suppressed' })\n      } else if (was.status === 'fail' && now.status === 'pass') {\n        fixed.push(entry)\n      }\n    }\n  }\n\n  const added: AddedRoute[] = current.routes\n    .filter(route => !baselineById.has(route.id))\n    .map(route => ({\n      path: route.path,\n      method: route.method,\n      file: route.file,\n      // The scan's own classifier, so an exempt route stays exempt here.\n      dark: classifyRouteObservability(route) === 'dark',\n    }))\n\n  const carried = current.routes.filter(route => baselineById.has(route.id))\n  const carriedBefore = baseline.routes.filter(route => currentById.has(route.id))\n\n  return {\n    source,\n    baselineScore: baseline.score,\n    score: current.score,\n    delta: scoreGlobal(carried) - scoreGlobal(carriedBefore),\n    totalDelta: current.score - baseline.score,\n    regressions,\n    fixed,\n    added,\n    removed,\n  }\n}\n\n/** Whether the comparison should fail the command (exit 1). */\nexport function hasRegressed(comparison: BaselineComparison): boolean {\n  return comparison.regressions.length > 0 || comparison.delta < 0\n}\n\n/**\n * Whether a committed baseline is comparable to the running CLI.\n *\n * Returns `'unknown'` (the caller warns rather than fails) when the map\n * predates version reporting, and throws a usage error when the rule set moved\n * underneath the committed file. Same reasoning as a malformed `--min-score`:\n * a gate that reports a regression it cannot justify is worse than one that\n * admits it cannot run.\n */\nexport type BaselineVersionStatus = 'ok' | 'unknown'\n\nexport function checkBaselineVersion(baseline: Pick<MapFile, 'cliVersion' | 'ruleSetVersion'>): BaselineVersionStatus {\n  if (baseline.ruleSetVersion === undefined) return 'unknown'\n  if (baseline.ruleSetVersion === RULE_SET_VERSION) return 'ok'\n  throw cliErrors.MAP_BASELINE_VERSION_MISMATCH({\n    baselineCli: baseline.cliVersion ?? 'unknown',\n    runningCli: CLI_VERSION,\n    baselineRuleSet: baseline.ruleSetVersion,\n    runningRuleSet: RULE_SET_VERSION,\n  })\n}\n","import type { CliContext } from '../../core/context'\nimport { gradientRule, HEADER_GRADIENT_WIDTH } from '../../core/brand'\nimport { DOCS_URL, createStyle } from '../../core/output'\nimport type { Style, StyleCode } from '../../core/output'\nimport { HONO_SHORTHAND_VERBS } from './adapters/hono'\nimport type { BaselineComparison } from './baseline'\nimport { hasRegressed } from './baseline'\nimport { countSuppressed } from './directives'\nimport { isInfrastructureRoute } from './exemptions'\nimport { REQUIREMENTS, getRule } from './rules/index'\nimport type { FixSlot, SuggestContext } from './rules/index'\nimport type { ProjectFacts } from './project-facts'\nimport { classifyRouteObservability, scoreGlobal } from './score'\nimport type { CheckId, CheckResult, Framework, RouteEntry, ScanResult } from './types'\nimport { frameworkLabel } from './utils'\nimport { MAP_FILE_NAME } from './write'\n\n/* ── measuring text that contains ANSI ─────────────────────────────────── */\n\nconst ANSI = /\\u001B\\[[0-9;]*m|\\u001B\\]8;;[^\\u0007]*\\u0007/g\n\nfunction visibleLength(text: string): number {\n  return text.replace(ANSI, '').length\n}\n\nfunction pad(text: string, width: number): string {\n  const missing = width - visibleLength(text)\n  return missing > 0 ? text + ' '.repeat(missing) : text\n}\n\nfunction padStart(text: string, width: number): string {\n  const missing = width - visibleLength(text)\n  return missing > 0 ? ' '.repeat(missing) + text : text\n}\n\n/* ── shared derivations ────────────────────────────────────────────────── */\n\nfunction scoreColor(score: number): StyleCode {\n  if (score >= 90) return 'green'\n  if (score >= 70) return 'cyan'\n  if (score >= 50) return 'yellow'\n  return 'red'\n}\n\nfunction methodColor(method: string | null): StyleCode {\n  switch (method) {\n    case 'GET': return 'blue'\n    case 'POST': return 'green'\n    case 'PUT':\n    case 'PATCH': return 'yellow'\n    case 'DELETE': return 'red'\n    default: return 'dim'\n  }\n}\n\n/** Short label for entry points that have no HTTP method. */\nconst KIND_SHORT: Record<string, string> = {\n  /* A catch-all route answers any verb, which is what the column should say. */\n  'api': 'ANY',\n  'page': 'PAGE',\n  'middleware': 'MID',\n  'server-action': 'ACT',\n  'cron': 'CRON',\n  'websocket': 'WS',\n}\n\nfunction methodOf(route: RouteEntry): string {\n  return route.method ?? KIND_SHORT[route.kind] ?? route.kind.toUpperCase().slice(0, 6)\n}\n\nfunction failedChecks(route: RouteEntry): CheckId[] {\n  return (Object.entries(route.checks) as [CheckId, CheckResult][])\n    .filter(([, check]) => check.status === 'fail')\n    .map(([id]) => id)\n}\n\nfunction hasGaps(route: RouteEntry): boolean {\n  return failedChecks(route).length > 0\n}\n\nfunction miniBar(style: ReportStyle, score: number, width = 10): string {\n  const filled = Math.round((score / 100) * width)\n  return style.paint(scoreColor(score), '▰'.repeat(filled))\n    + style.paint('dim', '▱'.repeat(width - filled))\n}\n\nconst DIGITS: Record<string, readonly string[]> = {\n  0: ['█▀█', '█ █', '▀▀▀'],\n  1: [' ▄█', '  █', '  ▀'],\n  2: ['▀▀█', '█▀▀', '▀▀▀'],\n  3: ['▀▀█', ' ▀█', '▀▀▀'],\n  4: ['█ █', '▀▀█', '  ▀'],\n  5: ['█▀▀', '▀▀█', '▀▀▀'],\n  6: ['█▀▀', '█▀█', '▀▀▀'],\n  7: ['▀▀█', '  █', '  ▀'],\n  8: ['█▀█', '█▀█', '▀▀▀'],\n  9: ['█▀█', '▀▀█', '▀▀▀'],\n}\n\n/** The score as three rows of block art. */\nfunction bigDigits(value: number): string[] {\n  const chars = String(value).split('')\n  return [0, 1, 2].map(row => chars.map(char => DIGITS[char]![row]).join(' '))\n}\n\nfunction sensitivityBadges(style: ReportStyle, route: RouteEntry): string {\n  const reasons = route.sensitivity.reasons.join(' ')\n  const parts: string[] = []\n  if (reasons.includes('money:')) parts.push(style.paint('magenta', '$'))\n  if (reasons.includes('auth:')) parts.push(style.paint('cyan', 'A'))\n  if (reasons.includes('pii:')) parts.push(style.paint('yellow', '@'))\n  return parts.join('')\n}\n\n/**\n * `POST   /api/checkout` — the method column, then what was matched.\n *\n * Entry points without a path of their own say what they are instead: a\n * middleware rendered as `MID *` told the reader nothing.\n */\nfunction entryLabel(style: ReportStyle, route: RouteEntry): string {\n  const method = style.paint(methodColor(route.method), pad(methodOf(route), 6))\n  return `${method} ${matchedTarget(route)}`\n}\n\n/** What this entry point matches, for kinds whose \"path\" is a wildcard. */\nfunction matchedTarget(route: RouteEntry): string {\n  if (route.kind === 'middleware') return route.path === '*' ? 'every request' : route.path\n  if (route.kind === 'cron') return `job ${route.path}`\n  return route.path\n}\n\n/** What kind of thing this entry point is, in plain words. */\nfunction entryKindText(route: RouteEntry): string {\n  switch (route.kind) {\n    case 'api': return `${route.method ?? 'ANY'} ${route.path} — server handler`\n    case 'page': return 'page that fetches data server-side'\n    case 'middleware': return 'middleware — runs on every matching request'\n    case 'cron': return 'scheduled job'\n    case 'server-action': return 'server action invoked from the client'\n    case 'websocket': return 'websocket handler'\n  }\n}\n\nfunction displayName(route: RouteEntry): string {\n  if (route.kind === 'middleware') return 'middleware'\n  if (route.kind === 'cron') return `job ${route.path}`\n  return route.path\n}\n\n/**\n * Narrowest width the report lays out for, and the widest it spreads to.\n *\n * The floor is a contract: below 80 columns a sentence like \"missing audit\n * trails\" cannot be shown next to a score without being cut mid-word, so the\n * report keeps laying out for 80 and lets the terminal wrap rather than\n * mangling its own text. The ceiling stops a maximised window from stretching a\n * route list into one unreadable line.\n */\nexport const MIN_WIDTH = 80\nconst MAX_WIDTH = 110\n\ninterface ReportStyle extends Style {\n  doc: (path: string) => string\n  /** Columns the report may fill, clamped to a readable range. */\n  width: number\n}\n\n/**\n * The style kit plus a documentation link that reads well either way.\n *\n * `Style.link` falls back to `label (url)` without colors, which would print\n * the same address twice here since the label *is* the address. Plain mode gets\n * the bare URL instead.\n */\nfunction createReportStyle(ctx: CliContext): ReportStyle {\n  const style = createStyle(ctx)\n  return {\n    ...style,\n    /* Both modes show the same label so a line measured in one fits in the\n       other: spelling out `https://` only in plain mode made the evidence line\n       overflow 80 columns exactly where colour was unavailable, which is CI. */\n    doc: path => ctx.color ? style.link(`${DOCS_URL}${path}`, `evlog.dev${path}`) : `evlog.dev${path}`,\n    width: Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, ctx.columns)),\n  }\n}\n\nfunction ruleDocs(id: CheckId): string {\n  return getRule(id)?.docs ?? '/cli/rules'\n}\n\nfunction ruleExpects(id: CheckId): string {\n  return getRule(id)?.expects ?? id\n}\n\n/**\n * Why an entry point is worth fixing first, as a sentence.\n *\n * Deliberately human: \"moves money with no audit trail\" tells you what is at\n * stake, where \"audit: fail\" only tells you a box is unticked.\n */\nfunction priorityReason(route: RouteEntry): { sentence: string, doc: string } {\n  const reasons = route.sensitivity.reasons.join(' ')\n  const failed = failedChecks(route)\n\n  if (reasons.includes('money:') && failed.includes('audit')) {\n    return { sentence: 'moves money with no audit trail', doc: ruleDocs('audit') }\n  }\n  if (reasons.includes('money:') && failed.includes('wide-event')) {\n    return { sentence: 'moves money and logs nothing — invisible in production', doc: ruleDocs('wide-event') }\n  }\n  if (reasons.includes('auth:') && failed.includes('wide-event')) {\n    return { sentence: 'touches auth and logs nothing', doc: ruleDocs('wide-event') }\n  }\n  if (failed.includes('wide-event')) {\n    return { sentence: 'when it breaks, the event will not say why', doc: ruleDocs('wide-event') }\n  }\n  if (failed.includes('structured-errors')) {\n    return { sentence: 'throws plain errors with no why or fix', doc: ruleDocs('structured-errors') }\n  }\n  if (failed.includes('page-error-handling')) {\n    return { sentence: 'swallows fetch errors — users see a blank page', doc: ruleDocs('page-error-handling') }\n  }\n  const [first] = failed\n  return first\n    ? { sentence: `missing ${ruleExpects(first)}`, doc: ruleDocs(first) }\n    : { sentence: 'has gaps', doc: '/cli/rules' }\n}\n\n/** Worst first, sensitive entry points ahead of the rest. */\nfunction prioritize(routes: RouteEntry[]): RouteEntry[] {\n  return [...routes]\n    .filter(hasGaps)\n    .sort((a, b) => {\n      const sensitiveA = a.sensitivity.level !== 'none' ? 1 : 0\n      const sensitiveB = b.sensitivity.level !== 'none' ? 1 : 0\n      if (sensitiveA !== sensitiveB) return sensitiveB - sensitiveA\n      return a.score - b.score\n    })\n}\n\n/* ── the default report ────────────────────────────────────────────────── */\n\ninterface CoverageArea {\n  label: string\n  routes: RouteEntry[]\n  meaning: (routes: RouteEntry[], gaps: number) => string\n}\n\nfunction coverageAreas(active: RouteEntry[]): CoverageArea[] {\n  return [\n    {\n      label: 'API handlers',\n      routes: active.filter(route => route.kind === 'api'),\n      meaning: (routes, gaps) => gaps === 0 ? 'every handler covered' : `${gaps} of ${routes.length} have gaps`,\n    },\n    {\n      label: 'Pages',\n      routes: active.filter(route => route.kind === 'page'),\n      meaning: (_routes, gaps) => gaps === 0\n        ? 'data fetching covered'\n        : `${gaps} swallow${gaps === 1 ? 's' : ''} fetch errors`,\n    },\n    {\n      label: 'Middleware & jobs',\n      routes: active.filter(route => !['api', 'page'].includes(route.kind)),\n      meaning: (_routes, gaps) => gaps === 0 ? 'fully covered' : 'run without any logging',\n    },\n    {\n      label: 'Money & auth',\n      routes: active.filter(route => route.sensitivity.level !== 'none'),\n      meaning: (_routes, gaps) => gaps === 0 ? 'fully traced & audited' : 'missing audit trails',\n    },\n  ]\n}\n\n/**\n * One glyph per entry point, downsampled to `width`.\n *\n * A bar that grows with the project is not a bar: at 2000 entry points this was\n * a single 2000-character line that wrapped over the whole report. Bucketing\n * keeps the shape readable at any size, and since the entry points are sorted\n * worst-first each bucket is represented by its worst one — the reader is\n * looking for where the trouble is, not for an average.\n */\nfunction skylineBar(style: ReportStyle, routes: readonly RouteEntry[], width: number): string {\n  const sorted = [...routes].sort((a, b) => a.score - b.score)\n  if (sorted.length === 0 || width <= 0) return ''\n\n  const buckets = Math.min(width, sorted.length)\n  const perBucket = sorted.length / buckets\n  const glyphs: string[] = []\n\n  for (let index = 0; index < buckets; index++) {\n    const route = sorted[Math.floor(index * perBucket)]!\n    if (classifyRouteObservability(route) === 'exempt') {\n      glyphs.push(style.paint('dim', '▁'))\n      continue\n    }\n    const height = route.score >= 90\n      ? '█'\n      : route.score >= 70 ? '▆' : route.score >= 50 ? '▄' : route.score >= 30 ? '▃' : '▂'\n    glyphs.push(style.paint(scoreColor(route.score), height))\n  }\n\n  return glyphs.join('')\n}\n\n/** Width the headline spends on the block digits, the gauge, and their gutters. */\nconst HEADLINE_GAUGE_WIDTH = 22\n\n/** Room kept for the ` +12` tail on a clipped list. */\nconst MORE_WIDTH = 5\n\n/** The score, as a headline: block digits, gauge, grade, per-entry skyline. */\nfunction scoreHeadline(style: ReportStyle, result: ScanResult): string[] {\n  const { map, grade } = result\n  const color = scoreColor(map.score)\n  const digits = bigDigits(map.score)\n\n  const gaugeFilled = Math.round((map.score / 100) * 20)\n  const gauge = style.paint(color, '▰'.repeat(gaugeFilled))\n    + style.paint('dim', '▱'.repeat(20 - gaugeFilled))\n\n  /* The skyline shares its row with the digits and the gauge, so it gets what\n     they leave rather than a width of its own. */\n  const prefixWidth = visibleLength(digits[0] ?? '') + 3 + HEADLINE_GAUGE_WIDTH + 2\n\n  const side = [\n    style.paint('dim', `${map.projectName} · ${frameworkLabel(map.framework)}`),\n    style.paint('dim', `${map.routes.length} entry points scanned`),\n    skylineBar(style, map.routes, style.width - prefixWidth),\n  ]\n\n  return digits.map((digitRow, index) => {\n    const middle = index === 0\n      ? style.paint('dim', 'score /100')\n      : index === 1 ? gauge : style.paint(color, grade.replace('-', ' '))\n    return `${style.paint([color, 'bold'], digitRow)}   ${pad(middle, HEADLINE_GAUGE_WIDTH)}  ${side[index] ?? ''}`\n  })\n}\n\n/**\n * As many items as fit in `budget`, plus how many were left out.\n *\n * Route lists used to keep a fixed three or four items whatever the terminal, so\n * a narrow window wrapped and a wide one wasted the space it had. Items are\n * measured unpainted; the caller paints what comes back.\n */\nfunction fitItems(items: readonly string[], separator: string, budget: number): { shown: string[], hidden: number } {\n  const shown: string[] = []\n  let used = 0\n\n  for (const item of items) {\n    const cost = item.length + (shown.length > 0 ? separator.length : 0)\n    /* One item always shows, even when it alone overflows: a truncated name\n       still tells the reader where to look, an empty list does not. */\n    if (shown.length > 0 && used + cost > budget) break\n    shown.push(item)\n    used += cost\n  }\n\n  return { shown, hidden: items.length - shown.length }\n}\n\n/**\n * The report `evlog map` prints.\n *\n * Ordered the way it is meant to be read: the score, where the gaps are, the\n * three things to fix first, then everything else grouped so it is a decision\n * rather than a list. The branded header is owned by `defineEvlogCommand`, so\n * it is deliberately absent here.\n */\nexport function formatMapReport(\n  ctx: CliContext,\n  result: ScanResult,\n  options: { mapPath?: string | null } = {},\n): string {\n  const style = createReportStyle(ctx)\n  const { paint } = style\n  const { map } = result\n  const lines: string[] = []\n\n  lines.push(...scoreHeadline(style, result))\n  lines.push('')\n\n  const active = map.routes.filter(route => classifyRouteObservability(route) !== 'exempt')\n\n  lines.push(paint('dim', 'COVERAGE'))\n  for (const area of coverageAreas(active)) {\n    if (area.routes.length === 0) continue\n    const areaScore = Math.round(area.routes.reduce((sum, route) => sum + route.score, 0) / area.routes.length)\n    const gaps = area.routes.filter(hasGaps).length\n    const glyph = area.label === 'Money & auth' && areaScore < 70\n      ? paint('red', '⚠')\n      : paint(scoreColor(areaScore), '●')\n    lines.push([\n      glyph,\n      pad(area.label, 18),\n      miniBar(style, areaScore),\n      padStart(paint(scoreColor(areaScore), String(areaScore)), 4),\n      ` ${paint('dim', area.meaning(area.routes, gaps))}`,\n    ].join(' '))\n  }\n  lines.push('')\n\n  const priorities = prioritize(active).slice(0, 3)\n  if (priorities.length > 0) {\n    lines.push(paint('dim', 'FIX FIRST'))\n    priorities.forEach((route, index) => {\n      const { sentence, doc } = priorityReason(route)\n      const line = route.handler?.line ?? 1\n      lines.push([\n        paint('dim', `${index + 1}.`),\n        entryLabel(style, route),\n        sensitivityBadges(style, route),\n        paint('dim', `— ${sentence}`),\n      ].filter(part => part.length > 0).join(' '))\n      lines.push(`   ${paint('dim', `${route.file}:${line} ·`)} ${style.doc(doc)}`)\n    })\n    lines.push('')\n  }\n\n  const rest = active.filter(route => !priorities.includes(route) && hasGaps(route))\n  if (rest.length > 0) {\n    /* Grouped by which gaps they share: one decision per group beats one line\n       per route saying almost the same thing. */\n    const byGapSignature = new Map<string, RouteEntry[]>()\n    for (const route of rest) {\n      const signature = failedChecks(route).map(ruleExpects).join(' + ')\n      const group = byGapSignature.get(signature)\n      if (group) group.push(route)\n      else byGapSignature.set(signature, [route])\n    }\n\n    lines.push(paint('dim', 'THEN'))\n    const groups = [...byGapSignature].sort((a, b) => b[1].length - a[1].length)\n    for (const [signature, routes] of groups) {\n      const lead = `· add ${signature} to `\n      const { shown, hidden } = fitItems(routes.map(displayName), ', ', style.width - lead.length - MORE_WIDTH)\n      const names = shown.join(paint('dim', ', '))\n      const more = hidden > 0 ? paint('dim', ` +${hidden}`) : ''\n      lines.push(`${paint('yellow', '·')} ${paint('dim', `add ${signature} to`)} ${names}${more}`)\n    }\n    lines.push('')\n  }\n\n  lines.push(...suggestionSection(style, result))\n\n  /* An entry point with a waived finding is not \"solid\": something was found and\n     set aside. It is accounted for by the disabled count instead. */\n  const solid = active.filter(route => !hasGaps(route) && countSuppressed(route) === 0)\n  if (solid.length > 0) {\n    const lead = '✓ Already solid: '\n    const { shown, hidden } = fitItems(solid.map(displayName), ' · ', style.width - lead.length - MORE_WIDTH)\n    const more = hidden > 0 ? ` +${hidden}` : ''\n    lines.push(`${paint('green', '✓')} ${paint('dim', `Already solid: ${shown.join(' · ')}${more}`)}`)\n  }\n\n  const projected = scoreGlobal(\n    map.routes.map(route => priorities.includes(route) ? { ...route, score: 100 } : route),\n  )\n  if (projected > map.score) {\n    lines.push(`${paint('green', '▲')} ${paint('bold', `${map.score} → ${projected}`)} ${paint('dim', `by fixing the ${priorities.length} above`)}`)\n  }\n\n  lines.push(...suppressedLine(style, result))\n\n  lines.push('')\n  lines.push(gradientRule(ctx, HEADER_GRADIENT_WIDTH))\n  const written = options.mapPath ? 'evlog.map.json updated · ' : ''\n  lines.push(`${paint('dim', `${written}how this score works →`)} ${style.doc('/cli/scoring')}`)\n  lines.push(...hintLines(style))\n\n  return lines.join('\\n')\n}\n\n/**\n * What the project turned off, when it turned anything off.\n *\n * A score that is partly the result of disabled checks has to say so, or the\n * escape hatch quietly becomes a way to score 100 on an app that logs nothing.\n */\nfunction suppressedLine(style: ReportStyle, result: ScanResult): string[] {\n  const count = result.summary.suppressedChecks\n  if (count === 0) return []\n\n  const files = result.map.routes.filter(route => countSuppressed(route) > 0).length\n  const checks = count === 1 ? '1 check' : `${count} checks`\n  const entries = files === 1 ? '1 entry point' : `${files} entry points`\n  return [`${style.paint('dim', '○')} ${style.paint('dim', `${checks} disabled by comment in ${entries}`)}`]\n}\n\n/** What to run next, on one line when it fits and stacked when it does not. */\nfunction hintLines(style: ReportStyle): string[] {\n  const hints = ['evlog map --all every entry point', 'evlog map <file> inspect one', '--min-score 80 CI gate']\n  const rows: string[][] = [[]]\n  let used = 2\n\n  for (const hint of hints) {\n    const row = rows[rows.length - 1]!\n    if (row.length > 0 && used + hint.length + 3 > style.width) {\n      rows.push([hint])\n      used = 2 + hint.length\n      continue\n    }\n    row.push(hint)\n    used += hint.length + (row.length > 1 ? 3 : 0)\n  }\n\n  return rows.map((row, index) => `${style.paint('dim', index === 0 ? '▸' : ' ')} ${style.paint('dim', row.join(' · '))}`)\n}\n\n/**\n * Features the project already uses that some entry points do not.\n *\n * Rendered as an invitation, never as a failure: no red, no ✗, and an explicit\n * note that the score is untouched. Suggesting a feature is only welcome when\n * it cannot be mistaken for an accusation.\n */\nfunction suggestionSection(style: ReportStyle, result: ScanResult): string[] {\n  const { paint } = style\n  const byRule = new Map<CheckId, { count: number, first: string }>()\n\n  for (const route of result.map.routes) {\n    for (const [id, check] of Object.entries(route.suggestions) as [CheckId, CheckResult][]) {\n      if (check.status !== 'fail') continue\n      const where = `${route.file}:${check.evidence?.line ?? 1}`\n      const entry = byRule.get(id)\n      if (entry) entry.count++\n      else byRule.set(id, { count: 1, first: where })\n    }\n  }\n\n  if (byRule.size === 0 && result.suggestions.length === 0) return []\n\n  const lines = [\n    paint('dim', 'GOING FURTHER'),\n    paint('dim', 'you already use these — your app could get more out of them'),\n  ]\n\n  /* Project-wide first: it is one edit, so it is the cheapest thing on the list. */\n  for (const suggestion of result.suggestions) {\n    lines.push(`${paint('cyan', '+')} ${paint('dim', suggestion.message)}`)\n    const where = suggestion.evidence ? `${suggestion.evidence.file}:${suggestion.evidence.line} · ` : ''\n    lines.push(`   ${paint('dim', `one-time setup · ${where}`)}${style.doc(ruleDocs(suggestion.id))}`)\n  }\n\n  for (const [id, entry] of byRule) {\n    const question = getRule(id)?.question ?? id\n    const where = entry.count > 1 ? `${entry.count} entry points` : '1 entry point'\n    lines.push(`${paint('cyan', '+')} ${paint('dim', question)} ${paint('dim', `— ${where}`)}`)\n    lines.push(`   ${paint('dim', `${entry.first} ·`)} ${style.doc(ruleDocs(id))}`)\n  }\n\n  lines.push(paint('dim', 'Suggestions never change the score.'))\n  lines.push('')\n  return lines\n}\n\n/* ── --all: every entry point as a check matrix ────────────────────────── */\n\nconst MATRIX_CELL = 6\n\n/** Below this a file name says nothing, so the matrix overflows instead. */\nconst MIN_LABEL_WIDTH = 18\n\n/**\n * Keep the end of a path that is too long for its column.\n *\n * The tail is what identifies an entry point — `…/invoices/[id]/route.ts` is\n * readable, `app/(dashboard)/settin…` is not.\n */\nfunction clipStart(text: string, width: number): string {\n  return text.length <= width ? text : `…${text.slice(text.length - width + 1)}`\n}\n\nfunction matrixColumns(): { id: CheckId, label: string }[] {\n  return [\n    { id: 'wide-event', label: 'log' },\n    { id: 'context', label: 'ctx' },\n    { id: 'structured-errors', label: 'err' },\n    { id: 'audit', label: 'audit' },\n    { id: 'error-handling', label: 'catch' },\n    { id: 'page-error-handling', label: 'fetch' },\n  ]\n}\n\n/**\n * Every entry point, grouped by directory, with one dot per rule.\n *\n * The column headers are positioned from the same measurements as the rows, so\n * a dot is always under its own header no matter how long the file names are.\n */\nexport function formatMapMatrix(ctx: CliContext, result: ScanResult): string {\n  const style = createReportStyle(ctx)\n  const { paint } = style\n  const { map } = result\n  const columns = matrixColumns()\n  const lines: string[] = []\n\n  lines.push([\n    paint('dim', `${map.projectName} · ${frameworkLabel(map.framework)} ·`),\n    `${paint([scoreColor(map.score), 'bold'], String(map.score))}${paint('dim', '/100')}`,\n    paint('dim', `· ${map.routes.length} entry points, worst first`),\n  ].join(' '))\n  lines.push('')\n\n  /* Root-level entry points (Next's `middleware.ts`) group under `./` rather\n     than becoming a directory of their own with a nameless row in it. */\n  const groupOf = (route: RouteEntry): string => route.file.includes('/') ? route.file.split('/')[0]! : '.'\n  const labelOf = (route: RouteEntry): string => route.file.includes('/')\n    ? route.file.split('/').slice(1).join('/')\n    : route.file\n\n  const byDirectory = new Map<string, RouteEntry[]>()\n  for (const route of map.routes) {\n    const group = byDirectory.get(groupOf(route))\n    if (group) group.push(route)\n    else byDirectory.set(groupOf(route), [route])\n  }\n  /* branch + space + label + bar + space + score + space + badge + space */\n  const fixedWidth = 2 + 1 + 10 + 1 + 3 + 1 + 2 + 1 + columns.length * MATRIX_CELL\n  const longest = Math.max(...map.routes.map(route => labelOf(route).length)) + 2\n  const labelWidth = Math.max(MIN_LABEL_WIDTH, Math.min(longest, style.width - fixedWidth))\n  const prefixWidth = fixedWidth - columns.length * MATRIX_CELL + labelWidth\n\n  lines.push(`${' '.repeat(prefixWidth)}${columns.map(col => pad(paint('dim', col.label), MATRIX_CELL)).join('')}`)\n\n  for (const directory of [...byDirectory.keys()].sort()) {\n    lines.push(paint('blue', `${directory}/`))\n    const routes = byDirectory.get(directory)!.sort((a, b) => a.score - b.score)\n    routes.forEach((route, index) => {\n      const branch = paint('dim', index === routes.length - 1 ? '└─' : '├─')\n      const label = clipStart(labelOf(route), labelWidth - 2)\n\n      if (classifyRouteObservability(route) === 'exempt') {\n        const why = isInfrastructureRoute(route) ? 'evlog internals' : 'nothing to instrument'\n        lines.push(`${branch} ${pad(paint('dim', label), labelWidth)}${paint('dim', `exempt — ${why}`)}`)\n        return\n      }\n\n      const cells = columns.map((column) => {\n        const check = route.checks[column.id]\n        if (check?.suppressed) return pad(paint('dim', '○'), MATRIX_CELL)\n        if (!check || check.status === 'n/a') return pad(paint('dim', '·'), MATRIX_CELL)\n        return pad(check.status === 'pass' ? paint('green', '●') : paint('red', '●'), MATRIX_CELL)\n      }).join('')\n\n      const prefix = [\n        branch,\n        pad(label, labelWidth - 1),\n        miniBar(style, route.score),\n        padStart(paint(scoreColor(route.score), String(route.score)), 3),\n        pad(sensitivityBadges(style, route), 2),\n      ].join(' ')\n      lines.push(`${prefix} ${cells}`)\n    })\n  }\n\n  lines.push('')\n  lines.push([\n    `${paint('green', '●')} ${paint('dim', 'covered')}`,\n    `${paint('red', '●')} ${paint('dim', 'gap')}`,\n    paint('dim', '·  not applicable'),\n    ...(result.summary.suppressedChecks > 0 ? [paint('dim', '○  disabled')] : []),\n    `${paint('magenta', '$')}${paint('dim', ' money')}`,\n    `${paint('cyan', 'A')}${paint('dim', ' auth')}`,\n    `${paint('yellow', '@')}${paint('dim', ' pii')}`,\n  ].join('   '))\n  lines.push(`${paint('dim', 'what each column checks →')} ${style.doc('/cli/rules')}`)\n\n  return lines.join('\\n')\n}\n\n/* ── inspecting one entry point ───────────────────────────────────────── */\n\n/** How each rule reads when it passes and when it fails, in the deep dive. */\nconst EXPLAIN: Partial<Record<CheckId, { fail: string, pass: string }>> = {\n  'wide-event': { fail: 'no logger — nothing is added to the request event', pass: 'wide event emitted per request' },\n  'context': { fail: 'nothing attached — the event carries no business context', pass: 'context attached with log.set()' },\n  'structured-errors': { fail: 'throws plain errors — no why, no fix', pass: 'errors carry why and fix' },\n  'audit': { fail: 'sensitive action with no audit trail', pass: 'audit trail present' },\n  'error-handling': { fail: 'exceptions escape unlogged', pass: 'failures are caught and logged' },\n  'page-error-handling': { fail: 'fetch errors are swallowed silently', pass: 'fetch errors are surfaced' },\n}\n\nconst indent = (depth: number, text: string): string => (text.length > 0 ? `${'  '.repeat(depth)}${text}` : text)\n\n/**\n * The fix each failing rule asks for, in the order the rules are registered.\n *\n * Rules are the single source here on purpose: this renderer used to spell the\n * fixes out itself, which is how a page ended up shown an empty event handler\n * and how every route was told to audit `payment.captured`.\n */\nfunction fixesInSlot(slot: FixSlot, route: RouteEntry, context: SuggestContext): string[] {\n  const failed = new Set(failedChecks(route))\n  return REQUIREMENTS\n    .filter(rule => failed.has(rule.id) && (rule.fixSlot ?? 'body') === slot)\n    .flatMap(rule => rule.suggest?.(context) ?? [])\n}\n\n/** The evlog calls an entry point is missing, in the host framework's shape. */\nfunction suggestedShape(route: RouteEntry, framework: Framework, project: ProjectFacts): string[] {\n  const context: SuggestContext = { target: route, framework, project }\n  const slot = (name: FixSlot): string[] => fixesInSlot(name, route, context)\n\n  const guard = slot('guard')\n  const exit = slot('exit')\n  const body = [...slot('setup')]\n\n  if (guard.length > 0) {\n    body.push(\n      'try {',\n      ...['// …your existing work', ...slot('body')].map(line => indent(1, line)),\n      `} ${guard[0]}`,\n      ...guard.slice(1),\n      ...(exit.length > 0 ? exit : ['throw error']).map(line => indent(1, line)),\n      '}',\n    )\n  } else {\n    body.push(...slot('body'), ...exit)\n  }\n\n  if (body.length === 0) return []\n  /* A page fix lives inline in the component, so wrapping it in a server\n     handler skeleton would suggest moving code that should not move. */\n  if (route.kind === 'page') return body\n\n  switch (framework) {\n    case 'nuxt':\n    case 'nitro':\n      return ['export default defineEventHandler(async (event) => {', ...body.map(line => indent(1, line)), '})']\n    case 'next':\n      return [`export async function ${route.method ?? 'POST'}(request: Request) {`, ...body.map(line => indent(1, line)), '}']\n    case 'tanstack-start':\n      return [\n        `export const Route = createFileRoute('${route.path}')({`,\n        indent(1, 'server: { handlers: {'),\n        indent(2, `${route.method ?? 'POST'}: async () => {`),\n        ...body.map(line => indent(3, line)),\n        indent(2, '},'),\n        indent(1, '} },'),\n        '})',\n      ]\n    case 'hono': {\n      /* `app.on('PURGE', …)` routes have no `app.purge()` shorthand to suggest. */\n      const open = route.method === null || HONO_SHORTHAND_VERBS.has(route.method)\n        ? `app.${(route.method ?? 'all').toLowerCase()}('${route.path}', async (c) => {`\n        : `app.on('${route.method}', '${route.path}', async (c) => {`\n      return [open, ...body.map(line => indent(1, line)), '})']\n    }\n  }\n  /* A new Framework member fails to compile here until it has a shape. */\n  return framework satisfies never\n}\n\n/**\n * A query as the scan knows it.\n *\n * Shells complete `./server/api/foo.ts`, the map stores `server/api/foo.ts`;\n * both the lookup and the suggestions have to strip the prefix, or a typo'd\n * path is answered with \"no entry point matches\" and no suggestions at all.\n */\nfunction normalizeQuery(query: string): string {\n  return query.replace(/^\\.\\//, '')\n}\n\n/** Find an entry point by route path or by file path. */\nexport function findEntryPoint(result: ScanResult, query: string): RouteEntry | undefined {\n  const needle = normalizeQuery(query)\n  return result.map.routes.find(route => route.path === needle)\n    ?? result.map.routes.find(route => route.file === needle)\n    ?? result.map.routes.find(route => route.file.endsWith(needle))\n}\n\n/**\n * One entry point in full: why it was scanned, why it is sensitive, every rule\n * with its verdict and its docs, and the shape the code could take.\n */\nexport function formatMapInspect(ctx: CliContext, result: ScanResult, route: RouteEntry): string {\n  const style = createReportStyle(ctx)\n  const { paint } = style\n  const { framework } = result.map\n  const lines: string[] = []\n\n  lines.push([\n    entryLabel(style, route),\n    sensitivityBadges(style, route),\n    `  ${miniBar(style, route.score)}`,\n    `${paint([scoreColor(route.score), 'bold'], String(route.score))}${paint('dim', '/100')}`,\n  ].filter(part => part.length > 0).join(' '))\n  lines.push(paint('dim', `${route.file} · ${frameworkLabel(framework)}`))\n  lines.push('')\n\n  lines.push(paint('dim', 'WHY THIS FILE IS SCANNED'))\n  lines.push(`${paint('blue', '▍')} ${paint('dim', entryKindText(route))}`)\n  lines.push('')\n\n  if (route.sensitivity.reasons.length > 0) {\n    lines.push(paint('dim', 'FLAGGED SENSITIVE BECAUSE'))\n    for (const reason of route.sensitivity.reasons) {\n      lines.push(`${paint('magenta', '▍')} ${paint('dim', reason)}`)\n    }\n    lines.push('')\n  }\n\n  /* Waived checks stay in the list: a finding the author set aside is a decision\n     worth seeing when you open this file, unlike a rule that never applied. */\n  const entries = (Object.entries(route.checks) as [CheckId, CheckResult][])\n    .filter(([, check]) => check.status !== 'n/a' || check.suppressed)\n  if (entries.length > 0) {\n    lines.push(paint('dim', 'CHECKS'))\n    const width = Math.max(...entries.map(([id]) => ruleExpects(id).length)) + 2\n    for (const [id, check] of entries) {\n      const label = pad(ruleExpects(id), width)\n      if (check.suppressed) {\n        lines.push(`${paint('dim', '○')} ${label}${paint('dim', check.message ?? 'disabled')}`)\n      } else if (check.status === 'pass') {\n        lines.push(`${paint('green', '✓')} ${label}${paint('dim', EXPLAIN[id]?.pass ?? 'ok')}`)\n      } else {\n        const why = EXPLAIN[id]?.fail ?? check.message ?? 'failed'\n        lines.push(`${paint('red', '✗')} ${label}${paint('dim', why)}  ${style.doc(ruleDocs(id))}`)\n      }\n    }\n    lines.push('')\n  }\n\n  const suggestions = (Object.entries(route.suggestions) as [CheckId, CheckResult][])\n    .filter(([, check]) => check.status === 'fail')\n  if (suggestions.length > 0) {\n    lines.push(paint('dim', 'GOING FURTHER'))\n    for (const [id, check] of suggestions) {\n      lines.push(`${paint('cyan', '+')} ${paint('dim', check.message ?? getRule(id)?.question ?? id)}`)\n      const shape = getRule(id)?.suggest?.({ target: route, framework, project: result.project }) ?? []\n      for (const codeLine of shape) {\n        lines.push(`  ${paint('dim', '│')} ${paint('dim', codeLine)}`)\n      }\n      lines.push(`  ${style.doc(ruleDocs(id))}`)\n    }\n    lines.push('')\n  }\n\n  const shape = suggestedShape(route, framework, result.project)\n  if (shape.length > 0) {\n    lines.push(paint('dim', `SUGGESTED SHAPE — ${frameworkLabel(framework)}`))\n    for (const codeLine of shape) {\n      const [indentation] = codeLine.match(/^\\s*/)!\n      const text = codeLine.trim()\n      const color: StyleCode = text.startsWith('//')\n        ? 'dim'\n        : /useLogger|log\\.set|log\\.audit|log\\.error|createError/.test(text) ? 'green' : 'dim'\n      lines.push(`${paint('dim', '│')} ${indentation}${paint(color, text)}`)\n    }\n    lines.push('')\n    lines.push(`${paint('green', '▲')} ${paint('dim', 'fixing this entry point:')} ${paint('bold', `${route.score} → 100`)}`)\n  } else {\n    /* Two sentences on purpose: \"nothing to fix\" alone read as a contradiction\n       right under a list of suggestions, and one merged sentence made the\n       suggestions sound like unfinished work. Requirements are met; the rest is\n       upside. */\n    const disabled = countSuppressed(route)\n    const checks = disabled === 1 ? '1 check is' : `${disabled} checks are`\n    /* \"Nothing to fix\" would be a lie when the requirements were turned off\n       rather than met, so a fully disabled entry point says so instead. */\n    if (disabled > 0 && !entries.some(([, check]) => check.status === 'pass')) {\n      lines.push(`${paint('dim', '○')} ${paint('dim', `Nothing was checked here — ${checks} disabled by comment.`)}`)\n    } else {\n      lines.push(`${paint('green', '✓')} ${paint('dim', 'Nothing to fix — every requirement that applies here passes.')}`)\n      if (disabled > 0) {\n        lines.push(`${paint('dim', '○')} ${paint('dim', `${checks} disabled by comment, listed above.`)}`)\n      }\n    }\n    if (suggestions.length > 0) {\n      const count = suggestions.length === 1 ? '1 thing' : `${suggestions.length} things`\n      lines.push(`${paint('cyan', '+')} ${paint('dim', `${count} left to gain, listed above. Optional — the score is already full.`)}`)\n    }\n  }\n\n  /* The escape hatch is shown next to the verdict a reader might disagree with.\n     A check nobody can turn off is a check people learn to ignore, and a tool\n     with a hidden escape hatch is one they stop running. */\n  const failing = entries.filter(([, check]) => check.status === 'fail')\n  if (failing.length > 0) {\n    const [id] = failing[0]!\n    lines.push('')\n    lines.push(paint('dim', `○ disagree? // evlog-map-disable-next-line ${id} -- why`))\n    lines.push(`  ${style.doc('/cli/rules')}`)\n  }\n\n  return lines.join('\\n')\n}\n\n/**\n * Framework-detection warnings, shown above whichever view ran.\n *\n * Every view depends on the framework being right, so an ambiguous detection\n * has to be visible in all of them — not only in the default report.\n */\nexport function formatMapWarnings(ctx: CliContext, warnings: readonly string[]): string {\n  const { paint } = createStyle(ctx)\n  return warnings.map(warning => paint('yellow', `⚠ ${warning}`)).join('\\n')\n}\n\n/**\n * The `--min-score` verdict, appended to whichever view ran.\n *\n * Spells out the exit code because this line is most often read in CI logs,\n * where the reader is looking for why the job went red.\n */\nexport function formatGate(ctx: CliContext, result: ScanResult, threshold: number): string {\n  const style = createReportStyle(ctx)\n  const { paint } = style\n  const { score } = result.map\n  const passed = score >= threshold\n  const badge = paint(['bold', passed ? 'green' : 'red'], ' GATE ')\n\n  const verdict = passed\n    ? `${paint('green', `score ${score} meets --min-score ${threshold}`)} ${paint('dim', '— exit code 0')}`\n    : `${paint('red', `score ${score} is below --min-score ${threshold}`)} ${paint('dim', '— exit code 1')}`\n\n  const lines = ['', `${badge} ${verdict}`]\n  if (!passed) {\n    lines.push(`${paint('dim', 'fix what is listed under FIX FIRST to pass ·')} ${style.doc('/cli/ci')}`)\n  }\n  return lines.join('\\n')\n}\n\n/**\n * The `--baseline` verdict — what changed since the committed map.\n *\n * Reads as a diff rather than a score, because that is the question the gate\n * answers: `--min-score` asks \"is this app good enough\", `--baseline` asks \"did\n * this pull request make it worse\". The two are printed the same way on purpose;\n * both end up in the same CI log next to the same red cross.\n */\nexport function formatBaseline(ctx: CliContext, comparison: BaselineComparison): string {\n  const style = createReportStyle(ctx)\n  const { paint } = style\n  const { regressions, fixed, added, removed, delta, totalDelta } = comparison\n  const passed = !hasRegressed(comparison)\n  const badge = paint(['bold', passed ? 'green' : 'red'], ' BASELINE ')\n\n  /* The headline shows the two global scores, so it has to show the arithmetic\n     between them — `delta` measures something narrower and would not add up. */\n  const move = totalDelta === 0\n    ? paint('dim', `score ${comparison.score}, unchanged`)\n    : paint(totalDelta > 0 ? 'green' : 'red', `score ${comparison.baselineScore} → ${comparison.score} (${totalDelta > 0 ? '+' : ''}${totalDelta})`)\n\n  const lines = ['', `${badge} ${move} ${paint('dim', `vs ${comparison.source.label}`)}`]\n\n  if (regressions.length > 0) {\n    lines.push('')\n    lines.push(paint('dim', 'REGRESSED'))\n    for (const item of regressions) {\n      const label = item.method ? `${item.method} ${item.path}` : item.path\n      const cause = item.to === 'suppressed'\n        ? paint('yellow', `${ruleExpects(item.check)} disabled by a comment`)\n        : paint('red', `${ruleExpects(item.check)} no longer passes`)\n      lines.push(`${paint('red', '✗')} ${paint('bold', label)} ${paint('dim', '—')} ${cause}`)\n      lines.push(`   ${paint('dim', `${item.file} ·`)} ${style.doc(ruleDocs(item.check))}`)\n    }\n  }\n\n  const darkAdded = added.filter(route => route.dark)\n  if (darkAdded.length > 0) {\n    /* Listed, not gated: on an app that is not green yet, failing every pull\n       request that adds an endpoint would make the gate something teams turn\n       off. `--min-score` is the bar for new work. */\n    lines.push('')\n    lines.push(paint('dim', 'NEW AND DARK'))\n    const lead = '⚠ '\n    const names = darkAdded.map(route => route.method ? `${route.method} ${route.path}` : route.path)\n    const { shown, hidden } = fitItems(names, ' · ', style.width - lead.length - MORE_WIDTH)\n    const more = hidden > 0 ? ` +${hidden}` : ''\n    lines.push(`${paint('yellow', '⚠')} ${paint('dim', `${shown.join(' · ')}${more} — added with no instrumentation`)}`)\n  }\n\n  if (fixed.length > 0 || removed.length > 0) {\n    const parts: string[] = []\n    if (fixed.length > 0) parts.push(`${fixed.length} check${fixed.length > 1 ? 's' : ''} fixed`)\n    if (removed.length > 0) parts.push(`${removed.length} entry point${removed.length > 1 ? 's' : ''} gone`)\n    lines.push(`${paint('green', '✓')} ${paint('dim', parts.join(' · '))}`)\n  }\n\n  lines.push('')\n  if (passed) {\n    lines.push(`${paint('green', 'no regression')} ${paint('dim', '— exit code 0')}`)\n  } else {\n    /* `delta`, not `totalDelta`: this sentence explains the exit code, and what\n       gates is the movement on the entry points that already existed. */\n    const counted = `${regressions.length} regression${regressions.length === 1 ? '' : 's'}${delta < 0 ? ` and a ${-delta} point drop on existing entry points` : ''}`\n    lines.push(`${paint('red', counted)} ${paint('dim', '— exit code 1 ·')} ${style.doc('/cli/ci')}`)\n    lines.push(paint('dim', `${MAP_FILE_NAME} was not rewritten — fix the regression, or re-run without --baseline to accept it`))\n  }\n\n  return lines.join('\\n')\n}\n\n/** Shown when `evlog map <file>` matches nothing the scan found. */\nexport function formatEntryPointNotFound(ctx: CliContext, result: ScanResult, query: string): string {\n  const { paint } = createStyle(ctx)\n  const needle = normalizeQuery(query)\n  const nearby = result.map.routes\n    .filter(route => route.file.includes(needle) || route.path.includes(needle))\n    .slice(0, 5)\n\n  const lines = [paint('yellow', `No entry point matches ${query}`)]\n  if (nearby.length > 0) {\n    lines.push(paint('dim', 'Did you mean:'))\n    for (const route of nearby) lines.push(paint('dim', `  ${route.path} — ${route.file}`))\n  } else {\n    lines.push(paint('dim', `${result.map.routes.length} entry points were scanned — run evlog map --all to list them.`))\n  }\n  return lines.join('\\n')\n}\n","import { telemetry } from '@evlog/telemetry'\nimport type { BaselineComparison } from './baseline'\nimport { hasRegressed } from './baseline'\nimport { RULES } from './rules/index'\nimport { classifyRouteObservability } from './score'\nimport { sensitivityLabel } from './sensitivity'\nimport type { CheckId, Framework, Grade, RouteEntry, RouteKind, ScanResult } from './types'\n\n/**\n * What `evlog map` reports about a scan.\n *\n * Counts, grades and rule ids — never a route path, a file name or a project\n * name. Rule ids are this CLI's own closed set and are already public, so they\n * can travel as values; everything read out of the user's source stays a count.\n *\n * The distribution these fields produce is what calibrates the tool itself: the\n * 90/70/50 grade bands are a guess until real scores land against them, a rule\n * suppressed on most of the entry points it fires on is a bad rule rather than\n * bad code, and the kind split says whether the next rule should be about\n * scheduled jobs or server actions.\n */\nconst PREFIX = 'map'\n\nconst FRAMEWORKS: readonly Framework[] = ['nuxt', 'nitro', 'next', 'tanstack-start', 'hono']\nconst GRADES: readonly Grade[] = ['excellent', 'good', 'needs-work', 'at-risk']\n\n/** Entry-point kinds the map can scan, a closed set, in scan order. */\nconst KINDS: readonly RouteKind[] = ['api', 'page', 'middleware', 'server-action', 'cron', 'websocket']\n\n/** Sensitivity labels the classifier can assign, in precedence order. */\nconst SENSITIVITIES = ['money', 'auth', 'pii'] as const\ntype SensitivityLabel = typeof SENSITIVITIES[number]\n\n/** Which gate the run asked for — `--min-score`, `--baseline`, both, neither. */\nconst GATES = ['none', 'min-score', 'baseline', 'both'] as const\nexport type MapGate = typeof GATES[number]\n\n/** Which of the three renderers the run asked for. */\nconst VIEWS = ['summary', 'all', 'inspect'] as const\nexport type MapView = typeof VIEWS[number]\n\n/** String fields, with the exact set of values each may take. */\nexport const MAP_TELEMETRY_FIELDS = {\n  mapFramework: FRAMEWORKS,\n  mapGrade: GRADES,\n  mapGate: GATES,\n  mapView: VIEWS,\n} as const satisfies Record<string, readonly string[]>\n\n/** `wide-event` → `WideEvent`. */\nfunction pascal(id: string): string {\n  return id.split('-').map(part => part[0]!.toUpperCase() + part.slice(1)).join('')\n}\n\n/** Field name for a per-rule tally: `wide-event` → `mapFailWideEvent`. */\nexport function ruleField(group: 'Fail' | 'Suppressed', id: CheckId): string {\n  return `${PREFIX}${group}${pascal(id)}`\n}\n\n/** Field name for a per-kind tally: `server-action` → `mapKindServerAction`. */\nexport function kindField(group: 'Kind' | 'Dark', kind: RouteKind): string {\n  return `${PREFIX}${group}${pascal(kind)}`\n}\n\n/** Field name for a per-sensitivity tally: `money` → `mapSensitiveMoney`. */\nexport function sensitiveField(group: 'Sensitive' | 'Dark', label: SensitivityLabel): string {\n  return `${PREFIX}${group}${pascal(label)}`\n}\n\n/** What the run was asked to gate on, from the two flags that can gate it. */\nexport function resolveGate(input: { minScore: boolean, baseline: boolean }): MapGate {\n  if (input.minScore && input.baseline) return 'both'\n  if (input.minScore) return 'min-score'\n  if (input.baseline) return 'baseline'\n  return 'none'\n}\n\n/** Per-rule failure and suppression tallies across every scanned entry point. */\nfunction ruleTallies(scan: ScanResult): Record<string, number> {\n  const out: Record<string, number> = {}\n  for (const rule of RULES) {\n    out[ruleField('Fail', rule.id)] = 0\n    out[ruleField('Suppressed', rule.id)] = 0\n  }\n\n  for (const route of scan.map.routes) {\n    for (const [id, check] of Object.entries(route.checks) as [CheckId, { status: string, suppressed?: true }][]) {\n      if (check.suppressed) out[ruleField('Suppressed', id)]! += 1\n      else if (check.status === 'fail') out[ruleField('Fail', id)]! += 1\n    }\n  }\n\n  return out\n}\n\n/**\n * Per-kind totals and dark tallies across every scanned entry point.\n *\n * A kind absent from the project is omitted rather than sent as zero, the\n * same convention as flags left at their default. A kind that is present but\n * fully covered still reports its dark count as 0, so the pair reads as\n * \"12 pages, 3 dark\" and never as \"12 pages, count missing\".\n */\nfunction kindTallies(routes: RouteEntry[]): Record<string, number> {\n  const total: Partial<Record<RouteKind, number>> = {}\n  const dark: Partial<Record<RouteKind, number>> = {}\n  for (const route of routes) {\n    total[route.kind] = (total[route.kind] ?? 0) + 1\n    if (classifyRouteObservability(route) === 'dark') dark[route.kind] = (dark[route.kind] ?? 0) + 1\n  }\n\n  const out: Record<string, number> = {}\n  for (const kind of KINDS) {\n    const count = total[kind]\n    if (count === undefined) continue\n    out[kindField('Kind', kind)] = count\n    out[kindField('Dark', kind)] = dark[kind] ?? 0\n  }\n  return out\n}\n\n/**\n * Per-sensitivity totals and dark tallies (money / auth / pii).\n *\n * Sensitivity is a heuristic classification, not ground truth: these counts\n * say what the classifier found, so a population-level \"dark money handlers\"\n * number has to be read as an estimate. Labels are mutually exclusive per\n * entry point (`sensitivityLabel` precedence), so the total and dark buckets\n * stay disjoint.\n */\nfunction sensitiveTallies(routes: RouteEntry[]): Record<string, number> {\n  const total: Partial<Record<SensitivityLabel, number>> = {}\n  const dark: Partial<Record<SensitivityLabel, number>> = {}\n  for (const route of routes) {\n    const label = sensitivityLabel(route.sensitivity)\n    if (!label) continue\n    total[label] = (total[label] ?? 0) + 1\n    if (classifyRouteObservability(route) === 'dark') dark[label] = (dark[label] ?? 0) + 1\n  }\n\n  const out: Record<string, number> = {}\n  for (const label of SENSITIVITIES) {\n    const count = total[label]\n    if (count === undefined) continue\n    out[sensitiveField('Sensitive', label)] = count\n    out[sensitiveField('Dark', label)] = dark[label] ?? 0\n  }\n  return out\n}\n\n/** Every field {@link recordMapRun} can emit — the payload shape, in one place. */\nexport function mapTelemetryFields(input: {\n  scan: ScanResult\n  frameworkForced: boolean\n  gate: MapGate\n  minScore?: number\n  baseline: BaselineComparison | null\n  view: MapView\n  wrote: boolean\n}): Record<string, boolean | number | string> {\n  const { scan } = input\n  const { routes } = scan.map\n\n  const fields: Record<string, boolean | number | string> = {\n    mapFramework: scan.map.framework,\n    mapFrameworkForced: input.frameworkForced,\n    mapScore: scan.map.score,\n    mapGrade: scan.grade,\n    mapView: input.view,\n    mapWrote: input.wrote,\n    mapEntryPoints: routes.length,\n    mapSensitive: routes.filter(route => route.sensitivity.level === 'high').length,\n    mapInstrumented: scan.summary.instrumented,\n    mapPartial: scan.summary.partial,\n    mapDark: scan.summary.dark,\n    mapExempt: scan.summary.exempt,\n    mapSuppressedChecks: scan.summary.suppressedChecks,\n    mapWarnings: scan.warnings.length,\n    mapSuggestions: routes.reduce((total, route) => total + Object.keys(route.suggestions).length, 0),\n    mapProjectSuggestions: scan.suggestions.length,\n    mapGate: input.gate,\n    ...kindTallies(routes),\n    ...sensitiveTallies(routes),\n    ...ruleTallies(scan),\n  }\n\n  if (input.minScore !== undefined) fields.mapMinScore = input.minScore\n  if (input.baseline) {\n    fields.mapBaselineDelta = input.baseline.delta\n    fields.mapBaselineRegressions = input.baseline.regressions.length\n    fields.mapBaselineFixed = input.baseline.fixed.length\n    fields.mapBaselineAdded = input.baseline.added.length\n  }\n\n  /* Whether CI actually went red. The count of people who wired a gate at all\n     is the adoption number; this is the one that says it does something. */\n  fields.mapGateFailed\n    = (input.minScore !== undefined && scan.map.score < input.minScore)\n      || (input.baseline !== null && hasRegressed(input.baseline))\n\n  return fields\n}\n\n/** Record one `evlog map` scan on the active telemetry run. */\nexport function recordMapRun(input: Parameters<typeof mapTelemetryFields>[0]): void {\n  /* Typed for numbers and booleans because strings need an allowlisted key —\n     ours are, on the wrapper. The cast cannot get an unlisted value past\n     `sanitizeCustom`. */\n  telemetry.set(mapTelemetryFields(input) as Record<string, boolean | number>)\n}\n\n/**\n * Every field name this module can emit — used to document the disclosure.\n *\n * Read off a synthetic payload rather than listed again: a field added to one\n * and not the other would leave the disclosure quietly incomplete, and what\n * this CLI transmits is exactly the thing that must not drift.\n *\n * The kind and sensitivity tallies are the one deliberate exception: absent\n * kinds are omitted from the payload, so the empty synthetic scan cannot name\n * them, and the disclosure has to list every field the module *can* emit\n * rather than every field an empty project would.\n */\nexport function mapTelemetryFieldNames(): string[] {\n  const empty: ScanResult = {\n    map: { version: 1, generatedAt: '', framework: 'nuxt', projectName: '', score: 100, routes: [] },\n    grade: 'excellent',\n    project: {} as ScanResult['project'],\n    suggestions: [],\n    warnings: [],\n    summary: { instrumented: 0, partial: 0, dark: 0, exempt: 0, suppressedChecks: 0 },\n  }\n\n  const emptyBaseline: BaselineComparison = {\n    source: { kind: 'file', label: '' },\n    baselineScore: 100,\n    score: 100,\n    delta: 0,\n    totalDelta: 0,\n    regressions: [],\n    fixed: [],\n    added: [],\n    removed: [],\n  }\n\n  const payload = Object.keys(mapTelemetryFields({\n    scan: empty,\n    frameworkForced: false,\n    gate: 'none',\n    minScore: 0,\n    baseline: emptyBaseline,\n    view: 'summary',\n    wrote: false,\n  }))\n\n  const tallies = [\n    ...KINDS.flatMap(kind => [kindField('Kind', kind), kindField('Dark', kind)]),\n    ...SENSITIVITIES.flatMap(label => [sensitiveField('Sensitive', label), sensitiveField('Dark', label)]),\n  ]\n\n  return [...payload, ...tallies]\n}\n","import { EvlogError } from 'evlog'\nimport type { CliContext } from '../core/context'\nimport { EXIT_FAIL, EXIT_USAGE } from '../core/output'\nimport { defineEvlogCommand } from '../lib/command'\nimport type { CliDebug } from '../lib/debug'\nimport { createNoopCliDebug } from '../lib/debug'\nimport { cliErrors } from '../lib/errors'\nimport { resolveEvlog, resolveProject } from '../lib/project'\nimport type { ProjectInfo } from '../lib/project'\nimport { checkBaselineVersion, compareToBaseline, hasRegressed, loadBaseline } from '../lib/map/baseline'\nimport type { BaselineComparison } from '../lib/map/baseline'\nimport { detectFramework } from '../lib/map/detect'\nimport {\n  findEntryPoint,\n  formatBaseline,\n  formatEntryPointNotFound,\n  formatGate,\n  formatMapInspect,\n  formatMapMatrix,\n  formatMapReport as formatMapReportView,\n  formatMapWarnings,\n} from '../lib/map/report'\nimport { scan } from '../lib/map/scan'\nimport { recordMapRun, resolveGate } from '../lib/map/telemetry'\nimport type { MapView } from '../lib/map/telemetry'\nimport type { Framework, ScanContext, ScanResult } from '../lib/map/types'\nimport { writeMapFile } from '../lib/map/write'\n\nconst FRAMEWORKS: readonly Framework[] = ['nuxt', 'nitro', 'next', 'tanstack-start', 'hono']\n\nfunction isFramework(value: string): value is Framework {\n  return (FRAMEWORKS as readonly string[]).includes(value)\n}\n\n/** Typed result of `evlog map` — rendered by {@link formatMapReport}. */\nexport interface MapResult {\n  project: Pick<ProjectInfo, 'cwd' | 'root' | 'packageDir' | 'kind' | 'packageName'>\n  framework: Framework\n  frameworkWarnings: string[]\n  scan: ScanResult\n  /** Path `evlog.map.json` was written to, or `null` with `--no-write`. */\n  mapPath: string | null\n  /** Diff against the committed map, when `--baseline` was passed. */\n  baseline: BaselineComparison | null\n  /** Baseline problems that do not stop the run — a map that predates version reporting. */\n  baselineWarnings: string[]\n}\n\n/**\n * Scan `ctx.cwd` for routes and score their wide-event coverage (monorepo-aware).\n * Pure with respect to the context except for the `evlog.map.json` write.\n */\nexport async function runMap(\n  ctx: CliContext,\n  log: CliDebug = createNoopCliDebug(),\n  options: { framework?: Framework, noWrite?: boolean, verbose?: boolean, baseline?: string | true } = {},\n): Promise<MapResult> {\n  const project = await log.step(\n    'resolveProject',\n    () => resolveProject(ctx.cwd),\n    p => ({\n      cwd: ctx.cwd,\n      project: { kind: p.kind, root: p.root, packageDir: p.packageDir, name: p.packageName },\n    }),\n  )\n\n  const { framework, warnings } = await log.step(\n    'detectFramework',\n    () => detectFramework(project, options.framework),\n    r => ({ framework: r.framework, frameworkWarnings: r.warnings }),\n  )\n\n  const resolved = await log.step(\n    'resolveEvlog',\n    () => resolveEvlog(project),\n    r => ({ hasEvlog: !!r.install }),\n  )\n\n  const scanCtx: ScanContext = {\n    projectRoot: project.packageDir,\n    framework,\n    projectName: project.packageName ?? 'unknown',\n    hasEvlog: !!resolved.install,\n    verbose: options.verbose ?? false,\n  }\n\n  /* Read before the scan writes: `writeMapFile` overwrites `evlog.map.json` in\n     place, so loading the baseline afterwards would compare this run against\n     itself and never report a regression. */\n  const baselineMap = options.baseline\n    ? await log.step(\n      'loadBaseline',\n      () => loadBaseline(project.packageDir, typeof options.baseline === 'string' ? options.baseline : undefined),\n      r => ({ baselineSource: r.source.label, baselineScore: r.map.score }),\n    )\n    : null\n\n  /* A map written before version reporting cannot prove its rule set matches\n     the running one, so it gets a warning instead of a gate: hard-failing every\n     project on upgrade would punish the ones that never saw the feature. */\n  const baselineWarnings: string[] = []\n  if (baselineMap && checkBaselineVersion(baselineMap.map) === 'unknown') {\n    baselineWarnings.push(\n      `the baseline ${baselineMap.source.label} predates map version reporting, so its rule set cannot be verified; regenerate it with evlog map`,\n    )\n  }\n\n  const scanResult = await log.step(\n    'scan',\n    () => scan(scanCtx),\n    r => ({ routes: r.map.routes.length, score: r.map.score, grade: r.grade }),\n  )\n\n  const baseline = baselineMap\n    ? compareToBaseline(baselineMap.map, scanResult.map, baselineMap.source)\n    : null\n\n  /* A run that just reported a regression must not overwrite the file it\n     compared against: doing so moves the ratchet down to the worse state, and\n     the same command run a second time reports no regression and exits 0. */\n  const wouldClobberBaseline = baseline !== null && hasRegressed(baseline)\n\n  let mapPath: string | null = null\n  if (!options.noWrite && !wouldClobberBaseline) {\n    mapPath = await log.step('writeMapFile', () => writeMapFile(project.packageDir, scanResult.map))\n  }\n\n  log.set({ steps: ['done'] })\n\n  return {\n    project,\n    framework,\n    frameworkWarnings: warnings,\n    scan: scanResult,\n    mapPath,\n    baseline,\n    baselineWarnings,\n  }\n}\n\n/**\n * Pick the view for the flags that were passed.\n *\n * The three views answer three different questions — \"how am I doing\", \"show me\n * everything\", \"explain this one file\" — so they are separate renderers rather\n * than one renderer with three modes. Rendering lives in `lib/map/report`; this\n * function only routes.\n */\nexport function formatMapReport(\n  ctx: CliContext,\n  result: MapResult,\n  options: { all?: boolean, entry?: string, minScore?: number } = {},\n): string {\n  const sections: string[] = []\n\n  /* Framework detection and disable-comment problems share one channel: both\n     mean \"the numbers below were produced under an assumption you should see\",\n     and both have to appear above every view rather than only the default one. */\n  const warnings = [...result.frameworkWarnings, ...result.baselineWarnings, ...result.scan.warnings]\n  if (warnings.length > 0) {\n    sections.push(formatMapWarnings(ctx, warnings))\n  }\n\n  if (options.entry) {\n    const route = findEntryPoint(result.scan, options.entry)\n    sections.push(route\n      ? formatMapInspect(ctx, result.scan, route)\n      : formatEntryPointNotFound(ctx, result.scan, options.entry))\n  } else if (options.all) {\n    sections.push(formatMapMatrix(ctx, result.scan))\n  } else {\n    sections.push(formatMapReportView(ctx, result.scan, { mapPath: result.mapPath }))\n  }\n\n  if (result.baseline) {\n    sections.push(formatBaseline(ctx, result.baseline))\n  }\n\n  if (options.minScore !== undefined) {\n    sections.push(formatGate(ctx, result.scan, options.minScore))\n  }\n\n  return sections.join('\\n')\n}\n\nfunction parseFrameworkArg(value: unknown): Framework | undefined {\n  if (typeof value !== 'string' || value.length === 0) return undefined\n  if (!isFramework(value)) {\n    throw cliErrors.MAP_INVALID_FRAMEWORK({ value })\n  }\n  return value\n}\n\n/**\n * Read `--min-score`, rejecting anything that is not a whole 0-100.\n *\n * The whole string has to parse: `parseInt` reads `80oops` as 80 and `abc` as\n * nothing at all, and a threshold that quietly becomes `undefined` turns the\n * gate off — CI then reports success for a bar it never checked.\n */\nfunction parseMinScoreArg(value: unknown): number | undefined {\n  if (typeof value !== 'string' || value.length === 0) return undefined\n  const threshold = Number(value)\n  if (!Number.isInteger(threshold) || threshold < 0 || threshold > 100) {\n    throw cliErrors.MAP_INVALID_MIN_SCORE({ value })\n  }\n  return threshold\n}\n\n/**\n * Read `--baseline`, which is a flag and an option at once.\n *\n * Bare (`--baseline`) means \"the committed map, wherever it is\"; with a value it\n * is a path or a `git:<ref>`. citty hands a bare string flag back as `true` or\n * as an empty string depending on how it was written, and both spellings mean\n * the same thing to a user.\n */\nfunction parseBaselineArg(value: unknown): string | true | undefined {\n  if (value === true) return true\n  if (typeof value !== 'string') return undefined\n  return value.length > 0 ? value : true\n}\n\n/**\n * `evlog map` — static observability map: Lighthouse for wide events.\n * Logic lives in {@link runMap}; this file owns the citty surface.\n */\nexport default defineEvlogCommand('map', {\n  meta: { name: 'map', description: 'Static observability map — Lighthouse for wide events' },\n  args: {\n    entry: { type: 'positional', required: false, description: 'Inspect one entry point by route or file path' },\n    cwd: { type: 'string', description: 'Project directory (default: current)' },\n    framework: { type: 'string', description: 'Override framework detection (nuxt, nitro, next, tanstack-start, hono)' },\n    all: { type: 'boolean', description: 'Every entry point, as a check matrix' },\n    minScore: { type: 'string', description: 'Exit 1 if the global score is below this threshold' },\n    baseline: {\n      type: 'string',\n      description: 'Compare against the committed evlog.map.json and exit 1 on regression (path, or git:<ref>)',\n    },\n    // `default: true` + citty's `--no-write` negation — declaring this as `noWrite`\n    // directly would not work: citty's parser treats any `--no-x` flag as negating\n    // `x`, not as setting `noX` (see `wantsHeader`'s `--no-header` argv fallback).\n    write: { type: 'boolean', default: true, description: 'Write evlog.map.json (--no-write to skip)' },\n    verbose: { type: 'boolean', description: 'Show per-file parse warnings' },\n  },\n  async run({ args, cli, log, ui }) {\n    const cwd = typeof args.cwd === 'string' && args.cwd.length > 0 ? args.cwd : undefined\n    const ctx = cwd ? { ...cli, cwd } : cli\n\n    const entry = typeof args.entry === 'string' && args.entry.length > 0 ? args.entry : undefined\n    const view: MapView = entry ? 'inspect' : args.all ? 'all' : 'summary'\n\n    let result: MapResult\n    let threshold: number | undefined\n    let framework: Framework | undefined\n    try {\n      /* Before the scan, not after: an unusable threshold should cost nothing,\n         and validating it afterwards means the command reads the whole project\n         and writes evlog.map.json before admitting it cannot gate on it. */\n      threshold = parseMinScoreArg(args.minScore)\n      framework = parseFrameworkArg(args.framework)\n      result = await runMap(ctx, log, {\n        framework,\n        noWrite: !args.write,\n        verbose: args.verbose,\n        baseline: parseBaselineArg(args.baseline),\n      })\n    } catch (error) {\n      if (error instanceof EvlogError) {\n        log.finding({ code: error.code ?? 'cli.MAP_FAILED', why: error.why, fix: error.fix, link: error.link }, { status: 'fail' })\n        ui.done({\n          jsonMode: args.json,\n          json: { error: { code: error.code, message: error.message, why: error.why, fix: error.fix } },\n          human: error.fix ? `${error.message}\\n→ ${error.fix}` : error.message,\n        })\n        /* A baseline whose rule set does not match is a usage error, not a\n           check failure: the app did not get worse, the comparison is invalid. */\n        ui.exit(error.code === cliErrors.MAP_BASELINE_VERSION_MISMATCH.code ? EXIT_USAGE : EXIT_FAIL)\n        return\n      }\n      throw error\n    }\n\n    recordMapRun({\n      scan: result.scan,\n      frameworkForced: framework !== undefined,\n      gate: resolveGate({ minScore: threshold !== undefined, baseline: result.baseline !== null }),\n      minScore: threshold,\n      baseline: result.baseline,\n      view,\n      wrote: result.mapPath !== null,\n    })\n\n    ui.done({\n      jsonMode: args.json,\n      json: {\n        map: result.scan.map,\n        summary: result.scan.summary,\n        mapPath: result.mapPath,\n        ...(result.baseline ? { baseline: result.baseline } : {}),\n      },\n      human: formatMapReport(ctx, result, { all: args.all, entry, minScore: threshold }),\n    })\n\n    if (threshold !== undefined && result.scan.map.score < threshold) {\n      ui.exit(EXIT_FAIL)\n      return\n    }\n\n    if (result.baseline && hasRegressed(result.baseline)) {\n      ui.exit(EXIT_FAIL)\n    }\n  },\n})\n","import { defineTelemetryCommands } from '@evlog/telemetry'\nimport type { CommandDef } from 'citty'\nimport { TOOL_NAME } from '../lib/constants'\nimport { withCommandHeaders } from '../lib/command'\n\n/**\n * `evlog telemetry *` — `@evlog/telemetry` consent commands, wrapped with\n * the branded command header on every leaf.\n */\nexport default withCommandHeaders(\n  defineTelemetryCommands({ name: TOOL_NAME }) as CommandDef,\n  ['telemetry'],\n)\n","import agents from './agents'\nimport doctor from './doctor'\nimport init from './init'\nimport map from './map'\nimport telemetry from './telemetry'\n\n/**\n * Root subcommand registry.\n *\n * Adding a command:\n * 1. Create `src/commands/<name>.ts` exporting a default citty `defineCommand`\n *    (prefer `defineEvlogCommand` from `lib/command` so the branded header is automatic)\n * 2. Import it here and add one line to {@link subCommands}\n *\n * Keep `index.ts` free of command bodies — this file is the only place that\n * grows when the surface expands (audit, map, push, …).\n */\nexport const subCommands = {\n  init,\n  agents,\n  doctor,\n  map,\n  telemetry,\n}\n","import { defineCommand } from 'citty'\nimport { withTelemetry } from '@evlog/telemetry'\nimport { subCommands } from './commands'\nimport { COMMON_ARGS } from './lib/command'\nimport { TELEMETRY_ENDPOINT, TOOL_NAME, VERSION } from './lib/constants'\nimport { resolveCliEnvironment } from './lib/environment'\nimport { INIT_TELEMETRY_FIELDS } from './lib/init/telemetry'\nimport { MAP_TELEMETRY_FIELDS } from './lib/map/telemetry'\n\n/**\n * The evlog CLI command tree, telemetry-wrapped and ready for `runMain()`.\n * Command bodies live under `commands/` — see `commands/index.ts` to register one.\n */\nexport const main = withTelemetry(\n  defineCommand({\n    meta: {\n      name: 'evlog',\n      description: 'evlog — digging through logs is not observability. it\\'s hope · https://evlog.dev',\n      version: VERSION,\n    },\n    args: {\n      debug: COMMON_ARGS.debug,\n    },\n    subCommands,\n  }),\n  {\n    name: TOOL_NAME,\n    version: VERSION,\n    // Packaged installs report `production`; workspace builds report `development`.\n    environment: resolveCliEnvironment(),\n    endpoint: TELEMETRY_ENDPOINT,\n    /* Which setup options people actually pick and how projects actually score,\n       so the flow can lead with the options that get used and the grade bands\n       can be calibrated against reality. Values are ids from this CLI's own\n       catalog — the allowlist is what keeps a free-text answer from ever being\n       sent. */\n    collect: { fields: { ...INIT_TELEMETRY_FIELDS, ...MAP_TELEMETRY_FIELDS } },\n  },\n)\n\nexport { TOOL_NAME, VERSION as version }\n"],"mappings":"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"}