uidex 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/cli/cli.cjs +1273 -343
  2. package/dist/cli/cli.cjs.map +1 -1
  3. package/dist/headless/index.cjs +3 -0
  4. package/dist/headless/index.cjs.map +1 -1
  5. package/dist/headless/index.d.cts +19 -13
  6. package/dist/headless/index.d.ts +19 -13
  7. package/dist/headless/index.js +3 -0
  8. package/dist/headless/index.js.map +1 -1
  9. package/dist/index.cjs +3 -0
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +19 -13
  12. package/dist/index.d.ts +19 -13
  13. package/dist/index.js +3 -0
  14. package/dist/index.js.map +1 -1
  15. package/dist/playwright/index.cjs +36 -7
  16. package/dist/playwright/index.cjs.map +1 -1
  17. package/dist/playwright/index.js +36 -7
  18. package/dist/playwright/index.js.map +1 -1
  19. package/dist/playwright/states-reporter.cjs +36 -7
  20. package/dist/playwright/states-reporter.cjs.map +1 -1
  21. package/dist/playwright/states-reporter.d.cts +15 -0
  22. package/dist/playwright/states-reporter.d.ts +15 -0
  23. package/dist/playwright/states-reporter.js +36 -7
  24. package/dist/playwright/states-reporter.js.map +1 -1
  25. package/dist/playwright/states.cjs +8 -0
  26. package/dist/playwright/states.cjs.map +1 -1
  27. package/dist/playwright/states.d.cts +44 -1
  28. package/dist/playwright/states.d.ts +44 -1
  29. package/dist/playwright/states.js +7 -0
  30. package/dist/playwright/states.js.map +1 -1
  31. package/dist/react/index.cjs +3 -0
  32. package/dist/react/index.cjs.map +1 -1
  33. package/dist/react/index.d.cts +19 -13
  34. package/dist/react/index.d.ts +19 -13
  35. package/dist/react/index.js +3 -0
  36. package/dist/react/index.js.map +1 -1
  37. package/dist/scan/index.cjs +1217 -257
  38. package/dist/scan/index.cjs.map +1 -1
  39. package/dist/scan/index.d.cts +410 -104
  40. package/dist/scan/index.d.ts +410 -104
  41. package/dist/scan/index.js +1197 -253
  42. package/dist/scan/index.js.map +1 -1
  43. package/package.json +17 -17
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/scanner/scan/discover.ts","../../src/scanner/scan/config.ts","../../src/scanner/scan/walk.ts","../../src/scanner/scan/ast.ts","../../src/shared/entities/types.ts","../../src/shared/entities/registry.ts","../../src/scanner/scan/extract-uidex-export.ts","../../src/scanner/scan/flow-facts.ts","../../src/scanner/scan/jsx-ancestry.ts","../../src/scanner/scan/extract.ts","../../src/scanner/scan/resolve.ts","../../src/scanner/scan/routes.ts","../../src/scanner/scan/audit.ts","../../src/scanner/scan/page-coverage.ts","../../src/scanner/scan/state-coverage.ts","../../src/scanner/scan/state-matrix.ts","../../src/scanner/scan/emit.ts","../../src/scanner/scan/git.ts","../../src/scanner/scan/scaffold.ts","../../src/scanner/scan/pipeline.ts","../../src/scanner/scan/fix.ts","../../src/scanner/scan/rename.ts","../../src/scanner/scan/cli.ts","../../src/scanner/scan/ai/index.ts","../../src/scanner/scan/ai/providers/claude.ts","../../src/scanner/scan/ai/templates.ts","../../src/scanner/scan/ai/providers/index.ts","../../src/scanner/cli/parse-args.ts"],"sourcesContent":["import * as fs from \"node:fs\"\nimport * as path from \"node:path\"\nimport { parseConfig } from \"./config\"\nimport type { DiscoveredConfig } from \"./types\"\n\nexport const CONFIG_FILENAME = \".uidex.json\"\n\nconst SKIP_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \"dist\",\n \"build\",\n \".next\",\n \".turbo\",\n \".cache\",\n \"coverage\",\n])\n\nconst MAX_DEPTH = 4\n\nexport interface DiscoverOptions {\n cwd?: string\n maxDepth?: number\n}\n\nfunction tryReadConfig(configPath: string): DiscoveredConfig | null {\n let source: string\n try {\n source = fs.readFileSync(configPath, \"utf8\")\n } catch {\n return null\n }\n return {\n configPath,\n configDir: path.dirname(configPath),\n config: parseConfig(source),\n }\n}\n\nexport function discover(options: DiscoverOptions = {}): DiscoveredConfig[] {\n const cwd = options.cwd ?? process.cwd()\n const maxDepth = options.maxDepth ?? MAX_DEPTH\n\n const rootMatch = tryReadConfig(path.join(cwd, CONFIG_FILENAME))\n if (rootMatch) return [rootMatch]\n\n const results: DiscoveredConfig[] = []\n const queue: Array<[string, number]> = [[cwd, 0]]\n\n while (queue.length > 0) {\n const [dir, depth] = queue.shift()!\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n continue\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n if (SKIP_DIRS.has(entry.name)) continue\n if (entry.name.startsWith(\".\")) continue\n\n const childDir = path.join(dir, entry.name)\n const candidate = tryReadConfig(path.join(childDir, CONFIG_FILENAME))\n\n if (candidate) {\n results.push(candidate)\n continue\n }\n\n if (depth + 1 < maxDepth) {\n queue.push([childDir, depth + 1])\n }\n }\n }\n\n return results.sort((a, b) => a.configPath.localeCompare(b.configPath))\n}\n","import type { UidexConfig } from \"./types\"\n\nexport const WELL_KNOWN_FILES = {\n page: \"uidex.page.ts\",\n feature: \"uidex.feature.ts\",\n} as const satisfies Record<\"page\" | \"feature\", string>\n\nexport class ConfigError extends Error {\n constructor(message: string) {\n super(message)\n this.name = \"ConfigError\"\n }\n}\n\nconst LEGACY_KEYS = new Set([\n \"scanner\",\n \"defaults\",\n \"colors\",\n \"components\",\n \"triggerElement\",\n \"devtools\",\n])\n\nconst ALLOWED_TOP_LEVEL_KEYS = new Set([\n \"$schema\",\n \"sources\",\n \"exclude\",\n \"output\",\n \"flows\",\n \"audit\",\n \"conventions\",\n \"statesManifest\",\n \"coverageBaseline\",\n])\n\nconst ALLOWED_SOURCE_KEYS = new Set([\"rootDir\", \"include\", \"exclude\", \"prefix\"])\n\nconst ALLOWED_CONVENTIONS_KEYS = new Set([\n \"primitives\",\n \"features\",\n \"pages\",\n \"flows\",\n \"regions\",\n])\n\nconst ALLOWED_AUDIT_KEYS = new Set([\n \"scopeLeak\",\n \"coverage\",\n \"acceptance\",\n \"states\",\n \"pageCoverage\",\n \"stateMatrix\",\n])\n\nfunction fail(msg: string): never {\n throw new ConfigError(`Invalid .uidex.json: ${msg}`)\n}\n\nfunction assertObject(\n value: unknown,\n path: string\n): asserts value is Record<string, unknown> {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n fail(`${path} must be an object`)\n }\n}\n\nfunction assertStringArray(\n value: unknown,\n path: string\n): asserts value is string[] {\n if (!Array.isArray(value) || !value.every((v) => typeof v === \"string\")) {\n fail(`${path} must be a string[]`)\n }\n}\n\nexport function validateConfig(raw: unknown): UidexConfig {\n assertObject(raw, \"root\")\n\n for (const key of Object.keys(raw)) {\n if (LEGACY_KEYS.has(key)) {\n fail(\n `legacy nested key \"${key}\" is not supported; v2 uses a flat schema (sources[], output, flows, audit, conventions)`\n )\n }\n if (!ALLOWED_TOP_LEVEL_KEYS.has(key)) {\n fail(`unknown top-level key \"${key}\"`)\n }\n }\n\n if (!(\"sources\" in raw)) {\n fail(\n `required key \"sources\" is missing (must be an array with at least one entry)`\n )\n }\n\n const sources = raw.sources\n if (!Array.isArray(sources) || sources.length === 0) {\n fail(`\"sources\" must be a non-empty array`)\n }\n\n const validatedSources = sources.map((src, i) => {\n assertObject(src, `sources[${i}]`)\n for (const key of Object.keys(src)) {\n if (!ALLOWED_SOURCE_KEYS.has(key)) {\n fail(`unknown key \"${key}\" in sources[${i}]`)\n }\n }\n if (typeof src.rootDir !== \"string\" || src.rootDir.length === 0) {\n fail(`sources[${i}].rootDir must be a non-empty string`)\n }\n if (src.include !== undefined)\n assertStringArray(src.include, `sources[${i}].include`)\n if (src.exclude !== undefined)\n assertStringArray(src.exclude, `sources[${i}].exclude`)\n if (src.prefix !== undefined && typeof src.prefix !== \"string\") {\n fail(`sources[${i}].prefix must be a string`)\n }\n return src as unknown as UidexConfig[\"sources\"][number]\n })\n\n if (typeof raw.output !== \"string\" || raw.output.length === 0) {\n fail(`\"output\" must be a non-empty string`)\n }\n\n if (raw.exclude !== undefined) assertStringArray(raw.exclude, `exclude`)\n if (raw.flows !== undefined) assertStringArray(raw.flows, `flows`)\n\n if (\n raw.statesManifest !== undefined &&\n typeof raw.statesManifest !== \"string\"\n ) {\n fail(`\"statesManifest\" must be a string`)\n }\n if (\n raw.coverageBaseline !== undefined &&\n typeof raw.coverageBaseline !== \"string\"\n ) {\n fail(`\"coverageBaseline\" must be a string`)\n }\n\n if (raw.audit !== undefined) {\n assertObject(raw.audit, \"audit\")\n for (const key of Object.keys(raw.audit)) {\n if (!ALLOWED_AUDIT_KEYS.has(key)) fail(`unknown key \"${key}\" in audit`)\n const v = (raw.audit as Record<string, unknown>)[key]\n if (typeof v !== \"boolean\") fail(`audit.${key} must be a boolean`)\n }\n }\n\n if (raw.conventions !== undefined) {\n assertObject(raw.conventions, \"conventions\")\n const c = raw.conventions as Record<string, unknown>\n for (const key of Object.keys(c)) {\n if (!ALLOWED_CONVENTIONS_KEYS.has(key)) {\n fail(`unknown key \"${key}\" in conventions`)\n }\n }\n if (c.primitives !== undefined && c.primitives !== false) {\n assertStringArray(c.primitives, \"conventions.primitives\")\n }\n if (\n c.features !== undefined &&\n c.features !== false &&\n typeof c.features !== \"string\"\n ) {\n fail(`conventions.features must be a string or false`)\n }\n if (c.pages !== undefined && c.pages !== false && c.pages !== \"auto\") {\n fail(`conventions.pages must be \"auto\" or false`)\n }\n if (c.flows !== undefined && c.flows !== false) {\n assertStringArray(c.flows, \"conventions.flows\")\n }\n if (\n c.regions !== undefined &&\n c.regions !== false &&\n c.regions !== \"landmarks\"\n ) {\n fail(`conventions.regions must be \"landmarks\" or false`)\n }\n }\n\n return {\n $schema: typeof raw.$schema === \"string\" ? raw.$schema : undefined,\n sources: validatedSources,\n exclude: raw.exclude as string[] | undefined,\n output: raw.output,\n flows: raw.flows as string[] | undefined,\n audit: raw.audit as UidexConfig[\"audit\"],\n conventions: raw.conventions as UidexConfig[\"conventions\"],\n statesManifest: raw.statesManifest as string | undefined,\n coverageBaseline: raw.coverageBaseline as string | undefined,\n }\n}\n\nexport function parseConfig(json: string): UidexConfig {\n let raw: unknown\n try {\n raw = JSON.parse(json)\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e)\n throw new ConfigError(`Invalid .uidex.json: JSON parse error: ${msg}`)\n }\n return validateConfig(raw)\n}\n\nexport const DEFAULT_CONVENTIONS: Required<\n Pick<\n NonNullable<UidexConfig[\"conventions\"]>,\n \"primitives\" | \"features\" | \"pages\" | \"flows\" | \"regions\"\n >\n> = {\n primitives: [\"src/ui/**\", \"src/components/ui/**\"],\n features: \"src/features/*\",\n pages: \"auto\",\n flows: [\"e2e/**/*.spec.ts\"],\n regions: \"landmarks\",\n}\n","import * as fs from \"node:fs\"\nimport * as path from \"node:path\"\nimport type { ScannedFile, SourceConfig } from \"./types\"\n\nconst DEFAULT_INCLUDES = [\"**/*.{ts,tsx,js,jsx,mjs,cjs}\"]\nconst BASE_EXCLUDES = [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/.next/**\",\n // Exclude the scanner's own generated siblings so a scan never re-ingests its\n // output. Enumerated (not `*.gen.*`) so a hand-written file that merely contains\n // a `.gen.` segment, e.g. `foo.gen.helpers.ts`, is still scanned.\n \"**/*.gen.ts\",\n \"**/*.gen.data.ts\",\n \"**/*.gen.locs.ts\",\n]\nconst TEST_EXCLUDES = [\n \"**/*.test.ts\",\n \"**/*.test.tsx\",\n \"**/*.spec.ts\",\n \"**/*.spec.tsx\",\n]\nconst DEFAULT_EXCLUDES = [...BASE_EXCLUDES, ...TEST_EXCLUDES]\n\n/**\n * Translate a glob to a RegExp. Supports `**`, `*`, `?`, and `{a,b,c}` alternation.\n * The produced pattern matches the full relative path with forward slashes.\n */\nexport function globToRegExp(glob: string): RegExp {\n let i = 0\n let out = \"\"\n while (i < glob.length) {\n const c = glob[i]\n if (c === \"*\" && glob[i + 1] === \"*\") {\n // `**/` → matches zero or more path segments\n if (glob[i + 2] === \"/\") {\n out += \"(?:.*/)?\"\n i += 3\n continue\n }\n out += \".*\"\n i += 2\n continue\n }\n if (c === \"*\") {\n out += \"[^/]*\"\n i++\n continue\n }\n if (c === \"?\") {\n out += \"[^/]\"\n i++\n continue\n }\n if (c === \"{\") {\n const end = glob.indexOf(\"}\", i)\n if (end === -1) {\n out += \"\\\\{\"\n i++\n continue\n }\n const parts = glob\n .slice(i + 1, end)\n .split(\",\")\n .map((p) => p.replace(/[.+^$()|\\\\]/g, \"\\\\$&\"))\n out += `(?:${parts.join(\"|\")})`\n i = end + 1\n continue\n }\n if (/[.+^$()|\\\\]/.test(c)) {\n out += \"\\\\\" + c\n i++\n continue\n }\n out += c\n i++\n }\n return new RegExp(`^${out}$`)\n}\n\nfunction toPosix(p: string): string {\n return p.split(path.sep).join(\"/\")\n}\n\nfunction matchesAny(rel: string, patterns: string[]): boolean {\n return patterns.some((g) => globToRegExp(g).test(rel))\n}\n\nexport interface WalkOptions {\n cwd: string\n globalExcludes?: string[]\n /**\n * When true, do not auto-exclude `*.spec.{ts,tsx}` and `*.test.{ts,tsx}`.\n * Used by flow-file walking, where spec files are the targets.\n */\n includeTests?: boolean\n}\n\nexport function walk(\n sources: SourceConfig[],\n options: WalkOptions\n): ScannedFile[] {\n const { cwd, globalExcludes = [], includeTests = false } = options\n const out: ScannedFile[] = []\n const baseDefaults = includeTests ? BASE_EXCLUDES : DEFAULT_EXCLUDES\n\n for (const source of sources) {\n const includes = source.include?.length ? source.include : DEFAULT_INCLUDES\n const excludes = [\n ...baseDefaults,\n ...globalExcludes,\n ...(source.exclude ?? []),\n ]\n const absRoot = path.resolve(cwd, source.rootDir)\n\n for (const filePath of walkDir(absRoot, absRoot)) {\n const rel = toPosix(path.relative(absRoot, filePath))\n if (matchesAny(rel, excludes)) continue\n if (!matchesAny(rel, includes)) continue\n\n let content: string\n try {\n content = fs.readFileSync(filePath, \"utf8\")\n } catch {\n continue\n }\n\n const relFromCwd = toPosix(path.relative(cwd, filePath))\n const displayPath = source.prefix\n ? `${source.prefix.replace(/\\/$/, \"\")}/${rel}`\n : relFromCwd\n\n out.push({\n sourcePath: filePath,\n relativePath: rel,\n displayPath,\n content,\n })\n }\n }\n\n return out.sort((a, b) => a.displayPath.localeCompare(b.displayPath))\n}\n\nfunction* walkDir(root: string, dir: string): Generator<string> {\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n return\n }\n for (const entry of entries) {\n const full = path.join(dir, entry.name)\n if (entry.isDirectory()) {\n if (\n entry.name === \"node_modules\" ||\n entry.name === \"dist\" ||\n entry.name === \".git\" ||\n entry.name === \"build\" ||\n entry.name === \".next\"\n ) {\n continue\n }\n yield* walkDir(root, full)\n } else if (entry.isFile()) {\n yield full\n }\n }\n}\n","import * as path from \"node:path\"\nimport { parseSync } from \"oxc-parser\"\nimport type { Program } from \"oxc-parser\"\nimport type { ScannedFile } from \"./types\"\n\n/**\n * Shared parse layer for the scanner. Each file is parsed exactly once in\n * the extract phase; the resulting AST never leaves it (ExtractedFile must\n * stay JSON-serializable for the bundler-plugin watchers).\n *\n * oxc spans are UTF-16 code-unit offsets, i.e. they index directly into the\n * JS source string (verified against oxc-parser@0.135.0).\n */\nexport interface ParsedComment {\n type: \"Line\" | \"Block\"\n value: string\n start: number\n end: number\n}\n\nexport interface ParsedSource {\n /** null when parsing failed catastrophically — callers degrade to empty facts */\n program: Program | null\n /** true when oxc reported recoverable errors (program is still usable) */\n hasErrors: boolean\n /** all comments in source order; empty when parsing failed */\n comments: ParsedComment[]\n /** offset → 1-based line */\n lineAt(offset: number): number\n}\n\ntype Lang = \"js\" | \"jsx\" | \"ts\" | \"tsx\"\n\nfunction langFor(sourcePath: string): Lang {\n switch (path.extname(sourcePath)) {\n case \".tsx\":\n return \"tsx\"\n case \".ts\":\n case \".mts\":\n case \".cts\":\n return \"ts\"\n default:\n // .js/.jsx/.mjs/.cjs — JSX-in-.js is common in React repos, and jsx\n // is a superset of what the scanner needs from plain js.\n return \"jsx\"\n }\n}\n\nfunction makeLineAt(content: string): (offset: number) => number {\n // Offsets of each line start; binary-searched per lookup.\n const starts = [0]\n for (let i = 0; i < content.length; i++) {\n if (content[i] === \"\\n\") starts.push(i + 1)\n }\n return (offset) => {\n let lo = 0\n let hi = starts.length - 1\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1\n if (starts[mid] <= offset) lo = mid\n else hi = mid - 1\n }\n return lo + 1\n }\n}\n\nexport function parseSource(file: ScannedFile): ParsedSource {\n const lineAt = makeLineAt(file.content)\n try {\n const result = parseSync(file.sourcePath, file.content, {\n lang: langFor(file.sourcePath),\n sourceType: \"module\",\n })\n return {\n program: result.program,\n hasErrors: result.errors.length > 0,\n comments: (result.comments ?? []) as ParsedComment[],\n lineAt,\n }\n } catch {\n // Same contract as the old state machine: malformed input yields no\n // facts rather than wrong facts.\n return { program: null, hasErrors: true, comments: [], lineAt }\n }\n}\n\nexport interface AstNode {\n type: string\n start: number\n end: number\n [key: string]: unknown\n}\n\nfunction isNode(value: unknown): value is AstNode {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { type?: unknown }).type === \"string\"\n )\n}\n\n/**\n * Depth-first walk over every AST node. `visit` may return `false` to skip\n * the node's children. Hand-rolled (recurse into any object/array value\n * carrying a `type`) so we don't depend on oxc's Visitor API surface.\n */\nexport function walkAst(\n root: unknown,\n visit: (node: AstNode) => boolean | undefined\n): void {\n if (!isNode(root)) return\n if (visit(root) === false) return\n for (const key of Object.keys(root)) {\n if (key === \"type\" || key === \"start\" || key === \"end\") continue\n const value = root[key]\n if (Array.isArray(value)) {\n for (const item of value) walkAst(item, visit)\n } else if (isNode(value)) {\n walkAst(value, visit)\n }\n }\n}\n\n/**\n * Strips TypeScript expression wrappers (`as`, `satisfies`, `!`, parens) so\n * callers see the underlying expression.\n */\nexport function unwrapTsExpression(expr: AstNode): AstNode {\n let node = expr\n for (;;) {\n switch (node.type) {\n case \"TSAsExpression\":\n case \"TSSatisfiesExpression\":\n case \"TSNonNullExpression\":\n case \"TSTypeAssertion\":\n case \"ParenthesizedExpression\": {\n const inner = node.expression\n if (!isNode(inner)) return node\n node = inner\n break\n }\n default:\n return node\n }\n }\n}\n","export const ENTITY_KINDS = [\n \"route\",\n \"page\",\n \"feature\",\n \"widget\",\n \"region\",\n \"element\",\n \"primitive\",\n \"flow\",\n] as const\n\nexport type EntityKind = (typeof ENTITY_KINDS)[number]\n\nexport type Scope = string\n\nexport interface Location {\n file: string\n line?: number\n column?: number\n}\n\nexport interface EntityRef {\n kind: EntityKind\n id: string\n}\n\n/**\n * The four kinds every captured route is expected to render — the state-matrix\n * axis. A capture that only shoots the happy path leaves most of the value on\n * the table, so a missing core kind must be captured, waived (the page CANNOT\n * render it), or acknowledged in the MISSING_KINDS baseline.\n */\nexport const CORE_STATE_KINDS = [\n \"loading\",\n \"empty\",\n \"populated\",\n \"error\",\n] as const\nexport type CoreStateKind = (typeof CORE_STATE_KINDS)[number]\n/** `variant` is any state outside the matrix (a dialog, wizard step, multi-currency…). */\nexport type StateKind = CoreStateKind | \"variant\"\n\n/**\n * A declared render state of an entity — the \"story\"-like unit: a named\n * condition the page/feature/widget can render in (loading / empty / error /\n * multi-currency / …). Enumerated on the entity (not derived from syntax), it\n * is the contract the visual-states capture must satisfy and the anchor for\n * per-state acceptance criteria. Fixtures + capture mechanics stay in the spec;\n * the registry holds only the name (+ optional kind / per-state acceptance).\n */\nexport interface StateDecl {\n name: string\n /** Canonical kind for the state-matrix axis (defaults to `variant`). */\n kind?: StateKind\n /** Acceptance criteria that only this state can evidence. */\n acceptance?: string[]\n description?: string\n}\n\nexport interface Metadata {\n name?: string\n description?: string\n acceptance?: string[]\n notes?: string\n composes?: EntityRef[]\n flows?: readonly string[]\n features?: string[]\n widgets?: string[]\n /** Declared render states (see StateDecl); the capture-completeness gate. */\n states?: StateDecl[]\n /**\n * `false` opts this page/feature/widget out of visual-states capture forever\n * (a redirect, a static notice, an internal target). The page-coverage gate\n * treats an opted-out route as accounted-for. Reason belongs in `description`.\n */\n capture?: boolean\n /**\n * Per-core-kind waivers: a core kind this page's route legitimately CANNOT\n * render (a create form has no `empty`), mapped to a substantive reason. The\n * state-matrix gate treats a waived kind as accounted-for. A waiver is a\n * permanent design statement — unlike MISSING_KINDS backlog, which is debt.\n */\n waivers?: Partial<Record<CoreStateKind, string>>\n}\n\ninterface EntityWithMetaBase {\n id: string\n loc?: Location\n scopes?: Scope[]\n meta?: Metadata\n}\n\nexport interface Route {\n kind: \"route\"\n path: string\n page: string\n}\n\nexport interface FlowStep {\n entityId: string\n action?: string\n}\n\nexport interface Flow {\n kind: \"flow\"\n id: string\n loc: Location\n touches: string[]\n steps: FlowStep[]\n}\n\nexport interface Page extends EntityWithMetaBase {\n kind: \"page\"\n}\n\nexport interface Feature extends EntityWithMetaBase {\n kind: \"feature\"\n}\n\nexport interface Widget extends EntityWithMetaBase {\n kind: \"widget\"\n}\n\nexport interface Region extends EntityWithMetaBase {\n kind: \"region\"\n}\n\nexport interface Element extends EntityWithMetaBase {\n kind: \"element\"\n}\n\nexport interface Primitive extends EntityWithMetaBase {\n kind: \"primitive\"\n}\n\nexport type Entity =\n | Route\n | Page\n | Feature\n | Widget\n | Region\n | Element\n | Primitive\n | Flow\n\nexport type EntityByKind<K extends EntityKind> = Extract<Entity, { kind: K }>\n\nexport type MetaEntityKind = Exclude<EntityKind, \"route\" | \"flow\">\n\nexport function isMetaKind(kind: EntityKind): kind is MetaEntityKind {\n return kind !== \"route\" && kind !== \"flow\"\n}\n\nexport function isMetaEntity(\n entity: Entity\n): entity is Extract<Entity, { kind: MetaEntityKind }> {\n return isMetaKind(entity.kind)\n}\n\nexport function entityKey(entity: Entity): string {\n return entity.kind === \"route\" ? entity.path : entity.id\n}\n\nexport function sameRef(a: EntityRef | null, b: EntityRef | null): boolean {\n if (a === b) return true\n if (a === null || b === null) return false\n return a.kind === b.kind && a.id === b.id\n}\n\nexport class UnknownEntityKindError extends Error {\n readonly kind: string\n constructor(kind: string) {\n super(`Unknown entity kind: ${kind}`)\n this.name = \"UnknownEntityKindError\"\n this.kind = kind\n }\n}\n\nconst KIND_SET: ReadonlySet<string> = new Set<string>(ENTITY_KINDS)\n\nexport function assertEntityKind(kind: string): asserts kind is EntityKind {\n if (!KIND_SET.has(kind)) throw new UnknownEntityKindError(kind)\n}\n","import {\n assertEntityKind,\n entityKey,\n isMetaEntity,\n isMetaKind,\n type Entity,\n type EntityByKind,\n type EntityKind,\n type Flow,\n type Metadata,\n type Scope,\n} from \"./types\"\n\nexport interface ReportRecord {\n id: string\n entity?: string\n reporter?: { id?: string; email?: string; name?: string }\n title?: string\n body: string\n type: string\n severity: string\n status: string\n labels?: string[]\n url: string\n route?: string\n pageTitle?: string\n screenshot?: string\n createdAt: string\n}\n\nexport interface Registry {\n add(entity: Entity): void\n get<K extends EntityKind>(kind: K, id: string): EntityByKind<K> | undefined\n matchPattern<K extends EntityKind>(\n kind: K,\n id: string\n ): EntityByKind<K> | undefined\n list<K extends EntityKind>(kind: K): ReadonlyArray<EntityByKind<K>>\n query(predicate: (entity: Entity) => boolean): Entity[]\n byScope(scope: Scope): Entity[]\n touchedBy(flowId: string): Entity[]\n setReports(\n kind: EntityKind,\n id: string,\n reports: readonly ReportRecord[]\n ): void\n getReports(kind: EntityKind, id: string): readonly ReportRecord[]\n listReportKeys(): readonly string[]\n closeReport?: (reportId: string, status?: string) => void | Promise<void>\n onReportsChange(cb: () => void): () => void\n}\n\ntype KindStore = {\n [K in EntityKind]: Map<string, EntityByKind<K>>\n}\n\nfunction emptyStore(): KindStore {\n return {\n route: new Map(),\n page: new Map(),\n feature: new Map(),\n widget: new Map(),\n region: new Map(),\n element: new Map(),\n primitive: new Map(),\n flow: new Map(),\n }\n}\n\nfunction computeFlowIds(flows: Iterable<Flow>, targetId: string): string[] {\n const ids: string[] = []\n for (const flow of flows) {\n if (flow.touches.includes(targetId)) ids.push(flow.id)\n }\n return ids\n}\n\nfunction freezeEntity<E extends Entity>(entity: E, flows: Iterable<Flow>): E {\n if (!isMetaKind(entity.kind)) return entity\n const withMeta = entity as Extract<Entity, { meta?: Metadata }>\n if (withMeta.meta === undefined) return entity\n const computedFlows = Object.freeze(computeFlowIds(flows, withMeta.id))\n const mergedMeta: Metadata = { ...withMeta.meta, flows: computedFlows }\n return { ...entity, meta: Object.freeze(mergedMeta) } as E\n}\n\nexport function createRegistry(): Registry {\n const store = emptyStore()\n let flowsCache: Flow[] | null = null\n const patternCache = new Map<\n EntityKind,\n Array<{ segments: string[]; staticLength: number; entity: Entity }>\n >()\n\n const getFlows = (): Flow[] => {\n if (flowsCache === null) flowsCache = Array.from(store.flow.values())\n return flowsCache\n }\n\n const add = (entity: Entity): void => {\n assertEntityKind(entity.kind)\n const key = entityKey(entity)\n ;(store[entity.kind] as Map<string, Entity>).set(key, entity)\n flowsCache = null\n patternCache.delete(entity.kind)\n }\n\n const get = <K extends EntityKind>(\n kind: K,\n id: string\n ): EntityByKind<K> | undefined => {\n assertEntityKind(kind)\n const raw = store[kind].get(id) as EntityByKind<K> | undefined\n if (raw === undefined) return undefined\n return freezeEntity(raw, getFlows())\n }\n\n interface PatternEntry<K extends EntityKind> {\n /** static parts of the key around `*` wildcards, e.g. \"a-*-b\" → [\"a-\", \"-b\"] */\n segments: string[]\n staticLength: number\n entity: EntityByKind<K>\n }\n\n const getPatternsForKind = <K extends EntityKind>(\n kind: K\n ): Array<PatternEntry<K>> => {\n const cached = patternCache.get(kind)\n if (cached !== undefined) return cached as Array<PatternEntry<K>>\n const patterns: Array<PatternEntry<K>> = []\n for (const [key, entity] of store[kind]) {\n if (key.includes(\"*\")) {\n const segments = key.split(\"*\")\n patterns.push({\n segments,\n staticLength: segments.reduce((n, s) => n + s.length, 0),\n entity: entity as EntityByKind<K>,\n })\n }\n }\n patternCache.set(\n kind,\n patterns as Array<{\n segments: string[]\n staticLength: number\n entity: Entity\n }>\n )\n return patterns\n }\n\n // First segment anchored at the start, last at the end, middles matched\n // left-to-right; each `*` matches any run of characters (including none).\n const matchesSegments = (segments: string[], id: string): boolean => {\n const first = segments[0]\n const last = segments[segments.length - 1]\n if (!id.startsWith(first)) return false\n let pos = first.length\n for (let i = 1; i < segments.length - 1; i++) {\n const idx = id.indexOf(segments[i], pos)\n if (idx === -1) return false\n pos = idx + segments[i].length\n }\n return id.endsWith(last) && id.length - last.length >= pos\n }\n\n const matchPattern = <K extends EntityKind>(\n kind: K,\n id: string\n ): EntityByKind<K> | undefined => {\n assertEntityKind(kind)\n const patterns = getPatternsForKind(kind)\n if (patterns.length === 0) return undefined\n let best: PatternEntry<K> | undefined\n for (const entry of patterns) {\n if (\n matchesSegments(entry.segments, id) &&\n (best === undefined || entry.staticLength > best.staticLength)\n ) {\n best = entry\n }\n }\n if (best === undefined) return undefined\n return freezeEntity(best.entity, getFlows())\n }\n\n const list = <K extends EntityKind>(\n kind: K\n ): ReadonlyArray<EntityByKind<K>> => {\n assertEntityKind(kind)\n const flows = getFlows()\n return Array.from(store[kind].values(), (e) =>\n freezeEntity(e as EntityByKind<K>, flows)\n )\n }\n\n const allEntities = function* (): Generator<Entity> {\n for (const kind of Object.keys(store) as EntityKind[]) {\n for (const entity of store[kind].values()) {\n yield entity as Entity\n }\n }\n }\n\n const query = (predicate: (entity: Entity) => boolean): Entity[] => {\n const flows = getFlows()\n const result: Entity[] = []\n for (const entity of allEntities()) {\n if (predicate(entity)) result.push(freezeEntity(entity, flows))\n }\n return result\n }\n\n const byScope = (scope: Scope): Entity[] =>\n query(\n (entity) =>\n \"scopes\" in entity &&\n Array.isArray(entity.scopes) &&\n entity.scopes.includes(scope)\n )\n\n const touchedBy = (flowId: string): Entity[] => {\n const flow = store.flow.get(flowId)\n if (flow === undefined) return []\n const ids = new Set(flow.touches)\n return query((entity) => {\n if (!isMetaEntity(entity)) return false\n return ids.has(entity.id)\n })\n }\n\n const reports = new Map<string, readonly ReportRecord[]>()\n const reportsCbs = new Set<() => void>()\n\n const setReports = (\n kind: EntityKind,\n id: string,\n records: readonly ReportRecord[]\n ): void => {\n reports.set(`${kind}:${id}`, records)\n for (const cb of reportsCbs) cb()\n }\n\n const getReports = (kind: EntityKind, id: string): readonly ReportRecord[] =>\n reports.get(`${kind}:${id}`) ?? []\n\n const listReportKeys = (): readonly string[] => Array.from(reports.keys())\n\n const onReportsChange = (cb: () => void): (() => void) => {\n reportsCbs.add(cb)\n return () => reportsCbs.delete(cb)\n }\n\n return {\n add,\n get,\n matchPattern,\n list,\n query,\n byScope,\n touchedBy,\n setReports,\n getReports,\n listReportKeys,\n onReportsChange,\n }\n}\n","import { CORE_STATE_KINDS as CORE_KIND_LIST } from \"../../shared/entities\"\nimport { parseSource, unwrapTsExpression } from \"./ast\"\nimport type { AstNode, ParsedSource } from \"./ast\"\nimport type {\n Diagnostic,\n MetadataExport,\n MetadataExportKind,\n ParsedState,\n ScannedFile,\n Span,\n} from \"./types\"\n\n/**\n * Reads `export const uidex = <literal>` blocks from the shared oxc AST.\n * Only plain literals are accepted (objects / arrays / strings / numbers /\n * booleans / null, with optional `as const` / `satisfies` wrappers); anything\n * computed is rejected with an error diagnostic. Spans are recorded on the\n * extracted metadata so `--fix` codemods and `uidex rename` can edit source.\n */\n\ninterface SourcePos {\n offset: number\n line: number\n column: number\n}\n\ninterface LitEntry {\n key: string\n value: LitValue\n keyPos: SourcePos\n /** whole-property span, extended over one adjacent comma (removal-ready) */\n span: Span\n}\n\ntype LitValue =\n | { kind: \"string\"; value: string; pos: SourcePos; span: Span }\n | { kind: \"number\"; value: number; pos: SourcePos; span: Span }\n | { kind: \"boolean\"; value: boolean; pos: SourcePos; span: Span }\n | { kind: \"null\"; pos: SourcePos; span: Span }\n | { kind: \"array\"; items: LitValue[]; pos: SourcePos; span: Span }\n | { kind: \"object\"; entries: LitEntry[]; pos: SourcePos; span: Span }\n\nexport interface UidexExportExtractResult {\n exports: MetadataExport[]\n diagnostics: Diagnostic[]\n}\n\nconst KIND_DISCRIMINATORS = [\n \"page\",\n \"feature\",\n \"primitive\",\n \"widget\",\n \"region\",\n \"flow\",\n \"notFlow\",\n] as const\ntype Discriminator = (typeof KIND_DISCRIMINATORS)[number]\n\nconst ALLOWED_FIELDS: Record<MetadataExportKind, ReadonlySet<string>> = {\n page: new Set([\n \"page\",\n \"name\",\n \"features\",\n \"widgets\",\n \"acceptance\",\n \"states\",\n \"capture\",\n \"waivers\",\n \"description\",\n ]),\n // `capture` / `waivers` are route-scoped, and only a page maps to a route — so\n // they are page-only (the gates read them off the page). A feature/widget that\n // sets them gets an `uidex-export-unknown-field` error rather than a silent no-op.\n feature: new Set([\n \"feature\",\n \"name\",\n \"features\",\n \"acceptance\",\n \"states\",\n \"description\",\n ]),\n primitive: new Set([\"primitive\", \"name\", \"description\"]),\n widget: new Set([\"widget\", \"name\", \"acceptance\", \"states\", \"description\"]),\n region: new Set([\"region\", \"name\", \"description\"]),\n flow: new Set([\"flow\", \"notFlow\", \"name\", \"description\"]),\n}\n\n/** Allowed sub-fields of an object entry in `states`. */\nconst STATE_FIELDS: ReadonlySet<string> = new Set([\n \"name\",\n \"kind\",\n \"acceptance\",\n \"description\",\n])\n\n// Sourced from the shared registry constant so the accepted `kind`/`waiver`\n// values never drift from the kinds the state-matrix gate enforces.\nconst CORE_STATE_KINDS: ReadonlySet<string> = new Set(CORE_KIND_LIST)\nconst STATE_KINDS: ReadonlySet<string> = new Set([...CORE_KIND_LIST, \"variant\"])\n\nconst FALSEABLE: ReadonlySet<MetadataExportKind> = new Set([\n \"page\",\n \"feature\",\n \"primitive\",\n \"region\",\n])\n\n/** Expected `satisfies Uidex.<X>` type name per discriminator. */\nconst SATISFIES_NAMES: Record<Discriminator, string> = {\n page: \"Page\",\n feature: \"Feature\",\n primitive: \"Primitive\",\n widget: \"Widget\",\n region: \"Region\",\n flow: \"Flow\",\n notFlow: \"NotFlow\",\n}\nconst KNOWN_SATISFIES = new Set(Object.values(SATISFIES_NAMES))\n\nclass ExtractError extends Error {\n code: string\n hint?: string\n pos: SourcePos\n constructor(code: string, message: string, pos: SourcePos, hint?: string) {\n super(message)\n this.code = code\n this.pos = pos\n this.hint = hint\n }\n}\n\nexport function extractUidexExports(\n file: ScannedFile,\n parsed?: ParsedSource\n): UidexExportExtractResult {\n const exports: MetadataExport[] = []\n const diagnostics: Diagnostic[] = []\n const { content, displayPath } = file\n const p = parsed ?? parseSource(file)\n if (p.program === null) return { exports, diagnostics }\n\n for (const stmt of p.program.body as unknown as AstNode[]) {\n if (stmt.type !== \"ExportNamedDeclaration\") continue\n const decl = stmt.declaration as AstNode | null | undefined\n if (!isNode(decl) || decl.type !== \"VariableDeclaration\") continue\n if (decl.kind !== \"const\") continue\n for (const declarator of (decl.declarations as AstNode[] | undefined) ??\n []) {\n const id = declarator.id as AstNode | undefined\n if (!id || id.type !== \"Identifier\" || String(id.name) !== \"uidex\") {\n continue\n }\n const headerPos = posAt(content, stmt.start, p)\n try {\n const init = declarator.init as AstNode | null | undefined\n if (!isNode(init)) {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"`export const uidex` must be assigned an object literal.\",\n headerPos\n )\n }\n const value = toLitValue(unwrapTsExpression(init), content, p)\n const metadata = buildMetadata(\n value,\n displayPath,\n file.sourcePath,\n headerPos,\n diagnostics\n )\n metadata.span = statementSpan(stmt, content)\n checkSatisfies(init, metadata, displayPath, p, diagnostics)\n exports.push(metadata)\n } catch (e) {\n if (e instanceof ExtractError) {\n diagnostics.push({\n code: e.code,\n severity: \"error\",\n message: e.message,\n file: displayPath,\n line: e.pos.line,\n hint: e.hint,\n })\n } else {\n throw e\n }\n }\n }\n }\n\n return { exports, diagnostics }\n}\n\n/* ---------- AST → LitValue ---------- */\n\nfunction toLitValue(node: AstNode, content: string, p: ParsedSource): LitValue {\n const unwrapped = unwrapTsExpression(node)\n const pos = posAt(content, unwrapped.start, p)\n const span: Span = { start: unwrapped.start, end: unwrapped.end }\n\n switch (unwrapped.type) {\n case \"Literal\": {\n const v = unwrapped.value\n if (typeof v === \"string\") return { kind: \"string\", value: v, pos, span }\n if (typeof v === \"number\") {\n if (!Number.isFinite(v)) {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n `Invalid numeric literal in \\`export const uidex\\`.`,\n pos\n )\n }\n return { kind: \"number\", value: v, pos, span }\n }\n if (typeof v === \"boolean\") {\n return { kind: \"boolean\", value: v, pos, span }\n }\n if (v === null && unwrapped.raw === \"null\") {\n return { kind: \"null\", pos, span }\n }\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n `Unsupported literal in \\`export const uidex\\`; only strings, numbers, booleans, and null are allowed.`,\n pos\n )\n }\n case \"UnaryExpression\": {\n // Negative numbers parse as unary minus on a numeric literal.\n const arg = unwrapped.argument as AstNode | undefined\n if (\n unwrapped.operator === \"-\" &&\n isNode(arg) &&\n arg.type === \"Literal\" &&\n typeof arg.value === \"number\"\n ) {\n return { kind: \"number\", value: -(arg.value as number), pos, span }\n }\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Unary expressions are not allowed in `export const uidex`.\",\n pos\n )\n }\n case \"TemplateLiteral\": {\n const expressions = (unwrapped.expressions as AstNode[] | undefined) ?? []\n if (expressions.length > 0) {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Template literal with expression parts is not allowed in `export const uidex`; use a plain string literal.\",\n pos\n )\n }\n const quasis = (unwrapped.quasis as AstNode[] | undefined) ?? []\n const cooked =\n (quasis[0]?.value as { cooked?: string } | undefined)?.cooked ?? \"\"\n return { kind: \"string\", value: cooked, pos, span }\n }\n case \"Identifier\": {\n const name = String(unwrapped.name)\n if (name === \"undefined\") {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"`undefined` is not allowed as a value in `export const uidex`; omit the field instead.\",\n pos\n )\n }\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n `Identifier reference \"${name}\" is not allowed in \\`export const uidex\\`; the right-hand side must be a plain literal.`,\n pos\n )\n }\n case \"ObjectExpression\":\n return objectLit(unwrapped, content, p, pos, span)\n case \"ArrayExpression\":\n return arrayLit(unwrapped, content, p, pos, span)\n case \"SpreadElement\":\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Spread (`...`) is not allowed in `export const uidex`; the right-hand side must be a plain literal.\",\n pos\n )\n case \"CallExpression\":\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Function calls are not allowed in `export const uidex`; the right-hand side must be a plain literal.\",\n pos\n )\n case \"ConditionalExpression\":\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Conditional expressions are not allowed in `export const uidex`; the right-hand side must be a plain literal.\",\n pos\n )\n default:\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n `Computed expressions are not allowed in \\`export const uidex\\`; the right-hand side must be a plain literal.`,\n pos\n )\n }\n}\n\nfunction objectLit(\n node: AstNode,\n content: string,\n p: ParsedSource,\n pos: SourcePos,\n span: Span\n): LitValue {\n const entries: LitEntry[] = []\n const seen = new Set<string>()\n for (const prop of (node.properties as AstNode[] | undefined) ?? []) {\n if (prop.type === \"SpreadElement\") {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Spread (`...`) is not allowed inside `export const uidex`.\",\n posAt(content, prop.start, p)\n )\n }\n if (prop.type !== \"Property\") {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Unexpected member inside `export const uidex` object.\",\n posAt(content, prop.start, p)\n )\n }\n const keyNode = prop.key as AstNode\n const keyPos = posAt(content, keyNode.start, p)\n if (prop.shorthand) {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n `Shorthand property \"${String(keyNode.name)}\" is not allowed; write \"${String(keyNode.name)}: ...\" with a literal value.`,\n keyPos\n )\n }\n let key: string\n if (prop.computed) {\n if (keyNode.type !== \"Literal\" || typeof keyNode.value !== \"string\") {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Computed property keys must be string literals in `export const uidex`.\",\n keyPos\n )\n }\n key = keyNode.value\n } else if (keyNode.type === \"Identifier\") {\n key = String(keyNode.name)\n } else if (\n keyNode.type === \"Literal\" &&\n typeof keyNode.value === \"string\"\n ) {\n key = keyNode.value\n } else {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Numeric property keys are not allowed in `export const uidex`.\",\n keyPos\n )\n }\n if (seen.has(key)) {\n throw new ExtractError(\n \"uidex-export-duplicate-field\",\n `Duplicate field \"${key}\" in \\`export const uidex\\`.`,\n keyPos\n )\n }\n seen.add(key)\n const value = toLitValue(prop.value as AstNode, content, p)\n entries.push({\n key,\n value,\n keyPos,\n span: removalSpan(content, prop.start, prop.end),\n })\n }\n return { kind: \"object\", entries, pos, span }\n}\n\nfunction arrayLit(\n node: AstNode,\n content: string,\n p: ParsedSource,\n pos: SourcePos,\n span: Span\n): LitValue {\n const items: LitValue[] = []\n for (const el of (node.elements as Array<AstNode | null> | undefined) ?? []) {\n if (el === null) {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Array holes are not allowed in `export const uidex`.\",\n pos\n )\n }\n if (el.type === \"SpreadElement\") {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Spread (`...`) is not allowed inside `export const uidex`.\",\n posAt(content, el.start, p)\n )\n }\n items.push(toLitValue(el, content, p))\n }\n return { kind: \"array\", items, pos, span }\n}\n\n/* ---------- satisfies cross-check ---------- */\n\n/**\n * When the export is written `satisfies Uidex.<X>` and X is one of the known\n * kind names, warn if it contradicts the declared discriminator. Unknown or\n * unqualified type names are left alone — they may be project aliases.\n */\nfunction checkSatisfies(\n init: AstNode,\n metadata: MetadataExport,\n file: string,\n p: ParsedSource,\n diagnostics: Diagnostic[]\n): void {\n let node: AstNode | undefined = init\n let satisfiesType: AstNode | undefined\n while (isNode(node)) {\n if (node.type === \"TSSatisfiesExpression\") {\n satisfiesType = node.typeAnnotation as AstNode | undefined\n break\n }\n if (\n node.type === \"TSAsExpression\" ||\n node.type === \"TSNonNullExpression\" ||\n node.type === \"TSTypeAssertion\" ||\n node.type === \"ParenthesizedExpression\"\n ) {\n node = node.expression as AstNode | undefined\n continue\n }\n break\n }\n if (!isNode(satisfiesType) || satisfiesType.type !== \"TSTypeReference\") return\n const typeName = satisfiesType.typeName as AstNode | undefined\n if (!isNode(typeName) || typeName.type !== \"TSQualifiedName\") return\n const left = typeName.left as AstNode | undefined\n const right = typeName.right as AstNode | undefined\n if (!isNode(left) || left.type !== \"Identifier\" || left.name !== \"Uidex\") {\n return\n }\n if (!isNode(right) || right.type !== \"Identifier\") return\n const actual = String(right.name)\n if (!KNOWN_SATISFIES.has(actual)) return\n\n const discriminator: Discriminator = metadata.notFlow\n ? \"notFlow\"\n : (metadata.kind as Discriminator)\n const expected = SATISFIES_NAMES[discriminator]\n if (actual === expected) return\n diagnostics.push({\n code: \"uidex-export-satisfies-mismatch\",\n severity: \"warning\",\n message: `\\`export const uidex\\` declares kind \"${discriminator}\" but is annotated \\`satisfies Uidex.${actual}\\`; expected \\`Uidex.${expected}\\`.`,\n file,\n line: p.lineAt(satisfiesType.start),\n hint: `Change the annotation to \\`satisfies Uidex.${expected}\\` or fix the kind discriminator.`,\n })\n}\n\n/* ---------- metadata building ---------- */\n\nfunction buildMetadata(\n value: LitValue,\n file: string,\n sourcePath: string,\n headerPos: SourcePos,\n diagnostics: Diagnostic[]\n): MetadataExport {\n if (value.kind !== \"object\") {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"`export const uidex` must be assigned an object literal.\",\n value.pos\n )\n }\n\n const byKey = new Map<string, LitEntry>()\n for (const entry of value.entries) byKey.set(entry.key, entry)\n\n const presentKinds = KIND_DISCRIMINATORS.filter((k) =>\n byKey.has(k)\n ) as Discriminator[]\n if (presentKinds.length === 0) {\n throw new ExtractError(\n \"uidex-export-missing-kind\",\n \"`export const uidex` must declare one of: \" +\n KIND_DISCRIMINATORS.join(\", \") +\n \".\",\n value.pos\n )\n }\n if (presentKinds.length > 1) {\n throw new ExtractError(\n \"uidex-export-ambiguous-kind\",\n `\\`export const uidex\\` declares multiple kinds (${presentKinds.join(\n \", \"\n )}); exactly one kind discriminator is allowed per module.`,\n value.pos\n )\n }\n\n const discriminator = presentKinds[0]\n // notFlow is the only discriminator that maps to `flow` kind.\n const kind: MetadataExportKind =\n discriminator === \"notFlow\" ? \"flow\" : discriminator\n\n const allowed = ALLOWED_FIELDS[kind]\n for (const entry of value.entries) {\n if (!allowed.has(entry.key)) {\n throw new ExtractError(\n \"uidex-export-unknown-field\",\n `Unknown field \"${entry.key}\" in \\`export const uidex\\` for kind \"${kind}\". Allowed: ${Array.from(\n allowed\n )\n .sort()\n .join(\", \")}.`,\n entry.value.pos\n )\n }\n }\n\n // Parse required id and optional fields.\n const idField: string = discriminator === \"notFlow\" ? \"flow\" : discriminator\n const idValue = byKey.get(discriminator)!.value\n let id: string | false\n if (discriminator === \"notFlow\") {\n if (idValue.kind !== \"boolean\" || idValue.value !== true) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n \"`notFlow` must be `true`.\",\n idValue.pos\n )\n }\n // A flow-kind export with notFlow:true has no id — represent as false.\n id = false\n } else {\n id = readIdField(idValue, kind, idField)\n }\n\n const acceptance = readStringArrayField(byKey, \"acceptance\")?.values\n const description = readStringField(byKey, \"description\")\n const name = readStringField(byKey, \"name\")\n if (name === \"\") {\n const entry = byKey.get(\"name\")!\n diagnostics.push({\n code: \"uidex-export-empty-name\",\n severity: \"info\",\n message: \"`name` is an empty string; treating as unset.\",\n file,\n line: entry.value.pos.line,\n fix: {\n description: \"Remove the empty `name` field\",\n edits: [\n {\n path: sourcePath,\n start: entry.span.start,\n end: entry.span.end,\n replacement: \"\",\n },\n ],\n },\n })\n }\n const featuresField =\n kind === \"page\" || kind === \"feature\"\n ? readStringArrayField(byKey, \"features\")\n : undefined\n const widgetsField =\n kind === \"page\" ? readStringArrayField(byKey, \"widgets\") : undefined\n const states =\n kind === \"page\" || kind === \"feature\" || kind === \"widget\"\n ? readStatesField(byKey)\n : undefined\n const capture =\n kind === \"page\" ? readBooleanField(byKey, \"capture\") : undefined\n const waivers = kind === \"page\" ? readWaiversField(byKey) : undefined\n const notFlow =\n kind === \"flow\" && discriminator === \"notFlow\" ? true : undefined\n\n const metadata: MetadataExport = {\n source: \"ts-export\",\n kind,\n id,\n loc: {\n file,\n line: headerPos.line,\n column: headerPos.column,\n },\n }\n if (name) metadata.name = name\n if (acceptance) metadata.acceptance = acceptance\n if (description) metadata.description = description\n if (featuresField) {\n metadata.features = featuresField.values\n metadata.featureSpans = featuresField.spans\n }\n if (widgetsField) {\n metadata.widgets = widgetsField.values\n metadata.widgetSpans = widgetsField.spans\n }\n if (states?.length) metadata.states = states\n if (capture !== undefined) metadata.capture = capture\n if (waivers && Object.keys(waivers).length > 0) metadata.waivers = waivers\n if (notFlow) metadata.notFlow = true\n if (typeof id === \"string\" && idValue.kind === \"string\") {\n metadata.idSpan = idValue.span\n }\n const fieldSpans: Record<string, Span> = {}\n for (const entry of value.entries) fieldSpans[entry.key] = entry.span\n metadata.fieldSpans = fieldSpans\n return metadata\n}\n\nfunction readIdField(\n value: LitValue,\n kind: MetadataExportKind,\n fieldName: string\n): string | false {\n if (value.kind === \"string\") {\n if (value.value.length === 0) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `\\`${fieldName}\\` must be a non-empty string.`,\n value.pos\n )\n }\n return value.value\n }\n if (value.kind === \"boolean\" && value.value === false) {\n if (!FALSEABLE.has(kind)) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `\\`${fieldName}: false\\` is only valid for page, feature, and primitive kinds.`,\n value.pos\n )\n }\n return false\n }\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `\\`${fieldName}\\` must be a string${\n FALSEABLE.has(kind) ? \" or `false`\" : \"\"\n }.`,\n value.pos\n )\n}\n\n/**\n * Parse `waivers`: `{ <coreKind>: \"<reason>\" }`. Keys must be core kinds; each\n * reason must be a substantive non-empty string (why the route CANNOT render\n * that kind — enforced as non-empty here; \"why, not not-shot-yet\" is on review).\n */\nfunction readWaiversField(\n byKey: Map<string, LitEntry>\n): Record<string, string> | undefined {\n const entry = byKey.get(\"waivers\")\n if (!entry) return undefined\n if (entry.value.kind !== \"object\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n \"`waivers` must be an object mapping a core kind to a reason.\",\n entry.value.pos\n )\n }\n const waivers: Record<string, string> = {}\n for (const e of entry.value.entries) {\n if (!CORE_STATE_KINDS.has(e.key)) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `waiver key \"${e.key}\" is not a core kind; only ${[...CORE_STATE_KINDS].join(\", \")} participate in the matrix.`,\n e.keyPos\n )\n }\n if (e.value.kind !== \"string\" || e.value.value.length === 0) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `waiver \"${e.key}\" needs a non-empty reason (why the route cannot render this kind).`,\n e.value.pos\n )\n }\n waivers[e.key] = e.value.value\n }\n return waivers\n}\n\nfunction readBooleanField(\n byKey: Map<string, LitEntry>,\n name: string\n): boolean | undefined {\n const entry = byKey.get(name)\n if (!entry) return undefined\n if (entry.value.kind !== \"boolean\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `\\`${name}\\` must be a boolean.`,\n entry.value.pos\n )\n }\n return entry.value.value\n}\n\nfunction readStringField(\n byKey: Map<string, LitEntry>,\n name: string\n): string | undefined {\n const entry = byKey.get(name)\n if (!entry) return undefined\n if (entry.value.kind !== \"string\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `\\`${name}\\` must be a string.`,\n entry.value.pos\n )\n }\n return entry.value.value\n}\n\nfunction readStringArrayField(\n byKey: Map<string, LitEntry>,\n name: string\n): { values: string[]; spans: Span[] } | undefined {\n const entry = byKey.get(name)\n if (!entry) return undefined\n if (entry.value.kind !== \"array\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `\\`${name}\\` must be an array of strings.`,\n entry.value.pos\n )\n }\n const values: string[] = []\n const spans: Span[] = []\n for (const item of entry.value.items) {\n if (item.kind !== \"string\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `\\`${name}\\` must contain only string literals.`,\n item.pos\n )\n }\n values.push(item.value)\n spans.push(item.span)\n }\n return { values, spans }\n}\n\n/**\n * Parse `states`: a mixed array of bare state names (`\"loading\"`) and\n * `{ name, acceptance?, description? }` objects (per-state acceptance). Names\n * must be non-empty and unique within the entity — a duplicate or empty name is\n * an error (a silent dedupe would hide a mis-typed state from the gate).\n */\nfunction readStatesField(\n byKey: Map<string, LitEntry>\n): ParsedState[] | undefined {\n const entry = byKey.get(\"states\")\n if (!entry) return undefined\n if (entry.value.kind !== \"array\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n \"`states` must be an array of state names or `{ name, acceptance?, description? }` objects.\",\n entry.value.pos\n )\n }\n const states: ParsedState[] = []\n const seen = new Set<string>()\n for (const item of entry.value.items) {\n let state: ParsedState\n if (item.kind === \"string\") {\n state = { name: item.value, nameSpan: item.span }\n } else if (item.kind === \"object\") {\n const fieldByKey = new Map<string, LitEntry>()\n for (const e of item.entries) fieldByKey.set(e.key, e)\n for (const e of item.entries) {\n if (!STATE_FIELDS.has(e.key)) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `Unknown field \"${e.key}\" in a \\`states\\` entry. Allowed: ${Array.from(\n STATE_FIELDS\n )\n .sort()\n .join(\", \")}.`,\n e.value.pos\n )\n }\n }\n const nameEntry = fieldByKey.get(\"name\")\n if (!nameEntry || nameEntry.value.kind !== \"string\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n \"Each object `states` entry must have a string `name`.\",\n item.pos\n )\n }\n state = { name: nameEntry.value.value, nameSpan: nameEntry.value.span }\n const kind = readStringField(fieldByKey, \"kind\")\n if (kind !== undefined) {\n if (!STATE_KINDS.has(kind)) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `state \\`kind\\` must be one of ${[...STATE_KINDS].join(\", \")} (got \"${kind}\").`,\n fieldByKey.get(\"kind\")!.value.pos\n )\n }\n state.kind = kind\n }\n const acceptance = readStringArrayField(fieldByKey, \"acceptance\")?.values\n if (acceptance) state.acceptance = acceptance\n const description = readStringField(fieldByKey, \"description\")\n if (description) state.description = description\n } else {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n \"`states` items must be strings or `{ name, ... }` objects.\",\n item.pos\n )\n }\n if (state.name.length === 0) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n \"A `states` entry has an empty `name`.\",\n item.pos\n )\n }\n if (seen.has(state.name)) {\n throw new ExtractError(\n \"uidex-export-duplicate-state\",\n `Duplicate state \"${state.name}\" in \\`states\\`; each state name must be unique within the entity.`,\n item.pos\n )\n }\n seen.add(state.name)\n states.push(state)\n }\n return states\n}\n\n/* ---------- utilities ---------- */\n\nfunction posAt(content: string, offset: number, p: ParsedSource): SourcePos {\n const lineStart = content.lastIndexOf(\"\\n\", offset - 1) + 1\n return { offset, line: p.lineAt(offset), column: offset - lineStart + 1 }\n}\n\n/**\n * Extends a property span over one adjacent comma (trailing preferred) so\n * deleting the span removes the property without leaving a dangling comma.\n */\nfunction removalSpan(content: string, start: number, end: number): Span {\n let e = end\n while (e < content.length && /[ \\t]/.test(content[e])) e++\n if (content[e] === \",\") return { start, end: e + 1 }\n let s = start\n while (s > 0 && /[\\s]/.test(content[s - 1])) s--\n if (content[s - 1] === \",\") return { start: s - 1, end }\n return { start, end }\n}\n\n/**\n * Span of the whole export statement, extended over a trailing semicolon and\n * the line break that follows it, so deleting the span removes the line.\n */\nfunction statementSpan(stmt: AstNode, content: string): Span {\n let end = stmt.end\n while (end < content.length && /[ \\t]/.test(content[end])) end++\n if (content[end] === \";\") end++\n while (end < content.length && /[ \\t]/.test(content[end])) end++\n if (content[end] === \"\\r\") end++\n if (content[end] === \"\\n\") end++\n return { start: stmt.start, end }\n}\n\nfunction isNode(value: unknown): value is AstNode {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { type?: unknown }).type === \"string\"\n )\n}\n","import { walkAst } from \"./ast\"\nimport type { AstNode, ParsedSource } from \"./ast\"\nimport type { DynamicFlowCallFact, FlowCallFact, FlowFact } from \"./types\"\n\n/**\n * Extracts tagged flow describes (`test.describe(\"...\", { tag: \"@uidex:flow\" },\n * fn)`) and the `uidex(\"id\")` calls inside them from the parsed AST.\n *\n * Only statically analysable calls are captured: the describe title must be a\n * string literal and `uidex(...)` arguments must be string literals or\n * expressionless template literals. A chained method that is immediately\n * invoked (`uidex(\"x\").fill(...)`) contributes that method name as the call's\n * action.\n */\nexport function collectFlowFacts(\n parsed: ParsedSource,\n content: string\n): FlowFact[] {\n if (parsed.program === null || !content.includes(\"test.describe\")) {\n return []\n }\n\n const facts: FlowFact[] = []\n walkAst(parsed.program, (node) => {\n if (node.type !== \"CallExpression\") return undefined\n const fact = readTaggedDescribe(node, parsed)\n if (fact) facts.push(fact)\n return undefined\n })\n return facts\n}\n\nfunction readTaggedDescribe(\n call: AstNode,\n parsed: ParsedSource\n): FlowFact | null {\n const callee = call.callee as AstNode | undefined\n if (\n !callee ||\n callee.type !== \"MemberExpression\" ||\n !isIdentifier(callee.object, \"test\") ||\n !isIdentifier(callee.property, \"describe\")\n ) {\n return null\n }\n const args = (call.arguments as AstNode[] | undefined) ?? []\n const title = stringLiteralValue(args[0])\n if (title === null) return null\n if (!hasFlowTag(args[1])) return null\n\n const body = args[2]\n const { calls, dynamicCalls } = body\n ? collectUidexCalls(body, parsed)\n : { calls: [], dynamicCalls: [] }\n return {\n title,\n line: parsed.lineAt(call.start),\n calls,\n ...(dynamicCalls.length > 0 ? { dynamicCalls } : {}),\n }\n}\n\nfunction hasFlowTag(node: AstNode | undefined): boolean {\n if (!node || node.type !== \"ObjectExpression\") return false\n for (const prop of (node.properties as AstNode[] | undefined) ?? []) {\n if (prop.type !== \"Property\") continue\n const key = prop.key as AstNode | undefined\n const keyName =\n key?.type === \"Identifier\"\n ? String(key.name)\n : key?.type === \"Literal\"\n ? String(key.value)\n : null\n if (keyName !== \"tag\") continue\n const value = prop.value as AstNode | undefined\n if (!value) return false\n if (stringLiteralValue(value) === \"@uidex:flow\") return true\n if (value.type === \"ArrayExpression\") {\n for (const el of (value.elements as AstNode[] | undefined) ?? []) {\n if (el && stringLiteralValue(el) === \"@uidex:flow\") return true\n }\n }\n return false\n }\n return false\n}\n\nfunction collectUidexCalls(\n body: AstNode,\n parsed: ParsedSource\n): { calls: FlowCallFact[]; dynamicCalls: DynamicFlowCallFact[] } {\n const calls: FlowCallFact[] = []\n const dynamicCalls: DynamicFlowCallFact[] = []\n // Chained calls record the inner uidex(...) node here so the DFS doesn't\n // record it a second time when it reaches it.\n const claimed = new Set<AstNode>()\n\n const record = (node: AstNode, action?: string): void => {\n if (claimed.has(node)) return\n claimed.add(node)\n const resolved = uidexCallId(node)\n if (resolved === null) {\n // A uidex(...) call whose argument is not a static string literal —\n // invisible to the registry, so coverage silently shrinks. Surfaced\n // as a dynamic-flow-reference lint by the audit.\n dynamicCalls.push({ line: parsed.lineAt(node.start) })\n return\n }\n calls.push({\n id: resolved.id,\n ...(action ? { action } : {}),\n line: parsed.lineAt(node.start),\n span: resolved.span,\n })\n }\n\n walkAst(body, (node) => {\n if (node.type !== \"CallExpression\") return undefined\n\n // uidex(\"id\").action(...) — outer call whose callee member chain starts\n // at a uidex(...) call.\n const callee = node.callee as AstNode | undefined\n if (callee?.type === \"MemberExpression\") {\n const inner = callee.object as AstNode | undefined\n if (inner && isUidexCall(inner)) {\n const property = callee.property as AstNode | undefined\n const action =\n property?.type === \"Identifier\" ? String(property.name) : undefined\n record(inner, action)\n }\n return undefined\n }\n\n // Bare uidex(\"id\") call (or one reached before any chain claimed it).\n if (isUidexCall(node)) record(node)\n return undefined\n })\n\n return { calls, dynamicCalls }\n}\n\n/** True when the node is a `uidex(...)` call with at least one argument. */\nfunction isUidexCall(node: AstNode): boolean {\n if (node.type !== \"CallExpression\") return false\n if (!isIdentifier(node.callee, \"uidex\")) return false\n return ((node.arguments as AstNode[] | undefined) ?? []).length >= 1\n}\n\n/** Returns the static id (and its literal span) of a `uidex(\"...\")` call, else null. */\nfunction uidexCallId(\n node: AstNode\n): { id: string; span: { start: number; end: number } } | null {\n const args = (node.arguments as AstNode[] | undefined) ?? []\n const arg = args[0]\n const id = stringLiteralValue(arg)\n if (id === null) return null\n return { id, span: { start: arg.start, end: arg.end } }\n}\n\nfunction stringLiteralValue(node: AstNode | undefined | null): string | null {\n if (!node) return null\n if (node.type === \"Literal\" && typeof node.value === \"string\") {\n return node.value.length > 0 ? node.value : null\n }\n if (node.type === \"TemplateLiteral\") {\n const expressions = (node.expressions as AstNode[] | undefined) ?? []\n if (expressions.length > 0) return null\n const quasis = (node.quasis as AstNode[] | undefined) ?? []\n const cooked = (quasis[0]?.value as { cooked?: string } | undefined)?.cooked\n return cooked && cooked.length > 0 ? cooked : null\n }\n return null\n}\n\nfunction isIdentifier(node: unknown, name: string): boolean {\n return (\n typeof node === \"object\" &&\n node !== null &&\n (node as AstNode).type === \"Identifier\" &&\n String((node as AstNode).name) === name\n )\n}\n","import { unwrapTsExpression, walkAst } from \"./ast\"\nimport type { AstNode, ParsedSource } from \"./ast\"\nimport type {\n AnnotationAncestor,\n DomAttrKind,\n DynamicAttrFact,\n InteractiveElementFact,\n LandmarkFact,\n Span,\n} from \"./types\"\n\n/**\n * Walks the parsed JSX AST and emits each `data-uidex*` attribute occurrence\n * paired with its JSX ancestor chain (outermost to innermost).\n *\n * Ancestry follows the AST: conditional JSX (`{cond && <div/>}`), `.map()`\n * callbacks, fragments, and JSX nested in attribute expressions all\n * contribute correct chains. A file that failed to parse (`program: null`)\n * yields no occurrences — empty ancestry rather than wrong ancestry.\n */\n\nconst ATTR_NAME_RE = /^data-uidex(?:-(region|widget|primitive))?$/\n\nexport interface DataAttrOccurrence {\n kind: DomAttrKind\n id: string\n line: number\n ancestors: AnnotationAncestor[]\n /** span of the value string literal, when the value is a single plain literal */\n span?: Span\n}\n\nexport interface JSXFacts {\n occurrences: DataAttrOccurrence[]\n /** data-uidex* attributes whose value could not be resolved statically */\n dynamicAttrs: DynamicAttrFact[]\n /** interactive host elements with no data-uidex* attribute at all */\n unannotatedInteractive: InteractiveElementFact[]\n /** HTML5 landmark elements (auto-registered as regions by convention) */\n landmarks: LandmarkFact[]\n}\n\n/** Host tags the audit nudges toward `data-uidex` annotation. */\nconst INTERACTIVE_TAGS = new Set([\"button\", \"a\", \"input\", \"select\", \"textarea\"])\n\n/** Host tags that auto-register as regions (HTML5 landmarks). */\nconst LANDMARK_TAGS = new Set([\"header\", \"nav\", \"main\", \"aside\", \"footer\"])\n\ninterface ResolvedAttr {\n kind: DomAttrKind\n id: string\n /** offset of the attribute node, for line reporting */\n start: number\n /** patterns (template-derived ids containing `*`) sort after static ids */\n isPattern: boolean\n /** span of the value literal, when the value is a single plain literal */\n span?: Span\n}\n\nfunction attrKind(node: AstNode): DomAttrKind | null {\n const name = node.name as AstNode | undefined\n if (!name || name.type !== \"JSXIdentifier\") return null\n const m = ATTR_NAME_RE.exec(String(name.name))\n if (!m) return null\n return (m[1] ?? \"element\") as DomAttrKind\n}\n\n/**\n * Same-file `const name = \"literal\"` bindings, used to resolve identifier\n * references in attribute values. Names bound more than once are dropped —\n * the scanner only inlines unambiguous constants.\n */\nfunction collectConstStrings(program: AstNode): Map<string, string> {\n const consts = new Map<string, string>()\n const seen = new Set<string>()\n walkAst(program, (node) => {\n if (node.type !== \"VariableDeclaration\" || node.kind !== \"const\") {\n return undefined\n }\n for (const decl of (node.declarations as AstNode[] | undefined) ?? []) {\n const id = decl.id as AstNode | undefined\n if (!id || id.type !== \"Identifier\") continue\n const name = String(id.name)\n if (seen.has(name)) {\n consts.delete(name)\n continue\n }\n seen.add(name)\n const init = decl.init as AstNode | undefined\n if (!init) continue\n const value = staticString(unwrapTsExpression(init))\n if (value !== null) consts.set(name, value)\n }\n return undefined\n })\n return consts\n}\n\n/** A plain string literal or expressionless template literal, else null. */\nfunction staticString(node: AstNode): string | null {\n if (node.type === \"Literal\" && typeof node.value === \"string\") {\n return node.value\n }\n if (node.type === \"TemplateLiteral\") {\n const expressions = (node.expressions as AstNode[] | undefined) ?? []\n if (expressions.length > 0) return null\n const quasis = (node.quasis as AstNode[] | undefined) ?? []\n return (quasis[0]?.value as { cooked?: string } | undefined)?.cooked ?? \"\"\n }\n return null\n}\n\ntype EvalResult =\n /** every branch resolved; ids may contain `*` wildcards (patterns) */\n { resolved: true; ids: string[] } | { resolved: false }\n\nconst UNRESOLVED: EvalResult = { resolved: false }\n\n/**\n * Static-id evaluator for data-uidex attribute expressions.\n *\n * - string literal / expressionless template → that id\n * - template with expressions → resolvable parts inline, opaque parts\n * become `*`; the result is a pattern id (requires ≥1 static char)\n * - identifier → unambiguous same-file `const name = \"literal\"`\n * - ternary → union of both branches (both must resolve)\n */\nfunction evalIdExpression(\n expr: AstNode,\n consts: Map<string, string>\n): EvalResult {\n const node = unwrapTsExpression(expr)\n\n const literal = staticString(node)\n if (literal !== null) {\n return literal.length > 0 ? { resolved: true, ids: [literal] } : UNRESOLVED\n }\n\n if (node.type === \"TemplateLiteral\") {\n const quasis = (node.quasis as AstNode[] | undefined) ?? []\n const expressions = (node.expressions as AstNode[] | undefined) ?? []\n let out = \"\"\n for (let i = 0; i < quasis.length; i++) {\n out += (quasis[i].value as { cooked?: string } | undefined)?.cooked ?? \"\"\n if (i < expressions.length) {\n const part = evalIdExpression(expressions[i], consts)\n out += part.resolved && part.ids.length === 1 ? part.ids[0] : \"*\"\n }\n }\n out = out.replace(/\\*{2,}/g, \"*\")\n if (!out.includes(\"*\")) {\n return out.length > 0 ? { resolved: true, ids: [out] } : UNRESOLVED\n }\n // A bare `*` (no static text at all) matches everything — useless as a\n // pattern, so it stays a dynamic attribute.\n return out.replace(/\\*/g, \"\").length > 0\n ? { resolved: true, ids: [out] }\n : UNRESOLVED\n }\n\n if (node.type === \"Identifier\") {\n const value = consts.get(String(node.name))\n return value !== undefined && value.length > 0\n ? { resolved: true, ids: [value] }\n : UNRESOLVED\n }\n\n if (node.type === \"ConditionalExpression\") {\n const left = evalIdExpression(node.consequent as AstNode, consts)\n const right = evalIdExpression(node.alternate as AstNode, consts)\n if (!left.resolved || !right.resolved) return UNRESOLVED\n return { resolved: true, ids: [...new Set([...left.ids, ...right.ids])] }\n }\n\n return UNRESOLVED\n}\n\nfunction collectElementAttrs(\n opening: AstNode,\n consts: Map<string, string>,\n dynamicAttrs: DynamicAttrFact[],\n lineAt: (offset: number) => number\n): ResolvedAttr[] {\n const statics: ResolvedAttr[] = []\n const patterns: ResolvedAttr[] = []\n const attributes = (opening.attributes as AstNode[] | undefined) ?? []\n for (const attr of attributes) {\n if (attr.type !== \"JSXAttribute\") continue\n const kind = attrKind(attr)\n if (!kind) continue\n const value = attr.value as AstNode | null | undefined\n if (!value) continue\n\n let result: EvalResult = UNRESOLVED\n let valueSpan: Span | undefined\n if (value.type === \"Literal\") {\n const v = staticString(value)\n result =\n v !== null && v.length > 0 ? { resolved: true, ids: [v] } : UNRESOLVED\n if (result.resolved) valueSpan = { start: value.start, end: value.end }\n } else if (value.type === \"JSXExpressionContainer\") {\n const expr = value.expression as AstNode | undefined\n if (expr && expr.type !== \"JSXEmptyExpression\") {\n result = evalIdExpression(expr, consts)\n const inner = unwrapTsExpression(expr)\n if (result.resolved && staticString(inner) !== null) {\n valueSpan = { start: inner.start, end: inner.end }\n }\n }\n if (!result.resolved) {\n dynamicAttrs.push({\n kind,\n attrName: kind === \"element\" ? \"data-uidex\" : `data-uidex-${kind}`,\n line: lineAt(attr.start),\n })\n continue\n }\n }\n\n if (!result.resolved) continue\n for (const id of result.ids) {\n const resolved: ResolvedAttr = {\n kind,\n id,\n start: attr.start,\n isPattern: id.includes(\"*\"),\n // Only a single plain string literal is renameable in place.\n ...(result.ids.length === 1 && valueSpan ? { span: valueSpan } : {}),\n }\n if (resolved.isPattern) patterns.push(resolved)\n else statics.push(resolved)\n }\n }\n // Static ids before patterns, matching the registration order entities\n // historically appeared in.\n return [...statics, ...patterns]\n}\n\nexport function collectJSXFacts(parsed: ParsedSource): JSXFacts {\n const occurrences: DataAttrOccurrence[] = []\n const dynamicAttrs: DynamicAttrFact[] = []\n const unannotatedInteractive: InteractiveElementFact[] = []\n const landmarks: LandmarkFact[] = []\n // Files with no data-uidex content can still contain unannotated\n // interactive elements, so only a failed parse short-circuits.\n if (parsed.program === null) {\n return { occurrences, dynamicAttrs, unannotatedInteractive, landmarks }\n }\n\n const consts = collectConstStrings(parsed.program as unknown as AstNode)\n const ancestors: AnnotationAncestor[] = []\n\n const visit = (node: unknown): void => {\n if (!isNode(node)) return\n\n if (node.type === \"JSXElement\") {\n const opening = node.openingElement as AstNode\n const attrs = collectElementAttrs(\n opening,\n consts,\n dynamicAttrs,\n parsed.lineAt\n )\n const interactive = readInteractive(node, parsed.lineAt)\n if (interactive) unannotatedInteractive.push(interactive)\n if (attrs.length > 0) {\n const snapshot = ancestors.slice()\n for (const a of attrs) {\n occurrences.push({\n kind: a.kind,\n id: a.id,\n line: parsed.lineAt(a.start),\n ancestors: snapshot,\n ...(a.span ? { span: a.span } : {}),\n })\n }\n }\n let pushed = attrs.length\n for (const a of attrs) ancestors.push({ kind: a.kind, id: a.id })\n // Landmarks register as convention regions; they join the ancestry so\n // child data-uidex elements compose onto them, unless the element also\n // carries an explicit data-uidex-region (which takes precedence and is\n // already on the stack).\n const landmark = readLandmark(opening, parsed.lineAt)\n if (landmark) {\n landmarks.push(landmark)\n if (!attrs.some((a) => a.kind === \"region\")) {\n ancestors.push({ kind: \"region\", id: landmark.tag })\n pushed++\n }\n }\n // Children, plus JSX nested inside attribute expressions (render\n // props), inherit this element's ancestry.\n visitChildren(opening)\n for (const child of (node.children as AstNode[] | undefined) ?? []) {\n visit(child)\n }\n const closing = node.closingElement\n if (isNode(closing)) visitChildren(closing)\n ancestors.length -= pushed\n return\n }\n\n visitChildren(node)\n }\n\n const visitChildren = (node: AstNode): void => {\n for (const key of Object.keys(node)) {\n if (key === \"type\" || key === \"start\" || key === \"end\") continue\n const value = node[key]\n if (Array.isArray(value)) {\n for (const item of value) visit(item)\n } else {\n visit(value)\n }\n }\n }\n\n visit(parsed.program)\n return { occurrences, dynamicAttrs, unannotatedInteractive, landmarks }\n}\n\n/**\n * Returns a fact when the opening element is an HTML5 landmark tag or\n * carries `role=\"region\"`. The fact's `tag` doubles as the convention\n * region id (\"header\", \"nav\", …, or \"region\" for role-based landmarks).\n */\nfunction readLandmark(\n opening: AstNode,\n lineAt: (offset: number) => number\n): LandmarkFact | null {\n const name = opening.name as AstNode | undefined\n if (!name || name.type !== \"JSXIdentifier\") return null\n const tag = String(name.name)\n if (LANDMARK_TAGS.has(tag)) {\n return { tag, line: lineAt(opening.start) }\n }\n for (const attr of (opening.attributes as AstNode[] | undefined) ?? []) {\n if (attr.type !== \"JSXAttribute\") continue\n const attrName = attr.name as AstNode | undefined\n if (!attrName || String(attrName.name) !== \"role\") continue\n const value = attr.value as AstNode | null | undefined\n if (value && value.type === \"Literal\" && value.value === \"region\") {\n return { tag: \"region\", line: lineAt(opening.start) }\n }\n }\n return null\n}\n\n/**\n * Returns a fact when the opening element is an interactive host tag with no\n * data-uidex* attribute of any form (static, pattern, or dynamic). Captures\n * the attribute-insertion offset and a static name hint so `--fix` can\n * deterministically generate a `data-uidex` id.\n */\nfunction readInteractive(\n element: AstNode,\n lineAt: (offset: number) => number\n): InteractiveElementFact | null {\n const opening = element.openingElement as AstNode\n const name = opening.name as AstNode | undefined\n if (!name || name.type !== \"JSXIdentifier\") return null\n const tag = String(name.name)\n if (!INTERACTIVE_TAGS.has(tag)) return null\n let hasSpread = false\n for (const attr of (opening.attributes as AstNode[] | undefined) ?? []) {\n if (attr.type === \"JSXSpreadAttribute\") {\n hasSpread = true\n continue\n }\n if (attr.type === \"JSXAttribute\" && attrKind(attr) !== null) return null\n }\n const nameHint = interactiveNameHint(element, opening)\n return {\n tag,\n line: lineAt(opening.start),\n hasSpread,\n nameEnd: name.end as number,\n ...(nameHint ? { nameHint } : {}),\n }\n}\n\n/** Static string value of a named attribute on the opening element, or null. */\nfunction staticAttrValue(opening: AstNode, attrName: string): string | null {\n for (const attr of (opening.attributes as AstNode[] | undefined) ?? []) {\n if (attr.type !== \"JSXAttribute\") continue\n const n = attr.name as AstNode | undefined\n if (!n || String(n.name) !== attrName) continue\n const value = attr.value as AstNode | null | undefined\n if (!value) return null\n if (value.type === \"Literal\") return staticString(value)\n if (value.type === \"JSXExpressionContainer\") {\n const expr = value.expression as AstNode | undefined\n return expr ? staticString(unwrapTsExpression(expr)) : null\n }\n return null\n }\n return null\n}\n\n/** Concatenated static JSXText children, whitespace-collapsed and trimmed. */\nfunction staticChildText(element: AstNode): string {\n const parts: string[] = []\n for (const child of (element.children as AstNode[] | undefined) ?? []) {\n if (child.type === \"JSXText\") {\n parts.push(String((child as { value?: unknown }).value ?? \"\"))\n }\n }\n return parts.join(\" \").replace(/\\s+/g, \" \").trim()\n}\n\n/**\n * Best static label for an interactive element, used to derive a `data-uidex`\n * id: accessible name first (aria-label), then visible text, then descriptive\n * attributes. Returns undefined when nothing statically usable exists.\n */\nfunction interactiveNameHint(\n element: AstNode,\n opening: AstNode\n): string | undefined {\n const ariaLabel = staticAttrValue(opening, \"aria-label\")\n if (ariaLabel) return ariaLabel\n const text = staticChildText(element)\n if (text) return text\n for (const attr of [\"title\", \"name\", \"placeholder\"]) {\n const v = staticAttrValue(opening, attr)\n if (v) return v\n }\n return undefined\n}\n\nfunction isNode(value: unknown): value is AstNode {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { type?: unknown }).type === \"string\"\n )\n}\n","import { parseSource } from \"./ast\"\nimport type { AstNode, ParsedSource } from \"./ast\"\nimport { extractUidexExports } from \"./extract-uidex-export\"\nimport { collectFlowFacts } from \"./flow-facts\"\nimport { collectJSXFacts } from \"./jsx-ancestry\"\nimport type {\n Annotation,\n Diagnostic,\n ExtractedFile,\n ImportFact,\n ScannedFile,\n} from \"./types\"\n\n/**\n * A fatal oxc failure (throw, or an empty program body alongside reported\n * errors — oxc's signature for unrecoverable input, e.g. a syntax error or a\n * Flow-typed .js file) means every AST-derived fact for the file is silently\n * empty. Surface that instead of letting the file's ids vanish from the gen\n * file with no trace. Recoverable errors keep a usable program and stay quiet.\n */\nfunction parseFailureDiagnostic(\n file: ScannedFile,\n parsed: ParsedSource\n): Diagnostic | null {\n const fatal =\n parsed.program === null ||\n (parsed.hasErrors && parsed.program.body.length === 0)\n if (!fatal) return null\n return {\n code: \"parse-error\",\n severity: \"warning\",\n message:\n \"File could not be parsed — data-uidex attributes and flow facts in it were skipped, and their ids will drop out of the gen file\",\n file: file.displayPath,\n line: 1,\n hint: \"Fix the file's syntax (or exclude it from .uidex.json sources) so the scanner can read its annotations\",\n }\n}\n\nexport function extract(files: ScannedFile[]): ExtractedFile[] {\n return files.map((file) => {\n // One parse per file; every AST-derived fact comes out of this pass and\n // the program itself never leaves the extract phase.\n const parsed = parseSource(file)\n const { exports, diagnostics } = extractUidexExports(file, parsed)\n const parseFailure = parseFailureDiagnostic(file, parsed)\n if (parseFailure) diagnostics.push(parseFailure)\n const out: ExtractedFile = { file, annotations: [] }\n out.annotations = extractOne(file, parsed, out)\n if (exports.length > 0) out.metadata = exports\n if (diagnostics.length > 0) out.diagnostics = diagnostics\n const flows = collectFlowFacts(parsed, file.content)\n if (flows.length > 0) out.flows = flows\n const imports = collectImportFacts(parsed)\n if (imports.length > 0) out.imports = imports\n return out\n })\n}\n\nfunction extractOne(\n file: ScannedFile,\n parsed: ParsedSource,\n out: ExtractedFile\n): Annotation[] {\n const annotations: Annotation[] = []\n const { displayPath } = file\n\n const jsx = collectJSXFacts(parsed)\n if (jsx.dynamicAttrs.length > 0) out.dynamicAttrs = jsx.dynamicAttrs\n if (jsx.unannotatedInteractive.length > 0) {\n out.unannotatedInteractive = jsx.unannotatedInteractive\n }\n if (jsx.landmarks.length > 0) out.landmarks = jsx.landmarks\n for (const occ of jsx.occurrences) {\n annotations.push({\n kind: occ.kind,\n id: occ.id,\n file: displayPath,\n line: occ.line,\n ...(occ.ancestors.length > 0 ? { ancestors: occ.ancestors } : {}),\n ...(occ.span ? { span: occ.span } : {}),\n })\n }\n\n return annotations\n}\n\n/**\n * Static import bindings from the top-level program body: `import` and\n * re-export (`export … from`) statements. Dynamic `import()` and `require()`\n * are intentionally out of scope — the scope-leak check is about module\n * dependency structure, which those don't declare statically.\n */\nfunction collectImportFacts(parsed: ParsedSource): ImportFact[] {\n if (parsed.program === null) return []\n const out: ImportFact[] = []\n for (const stmt of parsed.program.body as unknown as AstNode[]) {\n let source: AstNode | null | undefined\n let isTypeOnly = false\n const names: string[] = []\n if (stmt.type === \"ImportDeclaration\") {\n source = stmt.source as AstNode | undefined\n isTypeOnly = stmt.importKind === \"type\"\n for (const spec of (stmt.specifiers as AstNode[] | undefined) ?? []) {\n const local = spec.local as AstNode | undefined\n if (local && local.type === \"Identifier\") {\n names.push(String(local.name))\n }\n }\n } else if (\n (stmt.type === \"ExportNamedDeclaration\" ||\n stmt.type === \"ExportAllDeclaration\") &&\n stmt.source\n ) {\n source = stmt.source as AstNode\n isTypeOnly = stmt.exportKind === \"type\"\n } else {\n continue\n }\n if (!source || source.type !== \"Literal\") continue\n if (typeof source.value !== \"string\") continue\n out.push({\n specifier: source.value,\n line: parsed.lineAt(stmt.start),\n span: { start: stmt.start, end: stmt.end },\n isTypeOnly,\n names,\n })\n }\n return out\n}\n","import * as path from \"node:path\"\nimport {\n createRegistry,\n type Entity,\n type EntityRef,\n type Feature,\n type Flow,\n type Metadata,\n type Page,\n type Primitive,\n type Region,\n type Registry,\n type StateDecl,\n type Widget,\n type Element as UidexElement,\n} from \"../../shared/entities\"\nimport { DEFAULT_CONVENTIONS, WELL_KNOWN_FILES } from \"./config\"\nimport { detectRoutes } from \"./routes\"\nimport { globToRegExp } from \"./walk\"\nimport type {\n Annotation,\n ConventionsConfig,\n DetectedRoute,\n Diagnostic,\n DomAttrKind,\n ExtractedFile,\n MetadataExport,\n UidexConfig,\n} from \"./types\"\n\nconst DOM_ATTR_KINDS: ReadonlySet<Annotation[\"kind\"]> = new Set([\n \"element\",\n \"region\",\n \"widget\",\n \"primitive\",\n])\n\nexport interface ResolveContext {\n config: UidexConfig\n extracted: ExtractedFile[]\n flowFiles?: ExtractedFile[]\n}\n\nexport interface ResolveOutput {\n registry: Registry\n entities: Entity[]\n routes: DetectedRoute[]\n diagnostics: Diagnostic[]\n}\n\nfunction resolveConventions(c: ConventionsConfig | undefined): {\n primitives: string[] | false\n features: string | false\n pages: \"auto\" | false\n flows: string[] | false\n regions: \"landmarks\" | false\n} {\n return {\n primitives:\n c?.primitives === undefined\n ? DEFAULT_CONVENTIONS.primitives\n : c.primitives,\n features:\n c?.features === undefined ? DEFAULT_CONVENTIONS.features : c.features,\n pages: c?.pages === undefined ? DEFAULT_CONVENTIONS.pages : c.pages,\n flows: c?.flows === undefined ? DEFAULT_CONVENTIONS.flows : c.flows,\n regions: c?.regions === undefined ? DEFAULT_CONVENTIONS.regions : c.regions,\n }\n}\n\nfunction kebab(str: string): string {\n return str\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .replace(/[_\\s]+/g, \"-\")\n .replace(/[^a-zA-Z0-9-]/g, \"\")\n .toLowerCase()\n}\n\nfunction baseName(file: string): string {\n const b = path.posix.basename(file)\n return b.replace(/\\.(tsx|ts|jsx|js|mjs|cjs)$/, \"\")\n}\n\nfunction fileMatchesAny(displayPath: string, patterns: string[]): boolean {\n return patterns.some((g) => globToRegExp(g).test(displayPath))\n}\n\nfunction buildMetaFromExport(exp: MetadataExport): Metadata | undefined {\n const meta: Metadata = {}\n if (exp.name) meta.name = exp.name\n if (exp.description) meta.description = exp.description\n if (exp.acceptance?.length) meta.acceptance = exp.acceptance\n if (exp.features?.length) meta.features = exp.features\n if (exp.widgets?.length) meta.widgets = exp.widgets\n if (exp.states?.length) {\n // Strip parse-only name spans — the emitted Metadata is span-free.\n meta.states = exp.states.map((s) => ({\n name: s.name,\n ...(s.kind ? { kind: s.kind as StateDecl[\"kind\"] } : {}),\n ...(s.acceptance?.length ? { acceptance: s.acceptance } : {}),\n ...(s.description ? { description: s.description } : {}),\n }))\n }\n if (exp.capture === false) meta.capture = false\n if (exp.waivers && Object.keys(exp.waivers).length > 0) {\n meta.waivers = exp.waivers as Metadata[\"waivers\"]\n }\n return Object.keys(meta).length > 0 ? meta : undefined\n}\n\n/**\n * Resolve annotations + conventions into a typed Registry.\n * Precedence: configuration > `export const uidex` > DOM attribute > convention.\n */\nexport function resolve(ctx: ResolveContext): ResolveOutput {\n const conventions = resolveConventions(ctx.config.conventions)\n const registry = createRegistry()\n const diagnostics: Diagnostic[] = []\n\n // Index per-file exports by kind. Multiple kinds in one file are\n // disallowed by extract, so a file has at most one export per kind.\n const exportsByFile = new Map<string, Map<string, MetadataExport>>()\n for (const ef of ctx.extracted) {\n if (!ef.metadata) continue\n const map = new Map<string, MetadataExport>()\n for (const m of ef.metadata) map.set(m.kind, m)\n exportsByFile.set(ef.file.displayPath, map)\n }\n function exportFor(\n file: string,\n kind: MetadataExport[\"kind\"]\n ): MetadataExport | undefined {\n return exportsByFile.get(file)?.get(kind)\n }\n\n const allAnnotations: Annotation[] = []\n for (const ef of ctx.extracted) {\n for (const a of ef.annotations) allAnnotations.push(a)\n }\n\n // Parent → ordered, deduped direct-child refs. The parent key is\n // `kind:id` of the innermost JSX ancestor carrying a `data-uidex*`\n // attribute. Used to emit `meta.composes` on containers below.\n const directChildren = new Map<string, EntityRef[]>()\n const seenPerParent = new Map<string, Set<string>>()\n for (const ann of allAnnotations) {\n if (!DOM_ATTR_KINDS.has(ann.kind)) continue\n const parent = ann.ancestors?.[ann.ancestors.length - 1]\n if (!parent) continue\n const pk = `${parent.kind}:${parent.id}`\n const childKey = `${ann.kind}:${ann.id}`\n let seen = seenPerParent.get(pk)\n if (!seen) {\n seen = new Set()\n seenPerParent.set(pk, seen)\n }\n if (seen.has(childKey)) continue\n seen.add(childKey)\n let arr = directChildren.get(pk)\n if (!arr) {\n arr = []\n directChildren.set(pk, arr)\n }\n arr.push({ kind: ann.kind as DomAttrKind, id: ann.id })\n }\n\n function metaWithComposes(\n kind: \"widget\" | \"region\" | \"primitive\",\n id: string,\n base?: Metadata\n ): Metadata | undefined {\n const composes = directChildren.get(`${kind}:${id}`)\n if (!composes || composes.length === 0) return base\n return { ...(base ?? {}), composes }\n }\n\n // ---------- pages ----------\n const routes: DetectedRoute[] =\n conventions.pages === \"auto\"\n ? detectRoutes(ctx.extracted.map((e) => e.file))\n : []\n\n const handledPageFiles = new Set<string>()\n for (const route of routes) {\n const routeDir = path.posix.dirname(route.file)\n const wellKnownPath = `${routeDir}/${WELL_KNOWN_FILES.page}`\n const wellKnownExp = exportFor(wellKnownPath, \"page\")\n const routeExp = exportFor(route.file, \"page\")\n\n const exp = wellKnownExp ?? routeExp\n const locFile = wellKnownExp ? wellKnownPath : route.file\n\n if (wellKnownExp) handledPageFiles.add(wellKnownPath)\n handledPageFiles.add(route.file)\n\n if (wellKnownExp && routeExp) {\n diagnostics.push({\n code: \"competing-uidex-export\",\n severity: \"warning\",\n message: `Page metadata declared in both ${wellKnownPath} and ${route.file}; ${wellKnownPath} takes precedence.`,\n file: route.file,\n line: routeExp.loc.line,\n hint: `Remove the export from ${route.file} or delete ${wellKnownPath}.`,\n })\n }\n\n if (exp && exp.id === false) continue\n const effectiveId = exp && typeof exp.id === \"string\" ? exp.id : route.id\n const meta = exp ? buildMetaFromExport(exp) : undefined\n registry.add({ kind: \"route\", path: route.path, page: effectiveId })\n const page: Page = {\n kind: \"page\",\n id: effectiveId,\n loc: { file: locFile, line: exp?.loc.line },\n ...(meta ? { meta } : {}),\n }\n registry.add(page)\n }\n\n // Page exports in non-conventional locations.\n for (const ef of ctx.extracted) {\n const exp = exportFor(ef.file.displayPath, \"page\")\n if (!exp || typeof exp.id !== \"string\") continue\n if (handledPageFiles.has(ef.file.displayPath)) continue\n const meta = buildMetaFromExport(exp)\n registry.add({\n kind: \"page\",\n id: exp.id,\n loc: { file: ef.file.displayPath, line: exp.loc.line },\n ...(meta ? { meta } : {}),\n })\n }\n\n // ---------- features ----------\n const featureGlob =\n typeof conventions.features === \"string\" ? conventions.features : null\n const conventionalFeatureDirs = new Set<string>()\n const featureExportFilesByDir = new Map<\n string,\n Array<{ file: string; exp: MetadataExport }>\n >()\n const wellKnownFeatureFileByDir = new Map<string, string>()\n const suppressedFeatureDirs = new Set<string>()\n\n if (featureGlob) {\n const re = globToRegExp(featureGlob + \"/**\")\n for (const ef of ctx.extracted) {\n if (!re.test(ef.file.displayPath)) continue\n const dir = extractFeatureDir(ef.file.displayPath, featureGlob)\n if (!dir) continue\n conventionalFeatureDirs.add(dir)\n const isWellKnown =\n path.posix.basename(ef.file.displayPath) === WELL_KNOWN_FILES.feature\n if (isWellKnown) wellKnownFeatureFileByDir.set(dir, ef.file.displayPath)\n const exp = exportFor(ef.file.displayPath, \"feature\")\n if (exp) {\n if (exp.id === false) suppressedFeatureDirs.add(dir)\n else {\n let arr = featureExportFilesByDir.get(dir)\n if (!arr) {\n arr = []\n featureExportFilesByDir.set(dir, arr)\n }\n arr.push({ file: ef.file.displayPath, exp })\n }\n }\n }\n for (const dir of conventionalFeatureDirs) {\n if (suppressedFeatureDirs.has(dir)) continue\n const allExports = featureExportFilesByDir.get(dir) ?? []\n const wellKnownPath = wellKnownFeatureFileByDir.get(dir)\n const wellKnownEntry = wellKnownPath\n ? allExports.find((e) => e.file === wellKnownPath)\n : undefined\n\n let exp: MetadataExport | undefined\n if (wellKnownEntry) {\n exp = wellKnownEntry.exp\n for (const other of allExports) {\n if (other.file === wellKnownEntry.file) continue\n diagnostics.push({\n code: \"competing-uidex-export\",\n severity: \"warning\",\n message: `Feature metadata declared in both ${wellKnownEntry.file} and ${other.file}; ${wellKnownEntry.file} takes precedence.`,\n file: other.file,\n line: other.exp.loc.line,\n hint: `Remove the export from ${other.file} or delete ${wellKnownEntry.file}.`,\n })\n }\n } else if (allExports.length > 0) {\n exp = allExports[0].exp\n }\n\n const id =\n exp && typeof exp.id === \"string\" ? exp.id : path.posix.basename(dir)\n const meta = exp ? buildMetaFromExport(exp) : undefined\n const feature: Feature = {\n kind: \"feature\",\n id,\n loc: exp ? { file: exp.loc.file, line: exp.loc.line } : { file: dir },\n ...(meta ? { meta } : {}),\n }\n registry.add(feature)\n }\n }\n\n // Feature exports at non-conventional paths.\n for (const ef of ctx.extracted) {\n const exp = exportFor(ef.file.displayPath, \"feature\")\n if (!exp || typeof exp.id !== \"string\") continue\n if (featureGlob) {\n const dir = extractFeatureDir(ef.file.displayPath, featureGlob)\n if (dir && conventionalFeatureDirs.has(dir)) continue\n }\n const meta = buildMetaFromExport(exp)\n registry.add({\n kind: \"feature\",\n id: exp.id,\n loc: { file: ef.file.displayPath, line: exp.loc.line },\n ...(meta ? { meta } : {}),\n })\n }\n\n // ---------- widgets ----------\n const widgetDomByFile = new Map<string, Annotation[]>()\n for (const a of allAnnotations) {\n if (a.kind !== \"widget\") continue\n const list = widgetDomByFile.get(a.file) ?? []\n list.push(a)\n widgetDomByFile.set(a.file, list)\n }\n const widgetFiles = new Set<string>([\n ...widgetDomByFile.keys(),\n ...[...exportsByFile.entries()]\n .filter(([, kinds]) => kinds.has(\"widget\"))\n .map(([file]) => file),\n ])\n for (const file of widgetFiles) {\n const domAnnotations = widgetDomByFile.get(file) ?? []\n const exp = exportFor(file, \"widget\")\n if (exp && typeof exp.id === \"string\") {\n const exportId = exp.id\n const domIds = domAnnotations.map((a) => a.id)\n if (domAnnotations.length === 0) {\n diagnostics.push({\n code: \"widget-missing-dom\",\n severity: \"error\",\n message: `Widget \"${exportId}\" declared via export const uidex but no data-uidex-widget=\"${exportId}\" attribute found in the same file`,\n file,\n line: exp.loc.line,\n entity: { kind: \"widget\", id: exportId },\n hint: `Add \\`<... data-uidex-widget=\"${exportId}\">\\` at the widget's DOM root`,\n })\n continue\n }\n if (!domIds.includes(exportId)) {\n const domList = domIds.map((i) => `\"${i}\"`).join(\", \")\n diagnostics.push({\n code: \"widget-id-mismatch\",\n severity: \"error\",\n message: `Widget id mismatch in ${file}: export declares \"${exportId}\" but data-uidex-widget attribute(s) are [${domList}]`,\n file,\n line: exp.loc.line,\n entity: { kind: \"widget\", id: exportId },\n hint: `Update either the export or the DOM attribute so both sides use the same id`,\n })\n continue\n }\n const match = domAnnotations.find((a) => a.id === exportId)!\n const meta = metaWithComposes(\n \"widget\",\n exportId,\n buildMetaFromExport(exp)\n )\n const widget: Widget = {\n kind: \"widget\",\n id: exportId,\n loc: { file, line: match.line },\n ...(meta ? { meta } : {}),\n }\n registry.add(widget)\n } else {\n for (const a of domAnnotations) {\n const meta = metaWithComposes(\"widget\", a.id)\n const widget: Widget = {\n kind: \"widget\",\n id: a.id,\n loc: { file: a.file, line: a.line },\n ...(meta ? { meta } : {}),\n }\n registry.add(widget)\n }\n }\n }\n\n // ---------- regions ----------\n // Landmark facts come from the JSX AST (extract phase), so a `<header>`\n // inside a string or comment never registers, and landmark regions\n // participate in ancestry/composes like attribute regions do.\n if (conventions.regions === \"landmarks\") {\n for (const ef of ctx.extracted) {\n for (const lm of ef.landmarks ?? []) {\n const id = lm.tag\n if (!registry.get(\"region\", id)) {\n const meta = metaWithComposes(\"region\", id)\n const region: Region = {\n kind: \"region\",\n id,\n loc: { file: ef.file.displayPath, line: lm.line },\n ...(meta ? { meta } : {}),\n }\n registry.add(region)\n }\n }\n }\n }\n for (const r of allAnnotations.filter((a) => a.kind === \"region\")) {\n const meta = metaWithComposes(\"region\", r.id)\n const region: Region = {\n kind: \"region\",\n id: r.id,\n loc: { file: r.file, line: r.line },\n ...(meta ? { meta } : {}),\n }\n registry.add(region)\n }\n for (const ef of ctx.extracted) {\n const exp = exportFor(ef.file.displayPath, \"region\")\n if (!exp) continue\n if (exp.id === false) continue\n if (typeof exp.id === \"string\" && !registry.get(\"region\", exp.id)) {\n const meta = buildMetaFromExport(exp)\n const region: Region = {\n kind: \"region\",\n id: exp.id,\n loc: { file: ef.file.displayPath, line: exp.loc.line },\n ...(meta ? { meta } : {}),\n }\n registry.add(region)\n }\n }\n\n // ---------- primitives ----------\n const primitiveConventions = conventions.primitives\n for (const ef of ctx.extracted) {\n const file = ef.file.displayPath\n const exp = exportFor(file, \"primitive\")\n if (exp && exp.id === false) continue // suppression\n if (exp && typeof exp.id === \"string\") {\n const meta = metaWithComposes(\n \"primitive\",\n exp.id,\n buildMetaFromExport(exp)\n )\n const scope = computeScope(file)\n const primitive: Primitive = {\n kind: \"primitive\",\n id: exp.id,\n loc: { file, line: exp.loc.line },\n ...(scope ? { scopes: [scope] } : {}),\n ...(meta ? { meta } : {}),\n }\n registry.add(primitive)\n continue\n }\n const domPrimitives = allAnnotations.filter(\n (a) => a.kind === \"primitive\" && a.file === file\n )\n if (domPrimitives.length > 0) {\n for (const p of domPrimitives) {\n const meta = metaWithComposes(\"primitive\", p.id)\n const domScope = computeScope(p.file)\n const primitive: Primitive = {\n kind: \"primitive\",\n id: p.id,\n loc: { file: p.file, line: p.line },\n ...(domScope ? { scopes: [domScope] } : {}),\n ...(meta ? { meta } : {}),\n }\n registry.add(primitive)\n }\n continue\n }\n if (primitiveConventions && fileMatchesAny(file, primitiveConventions)) {\n const name = kebab(baseName(file))\n if (!name) continue\n const convScope = computeScope(file)\n const meta = metaWithComposes(\"primitive\", name)\n const primitive: Primitive = {\n kind: \"primitive\",\n id: name,\n loc: { file },\n ...(convScope ? { scopes: [convScope] } : {}),\n ...(meta ? { meta } : {}),\n }\n registry.add(primitive)\n }\n }\n\n // ---------- elements (annotation-only) ----------\n for (const e of allAnnotations.filter((a) => a.kind === \"element\")) {\n const element: UidexElement = {\n kind: \"element\",\n id: e.id,\n loc: { file: e.file, line: e.line },\n }\n registry.add(element)\n }\n\n // ---------- flows ----------\n if (ctx.flowFiles && conventions.flows) {\n for (const ff of ctx.flowFiles) {\n const notFlowExport = (ff.metadata ?? []).find(\n (m) => m.kind === \"flow\" && m.notFlow === true\n )\n if (notFlowExport) continue\n const flowExport = (ff.metadata ?? []).find(\n (m) => m.kind === \"flow\" && typeof m.id === \"string\"\n )\n const derived = flowsFromFacts(ff)\n if (\n flowExport &&\n typeof flowExport.id === \"string\" &&\n derived.length === 1\n ) {\n const base = derived[0]\n const flow: Flow = {\n kind: \"flow\",\n id: flowExport.id,\n loc: base.loc,\n touches: base.touches,\n steps: base.steps,\n }\n registry.add(flow)\n } else {\n for (const flow of derived) registry.add(flow)\n }\n }\n }\n\n const entities: Entity[] = []\n for (const kind of [\n \"route\",\n \"page\",\n \"feature\",\n \"widget\",\n \"region\",\n \"element\",\n \"primitive\",\n \"flow\",\n ] as const) {\n entities.push(...registry.list(kind))\n }\n\n return { registry, entities, routes, diagnostics }\n}\n\nfunction extractFeatureDir(\n displayPath: string,\n featureGlob: string\n): string | null {\n // featureGlob like \"src/features/*\"\n const parts = featureGlob.split(\"/\")\n const starIdx = parts.indexOf(\"*\")\n if (starIdx === -1) return null\n const prefixParts = parts.slice(0, starIdx)\n const pathParts = displayPath.split(\"/\")\n for (let i = 0; i < prefixParts.length; i++) {\n if (pathParts[i] !== prefixParts[i]) return null\n }\n if (pathParts.length <= starIdx) return null\n return pathParts.slice(0, starIdx + 1).join(\"/\")\n}\n\nfunction computeScope(displayPath: string): string | null {\n const parts = displayPath.split(\"/\")\n const featureIdx = parts.indexOf(\"features\")\n if (featureIdx !== -1 && parts[featureIdx + 1]) {\n return `feature:${parts[featureIdx + 1]}`\n }\n const pagesIdx = parts.indexOf(\"pages\")\n if (pagesIdx !== -1 && parts[pagesIdx + 1]) {\n return `page:${parts[pagesIdx + 1]}`\n }\n return null\n}\n\n// -------- flow derivation from extract-phase facts --------\n\nfunction flowsFromFacts(ff: ExtractedFile): Flow[] {\n return (ff.flows ?? []).map((fact) => ({\n kind: \"flow\",\n id: kebab(fact.title),\n loc: { file: ff.file.displayPath, line: fact.line },\n touches: dedupe(fact.calls.map((c) => c.id)),\n steps: fact.calls\n .filter((c) => c.action)\n .map((c) => ({ entityId: c.id, action: c.action })),\n }))\n}\n\nfunction dedupe<T>(arr: T[]): T[] {\n return Array.from(new Set(arr))\n}\n","import type { DetectedRoute, ScannedFile } from \"./types\"\n\nconst PAGE_BASENAME = /^page\\.(tsx|ts|jsx|js|mjs|cjs)$/\nconst PAGES_ROUTER_BASENAME = /\\.(tsx|ts|jsx|js|mjs|cjs)$/\nconst ROUTE_BASENAME = /^route\\.(tsx|ts|jsx|js|mjs|cjs)$/\n\n/**\n * Detect framework-aware routes:\n * - Next.js App Router: `**\\/app/**\\/page.tsx` -> `/segments`\n * - Next.js Pages Router: `**\\/pages/**\\/*.tsx` -> `/segments` (excludes _app, _document, api/)\n * - Vite + React Router / TanStack Router:\n * `**\\/routes/**\\/*.tsx` -> `/segments`\n */\nexport function detectRoutes(files: ScannedFile[]): DetectedRoute[] {\n const out: DetectedRoute[] = []\n const seen = new Set<string>()\n\n for (const f of files) {\n const rel = f.displayPath\n const parts = rel.split(\"/\")\n const base = parts[parts.length - 1]\n\n // Next.js App Router: segments after `app/` including page.tsx\n const appIdx = parts.indexOf(\"app\")\n if (appIdx !== -1 && PAGE_BASENAME.test(base)) {\n const routeSegments = parts.slice(appIdx + 1, parts.length - 1)\n const routePath = formatNextAppPath(routeSegments)\n push(out, seen, routePath, f.displayPath)\n continue\n }\n if (appIdx !== -1 && ROUTE_BASENAME.test(base)) {\n // app router \"route handler\" (API) — skip, not a page\n continue\n }\n\n // Next.js Pages Router\n const pagesIdx = parts.indexOf(\"pages\")\n if (pagesIdx !== -1 && PAGES_ROUTER_BASENAME.test(base)) {\n const segs = parts.slice(pagesIdx + 1)\n // skip pages/api\n if (segs[0] === \"api\") continue\n const last = segs[segs.length - 1]\n if (last.startsWith(\"_\")) continue\n const normalized = [\n ...segs.slice(0, -1),\n base.replace(/\\.[^.]+$/, \"\"),\n ].filter((s) => s !== \"index\")\n const routePath = formatNextAppPath(normalized)\n push(out, seen, routePath, f.displayPath)\n continue\n }\n\n // Vite React Router / TanStack Router: `routes/`\n const routesIdx = parts.indexOf(\"routes\")\n if (routesIdx !== -1 && PAGES_ROUTER_BASENAME.test(base)) {\n const segs = parts.slice(routesIdx + 1)\n const last = segs[segs.length - 1]\n if (last.startsWith(\"_\")) continue\n const normalized = [\n ...segs.slice(0, -1),\n base.replace(/\\.[^.]+$/, \"\"),\n ].filter((s) => s !== \"index\" && s !== \"__root\")\n const routePath = formatNextAppPath(normalized)\n push(out, seen, routePath, f.displayPath)\n continue\n }\n }\n\n return out.sort((a, b) => a.path.localeCompare(b.path))\n}\n\nfunction push(\n out: DetectedRoute[],\n seen: Set<string>,\n routePath: string,\n file: string\n): void {\n if (seen.has(routePath)) return\n seen.add(routePath)\n out.push({ id: pathToId(routePath), path: routePath, file })\n}\n\nfunction formatNextAppPath(segments: string[]): string {\n // Drop route groups like \"(marketing)\"\n const kept = segments.filter((s) => !(s.startsWith(\"(\") && s.endsWith(\")\")))\n if (kept.length === 0) return \"/\"\n return \"/\" + kept.join(\"/\")\n}\n\nexport function pathToId(routePath: string): string {\n if (routePath === \"/\") return \"root\"\n return routePath\n .replace(/^\\/+/, \"\")\n .replace(/\\[\\.{3}([^\\]]+)\\]/g, \"$1\")\n .replace(/\\[([^\\]]+)\\]/g, \"$1\")\n .replace(/\\//g, \"-\")\n .replace(/[^a-zA-Z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n}\n","import * as path from \"node:path\"\nimport type { Entity, Registry } from \"../../shared/entities\"\nimport { entityKey } from \"../../shared/entities\"\nimport { WELL_KNOWN_FILES } from \"./config\"\nimport { checkPageCoverage, type PageCoverageBaseline } from \"./page-coverage\"\nimport {\n checkStateCoverage,\n type CapturedStatesManifest,\n} from \"./state-coverage\"\nimport { checkStateMatrix } from \"./state-matrix\"\nimport type {\n AuditSummary,\n Diagnostic,\n ExtractedFile,\n InteractiveElementFact,\n ScannedFile,\n UidexConfig,\n} from \"./types\"\n\nexport interface AuditOptions {\n registry: Registry\n extracted: ExtractedFile[]\n files: ScannedFile[]\n /** Extract output for flow spec files; enables per-call reference checks. */\n flowExtracted?: ExtractedFile[]\n config: UidexConfig\n check?: boolean\n lint?: boolean\n resolveDiagnostics?: Diagnostic[]\n /** Freshly-emitted DATA-file bytes (the entity array), required for --check. */\n generated?: string\n /** On-disk contents of the data file at scan time; `null` if it does not exist. */\n existingOnDisk?: string | null\n /** Relative path of the data file; used in diagnostics. */\n outputPath?: string\n /** Freshly-emitted TYPES-file bytes; enables the types-file --check compare. */\n typesGenerated?: string\n /** On-disk contents of the types file at scan time; `null` if it does not exist. */\n typesOnDisk?: string | null\n /** Relative path of the configured `output` (types) file; used in diagnostics. */\n typesOutputPath?: string\n /** Freshly-emitted LOCS-file bytes; enables the locs-file --check compare. */\n locsGenerated?: string\n /** On-disk contents of the locs file at scan time; `null` if it does not exist. */\n locsOnDisk?: string | null\n /** Relative path of the `.locs` file; used in diagnostics. */\n locsOutputPath?: string\n /** Captured-states manifest for the completeness gate; absent → gate skipped. */\n capturedStates?: CapturedStatesManifest\n /** Page-coverage baseline (the shrink-only backlog); absent → empty baseline. */\n pageBaseline?: PageCoverageBaseline\n}\n\nexport function audit(opts: AuditOptions): AuditSummary {\n const diagnostics: Diagnostic[] = []\n const { registry, extracted, files, config } = opts\n const check = opts.check ?? false\n const lint = opts.lint ?? false\n const acceptanceEnabled = config.audit?.acceptance ?? true\n const scopeLeakEnabled = config.audit?.scopeLeak ?? true\n const coverageEnabled = config.audit?.coverage ?? true\n const statesEnabled = config.audit?.states ?? true\n const pageCoverageEnabled = config.audit?.pageCoverage ?? true\n const stateMatrixEnabled = config.audit?.stateMatrix ?? true\n\n // Always surface resolve-time diagnostics (widget cross-validation errors\n // etc.) — these are not gated on --check/--lint because they reflect\n // malformed source the scanner cannot silently register.\n if (opts.resolveDiagnostics) diagnostics.push(...opts.resolveDiagnostics)\n\n // Extract-phase diagnostics (malformed `export const uidex` blocks,\n // parse-error files whose annotations were skipped) are equally ungated:\n // each one means source the scanner could not read.\n for (const ef of extracted) {\n if (ef.diagnostics) diagnostics.push(...ef.diagnostics)\n }\n for (const ef of opts.flowExtracted ?? []) {\n if (ef.diagnostics) diagnostics.push(...ef.diagnostics)\n }\n\n // ---- Stale gen file (--check) ----\n if (check && opts.generated !== undefined) {\n const outRel = opts.outputPath ?? config.output\n const fresh = normalizeForCheck(opts.generated)\n if (opts.existingOnDisk === null || opts.existingOnDisk === undefined) {\n diagnostics.push({\n code: \"gen-missing\",\n severity: \"error\",\n message: `Generated file \"${outRel}\" does not exist on disk; run \\`uidex scan\\` and commit the result`,\n file: outRel,\n hint: \"Run `uidex scan` (without --check) to regenerate\",\n })\n } else {\n const existing = normalizeForCheck(opts.existingOnDisk)\n if (existing !== fresh) {\n const changed = diffEntities(existing, opts.generated, registry)\n const summary = formatChangedSummary(changed)\n diagnostics.push({\n code: \"gen-stale\",\n severity: \"error\",\n message: `Generated file \"${outRel}\" is stale${summary ? `; ${summary}` : \"\"}`,\n file: outRel,\n hint: \"Run `uidex scan` (without --check) to regenerate and commit the result\",\n })\n }\n }\n }\n\n // ---- Stale types file (--check) ----\n // The types file carries no entity array, so a plain content compare (no\n // entity diff). It changes far less often than the data file — only when the\n // id-union set or authoring-shape surface moves.\n if (check && opts.typesGenerated !== undefined) {\n const outRel = opts.typesOutputPath ?? config.output\n const fresh = normalizeForCheck(opts.typesGenerated)\n if (opts.typesOnDisk === null || opts.typesOnDisk === undefined) {\n diagnostics.push({\n code: \"gen-missing\",\n severity: \"error\",\n message: `Generated file \"${outRel}\" does not exist on disk; run \\`uidex scan\\` and commit the result`,\n file: outRel,\n hint: \"Run `uidex scan` (without --check) to regenerate\",\n })\n } else if (normalizeForCheck(opts.typesOnDisk) !== fresh) {\n diagnostics.push({\n code: \"gen-stale\",\n severity: \"error\",\n message: `Generated file \"${outRel}\" is stale`,\n file: outRel,\n hint: \"Run `uidex scan` (without --check) to regenerate and commit the result\",\n })\n }\n }\n\n // ---- Stale locs file (--check) ----\n // The deferred element/region source-location module; plain content compare.\n if (check && opts.locsGenerated !== undefined) {\n const outRel = opts.locsOutputPath ?? config.output\n const fresh = normalizeForCheck(opts.locsGenerated)\n if (opts.locsOnDisk === null || opts.locsOnDisk === undefined) {\n diagnostics.push({\n code: \"gen-missing\",\n severity: \"error\",\n message: `Generated file \"${outRel}\" does not exist on disk; run \\`uidex scan\\` and commit the result`,\n file: outRel,\n hint: \"Run `uidex scan` (without --check) to regenerate\",\n })\n } else if (normalizeForCheck(opts.locsOnDisk) !== fresh) {\n diagnostics.push({\n code: \"gen-stale\",\n severity: \"error\",\n message: `Generated file \"${outRel}\" is stale`,\n file: outRel,\n hint: \"Run `uidex scan` (without --check) to regenerate and commit the result\",\n })\n }\n }\n\n // ---- Acceptance coverage ----\n if (lint && acceptanceEnabled) {\n for (const kind of [\"widget\", \"feature\", \"page\"] as const) {\n for (const e of registry.list(kind)) {\n const criteria = e.meta?.acceptance ?? []\n if (criteria.length === 0) {\n if (kind === \"widget\") {\n diagnostics.push({\n code: \"widget-missing-acceptance\",\n severity: \"warning\",\n message: `Widget \"${e.id}\" has no acceptance metadata; add \\`export const uidex = { widget: \"${e.id}\", acceptance: [...] }\\` at the widget's definition site`,\n file: e.loc?.file,\n line: e.loc?.line,\n entity: { kind, id: e.id },\n hint: `Adding acceptance criteria allows \\`uidex scaffold widget ${e.id}\\` to generate a Playwright spec`,\n })\n }\n continue\n }\n const flowIds = (e.meta?.flows ?? []) as readonly string[]\n if (flowIds.length === 0) {\n const hint =\n kind === \"widget\"\n ? `uidex scaffold widget ${e.id}`\n : `Add a Playwright flow under e2e/** that touches ${kind} \"${e.id}\" (tag the describe with @uidex:flow)`\n for (const c of criteria) {\n diagnostics.push({\n code: \"acceptance-uncovered\",\n severity: \"warning\",\n message: `${kind} \"${e.id}\" has acceptance criterion not covered by any flow: \"${c}\"`,\n file: e.loc?.file,\n line: e.loc?.line,\n entity: { kind, id: e.id },\n hint,\n })\n }\n }\n }\n }\n }\n\n // ---- Prefer well-known file (uidex.page.ts / uidex.feature.ts) ----\n if (lint) {\n const scannedPaths = new Set(files.map((f) => f.displayPath))\n for (const ef of extracted) {\n if (!ef.metadata) continue\n for (const m of ef.metadata) {\n if (m.kind !== \"page\" && m.kind !== \"feature\") continue\n if (typeof m.id !== \"string\") continue\n const filePath = ef.file.displayPath\n const wellKnownName = WELL_KNOWN_FILES[m.kind]\n if (path.posix.basename(filePath) === wellKnownName) continue\n const dir = path.posix.dirname(filePath)\n const wellKnownPath =\n dir === \".\" ? wellKnownName : `${dir}/${wellKnownName}`\n if (scannedPaths.has(wellKnownPath)) continue\n const kindLabel = m.kind === \"page\" ? \"Page\" : \"Feature\"\n diagnostics.push({\n code: \"prefer-well-known-file\",\n severity: \"info\",\n message: `${kindLabel} \"${m.id}\" metadata lives on ${filePath}; prefer ${wellKnownPath}`,\n file: filePath,\n line: m.loc.line,\n entity: { kind: m.kind, id: m.id },\n hint: `Move the \\`export const uidex\\` block to ${wellKnownPath} and remove it from ${filePath}.`,\n })\n }\n }\n }\n\n // ---- Dynamic data-uidex* attribute (expression instead of string literal) ----\n // Extract is the single source of truth for what resolves statically:\n // anything its evaluator could not turn into an id or pattern arrives here\n // as a DynamicAttrFact, so audit can never disagree with registration.\n if (lint) {\n for (const ef of extracted) {\n for (const fact of ef.dynamicAttrs ?? []) {\n diagnostics.push({\n code: \"dynamic-attr\",\n severity: \"warning\",\n message: `\\`${fact.attrName}={…}\\` uses a dynamic expression; the scanner cannot resolve the ${fact.kind} id statically`,\n file: ef.file.displayPath,\n line: fact.line,\n hint: dynamicAttrHint(fact.kind),\n })\n }\n }\n }\n\n // ---- Missing element annotation candidates (interactive elements without data-uidex) ----\n // Each generated id is deterministic (from the element's accessible name or\n // visible text) and deduped against ids already in the registry and ones\n // generated earlier this pass, so `--fix` can annotate the whole tree without\n // collisions. `--fix` only writes the attribute when it is absent, so the id\n // becomes a normal source literal and never churns on re-scan.\n if (lint) {\n const usedElementIds = new Set(registry.list(\"element\").map((e) => e.id))\n for (const ef of extracted) {\n for (const fact of ef.unannotatedInteractive ?? []) {\n if (fact.hasSpread) {\n // The spread may legitimately deliver the annotation via props, so\n // this supersedes missing-element-annotation rather than stacking.\n diagnostics.push({\n code: \"spread-attr\",\n severity: \"info\",\n message: `Interactive <${fact.tag}> spreads dynamic props and has no static data-uidex attribute; if the annotation is forwarded via props the scanner cannot register it`,\n file: ef.file.displayPath,\n line: fact.line,\n hint: \"Prefer a string-literal data-uidex on the element itself, or annotate at the call site.\",\n })\n } else {\n const id = uniqueElementId(fact, usedElementIds)\n usedElementIds.add(id)\n diagnostics.push({\n code: \"missing-element-annotation\",\n severity: \"info\",\n message: `Interactive <${fact.tag}> without data-uidex annotation`,\n file: ef.file.displayPath,\n line: fact.line,\n hint: `Add \\`data-uidex=\"${id}\"\\` (or run \\`uidex scan --fix\\`).`,\n fix: {\n description: `Add data-uidex=\"${id}\" to <${fact.tag}>`,\n edits: [\n {\n path: ef.file.sourcePath,\n start: fact.nameEnd,\n end: fact.nameEnd,\n replacement: ` data-uidex=\"${id}\"`,\n },\n ],\n },\n })\n }\n }\n }\n }\n\n // ---- Scope leak (primitives used outside their scope) ----\n // Import facts come from the AST (extract phase): real import/export-from\n // statements only — nothing inside comments or strings — with type-only\n // imports excluded (a type dependency is not a runtime leak).\n if (lint && scopeLeakEnabled) {\n const primitives = registry.list(\"primitive\")\n const byName = new Map<string, (typeof primitives)[number]>()\n for (const p of primitives) byName.set(p.id, p)\n\n // Build lookup: file displayPath → declared feature cross-references\n const declaredFeatures = new Map<string, ReadonlySet<string>>()\n for (const ef of extracted) {\n if (!ef.metadata) continue\n for (const m of ef.metadata) {\n if (m.features && m.features.length > 0) {\n declaredFeatures.set(ef.file.displayPath, new Set(m.features))\n }\n }\n }\n\n for (const ef of extracted) {\n const displayPath = ef.file.displayPath\n for (const imp of ef.imports ?? []) {\n if (imp.isTypeOnly) continue\n const baseName = imp.specifier.split(\"/\").pop() ?? \"\"\n const primitive = byName.get(\n baseName\n .replace(/\\.(tsx|ts|jsx|js|mjs|cjs)$/, \"\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase()\n )\n if (!primitive) continue\n const scope = primitive.scopes?.[0]\n if (!scope) continue\n const [kind, id] = scope.split(\":\")\n const importerSegments = displayPath.split(\"/\")\n\n // Same scope directory — not a leak\n if (\n importerSegments.includes(id) &&\n importerSegments.includes(kind + \"s\")\n ) {\n continue\n }\n\n // Route-feature affinity: a page whose path contains the feature\n // id is the feature's UI surface (e.g. app/editor/page-config/page.tsx\n // importing from feature:page-config)\n if (kind === \"feature\" && importerSegments.includes(id)) continue\n\n // Declared cross-reference: the importer's `export const uidex`\n // lists this feature in its `features` array\n if (kind === \"feature\" && declaredFeatures.get(displayPath)?.has(id)) {\n continue\n }\n\n diagnostics.push({\n code: \"scope-leak\",\n severity: \"warning\",\n message: `Primitive \"${primitive.id}\" is scoped to ${scope} but is imported from ${displayPath}`,\n file: displayPath,\n line: imp.line,\n })\n }\n }\n }\n\n // ---- Coverage (entities referenced in flows must exist) ----\n if (lint && coverageEnabled) {\n // Per-call lines from the flow specs' extract facts, keyed by the\n // describe location (id-independent, so flowExport renames still match).\n const factsByLoc = new Map<string, Map<string, number>>()\n for (const ef of opts.flowExtracted ?? []) {\n for (const fact of ef.flows ?? []) {\n const lines = new Map<string, number>()\n for (const call of fact.calls) {\n if (!lines.has(call.id)) lines.set(call.id, call.line)\n }\n factsByLoc.set(`${ef.file.displayPath}:${fact.line}`, lines)\n }\n }\n\n for (const flow of registry.list(\"flow\")) {\n const callLines = factsByLoc.get(`${flow.loc.file}:${flow.loc.line}`)\n for (const touchedId of flow.touches) {\n const found =\n registry.get(\"element\", touchedId) ??\n registry.get(\"widget\", touchedId) ??\n registry.get(\"region\", touchedId) ??\n registry.matchPattern(\"element\", touchedId) ??\n registry.matchPattern(\"widget\", touchedId) ??\n registry.matchPattern(\"region\", touchedId)\n if (!found) {\n diagnostics.push({\n code: \"unknown-reference\",\n severity: \"warning\",\n message: `Flow \"${flow.id}\" references unknown entity \"${touchedId}\"`,\n file: flow.loc.file,\n // Point at the uidex() call itself when the spec facts are\n // available; the describe line is the fallback.\n line: callLines?.get(touchedId) ?? flow.loc.line,\n })\n }\n }\n }\n }\n\n // ---- Duplicate ids (same kind+id annotated in more than one file) ----\n // The registry is last-writer-wins, so a cross-file duplicate silently\n // collapses to one entity while the runtime has two DOM matches. Widget and\n // primitive duplicates are definition collisions (warning); element/region\n // duplicates are sometimes intentional (responsive variants), so info.\n if (lint) {\n const occurrences = new Map<string, Array<{ file: string; line: number }>>()\n for (const ef of extracted) {\n for (const a of ef.annotations) {\n if (\n a.kind !== \"element\" &&\n a.kind !== \"region\" &&\n a.kind !== \"widget\" &&\n a.kind !== \"primitive\"\n ) {\n continue\n }\n const key = `${a.kind}:${a.id}`\n let list = occurrences.get(key)\n if (!list) {\n list = []\n occurrences.set(key, list)\n }\n list.push({ file: a.file, line: a.line })\n }\n }\n for (const [key, list] of occurrences) {\n const filesSeen = new Set(list.map((o) => o.file))\n if (filesSeen.size < 2) continue\n const [kind, id] = key.split(/:(.*)/s) as [string, string]\n const others = list\n .slice(1)\n .map((o) => `${o.file}:${o.line}`)\n .join(\", \")\n diagnostics.push({\n code: \"duplicate-id\",\n severity:\n kind === \"widget\" || kind === \"primitive\" ? \"warning\" : \"info\",\n message: `${kind} id \"${id}\" is declared in ${filesSeen.size} files (also at ${others}); the registry keeps only one entry`,\n file: list[0].file,\n line: list[0].line,\n entity: { kind: kind as \"element\", id },\n hint:\n kind === \"element\" || kind === \"region\"\n ? \"If these are variants of the same logical element this is fine; otherwise rename one (`uidex rename` updates flow references too).\"\n : \"Rename one of the definitions; two definitions with the same id silently merge.\",\n })\n }\n }\n\n // ---- Dynamic uidex() references in tagged flows ----\n // Flow ids must be string literals; a dynamic argument silently drops out\n // of `touches`, shrinking coverage with no trace. Mirror of dynamic-attr.\n if (lint && coverageEnabled) {\n for (const ef of opts.flowExtracted ?? []) {\n for (const fact of ef.flows ?? []) {\n for (const dyn of fact.dynamicCalls ?? []) {\n diagnostics.push({\n code: \"dynamic-flow-reference\",\n severity: \"warning\",\n message: `\\`uidex(…)\\` call in flow \"${fact.title}\" uses a dynamic expression; the id is invisible to coverage and registry validation`,\n file: ef.file.displayPath,\n line: dyn.line,\n hint: \"Use a string-literal id (component ids inside uidex() must be statically analysable).\",\n })\n }\n }\n }\n }\n\n // ---- Declared cross-references must exist ----\n // `features:` / `widgets:` arrays are tsc-checked at the `satisfies` site,\n // but a runtime audit still catches refs the author never typechecked.\n // Mirror the flow unknown-reference check for metadata exports.\n if (lint && coverageEnabled) {\n for (const ef of extracted) {\n if (!ef.metadata) continue\n for (const m of ef.metadata) {\n const check = (\n refKind: \"feature\" | \"widget\",\n ids: readonly string[] | undefined,\n spans: ReadonlyArray<{ start: number }> | undefined\n ) => {\n for (let i = 0; i < (ids?.length ?? 0); i++) {\n const refId = ids![i]\n const found =\n registry.get(refKind, refId) ??\n registry.matchPattern(refKind, refId)\n if (found) continue\n diagnostics.push({\n code: \"unknown-reference\",\n severity: \"warning\",\n message: `\\`export const uidex\\` in ${ef.file.displayPath} references unknown ${refKind} \"${refId}\"`,\n file: ef.file.displayPath,\n line: spans?.[i]\n ? lineOfOffset(ef.file.content, spans[i].start)\n : m.loc.line,\n hint: `No ${refKind} with id \"${refId}\" exists in the registry; fix the reference or add the ${refKind}.`,\n })\n }\n }\n check(\"feature\", m.features, m.featureSpans)\n check(\"widget\", m.widgets, m.widgetSpans)\n }\n }\n }\n\n // ---- State-capture completeness gate ----\n // Cross-checks declared `states` against a capture run's manifest. Skipped\n // when no manifest is supplied, so a plain scan (no capture run) never fails.\n if (lint && statesEnabled && opts.capturedStates) {\n diagnostics.push(...checkStateCoverage(registry, opts.capturedStates))\n }\n\n // ---- Page-capture coverage gate ----\n // Every derived route must be captured, opted out (`capture: false`), or in\n // the shrink-only baseline. Runs only when a capture manifest is present.\n if (lint && pageCoverageEnabled && opts.capturedStates) {\n diagnostics.push(\n ...checkPageCoverage(registry, opts.capturedStates, opts.pageBaseline)\n )\n }\n\n // ---- State-matrix gate ----\n // Every captured route renders the four core kinds, or waives / baselines the\n // gap. Shares the coverage baseline's `missingKinds` axis.\n if (lint && stateMatrixEnabled && opts.capturedStates) {\n diagnostics.push(\n ...checkStateMatrix(registry, opts.capturedStates, {\n missingKinds: opts.pageBaseline?.missingKinds ?? {},\n })\n )\n }\n\n const summary = {\n errors: diagnostics.filter((d) => d.severity === \"error\").length,\n warnings: diagnostics.filter((d) => d.severity === \"warning\").length,\n }\n\n return { diagnostics, summary }\n}\n\nfunction lineOfOffset(content: string, offset: number): number {\n let line = 1\n for (let i = 0; i < offset && i < content.length; i++) {\n if (content[i] === \"\\n\") line++\n }\n return line\n}\n\n/** Fallback ids by tag when the element carries no static name hint. */\nconst TAG_FALLBACK_ID: Record<string, string> = {\n a: \"link\",\n button: \"button\",\n input: \"input\",\n select: \"select\",\n textarea: \"textarea\",\n}\n\nfunction kebabId(str: string): string {\n return str\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .replace(/[^a-zA-Z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .toLowerCase()\n}\n\n/** Deterministic kebab id from an element's name hint, capped at five words. */\nfunction deriveElementId(fact: InteractiveElementFact): string {\n const fromHint = fact.nameHint ? kebabId(fact.nameHint) : \"\"\n const capped = fromHint.split(\"-\").filter(Boolean).slice(0, 5).join(\"-\")\n return capped || TAG_FALLBACK_ID[fact.tag] || fact.tag\n}\n\n/** `deriveElementId`, made unique by suffixing `-2`, `-3`, … on collision. */\nfunction uniqueElementId(\n fact: InteractiveElementFact,\n used: ReadonlySet<string>\n): string {\n const base = deriveElementId(fact)\n if (!used.has(base)) return base\n for (let n = 2; ; n++) {\n const candidate = `${base}-${n}`\n if (!used.has(candidate)) return candidate\n }\n}\n\nfunction normalizeLineEndings(s: string): string {\n return s.replace(/\\r\\n/g, \"\\n\")\n}\n\n/**\n * Normalization for the staleness comparison. Besides line endings, the\n * embedded `gitContext` block is neutralized: it records the commit the file\n * was generated at, which is by construction one commit behind once the file\n * itself is committed — comparing it would make `--check` fail on every\n * freshly committed gen file.\n */\nfunction normalizeForCheck(s: string): string {\n return normalizeLineEndings(s).replace(\n /export const gitContext = \\{[\\s\\S]*?\\} as const/,\n \"export const gitContext = {} as const\"\n )\n}\n\ninterface EntityChange {\n added: string[]\n removed: string[]\n modified: string[]\n}\n\nfunction formatChangedSummary(change: EntityChange): string {\n const parts: string[] = []\n const fmt = (kind: string, names: string[]) => {\n if (names.length === 0) return\n const preview = names.slice(0, 3).join(\", \")\n const suffix = names.length > 3 ? ` (+${names.length - 3} more)` : \"\"\n parts.push(`${kind}: ${preview}${suffix}`)\n }\n fmt(\"added\", change.added)\n fmt(\"removed\", change.removed)\n fmt(\"modified\", change.modified)\n return parts.join(\"; \")\n}\n\nfunction diffEntities(\n existing: string,\n generated: string,\n registry: Registry\n): EntityChange {\n const oldEntities = extractEntitiesArray(existing)\n const newEntities = extractEntitiesArray(generated) ?? freshEntities(registry)\n\n const added: string[] = []\n const removed: string[] = []\n const modified: string[] = []\n\n if (!oldEntities) {\n for (const e of newEntities) added.push(labelFor(e))\n return { added, removed, modified }\n }\n\n const oldByKey = new Map<string, Entity>()\n for (const e of oldEntities) oldByKey.set(entityKey(e) + \"@\" + e.kind, e)\n const newByKey = new Map<string, Entity>()\n for (const e of newEntities) newByKey.set(entityKey(e) + \"@\" + e.kind, e)\n\n for (const [k, e] of newByKey) {\n const prev = oldByKey.get(k)\n if (!prev) {\n added.push(labelFor(e))\n } else if (stableStringify(prev) !== stableStringify(e)) {\n modified.push(labelFor(e))\n }\n }\n for (const [k, e] of oldByKey) {\n if (!newByKey.has(k)) removed.push(labelFor(e))\n }\n\n return { added, removed, modified }\n}\n\nfunction labelFor(e: Entity): string {\n return `${e.kind} \"${entityKey(e)}\"`\n}\n\nfunction freshEntities(registry: Registry): Entity[] {\n const kinds = [\n \"route\",\n \"page\",\n \"feature\",\n \"widget\",\n \"region\",\n \"element\",\n \"primitive\",\n \"flow\",\n ] as const\n const out: Entity[] = []\n for (const k of kinds) out.push(...(registry.list(k) as Entity[]))\n return out\n}\n\nfunction extractEntitiesArray(source: string): Entity[] | null {\n const marker = \"export const entities: ReadonlyArray<Entity> = \"\n const idx = source.indexOf(marker)\n if (idx === -1) return null\n const start = source.indexOf(\"[\", idx)\n if (start === -1) return null\n let depth = 0\n let inStr: string | null = null\n let escaped = false\n for (let i = start; i < source.length; i++) {\n const c = source[i]\n if (inStr) {\n if (escaped) {\n escaped = false\n } else if (c === \"\\\\\") {\n escaped = true\n } else if (c === inStr) {\n inStr = null\n }\n continue\n }\n if (c === '\"' || c === \"'\") {\n inStr = c\n continue\n }\n if (c === \"[\") depth++\n else if (c === \"]\") {\n depth--\n if (depth === 0) {\n const json = source.slice(start, i + 1)\n try {\n return JSON.parse(json) as Entity[]\n } catch {\n return null\n }\n }\n }\n }\n return null\n}\n\nfunction dynamicAttrHint(kind: string): string {\n if (kind === \"region\") {\n return (\n `Use a string literal: \\`data-uidex-region=\"id\"\\`, or declare the ` +\n `region via \\`export const uidex = { region: \"id\" } as const satisfies ` +\n `Uidex.Region\\` on the file that passes the region value`\n )\n }\n return (\n `The scanner resolves string literals, same-file const references, ` +\n `ternaries with literal branches, and template literals with static ` +\n `text (dynamic parts become \\`*\\` patterns). If this component forwards ` +\n `the annotation via a prop, restructure so the caller provides the ` +\n `annotated element directly (e.g. via a slot or render prop)`\n )\n}\n\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(value, stableReplacer)\n}\n\nfunction stableReplacer(_key: string, value: unknown): unknown {\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[k] = (value as Record<string, unknown>)[k]\n }\n return sorted\n }\n return value\n}\n","import type { Registry } from \"../../shared/entities\"\nimport type { CapturedState, CapturedStatesManifest } from \"./state-coverage\"\nimport type { Diagnostic } from \"./types\"\n\n/**\n * Page-capture coverage — the coarse gate above the per-state gate. Every\n * derived route must be accounted for: captured (a run drove it), opted out\n * (`export const uidex = { page, capture: false }`), or acknowledged backlog (a\n * tool-managed, shrink-only baseline). A route in none of those is a *new*\n * uncaptured page and fails hard — the ratchet that keeps debt from growing.\n *\n * uidex derives the route set (route groups stripped, dynamic segments kept), so\n * unlike a hand-rolled `src/app/**` walk there is no page list to enumerate or\n * keep from rotting: a route exists in the registry or it doesn't. And captures\n * observe the URL they ran against, so which route a capture covers is matched,\n * never hand-declared.\n */\n\n/** The committed, tool-managed backlog. Shrinks as pages/kinds get captured. */\nexport interface PageCoverageBaseline {\n /** Route patterns acknowledged as uncaptured (e.g. \"/[scope]/collections\"). */\n uncapturedPages: string[]\n /** route → core kinds acknowledged as not-yet-captured (the matrix backlog). */\n missingKinds?: Record<string, string[]>\n}\n\n/**\n * Turn a Next-style route pattern into an anchored matcher.\n * `/[scope]/products/[productId]/edit` → matches `/acme/products/p1/edit`\n * `/[...slug]` (catch-all) → matches one or more segments\n * Returns the literal-segment count as a specificity score, so the most literal\n * matching pattern wins when several match (e.g. `/x/new` beats `/x/[id]`).\n */\nexport function compileRoute(pattern: string): {\n test: (url: string) => boolean\n specificity: number\n} {\n const segs = pattern.split(\"/\").filter(Boolean)\n let specificity = 0\n // A trailing optional catch-all `[[...x]]` matches ZERO or more segments, so it\n // is dropped from the joined body and re-added as an optional tail below.\n const optionalTail =\n segs.length > 0 && /^\\[\\[\\.{3}.+\\]\\]$/.test(segs[segs.length - 1])\n const effective = optionalTail ? segs.slice(0, -1) : segs\n const parts = effective.map((seg) => {\n const catchAll = /^\\[\\.{3}.+\\]$/.test(seg) // required `[...x]` — one or more\n const dynamic = /^\\[.+\\]$/.test(seg)\n if (catchAll) return \"(?:[^/]+)(?:/[^/]+)*\"\n if (dynamic) return \"[^/]+\"\n specificity++\n return seg.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n })\n let body = parts.length === 0 ? \"\" : \"/\" + parts.join(\"/\")\n if (optionalTail) body += \"(?:/[^/]+)*\"\n if (body === \"\") body = \"/\"\n const re = new RegExp(`^${body}/?$`)\n return { test: (url) => re.test(url), specificity }\n}\n\n/** The route pattern (from the given set) that most-specifically matches a URL. */\nexport function matchUrlToRoute(\n url: string,\n routePaths: string[]\n): string | null {\n const path = stripQuery(url)\n let best: { path: string; specificity: number } | null = null\n for (const rp of routePaths) {\n const { test, specificity } = compileRoute(rp)\n if (!test(path)) continue\n if (!best || specificity > best.specificity)\n best = { path: rp, specificity }\n }\n return best?.path ?? null\n}\n\nfunction stripQuery(url: string): string {\n const q = url.indexOf(\"?\")\n const h = url.indexOf(\"#\")\n let end = url.length\n if (q !== -1) end = Math.min(end, q)\n if (h !== -1) end = Math.min(end, h)\n return url.slice(0, end)\n}\n\n/**\n * The single route a captured state exercised, shared by both coverage gates so\n * they can never disagree about attribution:\n * - an explicit `route` (if it names a real route), else\n * - the observed `url` matched to its most-specific route pattern, else\n * - only for an explicit `kind: \"page\"` capture, the route whose page id is the\n * entity (ids are unique per kind, so a same-id widget/feature must not\n * silently cover a page — it needs a URL or explicit route).\n * Returns null when nothing resolves (e.g. a `/shots/*` harness URL).\n */\nexport function routeForCapture(\n c: CapturedState,\n routes: ReadonlyArray<{ path: string; page: string }>,\n routePaths: string[]\n): string | null {\n if (c.route && routePaths.includes(c.route)) return c.route\n if (c.url) {\n const m = matchUrlToRoute(c.url, routePaths)\n if (m) return m\n }\n if (c.kind === \"page\") {\n const r = routes.find((r) => r.page === c.entity)\n if (r) return r.path\n }\n return null\n}\n\nexport function checkPageCoverage(\n registry: Registry,\n manifest: CapturedStatesManifest,\n baseline?: PageCoverageBaseline\n): Diagnostic[] {\n const routes = registry.list(\"route\")\n if (routes.length === 0) return []\n const routePaths = routes.map((r) => r.path)\n const captured = manifest.captured ?? []\n\n // A route is opted out when its page declares `capture: false`.\n const optedOut = new Set<string>()\n for (const r of routes) {\n const page = registry.get(\"page\", r.page)\n if (page?.meta?.capture === false) optedOut.add(r.path)\n }\n\n // Which routes a run actually covered (see routeForCapture).\n const covered = new Set<string>()\n for (const c of captured) {\n const route = routeForCapture(c, routes, routePaths)\n if (route) covered.add(route)\n }\n\n const baselineSet = new Set(baseline?.uncapturedPages ?? [])\n const diagnostics: Diagnostic[] = []\n\n for (const r of routes) {\n if (covered.has(r.path) || optedOut.has(r.path)) continue\n const loc = registry.get(\"page\", r.page)?.loc\n if (baselineSet.has(r.path)) {\n diagnostics.push({\n code: \"page-backlog\",\n severity: \"info\",\n message: `route \"${r.path}\" has no visual-states capture (acknowledged backlog)`,\n file: loc?.file,\n line: loc?.line,\n hint: `Capture it (drive the route in a states spec) and it drops off the baseline, or opt it out with \\`export const uidex = { page: \"${r.page}\", capture: false }\\`.`,\n })\n continue\n }\n diagnostics.push({\n code: \"page-no-capture\",\n severity: \"error\",\n message: `route \"${r.path}\" has no visual-states capture and is not accounted for`,\n file: loc?.file,\n line: loc?.line,\n entity: { kind: \"route\", id: r.path },\n hint: `Capture the route in a states spec, opt it out with \\`export const uidex = { page: \"${r.page}\", capture: false }\\`, or grandfather it as acknowledged backlog with \\`uidex scan --update-baseline\\` (the baseline change lands in the diff for review).`,\n })\n }\n\n // Baseline hygiene: prune-hints for entries now covered/opted-out, and stale\n // entries that no longer name a real route (so the baseline can't rot).\n for (const b of baselineSet) {\n if (!routePaths.includes(b)) {\n diagnostics.push({\n code: \"stale-page-baseline\",\n severity: \"warning\",\n message: `coverage baseline lists \"${b}\", which is not a route in the registry`,\n hint: `Remove it from the baseline (\\`uidex scan --update-baseline\\`); the route no longer exists.`,\n })\n } else if (covered.has(b) || optedOut.has(b)) {\n diagnostics.push({\n code: \"page-captured\",\n severity: \"warning\",\n message: `route \"${b}\" is now captured but is still in the coverage baseline`,\n hint: `Prune it with \\`uidex scan --update-baseline\\` so the backlog reflects reality.`,\n })\n }\n }\n\n return diagnostics\n}\n\n/**\n * Compute the shrink-only baseline for `--update-baseline`: every route with no\n * capture and no opt-out. Seeds on first run and prunes on later runs; growth\n * only ever happens through this explicit command, visible in the file's diff.\n */\nexport function computePageBaseline(\n registry: Registry,\n manifest: CapturedStatesManifest\n): PageCoverageBaseline {\n const uncaptured: string[] = []\n // Re-run the gate against an EMPTY baseline: anything that comes back as a\n // hard `page-no-capture` is a route with no capture and no opt-out.\n for (const d of checkPageCoverage(registry, manifest, {\n uncapturedPages: [],\n })) {\n if (d.code === \"page-no-capture\" && d.entity) uncaptured.push(d.entity.id)\n }\n return { uncapturedPages: uncaptured.sort() }\n}\n","import type { MetaEntityKind, Registry } from \"../../shared/entities\"\nimport type { Diagnostic } from \"./types\"\n\n/**\n * State-capture completeness — the deterministic replacement for a bespoke\n * `check-states.mjs`. Cross-checks the states DECLARED on registry entities\n * (`export const uidex = { states: [...] }`) against the states a capture run\n * actually produced (a `uidex-states.json` manifest written by the Playwright\n * states reporter):\n *\n * - `missing-state-capture` — a declared state no run captured. The gap the\n * acceptance-grounded analysis surfaces (a promised behavior with no pixel\n * evidence) becomes a mechanical audit failure.\n * - `orphan-state-capture` — a run captured a state the entity never declared,\n * so the contact sheet shows a state the registry doesn't know about.\n *\n * Pure: same (registry, manifest) → same diagnostics. Only runs when a manifest\n * is present, so a plain `uidex scan` (no capture run) never fails on it.\n */\n\n/** One `entity/state` a capture run recorded. */\nexport interface CapturedState {\n /** Registry entity id the capture rendered (e.g. \"products\"). */\n entity: string\n /** Entity kind, when the capture recorded it (page/feature/widget). */\n kind?: MetaEntityKind\n /** The declared state name captured (e.g. \"new-filled\"). */\n state: string\n /** Canonical matrix kind (loading/empty/populated/error/variant). */\n stateKind?: string\n /** URL pathname the capture ran against (page-coverage gate matches it to a route). */\n url?: string\n /** Explicit route pattern the capture covers, when supplied. */\n route?: string\n}\n\nexport interface CapturedStatesManifest {\n captured: CapturedState[]\n}\n\nconst STATE_KINDS: readonly MetaEntityKind[] = [\"page\", \"feature\", \"widget\"]\n\ninterface DeclaredEntity {\n kind: MetaEntityKind\n id: string\n states: string[]\n loc?: { file?: string; line?: number }\n}\n\nfunction declaredStateEntities(registry: Registry): DeclaredEntity[] {\n const out: DeclaredEntity[] = []\n for (const kind of STATE_KINDS) {\n for (const e of registry.list(kind)) {\n const states = e.meta?.states\n if (!states || states.length === 0) continue\n out.push({\n kind,\n id: e.id,\n states: states.map((s) => s.name),\n loc: e.loc,\n })\n }\n }\n return out\n}\n\n/** Whether a captured entry can refer to this declared entity. */\nfunction captureMatchesEntity(\n cap: CapturedState,\n ent: DeclaredEntity\n): boolean {\n if (cap.entity !== ent.id) return false\n return cap.kind === undefined || cap.kind === ent.kind\n}\n\nexport function checkStateCoverage(\n registry: Registry,\n manifest: CapturedStatesManifest\n): Diagnostic[] {\n const diagnostics: Diagnostic[] = []\n const declared = declaredStateEntities(registry)\n const captured = manifest.captured ?? []\n\n // ---- missing: declared but never captured ----\n for (const ent of declared) {\n for (const state of ent.states) {\n const hit = captured.some(\n (c) => captureMatchesEntity(c, ent) && c.state === state\n )\n if (hit) continue\n diagnostics.push({\n code: \"missing-state-capture\",\n severity: \"warning\",\n message: `${ent.kind} \"${ent.id}\" declares state \"${state}\" but no capture produced it`,\n file: ent.loc?.file,\n line: ent.loc?.line,\n entity: { kind: ent.kind, id: ent.id },\n hint: `Add a capture for \"${ent.id}/${state}\" to the states matrix, or remove the state from \\`export const uidex = { states: [...] }\\` if it no longer exists.`,\n })\n }\n }\n\n // ---- orphan: captured a state the entity never declared ----\n // Only flag when the entity DECLARES states (an entity with no `states` block\n // opts out of the gate, so extra captures for it are fine).\n for (const cap of captured) {\n const candidates = declared.filter((ent) => captureMatchesEntity(cap, ent))\n if (candidates.length === 0) continue // entity declares no states → not gated\n const declaredSomewhere = candidates.some((ent) =>\n ent.states.includes(cap.state)\n )\n if (declaredSomewhere) continue\n const ent = candidates[0]\n diagnostics.push({\n code: \"orphan-state-capture\",\n severity: \"warning\",\n message: `Capture produced state \"${cap.state}\" for ${ent.kind} \"${ent.id}\", which is not in its declared states [${ent.states.join(\", \")}]`,\n file: ent.loc?.file,\n line: ent.loc?.line,\n entity: { kind: ent.kind, id: ent.id },\n hint: `Declare \"${cap.state}\" in \\`export const uidex = { states: [...] }\\` for \"${ent.id}\", or rename the capture to a declared state.`,\n })\n }\n\n return diagnostics\n}\n","import { CORE_STATE_KINDS, type Registry } from \"../../shared/entities\"\nimport { routeForCapture } from \"./page-coverage\"\nimport type { CapturedState, CapturedStatesManifest } from \"./state-coverage\"\nimport type { Diagnostic } from \"./types\"\n\n/**\n * State-matrix coverage — the second completeness axis. A capture that only ever\n * shoots the happy path leaves most of the harness's value on the table, so\n * every *captured* route must render each of the four core kinds\n * (loading / empty / populated / error), or account for the gap:\n *\n * - a **waiver** (`export const uidex = { page, waivers: { empty: \"…\" } }`) —\n * the route CANNOT render that kind (a create form has no empty state);\n * - the **MISSING_KINDS baseline** — the route CAN render it and nobody has\n * captured it yet (a per-(route, kind) shrink-only backlog).\n *\n * Anything else is a `core-kind` error. Only *captured* routes are in scope: a\n * route with no capture at all is a page-coverage concern, not a matrix hole.\n */\n\n/** route → core kinds acknowledged as not-yet-captured (the finer ratchet). */\nexport interface StateMatrixBaseline {\n missingKinds: Record<string, string[]>\n}\n\nconst CORE_KINDS: readonly string[] = CORE_STATE_KINDS\nconst STATE_ENTITY_KINDS = [\"page\", \"feature\", \"widget\"] as const\n\n/**\n * The canonical matrix kind of a captured state: the recorded `stateKind`, else\n * the `kind` declared on the entity's `states: [{ name, kind }]`, else inferred\n * from the state name (a core-kind name → that kind, otherwise `variant`). So a\n * declared kind is honored even when the capture (e.g. `recordStates`) recorded\n * none, and a non-core-named state that declares a core kind still fills its cell.\n */\nfunction resolveMatrixKind(registry: Registry, c: CapturedState): string {\n if (c.stateKind) return c.stateKind\n for (const kind of STATE_ENTITY_KINDS) {\n const declared = registry\n .get(kind, c.entity)\n ?.meta?.states?.find((s) => s.name === c.state)?.kind\n if (declared) return declared\n }\n return CORE_KINDS.includes(c.state) ? c.state : \"variant\"\n}\n\n/** route → the core kinds a run actually captured for it. */\nfunction coreKindsByRoute(\n registry: Registry,\n manifest: CapturedStatesManifest\n): Map<string, Set<string>> {\n const routes = registry.list(\"route\")\n const routePaths = routes.map((r) => r.path)\n const byRoute = new Map<string, Set<string>>()\n for (const c of manifest.captured ?? []) {\n const route = routeForCapture(c, routes, routePaths)\n if (!route) continue\n // Every capture marks the route as \"captured\" (so the matrix applies), but\n // only core kinds fill the matrix cells.\n if (!byRoute.has(route)) byRoute.set(route, new Set())\n const kind = resolveMatrixKind(registry, c)\n if (CORE_KINDS.includes(kind)) byRoute.get(route)!.add(kind)\n }\n return byRoute\n}\n\nfunction pageWaivers(\n registry: Registry,\n routePage: string\n): Record<string, string> {\n return (registry.get(\"page\", routePage)?.meta?.waivers ?? {}) as Record<\n string,\n string\n >\n}\n\n/** An opted-out (`capture: false`) route is outside the matrix, mirroring the\n * page-coverage gate — otherwise a capture that incidentally hits a redirect /\n * static page would be forced to render all four core kinds. */\nfunction isOptedOut(registry: Registry, page: string | undefined): boolean {\n return page ? registry.get(\"page\", page)?.meta?.capture === false : false\n}\n\nexport function checkStateMatrix(\n registry: Registry,\n manifest: CapturedStatesManifest,\n baseline?: StateMatrixBaseline\n): Diagnostic[] {\n const routes = registry.list(\"route\")\n if (routes.length === 0) return []\n const pageOf = new Map(routes.map((r) => [r.path, r.page]))\n const captured = coreKindsByRoute(registry, manifest)\n const baselined = baseline?.missingKinds ?? {}\n const diagnostics: Diagnostic[] = []\n\n for (const [route, kinds] of captured) {\n const page = pageOf.get(route)\n if (isOptedOut(registry, page)) continue\n const waivers = page ? pageWaivers(registry, page) : {}\n const loc = page ? registry.get(\"page\", page)?.loc : undefined\n const baselinedKinds = new Set(baselined[route] ?? [])\n for (const kind of CORE_KINDS) {\n if (kinds.has(kind)) continue\n if (waivers[kind]) continue // the route CANNOT render this kind\n if (baselinedKinds.has(kind)) {\n diagnostics.push({\n code: \"matrix-backlog\",\n severity: \"info\",\n message: `route \"${route}\" does not render core kind \"${kind}\" (acknowledged MISSING_KINDS backlog)`,\n file: loc?.file,\n line: loc?.line,\n hint: `Capture the \"${kind}\" state for \"${route}\", waive it (\\`waivers: { ${kind}: \"why it can't\" }\\` on the page), or leave it in the baseline.`,\n })\n continue\n }\n diagnostics.push({\n code: \"core-kind\",\n severity: \"error\",\n message: `route \"${route}\" is captured but never renders core kind \"${kind}\"`,\n file: loc?.file,\n line: loc?.line,\n entity: { kind: \"route\", id: route },\n hint: `Capture the \"${kind}\" state, or if the route cannot render it add \\`export const uidex = { page: \"${page}\", waivers: { ${kind}: \"why it can't\" } }\\`, or grandfather it via \\`uidex scan --update-baseline\\` (the baseline change lands in the diff for review).`,\n })\n }\n }\n\n // Waiver hygiene: waiving a kind the route DOES render hides a real capture and\n // rots the reason. (A waiver on an uncaptured route is left alone — the page\n // may be opted out or backlogged, both outside the matrix.)\n for (const [route, kinds] of captured) {\n const page = pageOf.get(route)\n if (!page || isOptedOut(registry, page)) continue\n const waivers = pageWaivers(registry, page)\n const loc = registry.get(\"page\", page)?.loc\n for (const kind of Object.keys(waivers)) {\n if (kinds.has(kind)) {\n diagnostics.push({\n code: \"stale-waiver\",\n severity: \"warning\",\n message: `page \"${page}\" waives core kind \"${kind}\", but route \"${route}\" does render it`,\n file: loc?.file,\n line: loc?.line,\n entity: { kind: \"page\", id: page },\n hint: `Remove the \"${kind}\" waiver — the route renders that kind, so the waiver's reason is stale.`,\n })\n }\n }\n }\n\n return diagnostics\n}\n\n/**\n * Compute the shrink-only MISSING_KINDS baseline for `--update-baseline`: every\n * (captured route, core kind) that is neither captured nor waived.\n */\nexport function computeMissingKinds(\n registry: Registry,\n manifest: CapturedStatesManifest\n): Record<string, string[]> {\n const routes = registry.list(\"route\")\n const pageOf = new Map(routes.map((r) => [r.path, r.page]))\n const captured = coreKindsByRoute(registry, manifest)\n const out: Record<string, string[]> = {}\n for (const [route, kinds] of captured) {\n const page = pageOf.get(route)\n if (isOptedOut(registry, page)) continue\n const waivers = page ? pageWaivers(registry, page) : {}\n const missing = CORE_KINDS.filter((k) => !kinds.has(k) && !waivers[k])\n if (missing.length > 0) out[route] = missing\n }\n return out\n}\n","import type { Entity, Registry } from \"../../shared/entities\"\nimport type { GitContext } from \"./types\"\n\nexport interface EmitOptions {\n registry: Registry\n gitContext?: GitContext\n /** The import source for `createUidex` in the generated preconfigured export. */\n uidexImport?: string\n}\n\n/**\n * The scanner emits THREE artifacts, split by consumer:\n *\n * - `types` — the id unions + the `Uidex` authoring-shape namespace. Pure types,\n * no runtime, no `@ts-nocheck`. This is the file the ~dozens of\n * `import type { Uidex } from \"@/uidex.gen\"` sites resolve, so it must stay\n * small: an `import type` still forces tsc/tsserver to fully parse the target\n * module, so keeping the runtime entity data out of it is what keeps the editor\n * and type-checker responsive across every consumer file.\n * - `data` — the AUTHORED registry (route/page/feature/widget/primitive/flow) +\n * `gitContext` + `loadRegistry` + the preconfigured `uidex` instance. Runtime,\n * `@ts-nocheck`. Loaded eagerly by the devtools on mount.\n * - `locs` — the thin element/region `{ id, loc }` entities, emitted as positional\n * tuples (see `emitLocsModule`). Loaded lazily by the devtools (idle / first\n * inspect) via `loadLocs`, so ~90% of the entity count stays out of the initial\n * devtools chunk.\n */\nexport interface EmitResult {\n types: string\n /** Authored-metadata registry (pages/features/widgets/flows/…). */\n data: string\n /** Deferred `id → loc` module for the thin element/region entities. */\n locs: string\n}\n\n/**\n * Kinds shipped in the main (eagerly-loaded) registry: they carry authored\n * metadata (acceptance/states/flows/descriptions) the devtools renders. The thin\n * kinds (`element`, `region`) are just `{ id, loc }` and exist only so the\n * inspector can show a clicked node's source path — so they move to a SEPARATE\n * `.locs` module the devtools loads lazily (after mount / on first inspect),\n * keeping ~90% of the entity count out of the initial devtools chunk.\n */\nconst AUTHORED_KINDS = new Set([\n \"route\",\n \"page\",\n \"feature\",\n \"widget\",\n \"primitive\",\n \"flow\",\n])\n\n/**\n * Intern `loc.file` paths into a shared string table and serialize as a MINIFIED\n * `JSON.parse(\"…\")` payload (cheaper for a bundler to transform — a trivial AST —\n * and `tsc` sees `any`, not a giant literal). Returns the `files` declaration and\n * the `JSON.parse(...).map(hydrate)` expression; the caller emits a module-local\n * `hydrate()` that reverses the interning at load.\n */\nfunction internedPayload(entities: readonly Entity[]): {\n filesDecl: string\n parseExpr: string\n} {\n const fileIndex = new Map<string, number>()\n const files: string[] = []\n const compact = entities.map((e) => {\n const loc = (e as { loc?: { file?: unknown } }).loc\n if (!loc || typeof loc.file !== \"string\") return e\n let idx = fileIndex.get(loc.file)\n if (idx === undefined) {\n idx = files.length\n files.push(loc.file)\n fileIndex.set(loc.file, idx)\n }\n const rest = { ...(loc as Record<string, unknown>) }\n delete rest.file\n return { ...e, loc: { f: idx, ...rest } }\n })\n return {\n filesDecl: `const files: readonly string[] = ${jsonStable(files)}`,\n parseExpr: `(JSON.parse(${JSON.stringify(\n JSON.stringify(compact, replacerSorted)\n )}) as any[]).map(hydrate)`,\n }\n}\n\nconst HYDRATE_FN = [\n \"function hydrate(e: any): any {\",\n ' if (e.loc && typeof e.loc.f === \"number\") {',\n \" const { f, ...rest } = e.loc\",\n \" e.loc = { file: files[f], ...rest }\",\n \" }\",\n \" return e\",\n \"}\",\n].join(\"\\n\")\n\n/**\n * The `.locs` module holds thousands of thin element/region entities that are\n * almost all just `{ kind, id, loc }`. Rather than the generic object payload,\n * emit those as positional TUPLES `[kindIdx, id, fileIdx, line?, col?]` — which\n * drops every repeated JSON key (`\"kind\"`, `\"id\"`, `\"loc\"`, `\"line\"`, …) across\n * every row — and keep the handful of metadata-bearing entities (e.g. regions\n * with `composes`) as compact objects with an interned `loc`. `loadLocs`\n * reconstitutes the full `{ kind, id, loc, meta? }` entities.\n */\n/**\n * Shrink a rich thin-entity's `meta` for the `.locs` payload: collapse\n * `composes: [{ id, kind: \"element\" }]` → `[\"id\"]` (the common case — a region\n * composing elements; `loadLocs` re-wraps string entries as element refs).\n * Non-element refs keep their `{ id, kind }` object form. Every other field\n * (including `flows`) is preserved verbatim, so the reconstructed entity matches\n * the scanner's exactly.\n */\nfunction compactMeta(meta: unknown): unknown {\n if (!meta || typeof meta !== \"object\") return meta\n const composes = (meta as { composes?: unknown }).composes\n if (!Array.isArray(composes)) return meta\n return {\n ...(meta as Record<string, unknown>),\n composes: composes.map((c) =>\n c &&\n typeof c === \"object\" &&\n (c as { kind?: unknown }).kind === \"element\" &&\n Object.keys(c).length === 2 &&\n typeof (c as { id?: unknown }).id === \"string\"\n ? (c as { id: string }).id\n : c\n ),\n }\n}\n\nfunction emitLocsModule(thin: readonly Entity[], uidexImport: string): string {\n const kinds = [...new Set(thin.map((e) => e.kind))].sort()\n const kindIdx = new Map(kinds.map((k, i) => [k, i]))\n const fileIndex = new Map<string, number>()\n const files: string[] = []\n const fi = (f: string): number => {\n let i = fileIndex.get(f)\n if (i === undefined) {\n i = files.length\n files.push(f)\n fileIndex.set(f, i)\n }\n return i\n }\n\n const bare: Array<Array<string | number>> = []\n const rich: unknown[] = []\n for (const e of thin) {\n const loc = (e as { loc?: Record<string, unknown> }).loc\n const topOnlyKindIdLoc = Object.keys(e).every(\n (k) => k === \"kind\" || k === \"id\" || k === \"loc\"\n )\n const locOnlyKnown =\n !!loc &&\n typeof loc.file === \"string\" &&\n Object.keys(loc).every(\n (k) => k === \"file\" || k === \"line\" || k === \"column\"\n )\n if (topOnlyKindIdLoc && locOnlyKnown) {\n const row: Array<string | number> = [\n kindIdx.get(e.kind)!,\n (e as { id: string }).id,\n fi(loc.file as string),\n ]\n if (loc.line != null || loc.column != null)\n row.push(Number(loc.line ?? 0))\n if (loc.column != null) row.push(Number(loc.column))\n bare.push(row)\n } else {\n const richEntity: Record<string, unknown> = { ...e }\n if (loc && typeof loc.file === \"string\") {\n const { file, ...rest } = loc as { file: string } & Record<\n string,\n unknown\n >\n richEntity.loc = { f: fi(file), ...rest }\n }\n if (richEntity.meta) richEntity.meta = compactMeta(richEntity.meta)\n rich.push(richEntity)\n }\n }\n\n const str = (v: unknown): string =>\n JSON.stringify(JSON.stringify(v, replacerSorted))\n const l: string[] = []\n l.push(\"// THIS FILE IS AUTO-GENERATED BY `uidex scan`. DO NOT EDIT.\")\n l.push(\n \"// Deferred element/region source locations for the inspector's copy-path.\"\n )\n l.push(\"// @ts-nocheck\")\n l.push(\"/* eslint-disable */\")\n l.push(`import type { Entity, Registry } from ${JSON.stringify(uidexImport)}`)\n l.push(\"\")\n l.push(`const files: readonly string[] = ${jsonStable(files)}`)\n l.push(`const kinds: readonly string[] = ${jsonStable(kinds)}`)\n l.push(\"function loc(fi: number, line?: number, col?: number) {\")\n l.push(\" const o: any = { file: files[fi] }\")\n // Truthy (not `!= null`): a 0 is the placeholder for an absent line/column\n // (source positions are 1-based), so `[k,id,fi,0,col]` — a column with no line\n // — reconstructs without a spurious `line: 0`.\n l.push(\" if (line) o.line = line\")\n l.push(\" if (col) o.column = col\")\n l.push(\" return o\")\n l.push(\"}\")\n l.push(`const bare: any[] = JSON.parse(${str(bare)})`)\n l.push(`const rich: any[] = JSON.parse(${str(rich)})`)\n l.push(\"\")\n l.push(\n \"/** Add the thin element/region entities (source locations) to a registry. */\"\n )\n l.push(\"export function loadLocs(target: Registry): Registry {\")\n l.push(\" for (const r of bare)\")\n l.push(\n \" target.add({ kind: kinds[r[0]], id: r[1], loc: loc(r[2], r[3], r[4]) } as Entity)\"\n )\n // Build a fresh entity per call (don't mutate the shared module-level `rich`\n // objects), re-hydrating the interned loc and re-expanding string composes back\n // to `{ id, kind: \"element\" }` element refs.\n l.push(\" for (const e of rich) {\")\n l.push(\" const out: any = { ...e }\")\n l.push(' if (e.loc && typeof e.loc.f === \"number\") {')\n l.push(\" const { f, ...rest } = e.loc\")\n l.push(\" out.loc = { file: files[f], ...rest }\")\n l.push(\" }\")\n l.push(\" if (e.meta && Array.isArray(e.meta.composes)) {\")\n l.push(\n ' out.meta = { ...e.meta, composes: e.meta.composes.map((c: any) => typeof c === \"string\" ? { id: c, kind: \"element\" } : c) }'\n )\n l.push(\" }\")\n l.push(\" target.add(out)\")\n l.push(\" }\")\n l.push(\" return target\")\n l.push(\"}\")\n l.push(\"\")\n return l.join(\"\\n\")\n}\n\nfunction sortById<T extends { id: string }>(arr: readonly T[]): T[] {\n return [...arr].sort((a, b) => a.id.localeCompare(b.id))\n}\n\nfunction jsonStable(value: unknown, indent = 2): string {\n return JSON.stringify(value, replacerSorted, indent)\n}\n\nfunction replacerSorted(_key: string, value: unknown): unknown {\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[k] = (value as Record<string, unknown>)[k]\n }\n return sorted\n }\n return value\n}\n\nfunction emitIdUnion(name: string, ids: string[]): string {\n if (ids.length === 0) return `export type ${name} = never\\n`\n const sorted = [...ids].sort()\n const body = sorted.map((id) => ` | ${JSON.stringify(id)}`).join(\"\\n\")\n return `export type ${name} =\\n${body}\\n`\n}\n\n/**\n * Id kinds emitted as an opaque branded `string` instead of a literal union.\n * `element` ids number in the thousands, yet no `Uidex.*` authoring shape\n * references `ElementId`, so a multi-thousand-member literal union is pure\n * type-checker cost (parse + the quadratic union comparisons the TS Performance\n * guide warns about, and eventual TS2590 risk) for zero authoring value. A\n * branded string collapses the union to a single type while keeping the exported\n * name usable by any consumer that references it. The smaller, *referenced*\n * unions (PageId/FeatureId/WidgetId/RegionId/…) stay literal so `satisfies\n * Uidex.Page` etc. keep their id autocomplete.\n */\nconst OPAQUE_ID_UNIONS = new Set([\"ElementId\"])\n\nfunction emitId(name: string, ids: string[]): string {\n if (OPAQUE_ID_UNIONS.has(name)) {\n return `export type ${name} = string & { readonly __uidex?: ${JSON.stringify(name)} }\\n`\n }\n return emitIdUnion(name, ids)\n}\n\n/** The default suffix that derives the runtime-data module path from `output`. */\nexport function dataOutputPath(output: string): string {\n return output.replace(/\\.(d\\.ts|ts|tsx|mts|cts|js|mjs|cjs)$/, \".data.$1\")\n}\n\n/** The default suffix that derives the deferred `.locs` module path from `output`. */\nexport function locsOutputPath(output: string): string {\n return output.replace(/\\.(d\\.ts|ts|tsx|mts|cts|js|mjs|cjs)$/, \".locs.$1\")\n}\n\nexport function emit(opts: EmitOptions): EmitResult {\n const { registry, gitContext, uidexImport = \"uidex\" } = opts\n\n const routes = [...registry.list(\"route\")].sort((a, b) =>\n a.path.localeCompare(b.path)\n )\n const pages = sortById(registry.list(\"page\"))\n const features = sortById(registry.list(\"feature\"))\n const widgets = sortById(registry.list(\"widget\"))\n\n // Distinct declared render-state names across every state-bearing entity.\n const stateNames = new Set<string>()\n for (const e of [...pages, ...features, ...widgets]) {\n for (const s of e.meta?.states ?? []) stateNames.add(s.name)\n }\n const regions = sortById(registry.list(\"region\"))\n const elements = sortById(registry.list(\"element\"))\n const primitives = sortById(registry.list(\"primitive\"))\n const flows = sortById(registry.list(\"flow\"))\n\n // ---------------------------------------------------------------------------\n // Types file — pure types, no runtime, no `@ts-nocheck`. Kept small so the\n // `import type { Uidex }` sites (and tsserver, on every keystroke in them) parse\n // only this, never the entity data.\n // ---------------------------------------------------------------------------\n const t: string[] = []\n t.push(\"// THIS FILE IS AUTO-GENERATED BY `uidex scan`. DO NOT EDIT.\")\n t.push(\n \"// Types only — the runtime registry lives in the sibling `.data` module.\"\n )\n t.push(\"/* eslint-disable */\")\n t.push(\"\")\n t.push(\"// ---- id unions ----\")\n t.push(\n emitId(\n \"PageId\",\n pages.map((e) => e.id)\n )\n )\n t.push(\n emitId(\n \"FeatureId\",\n features.map((e) => e.id)\n )\n )\n t.push(\n emitId(\n \"WidgetId\",\n widgets.map((e) => e.id)\n )\n )\n t.push(\n emitId(\n \"RegionId\",\n regions.map((e) => e.id)\n )\n )\n t.push(\n emitId(\n \"ElementId\",\n elements.map((e) => e.id)\n )\n )\n t.push(\n emitId(\n \"PrimitiveId\",\n primitives.map((e) => e.id)\n )\n )\n t.push(\n emitId(\n \"FlowId\",\n flows.map((e) => e.id)\n )\n )\n t.push(\n emitId(\n \"RouteId\",\n routes.map((e) => e.path)\n )\n )\n t.push(emitId(\"StateId\", [...stateNames]))\n t.push(\"\")\n t.push(\"// ---- authoring-surface shape types ----\")\n t.push(\"export namespace Uidex {\")\n t.push(\n ' export type CoreStateKind = \"loading\" | \"empty\" | \"populated\" | \"error\"'\n )\n t.push(' export type StateKind = CoreStateKind | \"variant\"')\n t.push(\" export interface State {\")\n t.push(\" name: string\")\n t.push(\" kind?: StateKind\")\n t.push(\" acceptance?: readonly string[]\")\n t.push(\" description?: string\")\n t.push(\" }\")\n t.push(\" export type Waivers = Partial<Record<CoreStateKind, string>>\")\n t.push(\" export interface Page {\")\n t.push(\" page: PageId | false\")\n t.push(\" name?: string\")\n t.push(\" features?: readonly FeatureId[]\")\n t.push(\" widgets?: readonly WidgetId[]\")\n t.push(\" acceptance?: readonly string[]\")\n t.push(\" states?: readonly (string | State)[]\")\n t.push(\" capture?: boolean\")\n t.push(\" waivers?: Waivers\")\n t.push(\" description?: string\")\n t.push(\" }\")\n t.push(\" export interface Feature {\")\n t.push(\" feature: FeatureId | false\")\n t.push(\" name?: string\")\n t.push(\" features?: readonly FeatureId[]\")\n t.push(\" acceptance?: readonly string[]\")\n t.push(\" states?: readonly (string | State)[]\")\n t.push(\" description?: string\")\n t.push(\" }\")\n t.push(\" export interface Primitive {\")\n t.push(\" primitive: PrimitiveId\")\n t.push(\" name?: string\")\n t.push(\" description?: string\")\n t.push(\" }\")\n t.push(\" export interface Widget {\")\n t.push(\" widget: WidgetId\")\n t.push(\" name?: string\")\n t.push(\" acceptance?: readonly string[]\")\n t.push(\" states?: readonly (string | State)[]\")\n t.push(\" description?: string\")\n t.push(\" }\")\n t.push(\" export interface Region {\")\n t.push(\" region: RegionId | false\")\n t.push(\" name?: string\")\n t.push(\" description?: string\")\n t.push(\" }\")\n t.push(\" export interface Flow {\")\n t.push(\" flow: FlowId\")\n t.push(\" name?: string\")\n t.push(\" description?: string\")\n t.push(\" }\")\n t.push(\" export interface NotFlow {\")\n t.push(\" notFlow: true\")\n t.push(\" }\")\n t.push(\"}\")\n t.push(\"\")\n\n const allEntities: Entity[] = [\n ...routes,\n ...pages,\n ...features,\n ...widgets,\n ...regions,\n ...elements,\n ...primitives,\n ...flows,\n ]\n const authored = allEntities.filter((e) => AUTHORED_KINDS.has(e.kind))\n const thin = allEntities.filter((e) => !AUTHORED_KINDS.has(e.kind))\n const gc: GitContext = gitContext ?? { branch: null, commit: null, pr: null }\n\n // ---------------------------------------------------------------------------\n // Data module — the AUTHORED registry (metadata-bearing kinds). Eagerly loaded\n // by the devtools on mount. `@ts-nocheck` (machine-generated data).\n // ---------------------------------------------------------------------------\n const authoredPayload = internedPayload(authored)\n const d: string[] = []\n d.push(\"// THIS FILE IS AUTO-GENERATED BY `uidex scan`. DO NOT EDIT.\")\n d.push(\n \"// Authored-metadata registry. The thin element/region entities (source\"\n )\n d.push(\n \"// locations only) live in the sibling `.locs` module, loaded lazily.\"\n )\n d.push(\"// @ts-nocheck\")\n d.push(\"/* eslint-disable */\")\n d.push(`import { createUidex } from ${JSON.stringify(uidexImport)}`)\n d.push(`import type { Registry } from ${JSON.stringify(uidexImport)}`)\n d.push(\"\")\n d.push(authoredPayload.filesDecl)\n d.push(HYDRATE_FN)\n d.push(`export const entities = ${authoredPayload.parseExpr}`)\n d.push(\"\")\n d.push(`export const gitContext = ${jsonStable(gc)} as const`)\n d.push(\"\")\n d.push(\"export function loadRegistry(target: Registry): Registry {\")\n d.push(\" for (const entity of entities) target.add(entity)\")\n d.push(\" return target\")\n d.push(\"}\")\n d.push(\"\")\n d.push(\"export const uidex = createUidex()\")\n d.push(\"for (const entity of entities) uidex.registry.add(entity)\")\n d.push(\"\")\n\n // ---------------------------------------------------------------------------\n // Locs module — the thin `{ id, loc }` element/region entities, split out so\n // the devtools loads them lazily (after mount / on first inspect). Keeping them\n // out of the main data module keeps ~90% of the entity count out of the initial\n // devtools chunk. Emitted as positional tuples (see emitLocsModule). `@ts-nocheck`.\n // ---------------------------------------------------------------------------\n const locs = emitLocsModule(thin, uidexImport)\n\n return { types: t.join(\"\\n\"), data: d.join(\"\\n\"), locs }\n}\n","import { execSync } from \"node:child_process\"\nimport type { GitContext } from \"./types\"\n\nexport interface GitResolveOptions {\n cwd?: string\n env?: NodeJS.ProcessEnv\n}\n\nfunction runGit(args: string[], cwd: string): string | null {\n try {\n const out = execSync(`git ${args.join(\" \")}`, {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n encoding: \"utf8\",\n })\n return out.trim() || null\n } catch {\n return null\n }\n}\n\nexport function resolveGitContext(opts: GitResolveOptions = {}): GitContext {\n const cwd = opts.cwd ?? process.cwd()\n const env = opts.env ?? process.env\n\n const branch =\n env.GITHUB_HEAD_REF ||\n env.GITHUB_REF_NAME ||\n env.BUILDKITE_BRANCH ||\n env.CI_COMMIT_REF_NAME ||\n env.BITBUCKET_BRANCH ||\n runGit([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"], cwd) ||\n null\n\n const commit =\n env.GITHUB_SHA ||\n env.BUILDKITE_COMMIT ||\n env.CI_COMMIT_SHA ||\n env.BITBUCKET_COMMIT ||\n runGit([\"rev-parse\", \"HEAD\"], cwd) ||\n null\n\n const pr =\n env.PR_NUMBER ||\n env.GITHUB_PR_NUMBER ||\n parseGitHubRef(env.GITHUB_REF) ||\n env.BUILDKITE_PULL_REQUEST ||\n env.CI_MERGE_REQUEST_IID ||\n env.BITBUCKET_PR_ID ||\n null\n\n return {\n branch: branch || null,\n commit: commit || null,\n pr: pr && pr !== \"false\" ? String(pr) : null,\n }\n}\n\nfunction parseGitHubRef(ref: string | undefined): string | null {\n if (!ref) return null\n const m = ref.match(/^refs\\/pull\\/(\\d+)\\/merge$/)\n return m ? m[1] : null\n}\n","import * as fs from \"node:fs\"\nimport * as path from \"node:path\"\nimport type { Registry } from \"../../shared/entities\"\n\nexport type ScaffoldKind = \"widget\" | \"page\" | \"feature\"\n\nexport interface ScaffoldSpecOptions {\n registry: Registry\n kind: ScaffoldKind\n id: string\n outDir: string\n force?: boolean\n fixtureImport?: string\n}\n\nexport interface ScaffoldOptions {\n registry: Registry\n widgetId: string\n outDir: string\n force?: boolean\n fixtureImport?: string\n}\n\nexport interface ScaffoldResult {\n outputPath: string\n written: boolean\n skipped: boolean\n reason?: string\n}\n\nexport function scaffoldWidgetSpec(opts: ScaffoldOptions): ScaffoldResult {\n return scaffoldSpec({\n registry: opts.registry,\n kind: \"widget\",\n id: opts.widgetId,\n outDir: opts.outDir,\n force: opts.force,\n fixtureImport: opts.fixtureImport,\n })\n}\n\n/**\n * Emits a tagged Playwright stub from an entity's declared acceptance\n * criteria — one `test()` per criterion. Widgets keep the historical\n * `widget-<id>.spec.ts` name; pages and features emit `flow-<id>.spec.ts`\n * per the one-tagged-describe-per-flow-spec convention.\n */\nexport function scaffoldSpec(opts: ScaffoldSpecOptions): ScaffoldResult {\n const {\n registry,\n kind,\n id,\n outDir,\n force = false,\n fixtureImport = \"./fixtures\",\n } = opts\n const entity = registry.get(kind, id)\n if (!entity) {\n throw new Error(`${capitalize(kind)} \"${id}\" not found in registry`)\n }\n\n const criteria = entity.meta?.acceptance ?? []\n const filename =\n kind === \"widget\" ? `widget-${id}.spec.ts` : `flow-${id}.spec.ts`\n const outputPath = path.resolve(outDir, filename)\n\n if (fs.existsSync(outputPath) && !force) {\n return {\n outputPath,\n written: false,\n skipped: true,\n reason: `spec already exists at ${outputPath}; pass --force to overwrite`,\n }\n }\n\n const content = renderSpec({ id, criteria, fixtureImport })\n\n fs.mkdirSync(path.dirname(outputPath), { recursive: true })\n fs.writeFileSync(outputPath, content, \"utf8\")\n\n return { outputPath, written: true, skipped: false }\n}\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1)\n}\n\nfunction renderSpec(args: {\n id: string\n criteria: readonly string[]\n fixtureImport: string\n}): string {\n const lines: string[] = []\n lines.push(\n `import { test, expect } from ${JSON.stringify(args.fixtureImport)}`\n )\n lines.push(\"\")\n lines.push(\n `test.describe(${JSON.stringify(args.id)}, { tag: \"@uidex:flow\" }, () => {`\n )\n if (args.criteria.length === 0) {\n lines.push(` test(\"TODO: add acceptance criteria\", async () => {`)\n lines.push(` // TODO`)\n lines.push(` })`)\n } else {\n for (const criterion of args.criteria) {\n lines.push(` test(${JSON.stringify(criterion)}, async ({ uidex }) => {`)\n lines.push(` // TODO: implement criterion`)\n lines.push(` void uidex`)\n lines.push(` expect(true).toBe(true)`)\n lines.push(` })`)\n lines.push(\"\")\n }\n }\n lines.push(\"})\")\n lines.push(\"\")\n return lines.join(\"\\n\")\n}\n","import * as fs from \"node:fs\"\nimport * as path from \"node:path\"\nimport type { Registry } from \"../../shared/entities\"\nimport { audit } from \"./audit\"\nimport { discover } from \"./discover\"\nimport { emit, dataOutputPath, locsOutputPath } from \"./emit\"\nimport { extract } from \"./extract\"\nimport { resolveGitContext } from \"./git\"\nimport { resolve } from \"./resolve\"\nimport type { PageCoverageBaseline } from \"./page-coverage\"\nimport type { CapturedState, CapturedStatesManifest } from \"./state-coverage\"\nimport type {\n AuditSummary,\n DiscoveredConfig,\n GitContext,\n UidexConfig,\n} from \"./types\"\nimport { walk } from \"./walk\"\n\nexport interface RunScanOptions {\n cwd?: string\n check?: boolean\n lint?: boolean\n configs?: DiscoveredConfig[]\n /** Captured-states manifest for the completeness gate; overrides on-disk load. */\n capturedStates?: CapturedStatesManifest\n /** Page-coverage baseline; overrides on-disk load. */\n pageBaseline?: PageCoverageBaseline\n}\n\nconst DEFAULT_STATES_MANIFEST = \"uidex-states.json\"\nconst DEFAULT_COVERAGE_BASELINE = \"uidex-coverage-baseline.json\"\n\n/** Load the page-coverage baseline from disk, if present + well-formed. */\nexport function loadPageBaseline(\n configDir: string,\n config: UidexConfig\n): PageCoverageBaseline | undefined {\n const rel = config.coverageBaseline ?? DEFAULT_COVERAGE_BASELINE\n const abs = path.resolve(configDir, rel)\n let raw: string\n try {\n raw = fs.readFileSync(abs, \"utf8\")\n } catch {\n return undefined\n }\n try {\n const parsed = JSON.parse(raw) as Partial<PageCoverageBaseline>\n if (!parsed || !Array.isArray(parsed.uncapturedPages)) return undefined\n const uncapturedPages = parsed.uncapturedPages.filter(\n (p): p is string => typeof p === \"string\"\n )\n // Sanitize missingKinds to a record of route → string[]; a malformed value\n // (e.g. a bare string) would otherwise char-split via `new Set` downstream.\n let missingKinds: Record<string, string[]> | undefined\n const mkRaw = parsed.missingKinds\n if (mkRaw && typeof mkRaw === \"object\" && !Array.isArray(mkRaw)) {\n const mk: Record<string, string[]> = {}\n for (const [route, kinds] of Object.entries(mkRaw)) {\n if (Array.isArray(kinds)) {\n mk[route] = kinds.filter((k): k is string => typeof k === \"string\")\n }\n }\n missingKinds = mk\n }\n return { uncapturedPages, ...(missingKinds ? { missingKinds } : {}) }\n } catch {\n return undefined\n }\n}\n\n/** Load the captured-states manifest from disk, if present + well-formed. */\nfunction loadCapturedStates(\n configDir: string,\n config: UidexConfig\n): CapturedStatesManifest | undefined {\n const rel = config.statesManifest ?? DEFAULT_STATES_MANIFEST\n const abs = path.resolve(configDir, rel)\n let raw: string\n try {\n raw = fs.readFileSync(abs, \"utf8\")\n } catch {\n return undefined\n }\n try {\n const parsed = JSON.parse(raw) as Partial<CapturedStatesManifest>\n if (!parsed || !Array.isArray(parsed.captured)) return undefined\n // Sanitize each entry: a malformed one (null, missing/non-string fields)\n // would otherwise crash the gates that read `.entity` / `.url`.\n const captured: CapturedState[] = []\n for (const entry of parsed.captured as unknown[]) {\n if (!entry || typeof entry !== \"object\") continue\n const c = entry as Record<string, unknown>\n if (typeof c.entity !== \"string\" || typeof c.state !== \"string\") continue\n const rec: CapturedState = { entity: c.entity, state: c.state }\n if (typeof c.kind === \"string\") rec.kind = c.kind as CapturedState[\"kind\"]\n if (typeof c.stateKind === \"string\") rec.stateKind = c.stateKind\n if (typeof c.url === \"string\") rec.url = c.url\n if (typeof c.route === \"string\") rec.route = c.route\n captured.push(rec)\n }\n return { captured }\n } catch {\n return undefined\n }\n}\n\n/** One generated artifact: its bytes plus where it lands (abs + repo-relative). */\nexport interface ScanArtifact {\n generated: string\n /** Absolute path on disk. */\n outputPath: string\n /** Path relative to the config dir, for diagnostics. */\n outputRel: string\n}\n\nexport interface ScanResult {\n config: UidexConfig\n configDir: string\n registry: Registry\n gitContext: GitContext\n audit?: AuditSummary\n /** Pure-types artifact (`config.output`, e.g. `uidex.gen.ts`). */\n types: ScanArtifact\n /** Authored-registry artifact (the sibling `.data` module). */\n data: ScanArtifact\n /** Deferred element/region source-location artifact (the sibling `.locs` module). */\n locs: ScanArtifact\n /** The captured-states manifest in effect this run, if any (for --update-baseline). */\n capturedStates?: CapturedStatesManifest\n}\n\nexport function runScan(opts: RunScanOptions = {}): ScanResult[] {\n const cwd = opts.cwd ?? process.cwd()\n const configs = opts.configs ?? discover({ cwd })\n if (configs.length === 0) {\n throw new Error(`No .uidex.json found starting from ${cwd}`)\n }\n\n return configs.map((dc) => runOne(dc, opts))\n}\n\nfunction runOne(dc: DiscoveredConfig, opts: RunScanOptions): ScanResult {\n const { config, configDir } = dc\n\n const sourceFiles = walk(config.sources, {\n cwd: configDir,\n globalExcludes: config.exclude,\n })\n\n const extracted = extract(sourceFiles)\n\n const flowFiles = config.flows\n ? walk(\n config.flows.map((glob) => ({ rootDir: \".\", include: [glob] })),\n { cwd: configDir, includeTests: true }\n )\n : []\n const extractedFlows = extract(flowFiles)\n\n const resolved = resolve({\n config,\n extracted,\n flowFiles: extractedFlows,\n })\n\n const gitContext = resolveGitContext({ cwd: configDir })\n\n const emitted = emit({\n registry: resolved.registry,\n gitContext,\n })\n\n const typesRel = config.output\n const typesPath = path.resolve(configDir, typesRel)\n const dataRel = dataOutputPath(config.output)\n const dataPath = path.resolve(configDir, dataRel)\n const locsRel = locsOutputPath(config.output)\n const locsPath = path.resolve(configDir, locsRel)\n\n let typesOnDisk: string | null = null\n let dataOnDisk: string | null = null\n let locsOnDisk: string | null = null\n if (opts.check) {\n typesOnDisk = readOrNull(typesPath)\n dataOnDisk = readOrNull(dataPath)\n locsOnDisk = readOrNull(locsPath)\n }\n\n const hasExtractDiagnostics = [...extracted, ...extractedFlows].some(\n (ef) => (ef.diagnostics?.length ?? 0) > 0\n )\n const capturedStates =\n opts.capturedStates ?? loadCapturedStates(configDir, config)\n const pageBaseline = opts.pageBaseline ?? loadPageBaseline(configDir, config)\n\n let auditResult: AuditSummary | undefined\n if (\n opts.check ||\n opts.lint ||\n resolved.diagnostics.length > 0 ||\n hasExtractDiagnostics\n ) {\n auditResult = audit({\n registry: resolved.registry,\n extracted,\n files: sourceFiles,\n flowExtracted: extractedFlows,\n config,\n check: opts.check,\n lint: opts.lint,\n resolveDiagnostics: resolved.diagnostics,\n // The entity array (and thus the meaningful drift) lives in the data file,\n // so the entity-aware gen-stale diff runs against it; the types file gets a\n // plain content compare (see audit()).\n generated: emitted.data,\n existingOnDisk: dataOnDisk,\n outputPath: dataRel,\n typesGenerated: emitted.types,\n typesOnDisk,\n typesOutputPath: typesRel,\n locsGenerated: emitted.locs,\n locsOnDisk,\n locsOutputPath: locsRel,\n capturedStates,\n pageBaseline,\n })\n }\n\n return {\n config,\n configDir,\n registry: resolved.registry,\n gitContext,\n audit: auditResult,\n types: {\n generated: emitted.types,\n outputPath: typesPath,\n outputRel: typesRel,\n },\n data: { generated: emitted.data, outputPath: dataPath, outputRel: dataRel },\n locs: { generated: emitted.locs, outputPath: locsPath, outputRel: locsRel },\n capturedStates,\n }\n}\n\n/** Read a file's contents, or `null` if it does not exist. */\nfunction readOrNull(p: string): string | null {\n try {\n return fs.readFileSync(p, \"utf8\")\n } catch {\n return null\n }\n}\n\n/**\n * Write one artifact, but ONLY when its contents actually changed.\n *\n * A `uidex scan` runs on every edit (pre-commit + editor/agent hooks), yet most\n * edits touch no `data-uidex*` annotation, so the freshly-emitted file is\n * byte-identical to what is already on disk. An unconditional `writeFileSync`\n * still bumps the file's mtime, which a dev-server file watcher (Next/Turbopack,\n * Vite) treats as a change — forcing an HMR recompile of the (large, generated)\n * module for no reason. Comparing first makes a no-op scan a genuine no-op.\n *\n * Returns `true` if the file was written, `false` if it was already up to date.\n */\nexport function writeArtifact(artifact: ScanArtifact): boolean {\n if (readOrNull(artifact.outputPath) === artifact.generated) return false\n fs.mkdirSync(path.dirname(artifact.outputPath), { recursive: true })\n fs.writeFileSync(artifact.outputPath, artifact.generated, \"utf8\")\n return true\n}\n\n/**\n * Write all three generated artifacts (types + data + locs), each only if\n * changed. Splitting them means a change confined to one (e.g. adding an element\n * only touches `.locs`) never rewrites the others, so watchers recompile only what\n * actually moved. Returns `true` if any file was written.\n */\nexport function writeScanResult(result: ScanResult): boolean {\n const wroteTypes = writeArtifact(result.types)\n const wroteData = writeArtifact(result.data)\n const wroteLocs = writeArtifact(result.locs)\n return wroteTypes || wroteData || wroteLocs\n}\n\n/** Absolute path of the page-coverage baseline for a scan result. */\nexport function pageBaselinePath(result: ScanResult): string {\n const rel = result.config.coverageBaseline ?? DEFAULT_COVERAGE_BASELINE\n return path.resolve(result.configDir, rel)\n}\n","import * as fs from \"node:fs\"\nimport * as path from \"node:path\"\nimport type { Diagnostic, FixEdit } from \"./types\"\n\n/**\n * Applies the machine-generated fixes attached to diagnostics.\n *\n * Edits are offset-based against the content the scanner read, so this must\n * run before anything else touches the files. Within a file, edits apply\n * last-to-first; an edit overlapping one already applied is skipped. Identical\n * edits are deduped — two fixes in one file emitting the same edit collapse to\n * one application.\n */\n\nexport interface AppliedFix {\n code: string\n description: string\n file?: string\n}\n\nexport interface ApplyFixesResult {\n applied: AppliedFix[]\n /** fixes skipped because of overlapping edits or existing target files */\n skipped: Array<AppliedFix & { reason: string }>\n}\n\ninterface FixEntry {\n code: string\n description: string\n file?: string\n edits: FixEdit[]\n createFiles: Array<{ path: string; content: string }>\n deleteFiles: string[]\n skippedReason?: string\n}\n\nexport function applyFixes(diagnostics: Diagnostic[]): ApplyFixesResult {\n const entries: FixEntry[] = []\n for (const d of diagnostics) {\n if (!d.fix) continue\n entries.push({\n code: d.code,\n description: d.fix.description,\n file: d.file,\n edits: d.fix.edits ?? [],\n createFiles: d.fix.createFiles ?? [],\n deleteFiles: d.fix.deleteFiles ?? [],\n })\n }\n if (entries.length === 0) return { applied: [], skipped: [] }\n\n // Collect edits per file, deduping identical ones across fixes.\n const seenEdits = new Set<string>()\n const editsByFile = new Map<string, Array<FixEdit & { entry: FixEntry }>>()\n for (const entry of entries) {\n for (const edit of entry.edits) {\n const key = `${edit.path}:${edit.start}:${edit.end}:${edit.replacement}`\n if (seenEdits.has(key)) continue\n seenEdits.add(key)\n let list = editsByFile.get(edit.path)\n if (!list) {\n list = []\n editsByFile.set(edit.path, list)\n }\n list.push({ ...edit, entry })\n }\n }\n\n for (const [filePath, edits] of editsByFile) {\n let content: string\n try {\n content = fs.readFileSync(filePath, \"utf8\")\n } catch {\n for (const e of edits) e.entry.skippedReason ??= \"file is unreadable\"\n continue\n }\n // Resolve overlaps first-in-file-wins, then apply last-to-first so\n // earlier offsets stay valid.\n edits.sort((a, b) => a.start - b.start || a.end - b.end)\n const kept: typeof edits = []\n let prevEnd = -1\n for (const edit of edits) {\n if (edit.start < prevEnd) {\n edit.entry.skippedReason ??= \"overlapping edit\"\n continue\n }\n kept.push(edit)\n prevEnd = edit.end\n }\n for (let i = kept.length - 1; i >= 0; i--) {\n const edit = kept[i]\n content =\n content.slice(0, edit.start) +\n edit.replacement +\n content.slice(edit.end)\n }\n if (kept.length > 0) fs.writeFileSync(filePath, content, \"utf8\")\n }\n\n for (const entry of entries) {\n if (entry.skippedReason) continue\n for (const create of entry.createFiles) {\n if (fs.existsSync(create.path)) {\n entry.skippedReason = `${path.basename(create.path)} already exists`\n continue\n }\n fs.mkdirSync(path.dirname(create.path), { recursive: true })\n fs.writeFileSync(create.path, create.content, \"utf8\")\n }\n if (entry.skippedReason) continue\n for (const del of entry.deleteFiles) {\n try {\n fs.unlinkSync(del)\n } catch {\n // already gone — the goal state is reached\n }\n }\n }\n\n const applied: AppliedFix[] = []\n const skipped: Array<AppliedFix & { reason: string }> = []\n for (const entry of entries) {\n const summary: AppliedFix = {\n code: entry.code,\n description: entry.description,\n file: entry.file,\n }\n if (entry.skippedReason) {\n skipped.push({ ...summary, reason: entry.skippedReason })\n } else {\n applied.push(summary)\n }\n }\n return { applied, skipped }\n}\n","import { discover } from \"./discover\"\nimport { extract } from \"./extract\"\nimport { applyFixes } from \"./fix\"\nimport { runScan, writeScanResult } from \"./pipeline\"\nimport { walk } from \"./walk\"\nimport type { FixEdit } from \"./types\"\n\n/**\n * Cross-file id rename. The registry knows every reference surface for an\n * id — the DOM attribute, `uidex(\"…\")` calls in flow specs, the widget\n * export's discriminator, and `widgets:` arrays — so the rename rewrites all\n * of them in one pass and regenerates the gen file. Occurrences the scanner\n * can't edit mechanically (const indirection, ternaries, patterns) are\n * reported for manual follow-up instead of being guessed at.\n */\n\nexport type RenameKind = \"element\" | \"widget\" | \"region\"\n\nexport interface RenameOptions {\n cwd: string\n kind: RenameKind\n oldId: string\n newId: string\n /** allow renaming onto an id that already exists */\n force?: boolean\n}\n\nexport interface RenameResult {\n /** number of source edits applied */\n edits: number\n /** occurrences that need a human (no static literal to rewrite) */\n manual: Array<{ file: string; line: number; reason: string }>\n errors: string[]\n}\n\nconst ID_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/\n\nexport function renameEntity(opts: RenameOptions): RenameResult {\n const { cwd, kind, oldId, newId, force = false } = opts\n const manual: RenameResult[\"manual\"] = []\n const errors: string[] = []\n\n if (!ID_RE.test(newId)) {\n return {\n edits: 0,\n manual,\n errors: [`New id \"${newId}\" is not kebab-case`],\n }\n }\n\n const configs = discover({ cwd })\n if (configs.length === 0) {\n return { edits: 0, manual, errors: [`No .uidex.json found under ${cwd}`] }\n }\n\n const edits: FixEdit[] = []\n\n for (const dc of configs) {\n const { config, configDir } = dc\n const sourceFiles = walk(config.sources, {\n cwd: configDir,\n globalExcludes: config.exclude,\n })\n const extracted = extract(sourceFiles)\n const flowFiles = config.flows\n ? walk(\n config.flows.map((glob) => ({ rootDir: \".\", include: [glob] })),\n { cwd: configDir, includeTests: true }\n )\n : []\n const extractedFlows = extract(flowFiles)\n\n // Existence / collision checks against the live registry.\n const scan = runScan({ cwd: configDir, configs: [dc] })[0]\n const registry = scan.registry\n if (!registry.get(kind, oldId)) {\n if (registry.matchPattern(kind, oldId)) {\n errors.push(\n `${kind} \"${oldId}\" only matches via a pattern id; pattern-backed ids cannot be renamed mechanically`\n )\n } else {\n errors.push(`${kind} \"${oldId}\" not found in registry`)\n }\n continue\n }\n if (registry.get(kind, newId) && !force) {\n errors.push(\n `${kind} \"${newId}\" already exists; pass --force to merge the ids`\n )\n continue\n }\n\n const quoteAs = (content: string, start: number): string => {\n const q = content[start]\n return q === '\"' || q === \"'\" || q === \"`\"\n ? `${q}${newId}${q}`\n : `\"${newId}\"`\n }\n\n // 1. DOM attribute occurrences.\n for (const ef of extracted) {\n for (const a of ef.annotations) {\n if (a.kind !== kind || a.id !== oldId) continue\n if (a.span) {\n edits.push({\n path: ef.file.sourcePath,\n start: a.span.start,\n end: a.span.end,\n replacement: quoteAs(ef.file.content, a.span.start),\n })\n } else {\n manual.push({\n file: a.file,\n line: a.line,\n reason:\n \"attribute value is not a plain string literal (const reference, ternary, or template)\",\n })\n }\n }\n\n // 2. Metadata exports: the widget discriminator and widgets: arrays.\n for (const m of ef.metadata ?? []) {\n if (kind === \"widget\" && m.kind === \"widget\" && m.id === oldId) {\n if (m.idSpan) {\n edits.push({\n path: ef.file.sourcePath,\n start: m.idSpan.start,\n end: m.idSpan.end,\n replacement: quoteAs(ef.file.content, m.idSpan.start),\n })\n } else {\n manual.push({\n file: ef.file.displayPath,\n line: m.loc.line ?? 1,\n reason: \"widget export id is not a plain string literal\",\n })\n }\n }\n if (kind === \"widget\" && m.widgets) {\n for (let i = 0; i < m.widgets.length; i++) {\n if (m.widgets[i] !== oldId) continue\n const span = m.widgetSpans?.[i]\n if (span) {\n edits.push({\n path: ef.file.sourcePath,\n start: span.start,\n end: span.end,\n replacement: quoteAs(ef.file.content, span.start),\n })\n }\n }\n }\n }\n }\n\n // 3. uidex(\"…\") calls in flow specs.\n for (const ef of extractedFlows) {\n for (const fact of ef.flows ?? []) {\n for (const call of fact.calls) {\n if (call.id !== oldId) continue\n if (call.span) {\n edits.push({\n path: ef.file.sourcePath,\n start: call.span.start,\n end: call.span.end,\n replacement: quoteAs(ef.file.content, call.span.start),\n })\n } else {\n manual.push({\n file: ef.file.displayPath,\n line: call.line,\n reason: \"uidex() argument is not a plain string literal\",\n })\n }\n }\n }\n }\n }\n\n if (errors.length > 0) {\n return { edits: 0, manual, errors }\n }\n if (edits.length === 0 && manual.length === 0) {\n return {\n edits: 0,\n manual,\n errors: [\n `${kind} \"${oldId}\" has no editable occurrences (convention-derived ids like landmarks cannot be renamed)`,\n ],\n }\n }\n\n const result = applyFixes([\n {\n code: \"rename\",\n severity: \"info\",\n message: \"\",\n fix: {\n description: `Rename ${kind} \"${oldId}\" to \"${newId}\"`,\n edits,\n },\n },\n ])\n if (result.skipped.length > 0) {\n errors.push(`Some edits were skipped: ${result.skipped[0].reason}`)\n }\n\n // Regenerate the gen file on the renamed tree.\n for (const r of runScan({ cwd })) writeScanResult(r)\n\n return { edits: edits.length, manual, errors }\n}\n","import * as fs from \"node:fs\"\nimport * as path from \"node:path\"\nimport { runAiCommand } from \"./ai\"\nimport { discover, CONFIG_FILENAME } from \"./discover\"\nimport { applyFixes } from \"./fix\"\nimport type { AppliedFix } from \"./fix\"\nimport { runScan, writeArtifact, pageBaselinePath } from \"./pipeline\"\nimport type { ScanArtifact } from \"./pipeline\"\nimport { computePageBaseline } from \"./page-coverage\"\nimport { computeMissingKinds } from \"./state-matrix\"\nimport { renameEntity } from \"./rename\"\nimport type { RenameKind } from \"./rename\"\nimport { scaffoldSpec } from \"./scaffold\"\nimport type { ScaffoldKind } from \"./scaffold\"\nimport type { Diagnostic, UidexConfig } from \"./types\"\n\nexport interface CliResult {\n exitCode: number\n stdout: string\n stderr: string\n}\n\nexport interface CliOptions {\n argv: string[]\n cwd?: string\n}\n\nimport { parseArgs } from \"../cli/parse-args\"\n\ntype Flags = Record<string, string | boolean>\n\nexport async function run(opts: CliOptions): Promise<CliResult> {\n const cwd = opts.cwd ?? process.cwd()\n const { positional, flags } = parseArgs(opts.argv)\n const command = positional[0] ?? \"help\"\n\n const writer = createWriter()\n\n try {\n switch (command) {\n case \"help\":\n case \"--help\":\n case \"-h\":\n writer.out(helpText())\n return writer.result(0)\n\n case \"init\":\n return runInit(cwd, writer)\n\n case \"scan\":\n return runScanCommand(cwd, flags, writer)\n\n case \"scaffold\":\n return runScaffold(cwd, positional.slice(1), flags, writer)\n\n case \"rename\":\n return runRename(cwd, positional.slice(1), flags, writer)\n\n case \"ai\": {\n const result = await runAiCommand({\n cwd,\n argv: opts.argv.slice(1),\n })\n if (result.stdout) writer.out(result.stdout.replace(/\\n$/, \"\"))\n if (result.stderr) writer.err(result.stderr.replace(/\\n$/, \"\"))\n return writer.result(result.exitCode)\n }\n\n default:\n writer.err(`Unknown command: ${command}`)\n writer.err(helpText())\n return writer.result(1)\n }\n } catch (e) {\n writer.err(e instanceof Error ? e.message : String(e))\n return writer.result(1)\n }\n}\n\nfunction helpText(): string {\n return [\n \"uidex — scanner CLI\",\n \"\",\n \"Commands:\",\n \" init Create a .uidex.json\",\n \" scan [flags] Run the scanner pipeline\",\n \" scaffold <widget|page|feature> <id> Emit a Playwright spec from declared acceptance\",\n \" rename <element|widget|region> <old-id> <new-id> Rename an id everywhere (DOM attr, flows, exports)\",\n \" ai <install|uninstall|providers> Manage AI assistant integrations\",\n \"\",\n \"Flags:\",\n \" --check Verify the on-disk gen file matches a fresh scan; exit non-zero on drift (read-only)\",\n \" --lint Run lint diagnostics (missing annotations, scope leak, duplicate ids, coverage)\",\n \" --audit Equivalent to --check --lint (read-only)\",\n \" --fix Apply machine-generated fixes (add data-uidex to unannotated interactive elements, drop empty names), then rescan and write\",\n \" --update-baseline Regenerate the page-coverage baseline (uidex-coverage-baseline.json) from the current uncaptured routes\",\n \" --json Emit JSON diagnostics on stdout\",\n \" --force (scaffold) overwrite existing spec\",\n \"\",\n ].join(\"\\n\")\n}\n\nfunction runInit(cwd: string, w: ReturnType<typeof createWriter>): CliResult {\n const configPath = path.join(cwd, CONFIG_FILENAME)\n if (fs.existsSync(configPath)) {\n w.err(`.uidex.json already exists at ${configPath}`)\n return w.result(1)\n }\n const config: UidexConfig = {\n $schema: \"https://uidex.dev/schema/v2.json\",\n sources: [{ rootDir: \"src\" }],\n output: \"src/uidex.gen.ts\",\n }\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + \"\\n\", \"utf8\")\n w.out(`Created ${configPath}`)\n\n const gitignorePath = path.join(cwd, \".gitignore\")\n // `*.gen.*` covers both generated artifacts: the types file (`*.gen.ts`) and\n // the runtime data module (`*.gen.data.ts`).\n const entry = \"*.gen.*\"\n if (fs.existsSync(gitignorePath)) {\n const existing = fs.readFileSync(gitignorePath, \"utf8\")\n const hasEntry = existing.split(\"\\n\").some((line) => line.trim() === entry)\n if (!hasEntry) {\n const needsNewline = existing.length > 0 && !existing.endsWith(\"\\n\")\n fs.appendFileSync(\n gitignorePath,\n `${needsNewline ? \"\\n\" : \"\"}${entry}\\n`,\n \"utf8\"\n )\n w.out(`Appended ${entry} to ${gitignorePath}`)\n }\n } else {\n fs.writeFileSync(gitignorePath, `${entry}\\n`, \"utf8\")\n w.out(`Created ${gitignorePath} with ${entry}`)\n }\n return w.result(0)\n}\n\nfunction runScanCommand(\n cwd: string,\n flags: Flags,\n w: ReturnType<typeof createWriter>\n): CliResult {\n const fix = Boolean(flags.fix)\n const updateBaseline = Boolean(flags[\"update-baseline\"])\n // --fix re-scans and writes the gen file after applying fixes, so the\n // read-only --check pass is meaningless alongside it.\n const check = !fix && !updateBaseline && Boolean(flags.check || flags.audit)\n const lint = Boolean(flags.lint || flags.audit || fix || updateBaseline)\n const asJson = Boolean(flags.json)\n\n let configs = discover({ cwd })\n if (configs.length === 0) {\n w.err(`No ${CONFIG_FILENAME} found under ${cwd}`)\n return w.result(1)\n }\n\n let fixed: AppliedFix[] = []\n let fixSkipped: Array<AppliedFix & { reason: string }> = []\n if (fix) {\n // Discovery pass: check+lint so every fixable diagnostic is produced.\n const discovery = runScan({ cwd, check: true, lint: true, configs })\n const result = applyFixes(\n discovery.flatMap((r) => r.audit?.diagnostics ?? [])\n )\n fixed = result.applied\n fixSkipped = result.skipped\n // Fixes may create or delete files; re-discover before the real pass.\n configs = discover({ cwd })\n }\n\n const results = runScan({ cwd, check, lint, configs })\n\n const artifacts = results.flatMap((r) => [r.types, r.data, r.locs])\n const wrote = new Set<ScanArtifact>()\n if (!check) {\n for (const a of artifacts) {\n if (writeArtifact(a)) wrote.add(a)\n }\n }\n\n // --update-baseline: regenerate the shrink-only page-coverage backlog from the\n // current uncaptured set and exit. Growth only ever happens here, so it lands\n // in the file's diff for review; the default gate errors on new uncaptured\n // pages that were not deliberately baselined.\n if (updateBaseline) {\n for (const r of results) {\n const manifest = r.capturedStates ?? { captured: [] }\n const pageBaseline = computePageBaseline(r.registry, manifest)\n const missingKinds = computeMissingKinds(r.registry, manifest)\n const baseline = {\n ...pageBaseline,\n ...(Object.keys(missingKinds).length > 0 ? { missingKinds } : {}),\n }\n const p = pageBaselinePath(r)\n fs.writeFileSync(p, JSON.stringify(baseline, null, 2) + \"\\n\")\n const kindGaps = Object.values(missingKinds).reduce(\n (n, ks) => n + ks.length,\n 0\n )\n w.out(\n `Wrote ${p} — ${baseline.uncapturedPages.length} uncaptured page(s), ${kindGaps} missing core-kind(s) baselined`\n )\n }\n return w.result(0)\n }\n\n const allDiagnostics = results.flatMap((r) => r.audit?.diagnostics ?? [])\n const summary = results.reduce(\n (acc, r) => {\n acc.errors += r.audit?.summary.errors ?? 0\n acc.warnings += r.audit?.summary.warnings ?? 0\n return acc\n },\n { errors: 0, warnings: 0 }\n )\n\n if (asJson) {\n const out = {\n diagnostics: allDiagnostics.map(jsonDiagnostic),\n summary,\n ...(fix ? { fixed, fixSkipped } : {}),\n }\n w.out(JSON.stringify(out, null, 2))\n } else {\n for (const f of fixed) {\n w.out(`FIXED [${f.code}] ${f.file ?? \"\"} ${f.description}`)\n }\n for (const s of fixSkipped) {\n w.out(\n `SKIPPED [${s.code}] ${s.file ?? \"\"} ${s.description} (${s.reason})`\n )\n }\n for (const r of results) {\n for (const art of [r.types, r.data, r.locs]) {\n if (check) {\n w.out(`Checked ${art.outputPath}`)\n } else if (wrote.has(art)) {\n w.out(`Wrote ${art.outputPath}`)\n } else {\n w.out(`Unchanged ${art.outputPath}`)\n }\n }\n for (const d of r.audit?.diagnostics ?? []) {\n const loc = d.file ? `${d.file}${d.line ? `:${d.line}` : \"\"}` : \"\"\n const stream = d.severity === \"error\" ? w.err : w.out\n const fixable = d.fix && !fix ? \" [fixable: run with --fix]\" : \"\"\n stream(\n `${d.severity.toUpperCase()} [${d.code}] ${loc} ${d.message}${fixable}`\n )\n if (d.hint) stream(` hint: ${d.hint}`)\n }\n }\n if (check || lint) {\n w.out(`${summary.errors} error(s), ${summary.warnings} warning(s)`)\n }\n }\n\n const exit = summary.errors > 0 ? 1 : 0\n return w.result(exit)\n}\n\n/** Diagnostics serialized for --json: `fix` (absolute paths) → `fixable`. */\nfunction jsonDiagnostic(d: Diagnostic): Omit<Diagnostic, \"fix\"> & {\n fixable?: boolean\n} {\n const { fix, ...rest } = d\n return fix ? { ...rest, fixable: true } : rest\n}\n\nconst SCAFFOLD_KINDS = new Set<string>([\"widget\", \"page\", \"feature\"])\n\nfunction runScaffold(\n cwd: string,\n args: string[],\n flags: Flags,\n w: ReturnType<typeof createWriter>\n): CliResult {\n const [kind, id] = args\n if (!kind || !SCAFFOLD_KINDS.has(kind) || !id) {\n w.err(\"Usage: uidex scaffold <widget|page|feature> <id> [--force]\")\n return w.result(1)\n }\n const scaffoldKind = kind as ScaffoldKind\n\n const results = runScan({ cwd })\n for (const r of results) {\n const entity = r.registry.get(scaffoldKind, id)\n if (!entity) continue\n const outDir = path.resolve(r.configDir, \"e2e\")\n const result = scaffoldSpec({\n registry: r.registry,\n kind: scaffoldKind,\n id,\n outDir,\n force: Boolean(flags.force),\n })\n if (result.skipped) {\n w.err(result.reason ?? \"skipped\")\n return w.result(1)\n }\n w.out(`Wrote ${result.outputPath}`)\n return w.result(0)\n }\n\n w.err(\n `${scaffoldKind.charAt(0).toUpperCase() + scaffoldKind.slice(1)} \"${id}\" not found in registry`\n )\n return w.result(1)\n}\n\nconst RENAME_KINDS = new Set<string>([\"element\", \"widget\", \"region\"])\n\nfunction runRename(\n cwd: string,\n args: string[],\n flags: Flags,\n w: ReturnType<typeof createWriter>\n): CliResult {\n const [kind, oldId, newId] = args\n if (!kind || !RENAME_KINDS.has(kind) || !oldId || !newId) {\n w.err(\n \"Usage: uidex rename <element|widget|region> <old-id> <new-id> [--force]\"\n )\n return w.result(1)\n }\n\n const result = renameEntity({\n cwd,\n kind: kind as RenameKind,\n oldId,\n newId,\n force: Boolean(flags.force),\n })\n\n for (const e of result.errors) w.err(e)\n for (const m of result.manual) {\n w.err(`MANUAL ${m.file}:${m.line} — ${m.reason}`)\n }\n if (result.errors.length > 0) return w.result(1)\n\n w.out(\n `Renamed ${kind} \"${oldId}\" → \"${newId}\" (${result.edits} edit(s)); gen file regenerated`\n )\n if (result.manual.length > 0) {\n w.err(\n `${result.manual.length} occurrence(s) need manual follow-up (listed above)`\n )\n return w.result(1)\n }\n return w.result(0)\n}\n\nfunction createWriter() {\n let stdout = \"\"\n let stderr = \"\"\n return {\n out(msg: string) {\n stdout += msg + \"\\n\"\n },\n err(msg: string) {\n stderr += msg + \"\\n\"\n },\n result(exitCode: number): CliResult {\n return { exitCode, stdout, stderr }\n },\n }\n}\n","import * as p from \"@clack/prompts\"\nimport { PROVIDERS, getProvider } from \"./providers\"\nimport type { AiProvider, FileChange, InstallResult } from \"./types\"\n\nexport interface AiCommandOptions {\n cwd: string\n argv: string[]\n /**\n * Optional non-interactive mode. When set, prompts are skipped and the\n * provider id must come from `--provider` (or be the only registered one).\n */\n nonInteractive?: boolean\n /** Hooks for tests / programmatic use. Replaces clack prompts. */\n prompt?: {\n selectProvider?: (providers: AiProvider[]) => Promise<string | null>\n }\n}\n\nexport interface AiCommandResult {\n exitCode: number\n stdout: string\n stderr: string\n}\n\nexport async function runAiCommand(\n opts: AiCommandOptions\n): Promise<AiCommandResult> {\n const { cwd, argv } = opts\n const sub = argv[0]\n\n if (!sub || sub === \"--help\" || sub === \"-h\" || sub === \"help\") {\n return out(0, helpText())\n }\n\n if (sub === \"providers\") {\n return out(\n 0,\n PROVIDERS.map((pr) => ` ${pr.id.padEnd(10)} ${pr.label}`).join(\"\\n\") +\n \"\\n\"\n )\n }\n\n if (sub !== \"install\" && sub !== \"uninstall\") {\n return err(1, `Unknown ai subcommand: ${sub}\\n\\n${helpText()}`)\n }\n\n const flags = parseFlags(argv.slice(1))\n const provider = await selectProvider(opts, flags.provider)\n if (!provider) return out(0, \"Cancelled.\\n\")\n\n if (sub === \"install\") {\n const result = await provider.install({\n cwd,\n force: flags.force === true,\n })\n return out(0, formatChanges(provider, \"Installed\", result))\n }\n\n // uninstall\n const result = await provider.uninstall({ cwd })\n return out(0, formatChanges(provider, \"Uninstalled\", result))\n}\n\nasync function selectProvider(\n opts: AiCommandOptions,\n explicit: string | undefined\n): Promise<AiProvider | null> {\n if (explicit) {\n const found = getProvider(explicit)\n if (!found) {\n throw new Error(\n `Unknown provider: ${explicit}. Run 'uidex ai providers' to list.`\n )\n }\n return found\n }\n\n if (PROVIDERS.length === 1) return PROVIDERS[0]\n\n if (opts.nonInteractive) {\n throw new Error(\n \"Multiple providers available; pass --provider <id> in non-interactive mode.\"\n )\n }\n\n if (opts.prompt?.selectProvider) {\n const id = await opts.prompt.selectProvider(PROVIDERS)\n return id ? (getProvider(id) ?? null) : null\n }\n\n const choice = await p.select({\n message: \"Which AI assistant?\",\n options: PROVIDERS.map((pr) => ({\n value: pr.id,\n label: pr.label,\n hint: pr.description,\n })),\n })\n if (p.isCancel(choice)) return null\n return getProvider(choice as string) ?? null\n}\n\ninterface Flags {\n provider?: string\n force?: boolean\n}\n\nfunction parseFlags(args: string[]): Flags {\n const flags: Flags = {}\n for (let i = 0; i < args.length; i++) {\n const a = args[i]\n if (a === \"--force\") flags.force = true\n else if (a === \"--provider\" || a === \"-p\") flags.provider = args[++i]\n else if (a.startsWith(\"--provider=\")) flags.provider = a.slice(11)\n }\n return flags\n}\n\nfunction formatChanges(\n provider: AiProvider,\n verb: string,\n result: InstallResult\n): string {\n const lines: string[] = [`${verb} ${provider.label}:`]\n for (const c of result.changes) lines.push(` ${describe(c)}`)\n return lines.join(\"\\n\") + \"\\n\"\n}\n\nfunction describe(c: FileChange): string {\n switch (c.action) {\n case \"created\":\n return `+ ${c.path}`\n case \"overwritten\":\n return `~ ${c.path}`\n case \"removed\":\n return `- ${c.path}`\n case \"skipped\":\n return `· ${c.path}${c.reason ? ` (${c.reason})` : \"\"}`\n }\n}\n\nfunction helpText(): string {\n return [\n \"uidex ai — install AI assistant integrations\",\n \"\",\n \"Subcommands:\",\n \" install Install an AI integration into the current repo\",\n \" uninstall Remove an AI integration from the current repo\",\n \" providers List available providers\",\n \"\",\n \"Flags:\",\n \" --provider <id>, -p Skip the prompt and pick a provider by id\",\n \" --force (install) overwrite existing files\",\n \"\",\n ].join(\"\\n\")\n}\n\nfunction out(exitCode: number, stdout: string): AiCommandResult {\n return { exitCode, stdout, stderr: \"\" }\n}\n\nfunction err(exitCode: number, stderr: string): AiCommandResult {\n return { exitCode, stdout: \"\", stderr }\n}\n","import * as fs from \"node:fs\"\nimport * as path from \"node:path\"\nimport { readTemplate } from \"../templates\"\nimport type {\n AiProvider,\n FileChange,\n InstallOptions,\n InstallResult,\n UninstallOptions,\n UninstallResult,\n} from \"../types\"\n\nconst SKILL_FILES: { dest: string; template: string }[] = [\n { dest: \".claude/skills/uidex/SKILL.md\", template: \"claude/SKILL.md\" },\n {\n dest: \".claude/skills/uidex/references/conventions.md\",\n template: \"claude/references/conventions.md\",\n },\n {\n dest: \".claude/skills/uidex/references/audit.md\",\n template: \"claude/references/audit.md\",\n },\n {\n dest: \".claude/skills/uidex/references/api.md\",\n template: \"claude/references/api.md\",\n },\n]\n\nconst LEGACY_FILES = [\n \".claude/rules/uidex.md\",\n \".claude/commands/uidex/audit.md\",\n \".claude/commands/uidex/api.md\",\n]\n\nexport const claudeProvider: AiProvider = {\n id: \"claude\",\n label: \"Claude Code\",\n description:\n \"Adds .claude/skills/uidex/ skill with conventions, audit, and API references.\",\n\n async install({ cwd, force }: InstallOptions): Promise<InstallResult> {\n const changes: FileChange[] = []\n\n for (const file of SKILL_FILES) {\n const dest = path.join(cwd, file.dest)\n const exists = fs.existsSync(dest)\n\n if (exists && !force) {\n changes.push({\n path: file.dest,\n action: \"skipped\",\n reason: \"exists (use --force to overwrite)\",\n })\n continue\n }\n\n fs.mkdirSync(path.dirname(dest), { recursive: true })\n fs.writeFileSync(dest, readTemplate(file.template))\n changes.push({\n path: file.dest,\n action: exists ? \"overwritten\" : \"created\",\n })\n }\n\n for (const rel of LEGACY_FILES) {\n const dest = path.join(cwd, rel)\n if (fs.existsSync(dest)) {\n fs.unlinkSync(dest)\n changes.push({ path: rel, action: \"removed\" })\n }\n }\n cleanupEmpty(path.join(cwd, \".claude/commands/uidex\"))\n cleanupEmpty(path.join(cwd, \".claude/commands\"))\n cleanupEmpty(path.join(cwd, \".claude/rules\"))\n\n return { changes }\n },\n\n async uninstall({ cwd }: UninstallOptions): Promise<UninstallResult> {\n const changes: FileChange[] = []\n\n for (const file of SKILL_FILES) {\n const dest = path.join(cwd, file.dest)\n if (!fs.existsSync(dest)) {\n changes.push({ path: file.dest, action: \"skipped\", reason: \"absent\" })\n continue\n }\n fs.unlinkSync(dest)\n changes.push({ path: file.dest, action: \"removed\" })\n }\n\n cleanupEmpty(path.join(cwd, \".claude/skills/uidex/references\"))\n cleanupEmpty(path.join(cwd, \".claude/skills/uidex\"))\n cleanupEmpty(path.join(cwd, \".claude/skills\"))\n\n for (const rel of LEGACY_FILES) {\n const dest = path.join(cwd, rel)\n if (fs.existsSync(dest)) {\n fs.unlinkSync(dest)\n changes.push({ path: rel, action: \"removed\" })\n }\n }\n cleanupEmpty(path.join(cwd, \".claude/commands/uidex\"))\n cleanupEmpty(path.join(cwd, \".claude/commands\"))\n cleanupEmpty(path.join(cwd, \".claude/rules\"))\n\n return { changes }\n },\n}\n\nfunction cleanupEmpty(dir: string): void {\n try {\n const entries = fs.readdirSync(dir)\n if (entries.length === 0) fs.rmdirSync(dir)\n } catch {\n /* directory missing or non-empty — ignore */\n }\n}\n","import * as fs from \"node:fs\"\nimport * as path from \"node:path\"\n\n/**\n * Resolves a path inside the package's templates/ directory.\n *\n * In production the bin runs from `dist/cli/cli.cjs`, so templates live\n * at `../../templates/<rel>`. In tests we run via tsx from\n * `src/scan/ai/`, which resolves through `../../../templates`.\n */\nexport function templatePath(rel: string): string {\n const candidates = [\n path.resolve(__dirname, \"../../templates\", rel), // dist/cli/cli.cjs → ../../templates\n path.resolve(__dirname, \"../../../../templates\", rel), // src/scanner/scan/ai → ../../../../templates\n ]\n for (const c of candidates) {\n try {\n fs.accessSync(c, fs.constants.R_OK)\n return c\n } catch {\n continue\n }\n }\n throw new Error(\n `uidex: template not found: ${rel}. Looked in:\\n ${candidates.join(\"\\n \")}`\n )\n}\n\nexport function readTemplate(rel: string): string {\n return fs.readFileSync(templatePath(rel), \"utf8\")\n}\n","import type { AiProvider } from \"../types\"\nimport { claudeProvider } from \"./claude\"\n\nexport const PROVIDERS: AiProvider[] = [claudeProvider]\n\nexport function getProvider(id: string): AiProvider | undefined {\n return PROVIDERS.find((p) => p.id === id)\n}\n","export function parseArgs(args: string[]): {\n positional: string[]\n flags: Record<string, string | boolean>\n} {\n const positional: string[] = []\n const flags: Record<string, string | boolean> = {}\n for (let i = 0; i < args.length; i++) {\n const a = args[i]\n if (a.startsWith(\"--\")) {\n const eq = a.indexOf(\"=\")\n if (eq !== -1) {\n flags[a.slice(2, eq)] = a.slice(eq + 1)\n } else {\n const next = args[i + 1]\n if (next && !next.startsWith(\"--\")) {\n flags[a.slice(2)] = next\n i++\n } else {\n flags[a.slice(2)] = true\n }\n }\n } else {\n positional.push(a)\n }\n }\n return { positional, flags }\n}\n"],"mappings":"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","names":["path","fs","path","out","p","path","CORE_STATE_KINDS","p","isNode","out","isNode","out","path","out","resolve","p","path","path","r","STATE_KINDS","out","ent","out","summary","p","baseName","check","out","out","fs","path","fs","path","p","resolve","fs","path","fs","path","fs","path","fs","path","p","result","helpText","p","out"]}
1
+ {"version":3,"sources":["../../src/scanner/scan/discover.ts","../../src/scanner/scan/config.ts","../../src/scanner/scan/walk.ts","../../src/scanner/scan/ast.ts","../../src/shared/entities/types.ts","../../src/shared/entities/registry.ts","../../src/scanner/scan/acknowledge.ts","../../src/scanner/scan/extract-uidex-export.ts","../../src/scanner/scan/flow-facts.ts","../../src/scanner/scan/jsx-ancestry.ts","../../src/scanner/scan/extract.ts","../../src/scanner/scan/resolve.ts","../../src/scanner/scan/routes.ts","../../src/scanner/scan/audit.ts","../../src/scanner/scan/component-coverage.ts","../../src/scanner/scan/migrate-acknowledge.ts","../../src/scanner/scan/page-coverage.ts","../../src/scanner/scan/workspace.ts","../../src/scanner/scan/state-coverage.ts","../../src/scanner/scan/state-matrix.ts","../../src/scanner/scan/emit.ts","../../src/scanner/scan/git.ts","../../src/scanner/scan/scaffold.ts","../../src/scanner/scan/pipeline.ts","../../src/scanner/scan/states-merge.ts","../../src/scanner/scan/fix.ts","../../src/scanner/scan/rename.ts","../../src/scanner/scan/cli.ts","../../src/scanner/scan/ai/index.ts","../../src/scanner/scan/ai/providers/claude.ts","../../src/scanner/scan/ai/templates.ts","../../src/scanner/scan/ai/providers/index.ts","../../src/scanner/cli/parse-args.ts"],"sourcesContent":["import * as fs from \"node:fs\"\nimport * as path from \"node:path\"\nimport { parseConfig } from \"./config\"\nimport type { DiscoveredConfig } from \"./types\"\n\nexport const CONFIG_FILENAME = \".uidex.json\"\n\nconst SKIP_DIRS = new Set([\n \"node_modules\",\n \".git\",\n \"dist\",\n \"build\",\n \".next\",\n \".turbo\",\n \".cache\",\n \"coverage\",\n])\n\nconst MAX_DEPTH = 4\n\nexport interface DiscoverOptions {\n cwd?: string\n maxDepth?: number\n /**\n * Keep descending past a config found at `cwd` itself, so the result is EVERY\n * config in the tree rather than the innermost one. The workspace level needs\n * the whole set; a plain `uidex scan` wants the nearest, which is why that\n * stays the default.\n */\n all?: boolean\n}\n\nfunction tryReadConfig(configPath: string): DiscoveredConfig | null {\n let source: string\n try {\n source = fs.readFileSync(configPath, \"utf8\")\n } catch {\n return null\n }\n return {\n configPath,\n configDir: path.dirname(configPath),\n config: parseConfig(source),\n }\n}\n\nexport function discover(options: DiscoverOptions = {}): DiscoveredConfig[] {\n const cwd = options.cwd ?? process.cwd()\n const maxDepth = options.maxDepth ?? MAX_DEPTH\n\n const all = options.all ?? false\n\n const rootMatch = tryReadConfig(path.join(cwd, CONFIG_FILENAME))\n if (rootMatch && !all) return [rootMatch]\n\n const results: DiscoveredConfig[] = []\n if (rootMatch) results.push(rootMatch)\n const queue: Array<[string, number]> = [[cwd, 0]]\n\n while (queue.length > 0) {\n const [dir, depth] = queue.shift()!\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n continue\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n if (SKIP_DIRS.has(entry.name)) continue\n if (entry.name.startsWith(\".\")) continue\n\n const childDir = path.join(dir, entry.name)\n const candidate = tryReadConfig(path.join(childDir, CONFIG_FILENAME))\n\n if (candidate) {\n results.push(candidate)\n continue\n }\n\n if (depth + 1 < maxDepth) {\n queue.push([childDir, depth + 1])\n }\n }\n }\n\n return results.sort((a, b) => a.configPath.localeCompare(b.configPath))\n}\n","import type { UidexConfig } from \"./types\"\n\nexport const WELL_KNOWN_FILES = {\n page: \"uidex.page.ts\",\n feature: \"uidex.feature.ts\",\n} as const satisfies Record<\"page\" | \"feature\", string>\n\nexport class ConfigError extends Error {\n constructor(message: string) {\n super(message)\n this.name = \"ConfigError\"\n }\n}\n\nconst LEGACY_KEYS = new Set([\n \"scanner\",\n \"defaults\",\n \"colors\",\n \"components\",\n \"triggerElement\",\n \"devtools\",\n])\n\nconst ALLOWED_TOP_LEVEL_KEYS = new Set([\n \"$schema\",\n \"sources\",\n \"exclude\",\n \"output\",\n \"flows\",\n \"audit\",\n \"conventions\",\n \"statesManifest\",\n \"coverageBaseline\",\n \"workspace\",\n])\n\nconst ALLOWED_SOURCE_KEYS = new Set([\"rootDir\", \"include\", \"exclude\", \"prefix\"])\n\nconst ALLOWED_CONVENTIONS_KEYS = new Set([\n \"primitives\",\n \"features\",\n \"pages\",\n \"flows\",\n \"regions\",\n])\n\nconst ALLOWED_AUDIT_KEYS = new Set([\n \"scopeLeak\",\n \"coverage\",\n \"acceptance\",\n \"states\",\n \"pageCoverage\",\n \"stateMatrix\",\n \"severity\",\n])\n\n/**\n * Every diagnostic code the scanner can emit — the allow-list `audit.severity`\n * validates against, so a typo'd key fails loudly instead of silently leaving\n * the gate it was meant to govern at its default severity.\n *\n * Keep in sync when adding a diagnostic; `severity-codes.test.ts` asserts this\n * set matches the codes actually emitted by the source.\n */\nexport const DIAGNOSTIC_CODES = [\n \"acceptance-uncovered\",\n \"acknowledged-elsewhere\",\n \"competing-uidex-export\",\n \"component-state-uncaptured\",\n \"core-kind\",\n \"duplicate-id\",\n \"dynamic-attr\",\n \"dynamic-flow-reference\",\n \"gen-missing\",\n \"gen-stale\",\n \"legacy-acknowledge-field\",\n \"legacy-coverage-baseline\",\n \"matrix-backlog\",\n \"missing-element-annotation\",\n \"missing-state-capture\",\n \"orphan-state-capture\",\n \"page-backlog\",\n \"page-captured\",\n \"page-no-capture\",\n \"parse-error\",\n \"placeholder-reason\",\n \"prefer-well-known-file\",\n \"rename\",\n \"scope-leak\",\n \"spread-attr\",\n \"stale-acknowledgment\",\n \"stale-page-baseline\",\n \"uidex-export-ambiguous-kind\",\n \"uidex-export-duplicate-field\",\n \"uidex-export-duplicate-state\",\n \"uidex-export-empty-name\",\n \"uidex-export-invalid-field\",\n \"uidex-export-invalid-literal\",\n \"uidex-export-missing-kind\",\n \"uidex-export-satisfies-mismatch\",\n \"uidex-export-unknown-field\",\n \"unknown-reference\",\n \"widget-id-mismatch\",\n \"widget-missing-acceptance\",\n \"widget-missing-dom\",\n] as const\n\nconst DIAGNOSTIC_CODE_SET: ReadonlySet<string> = new Set(DIAGNOSTIC_CODES)\nconst SEVERITY_LEVELS = new Set([\"error\", \"warning\", \"info\", \"off\"])\n\nfunction fail(msg: string): never {\n throw new ConfigError(`Invalid .uidex.json: ${msg}`)\n}\n\nfunction assertObject(\n value: unknown,\n path: string\n): asserts value is Record<string, unknown> {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n fail(`${path} must be an object`)\n }\n}\n\nfunction assertStringArray(\n value: unknown,\n path: string\n): asserts value is string[] {\n if (!Array.isArray(value) || !value.every((v) => typeof v === \"string\")) {\n fail(`${path} must be a string[]`)\n }\n}\n\nexport function validateConfig(raw: unknown): UidexConfig {\n assertObject(raw, \"root\")\n\n for (const key of Object.keys(raw)) {\n if (LEGACY_KEYS.has(key)) {\n fail(\n `legacy nested key \"${key}\" is not supported; v2 uses a flat schema (sources[], output, flows, audit, conventions)`\n )\n }\n if (!ALLOWED_TOP_LEVEL_KEYS.has(key)) {\n fail(`unknown top-level key \"${key}\"`)\n }\n }\n\n if (!(\"sources\" in raw)) {\n fail(\n `required key \"sources\" is missing (must be an array with at least one entry)`\n )\n }\n\n const sources = raw.sources\n if (!Array.isArray(sources) || sources.length === 0) {\n fail(`\"sources\" must be a non-empty array`)\n }\n\n const validatedSources = sources.map((src, i) => {\n assertObject(src, `sources[${i}]`)\n for (const key of Object.keys(src)) {\n if (!ALLOWED_SOURCE_KEYS.has(key)) {\n fail(`unknown key \"${key}\" in sources[${i}]`)\n }\n }\n if (typeof src.rootDir !== \"string\" || src.rootDir.length === 0) {\n fail(`sources[${i}].rootDir must be a non-empty string`)\n }\n if (src.include !== undefined)\n assertStringArray(src.include, `sources[${i}].include`)\n if (src.exclude !== undefined)\n assertStringArray(src.exclude, `sources[${i}].exclude`)\n if (src.prefix !== undefined && typeof src.prefix !== \"string\") {\n fail(`sources[${i}].prefix must be a string`)\n }\n return src as unknown as UidexConfig[\"sources\"][number]\n })\n\n if (typeof raw.output !== \"string\" || raw.output.length === 0) {\n fail(`\"output\" must be a non-empty string`)\n }\n\n if (raw.exclude !== undefined) assertStringArray(raw.exclude, `exclude`)\n if (raw.flows !== undefined) assertStringArray(raw.flows, `flows`)\n\n if (\n raw.statesManifest !== undefined &&\n typeof raw.statesManifest !== \"string\"\n ) {\n fail(`\"statesManifest\" must be a string`)\n }\n if (\n raw.coverageBaseline !== undefined &&\n typeof raw.coverageBaseline !== \"string\"\n ) {\n fail(`\"coverageBaseline\" must be a string`)\n }\n if (\n raw.workspace !== undefined &&\n raw.workspace !== false &&\n typeof raw.workspace !== \"string\"\n ) {\n fail(`\"workspace\" must be a path string or false`)\n }\n\n if (raw.audit !== undefined) {\n assertObject(raw.audit, \"audit\")\n for (const key of Object.keys(raw.audit)) {\n if (!ALLOWED_AUDIT_KEYS.has(key)) fail(`unknown key \"${key}\" in audit`)\n const v = (raw.audit as Record<string, unknown>)[key]\n // `severity` is the one non-boolean audit key: a code → level map.\n if (key === \"severity\") {\n assertObject(v, \"audit.severity\")\n for (const [code, level] of Object.entries(v)) {\n if (!DIAGNOSTIC_CODE_SET.has(code)) {\n fail(\n `unknown diagnostic code \"${code}\" in audit.severity (a typo here would silently leave that gate at its default severity)`\n )\n }\n if (typeof level !== \"string\" || !SEVERITY_LEVELS.has(level)) {\n fail(\n `audit.severity[\"${code}\"] must be one of \"error\", \"warning\", \"info\", \"off\"`\n )\n }\n }\n continue\n }\n if (typeof v !== \"boolean\") fail(`audit.${key} must be a boolean`)\n }\n }\n\n if (raw.conventions !== undefined) {\n assertObject(raw.conventions, \"conventions\")\n const c = raw.conventions as Record<string, unknown>\n for (const key of Object.keys(c)) {\n if (!ALLOWED_CONVENTIONS_KEYS.has(key)) {\n fail(`unknown key \"${key}\" in conventions`)\n }\n }\n if (c.primitives !== undefined && c.primitives !== false) {\n assertStringArray(c.primitives, \"conventions.primitives\")\n }\n if (\n c.features !== undefined &&\n c.features !== false &&\n typeof c.features !== \"string\"\n ) {\n fail(`conventions.features must be a string or false`)\n }\n if (c.pages !== undefined && c.pages !== false && c.pages !== \"auto\") {\n const p = c.pages\n const routesDir =\n typeof p === \"object\" && p !== null && !Array.isArray(p)\n ? (p as Record<string, unknown>).routesDir\n : undefined\n if (\n typeof p !== \"object\" ||\n p === null ||\n Array.isArray(p) ||\n Object.keys(p as object).some((k) => k !== \"routesDir\") ||\n typeof routesDir !== \"string\" ||\n routesDir.length === 0\n ) {\n fail(\n `conventions.pages must be \"auto\", false, or { routesDir: string }`\n )\n }\n }\n if (c.flows !== undefined && c.flows !== false) {\n assertStringArray(c.flows, \"conventions.flows\")\n }\n if (\n c.regions !== undefined &&\n c.regions !== false &&\n c.regions !== \"landmarks\"\n ) {\n fail(`conventions.regions must be \"landmarks\" or false`)\n }\n }\n\n return {\n $schema: typeof raw.$schema === \"string\" ? raw.$schema : undefined,\n sources: validatedSources,\n exclude: raw.exclude as string[] | undefined,\n output: raw.output,\n flows: raw.flows as string[] | undefined,\n audit: raw.audit as UidexConfig[\"audit\"],\n conventions: raw.conventions as UidexConfig[\"conventions\"],\n statesManifest: raw.statesManifest as string | undefined,\n coverageBaseline: raw.coverageBaseline as string | undefined,\n workspace: raw.workspace as string | false | undefined,\n }\n}\n\nexport function parseConfig(json: string): UidexConfig {\n let raw: unknown\n try {\n raw = JSON.parse(json)\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e)\n throw new ConfigError(`Invalid .uidex.json: JSON parse error: ${msg}`)\n }\n return validateConfig(raw)\n}\n\nexport const DEFAULT_CONVENTIONS: Required<\n Pick<\n NonNullable<UidexConfig[\"conventions\"]>,\n \"primitives\" | \"features\" | \"pages\" | \"flows\" | \"regions\"\n >\n> = {\n primitives: [\"src/ui/**\", \"src/components/ui/**\"],\n features: \"src/features/*\",\n pages: \"auto\",\n flows: [\"e2e/**/*.spec.ts\"],\n regions: \"landmarks\",\n}\n","import * as fs from \"node:fs\"\nimport * as path from \"node:path\"\nimport type { ScannedFile, SourceConfig } from \"./types\"\n\nconst DEFAULT_INCLUDES = [\"**/*.{ts,tsx,js,jsx,mjs,cjs}\"]\nconst BASE_EXCLUDES = [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/.next/**\",\n // Exclude the scanner's own generated siblings so a scan never re-ingests its\n // output. Enumerated (not `*.gen.*`) so a hand-written file that merely contains\n // a `.gen.` segment, e.g. `foo.gen.helpers.ts`, is still scanned.\n \"**/*.gen.ts\",\n \"**/*.gen.data.ts\",\n \"**/*.gen.locs.ts\",\n]\nconst TEST_EXCLUDES = [\n \"**/*.test.ts\",\n \"**/*.test.tsx\",\n \"**/*.spec.ts\",\n \"**/*.spec.tsx\",\n]\nconst DEFAULT_EXCLUDES = [...BASE_EXCLUDES, ...TEST_EXCLUDES]\n\n/**\n * Translate a glob to a RegExp. Supports `**`, `*`, `?`, and `{a,b,c}` alternation.\n * The produced pattern matches the full relative path with forward slashes.\n */\nexport function globToRegExp(glob: string): RegExp {\n let i = 0\n let out = \"\"\n while (i < glob.length) {\n const c = glob[i]\n if (c === \"*\" && glob[i + 1] === \"*\") {\n // `**/` → matches zero or more path segments\n if (glob[i + 2] === \"/\") {\n out += \"(?:.*/)?\"\n i += 3\n continue\n }\n out += \".*\"\n i += 2\n continue\n }\n if (c === \"*\") {\n out += \"[^/]*\"\n i++\n continue\n }\n if (c === \"?\") {\n out += \"[^/]\"\n i++\n continue\n }\n if (c === \"{\") {\n const end = glob.indexOf(\"}\", i)\n if (end === -1) {\n out += \"\\\\{\"\n i++\n continue\n }\n const parts = glob\n .slice(i + 1, end)\n .split(\",\")\n .map((p) => p.replace(/[.+^$()|\\\\]/g, \"\\\\$&\"))\n out += `(?:${parts.join(\"|\")})`\n i = end + 1\n continue\n }\n if (/[.+^$()|\\\\]/.test(c)) {\n out += \"\\\\\" + c\n i++\n continue\n }\n out += c\n i++\n }\n return new RegExp(`^${out}$`)\n}\n\nfunction toPosix(p: string): string {\n return p.split(path.sep).join(\"/\")\n}\n\nfunction matchesAny(rel: string, patterns: string[]): boolean {\n return patterns.some((g) => globToRegExp(g).test(rel))\n}\n\nexport interface WalkOptions {\n cwd: string\n globalExcludes?: string[]\n /**\n * When true, do not auto-exclude `*.spec.{ts,tsx}` and `*.test.{ts,tsx}`.\n * Used by flow-file walking, where spec files are the targets.\n */\n includeTests?: boolean\n}\n\n/**\n * A predicate answering \"would `walk` have picked this absolute file up?\" —\n * the same rootDir / include / exclude rules, without touching the filesystem.\n *\n * The workspace level needs this to decide whether a SIBLING app registers a\n * given declaration: an entity file that sits inside another app's configured\n * sources is registered by that app too, so a capture of it over there covers\n * this very declaration. Sharing the matcher with `walk` is what makes that an\n * exact answer rather than a second, drifting approximation of the same rules.\n */\nexport function createSourceMatcher(\n sources: SourceConfig[],\n options: WalkOptions\n): (absFile: string) => boolean {\n const { cwd, globalExcludes = [], includeTests = false } = options\n const baseDefaults = includeTests ? BASE_EXCLUDES : DEFAULT_EXCLUDES\n const compiled = sources.map((source) => ({\n absRoot: path.resolve(cwd, source.rootDir),\n includes: source.include?.length ? source.include : DEFAULT_INCLUDES,\n excludes: [...baseDefaults, ...globalExcludes, ...(source.exclude ?? [])],\n }))\n\n return (absFile: string): boolean => {\n const abs = path.resolve(absFile)\n return compiled.some(({ absRoot, includes, excludes }) => {\n const rel = toPosix(path.relative(absRoot, abs))\n // Outside the root entirely (`../…`), or the root itself (empty rel).\n if (rel.length === 0 || rel.startsWith(\"../\") || path.isAbsolute(rel)) {\n return false\n }\n if (matchesAny(rel, excludes)) return false\n return matchesAny(rel, includes)\n })\n }\n}\n\nexport function walk(\n sources: SourceConfig[],\n options: WalkOptions\n): ScannedFile[] {\n const { cwd, globalExcludes = [], includeTests = false } = options\n const out: ScannedFile[] = []\n const baseDefaults = includeTests ? BASE_EXCLUDES : DEFAULT_EXCLUDES\n\n for (const source of sources) {\n const includes = source.include?.length ? source.include : DEFAULT_INCLUDES\n const excludes = [\n ...baseDefaults,\n ...globalExcludes,\n ...(source.exclude ?? []),\n ]\n const absRoot = path.resolve(cwd, source.rootDir)\n\n for (const filePath of walkDir(absRoot, absRoot)) {\n const rel = toPosix(path.relative(absRoot, filePath))\n if (matchesAny(rel, excludes)) continue\n if (!matchesAny(rel, includes)) continue\n\n let content: string\n try {\n content = fs.readFileSync(filePath, \"utf8\")\n } catch {\n continue\n }\n\n const relFromCwd = toPosix(path.relative(cwd, filePath))\n const displayPath = source.prefix\n ? `${source.prefix.replace(/\\/$/, \"\")}/${rel}`\n : relFromCwd\n\n out.push({\n sourcePath: filePath,\n relativePath: rel,\n displayPath,\n content,\n })\n }\n }\n\n return out.sort((a, b) => a.displayPath.localeCompare(b.displayPath))\n}\n\nfunction* walkDir(root: string, dir: string): Generator<string> {\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n return\n }\n for (const entry of entries) {\n const full = path.join(dir, entry.name)\n if (entry.isDirectory()) {\n if (\n entry.name === \"node_modules\" ||\n entry.name === \"dist\" ||\n entry.name === \".git\" ||\n entry.name === \"build\" ||\n entry.name === \".next\"\n ) {\n continue\n }\n yield* walkDir(root, full)\n } else if (entry.isFile()) {\n yield full\n }\n }\n}\n","import * as path from \"node:path\"\nimport { parseSync } from \"oxc-parser\"\nimport type { Program } from \"oxc-parser\"\nimport type { ScannedFile } from \"./types\"\n\n/**\n * Shared parse layer for the scanner. Each file is parsed exactly once in\n * the extract phase; the resulting AST never leaves it (ExtractedFile must\n * stay JSON-serializable for the bundler-plugin watchers).\n *\n * oxc spans are UTF-16 code-unit offsets, i.e. they index directly into the\n * JS source string (verified against oxc-parser@0.135.0).\n */\nexport interface ParsedComment {\n type: \"Line\" | \"Block\"\n value: string\n start: number\n end: number\n}\n\nexport interface ParsedSource {\n /** null when parsing failed catastrophically — callers degrade to empty facts */\n program: Program | null\n /** true when oxc reported recoverable errors (program is still usable) */\n hasErrors: boolean\n /** all comments in source order; empty when parsing failed */\n comments: ParsedComment[]\n /** offset → 1-based line */\n lineAt(offset: number): number\n}\n\ntype Lang = \"js\" | \"jsx\" | \"ts\" | \"tsx\"\n\nfunction langFor(sourcePath: string): Lang {\n switch (path.extname(sourcePath)) {\n case \".tsx\":\n return \"tsx\"\n case \".ts\":\n case \".mts\":\n case \".cts\":\n return \"ts\"\n default:\n // .js/.jsx/.mjs/.cjs — JSX-in-.js is common in React repos, and jsx\n // is a superset of what the scanner needs from plain js.\n return \"jsx\"\n }\n}\n\nfunction makeLineAt(content: string): (offset: number) => number {\n // Offsets of each line start; binary-searched per lookup.\n const starts = [0]\n for (let i = 0; i < content.length; i++) {\n if (content[i] === \"\\n\") starts.push(i + 1)\n }\n return (offset) => {\n let lo = 0\n let hi = starts.length - 1\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1\n if (starts[mid] <= offset) lo = mid\n else hi = mid - 1\n }\n return lo + 1\n }\n}\n\nexport function parseSource(file: ScannedFile): ParsedSource {\n const lineAt = makeLineAt(file.content)\n try {\n const result = parseSync(file.sourcePath, file.content, {\n lang: langFor(file.sourcePath),\n sourceType: \"module\",\n })\n return {\n program: result.program,\n hasErrors: result.errors.length > 0,\n comments: (result.comments ?? []) as ParsedComment[],\n lineAt,\n }\n } catch {\n // Same contract as the old state machine: malformed input yields no\n // facts rather than wrong facts.\n return { program: null, hasErrors: true, comments: [], lineAt }\n }\n}\n\nexport interface AstNode {\n type: string\n start: number\n end: number\n [key: string]: unknown\n}\n\nfunction isNode(value: unknown): value is AstNode {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { type?: unknown }).type === \"string\"\n )\n}\n\n/**\n * Depth-first walk over every AST node. `visit` may return `false` to skip\n * the node's children. Hand-rolled (recurse into any object/array value\n * carrying a `type`) so we don't depend on oxc's Visitor API surface.\n */\nexport function walkAst(\n root: unknown,\n visit: (node: AstNode) => boolean | undefined\n): void {\n if (!isNode(root)) return\n if (visit(root) === false) return\n for (const key of Object.keys(root)) {\n if (key === \"type\" || key === \"start\" || key === \"end\") continue\n const value = root[key]\n if (Array.isArray(value)) {\n for (const item of value) walkAst(item, visit)\n } else if (isNode(value)) {\n walkAst(value, visit)\n }\n }\n}\n\n/**\n * Strips TypeScript expression wrappers (`as`, `satisfies`, `!`, parens) so\n * callers see the underlying expression.\n */\nexport function unwrapTsExpression(expr: AstNode): AstNode {\n let node = expr\n for (;;) {\n switch (node.type) {\n case \"TSAsExpression\":\n case \"TSSatisfiesExpression\":\n case \"TSNonNullExpression\":\n case \"TSTypeAssertion\":\n case \"ParenthesizedExpression\": {\n const inner = node.expression\n if (!isNode(inner)) return node\n node = inner\n break\n }\n default:\n return node\n }\n }\n}\n","export const ENTITY_KINDS = [\n \"route\",\n \"page\",\n \"feature\",\n \"widget\",\n \"region\",\n \"element\",\n \"primitive\",\n \"flow\",\n] as const\n\nexport type EntityKind = (typeof ENTITY_KINDS)[number]\n\nexport type Scope = string\n\nexport interface Location {\n file: string\n line?: number\n column?: number\n}\n\nexport interface EntityRef {\n kind: EntityKind\n id: string\n}\n\n/**\n * The four kinds every captured route is expected to render — the state-matrix\n * axis. A capture that only shoots the happy path leaves most of the value on\n * the table, so a missing core kind must be captured or ACKNOWLEDGED (see\n * `Metadata.acknowledge`).\n */\nexport const CORE_STATE_KINDS = [\n \"loading\",\n \"empty\",\n \"populated\",\n \"error\",\n] as const\nexport type CoreStateKind = (typeof CORE_STATE_KINDS)[number]\n/** `variant` is any state outside the matrix (a dialog, wizard step, multi-currency…). */\nexport type StateKind = CoreStateKind | \"variant\"\n\n/**\n * A declared render state of an entity — the \"story\"-like unit: a named\n * condition the page/feature/widget can render in (loading / empty / error /\n * multi-currency / …). Enumerated on the entity (not derived from syntax), it\n * is the contract the visual-states capture must satisfy and the anchor for\n * per-state acceptance criteria. Fixtures + capture mechanics stay in the spec;\n * the registry holds only the name (+ optional kind / per-state acceptance).\n */\nexport interface StateDecl {\n name: string\n /** Canonical kind for the state-matrix axis (defaults to `variant`). */\n kind?: StateKind\n /** Acceptance criteria that only this state can evidence. */\n acceptance?: string[]\n description?: string\n}\n\nexport interface Metadata {\n name?: string\n description?: string\n acceptance?: string[]\n notes?: string\n composes?: EntityRef[]\n flows?: readonly string[]\n features?: string[]\n widgets?: string[]\n /** Declared render states (see StateDecl); the capture-completeness gate. */\n states?: StateDecl[]\n /**\n * The ONE way to say \"don't complain about this gap\": scope → typed reason.\n *\n * - scope `\"*\"` covers the whole entity (a redirect page that can never be\n * captured, a component whose states are not gated here);\n * - a core-kind scope covers that one cell of this page's route matrix.\n *\n * `type: \"impossible\"` is a permanent design statement and needs a `reason`;\n * `type: \"backlog\"` is debt and does not. Keeping both as values of one field\n * is what makes mislabeling debt as impossible a visible, reviewable edit.\n * `captured-elsewhere` is computed by the workspace and never authored here.\n */\n acknowledge?: Partial<Record<AcknowledgeScope, MetaAcknowledgment>>\n}\n\n/** Scope of an acknowledgment: one core kind, or the whole entity. */\nexport type AcknowledgeScope = CoreStateKind | \"*\"\n\nexport interface MetaAcknowledgment {\n type: \"impossible\" | \"backlog\"\n reason?: string\n}\n\ninterface EntityWithMetaBase {\n id: string\n loc?: Location\n scopes?: Scope[]\n meta?: Metadata\n}\n\nexport interface Route {\n kind: \"route\"\n path: string\n page: string\n}\n\nexport interface FlowStep {\n entityId: string\n action?: string\n}\n\nexport interface Flow {\n kind: \"flow\"\n id: string\n loc: Location\n touches: string[]\n steps: FlowStep[]\n}\n\nexport interface Page extends EntityWithMetaBase {\n kind: \"page\"\n}\n\nexport interface Feature extends EntityWithMetaBase {\n kind: \"feature\"\n}\n\nexport interface Widget extends EntityWithMetaBase {\n kind: \"widget\"\n}\n\nexport interface Region extends EntityWithMetaBase {\n kind: \"region\"\n}\n\nexport interface Element extends EntityWithMetaBase {\n kind: \"element\"\n}\n\nexport interface Primitive extends EntityWithMetaBase {\n kind: \"primitive\"\n}\n\nexport type Entity =\n | Route\n | Page\n | Feature\n | Widget\n | Region\n | Element\n | Primitive\n | Flow\n\nexport type EntityByKind<K extends EntityKind> = Extract<Entity, { kind: K }>\n\nexport type MetaEntityKind = Exclude<EntityKind, \"route\" | \"flow\">\n\nexport function isMetaKind(kind: EntityKind): kind is MetaEntityKind {\n return kind !== \"route\" && kind !== \"flow\"\n}\n\nexport function isMetaEntity(\n entity: Entity\n): entity is Extract<Entity, { kind: MetaEntityKind }> {\n return isMetaKind(entity.kind)\n}\n\nexport function entityKey(entity: Entity): string {\n return entity.kind === \"route\" ? entity.path : entity.id\n}\n\nexport function sameRef(a: EntityRef | null, b: EntityRef | null): boolean {\n if (a === b) return true\n if (a === null || b === null) return false\n return a.kind === b.kind && a.id === b.id\n}\n\nexport class UnknownEntityKindError extends Error {\n readonly kind: string\n constructor(kind: string) {\n super(`Unknown entity kind: ${kind}`)\n this.name = \"UnknownEntityKindError\"\n this.kind = kind\n }\n}\n\nconst KIND_SET: ReadonlySet<string> = new Set<string>(ENTITY_KINDS)\n\nexport function assertEntityKind(kind: string): asserts kind is EntityKind {\n if (!KIND_SET.has(kind)) throw new UnknownEntityKindError(kind)\n}\n","import {\n assertEntityKind,\n entityKey,\n isMetaEntity,\n isMetaKind,\n type Entity,\n type EntityByKind,\n type EntityKind,\n type Flow,\n type Metadata,\n type Scope,\n} from \"./types\"\n\nexport interface ReportRecord {\n id: string\n entity?: string\n reporter?: { id?: string; email?: string; name?: string }\n title?: string\n body: string\n type: string\n severity: string\n status: string\n labels?: string[]\n url: string\n route?: string\n pageTitle?: string\n screenshot?: string\n createdAt: string\n}\n\nexport interface Registry {\n add(entity: Entity): void\n get<K extends EntityKind>(kind: K, id: string): EntityByKind<K> | undefined\n matchPattern<K extends EntityKind>(\n kind: K,\n id: string\n ): EntityByKind<K> | undefined\n list<K extends EntityKind>(kind: K): ReadonlyArray<EntityByKind<K>>\n query(predicate: (entity: Entity) => boolean): Entity[]\n byScope(scope: Scope): Entity[]\n touchedBy(flowId: string): Entity[]\n setReports(\n kind: EntityKind,\n id: string,\n reports: readonly ReportRecord[]\n ): void\n getReports(kind: EntityKind, id: string): readonly ReportRecord[]\n listReportKeys(): readonly string[]\n closeReport?: (reportId: string, status?: string) => void | Promise<void>\n onReportsChange(cb: () => void): () => void\n}\n\ntype KindStore = {\n [K in EntityKind]: Map<string, EntityByKind<K>>\n}\n\nfunction emptyStore(): KindStore {\n return {\n route: new Map(),\n page: new Map(),\n feature: new Map(),\n widget: new Map(),\n region: new Map(),\n element: new Map(),\n primitive: new Map(),\n flow: new Map(),\n }\n}\n\nfunction computeFlowIds(flows: Iterable<Flow>, targetId: string): string[] {\n const ids: string[] = []\n for (const flow of flows) {\n if (flow.touches.includes(targetId)) ids.push(flow.id)\n }\n return ids\n}\n\nfunction freezeEntity<E extends Entity>(entity: E, flows: Iterable<Flow>): E {\n if (!isMetaKind(entity.kind)) return entity\n const withMeta = entity as Extract<Entity, { meta?: Metadata }>\n if (withMeta.meta === undefined) return entity\n const computedFlows = Object.freeze(computeFlowIds(flows, withMeta.id))\n const mergedMeta: Metadata = { ...withMeta.meta, flows: computedFlows }\n return { ...entity, meta: Object.freeze(mergedMeta) } as E\n}\n\nexport function createRegistry(): Registry {\n const store = emptyStore()\n let flowsCache: Flow[] | null = null\n const patternCache = new Map<\n EntityKind,\n Array<{ segments: string[]; staticLength: number; entity: Entity }>\n >()\n\n const getFlows = (): Flow[] => {\n if (flowsCache === null) flowsCache = Array.from(store.flow.values())\n return flowsCache\n }\n\n const add = (entity: Entity): void => {\n assertEntityKind(entity.kind)\n const key = entityKey(entity)\n ;(store[entity.kind] as Map<string, Entity>).set(key, entity)\n flowsCache = null\n patternCache.delete(entity.kind)\n }\n\n const get = <K extends EntityKind>(\n kind: K,\n id: string\n ): EntityByKind<K> | undefined => {\n assertEntityKind(kind)\n const raw = store[kind].get(id) as EntityByKind<K> | undefined\n if (raw === undefined) return undefined\n return freezeEntity(raw, getFlows())\n }\n\n interface PatternEntry<K extends EntityKind> {\n /** static parts of the key around `*` wildcards, e.g. \"a-*-b\" → [\"a-\", \"-b\"] */\n segments: string[]\n staticLength: number\n entity: EntityByKind<K>\n }\n\n const getPatternsForKind = <K extends EntityKind>(\n kind: K\n ): Array<PatternEntry<K>> => {\n const cached = patternCache.get(kind)\n if (cached !== undefined) return cached as Array<PatternEntry<K>>\n const patterns: Array<PatternEntry<K>> = []\n for (const [key, entity] of store[kind]) {\n if (key.includes(\"*\")) {\n const segments = key.split(\"*\")\n patterns.push({\n segments,\n staticLength: segments.reduce((n, s) => n + s.length, 0),\n entity: entity as EntityByKind<K>,\n })\n }\n }\n patternCache.set(\n kind,\n patterns as Array<{\n segments: string[]\n staticLength: number\n entity: Entity\n }>\n )\n return patterns\n }\n\n // First segment anchored at the start, last at the end, middles matched\n // left-to-right; each `*` matches any run of characters (including none).\n const matchesSegments = (segments: string[], id: string): boolean => {\n const first = segments[0]\n const last = segments[segments.length - 1]\n if (!id.startsWith(first)) return false\n let pos = first.length\n for (let i = 1; i < segments.length - 1; i++) {\n const idx = id.indexOf(segments[i], pos)\n if (idx === -1) return false\n pos = idx + segments[i].length\n }\n return id.endsWith(last) && id.length - last.length >= pos\n }\n\n const matchPattern = <K extends EntityKind>(\n kind: K,\n id: string\n ): EntityByKind<K> | undefined => {\n assertEntityKind(kind)\n const patterns = getPatternsForKind(kind)\n if (patterns.length === 0) return undefined\n let best: PatternEntry<K> | undefined\n for (const entry of patterns) {\n if (\n matchesSegments(entry.segments, id) &&\n (best === undefined || entry.staticLength > best.staticLength)\n ) {\n best = entry\n }\n }\n if (best === undefined) return undefined\n return freezeEntity(best.entity, getFlows())\n }\n\n const list = <K extends EntityKind>(\n kind: K\n ): ReadonlyArray<EntityByKind<K>> => {\n assertEntityKind(kind)\n const flows = getFlows()\n return Array.from(store[kind].values(), (e) =>\n freezeEntity(e as EntityByKind<K>, flows)\n )\n }\n\n const allEntities = function* (): Generator<Entity> {\n for (const kind of Object.keys(store) as EntityKind[]) {\n for (const entity of store[kind].values()) {\n yield entity as Entity\n }\n }\n }\n\n const query = (predicate: (entity: Entity) => boolean): Entity[] => {\n const flows = getFlows()\n const result: Entity[] = []\n for (const entity of allEntities()) {\n if (predicate(entity)) result.push(freezeEntity(entity, flows))\n }\n return result\n }\n\n const byScope = (scope: Scope): Entity[] =>\n query(\n (entity) =>\n \"scopes\" in entity &&\n Array.isArray(entity.scopes) &&\n entity.scopes.includes(scope)\n )\n\n const touchedBy = (flowId: string): Entity[] => {\n const flow = store.flow.get(flowId)\n if (flow === undefined) return []\n const ids = new Set(flow.touches)\n return query((entity) => {\n if (!isMetaEntity(entity)) return false\n return ids.has(entity.id)\n })\n }\n\n const reports = new Map<string, readonly ReportRecord[]>()\n const reportsCbs = new Set<() => void>()\n\n const setReports = (\n kind: EntityKind,\n id: string,\n records: readonly ReportRecord[]\n ): void => {\n reports.set(`${kind}:${id}`, records)\n for (const cb of reportsCbs) cb()\n }\n\n const getReports = (kind: EntityKind, id: string): readonly ReportRecord[] =>\n reports.get(`${kind}:${id}`) ?? []\n\n const listReportKeys = (): readonly string[] => Array.from(reports.keys())\n\n const onReportsChange = (cb: () => void): (() => void) => {\n reportsCbs.add(cb)\n return () => reportsCbs.delete(cb)\n }\n\n return {\n add,\n get,\n matchPattern,\n list,\n query,\n byScope,\n touchedBy,\n setReports,\n getReports,\n listReportKeys,\n onReportsChange,\n }\n}\n","import { CORE_STATE_KINDS } from \"../../shared/entities\"\nimport type { Metadata, Registry } from \"../../shared/entities\"\n\n/**\n * ACKNOWLEDGMENT — the single primitive for \"don't complain about this\".\n *\n * There used to be four mechanisms plus an implicit fifth (`waivers`, the\n * baseline's `missingKinds` / `uncapturedPages`, `capture: false`, and a\n * borrowed-entity inference). They overlapped, lived in unrelated files with\n * unrelated shapes, and the rule keeping them straight — \"don't fold capturable\n * debt into a waiver\" — was enforced socially, in prose, because nothing\n * structural stopped you reaching for the wrong one.\n *\n * They are now one map from a SCOPE to a typed REASON:\n *\n * acknowledge: {\n * empty: { type: \"impossible\", reason: \"a create form has no empty state\" },\n * \"*\": { type: \"backlog\" },\n * }\n *\n * SCOPE is a core kind (that kind of this route) or `\"*\"` (the whole entity —\n * every axis of it). TYPE is why:\n *\n * - `impossible` — human-authored. The surface CANNOT render this; a\n * substantive `reason` is REQUIRED. Contradicted by an actual capture →\n * `stale-acknowledgment`.\n * - `backlog` — debt. It CAN render this and nobody has captured it yet.\n * `reason` is optional. Tool-managed in the coverage baseline\n * (`--update-baseline`, shrink-only), and authorable in source when you want\n * the debt to sit next to the declaration.\n * - `captured-elsewhere` — COMPUTED by the workspace level, never authored: a\n * sibling app that registers this same declaration captured it. Replaces the\n * borrowed-entity guess with an exact answer.\n *\n * The anti-laundering property is now structural rather than social:\n * `impossible` and `backlog` are sibling values of ONE field, so choosing wrongly\n * is a one-token, greppable, reviewable edit — not a choice between two\n * unrelated files. And the reason rule points the lazy path at the honest\n * answer: `impossible` costs you a sentence, `backlog` is free.\n */\n\n/** The scope key meaning \"the whole entity\", not one core kind. */\nexport const ACK_ALL = \"*\"\n\n/** Every valid scope key: the four core kinds plus `\"*\"`. */\nexport const ACK_SCOPES: readonly string[] = [ACK_ALL, ...CORE_STATE_KINDS]\n\n/** Scopes valid on a feature/widget: only `\"*\"` — a component has no route, so\n * the route-scoped core-kind matrix is meaningless on one. */\nexport const COMPONENT_ACK_SCOPES: readonly string[] = [ACK_ALL]\n\nexport type AcknowledgeType = \"impossible\" | \"backlog\" | \"captured-elsewhere\"\n\n/** Types a human may write; `captured-elsewhere` is computed, never authored. */\nexport const AUTHORABLE_ACK_TYPES: readonly AcknowledgeType[] = [\n \"impossible\",\n \"backlog\",\n]\n\nexport interface Acknowledgment {\n type: AcknowledgeType\n /** Why. Required for `impossible`, optional for `backlog`. */\n reason?: string\n /** `captured-elsewhere` only: the workspace app whose capture covers this. */\n by?: string\n}\n\n/** scope (`\"*\"` | core kind) → why it is acknowledged. */\nexport type AcknowledgeMap = Record<string, Acknowledgment>\n\n/** Where an acknowledgment came from, so diagnostics can point at the right file. */\nexport type AcknowledgeOrigin = \"source\" | \"baseline\" | \"workspace\"\n\nexport interface ResolvedAcknowledgment extends Acknowledgment {\n scope: string\n origin: AcknowledgeOrigin\n}\n\n/**\n * The committed, tool-managed coverage backlog. Same `Acknowledgment` shape as\n * the source-authored field, keyed by route pattern — so the two really are the\n * same primitive in two homes, not two lookalikes.\n */\nexport interface CoverageBaseline {\n version: 2\n /** route pattern → scope → acknowledgment (always `type: \"backlog\"`). */\n acknowledge: Record<string, AcknowledgeMap>\n}\n\n/** The pre-`acknowledge` baseline shape, recognized only to migrate it. */\nexport interface LegacyCoverageBaseline {\n uncapturedPages?: string[]\n missingKinds?: Record<string, string[]>\n}\n\nconst CORE_SET: ReadonlySet<string> = new Set(CORE_STATE_KINDS)\n\nexport function isCoreKind(scope: string): boolean {\n return CORE_SET.has(scope)\n}\n\n/** A reason the codemod planted because the legacy field carried none. */\nexport const PLACEHOLDER_REASON = \"TODO: why can this never be captured?\"\n\n/** Whether a reason is an unfilled migration placeholder rather than a real one. */\nexport function isPlaceholderReason(reason: string | undefined): boolean {\n return typeof reason === \"string\" && /^\\s*TODO\\b/i.test(reason)\n}\n\n/** Human-readable tail for a diagnostic message: `impossible (\"…\")`. */\nexport function describeAck(a: Acknowledgment): string {\n if (a.type === \"captured-elsewhere\") {\n return a.by ? `captured-elsewhere (${a.by})` : \"captured-elsewhere\"\n }\n return a.reason ? `${a.type} (\"${a.reason}\")` : a.type\n}\n\n/** Where to go to remove this acknowledgment, for a hygiene hint. */\nexport function originHint(a: ResolvedAcknowledgment, page?: string): string {\n if (a.origin === \"baseline\") {\n return \"Prune it with `uidex scan --update-baseline` so the backlog reflects reality.\"\n }\n if (a.origin === \"workspace\") {\n return \"This is computed from the workspace; it resolves itself once the sibling capture changes.\"\n }\n const where = page ? ` on page \"${page}\"` : \"\"\n return `Remove the \\`acknowledge.${a.scope}\\` entry${where} — a capture contradicts it.`\n}\n\n/* ---------- resolution ---------- */\n\nfunction toResolved(\n map: AcknowledgeMap | undefined,\n origin: AcknowledgeOrigin,\n into: Map<string, ResolvedAcknowledgment>\n): void {\n for (const [scope, ack] of Object.entries(map ?? {})) {\n into.set(scope, { ...ack, scope, origin })\n }\n}\n\n/**\n * The acknowledgments in force for one ROUTE: the baseline's entry for the route\n * layered UNDER the page's own `acknowledge`. Source wins — a human statement\n * outranks tool-recorded debt, and `--update-baseline` drops the shadowed entry\n * on its next run.\n */\nexport function routeAcknowledge(\n registry: Registry,\n baseline: CoverageBaseline | undefined,\n route: string,\n page: string | undefined\n): Map<string, ResolvedAcknowledgment> {\n const out = new Map<string, ResolvedAcknowledgment>()\n toResolved(baseline?.acknowledge?.[route], \"baseline\", out)\n if (page) {\n toResolved(registry.get(\"page\", page)?.meta?.acknowledge, \"source\", out)\n }\n return out\n}\n\n/**\n * The acknowledgments in force for one ENTITY (page/feature/widget). Only `\"*\"`\n * is meaningful here — the core-kind axis is route-scoped. `capturedElsewhere`\n * is the workspace's computed verdict; source still wins, so an explicit\n * `impossible` is never silently reinterpreted.\n */\nexport function entityAcknowledge(\n meta: Metadata | undefined,\n capturedElsewhereBy?: string\n): ResolvedAcknowledgment | undefined {\n const source = meta?.acknowledge?.[ACK_ALL]\n if (source) return { ...source, scope: ACK_ALL, origin: \"source\" }\n if (capturedElsewhereBy) {\n return {\n type: \"captured-elsewhere\",\n by: capturedElsewhereBy,\n scope: ACK_ALL,\n origin: \"workspace\",\n }\n }\n return undefined\n}\n\n/* ---------- baseline (de)serialization ---------- */\n\nfunction readAck(raw: unknown): Acknowledgment | undefined {\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return undefined\n const r = raw as Record<string, unknown>\n if (r.type !== \"impossible\" && r.type !== \"backlog\") return undefined\n const out: Acknowledgment = { type: r.type }\n if (typeof r.reason === \"string\" && r.reason.length > 0) out.reason = r.reason\n return out\n}\n\n/**\n * Parse a v2 baseline. Malformed entries are dropped rather than thrown on: a\n * hand-mangled baseline must not crash the scan, and every dropped entry simply\n * re-appears as an unacknowledged gap the gate reports.\n */\nexport function parseCoverageBaseline(raw: unknown): CoverageBaseline | null {\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return null\n const r = raw as Record<string, unknown>\n const ackRaw = r.acknowledge\n if (!ackRaw || typeof ackRaw !== \"object\" || Array.isArray(ackRaw))\n return null\n const acknowledge: Record<string, AcknowledgeMap> = {}\n for (const [route, scopesRaw] of Object.entries(\n ackRaw as Record<string, unknown>\n )) {\n if (!scopesRaw || typeof scopesRaw !== \"object\" || Array.isArray(scopesRaw))\n continue\n const scopes: AcknowledgeMap = {}\n for (const [scope, ackVal] of Object.entries(\n scopesRaw as Record<string, unknown>\n )) {\n if (scope !== ACK_ALL && !isCoreKind(scope)) continue\n const ack = readAck(ackVal)\n if (ack) scopes[scope] = ack\n }\n if (Object.keys(scopes).length > 0) acknowledge[route] = scopes\n }\n return { version: 2, acknowledge }\n}\n\n/** Whether a parsed baseline JSON is the pre-`acknowledge` shape. */\nexport function isLegacyBaseline(raw: unknown): raw is LegacyCoverageBaseline {\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return false\n const r = raw as Record<string, unknown>\n if (\"acknowledge\" in r) return false\n return \"uncapturedPages\" in r || \"missingKinds\" in r\n}\n\n/** Convert the pre-`acknowledge` baseline shape to v2. Pure; no I/O. */\nexport function migrateBaseline(\n legacy: LegacyCoverageBaseline\n): CoverageBaseline {\n const acknowledge: Record<string, AcknowledgeMap> = {}\n const at = (route: string): AcknowledgeMap =>\n (acknowledge[route] ??= {} as AcknowledgeMap)\n for (const route of legacy.uncapturedPages ?? []) {\n if (typeof route === \"string\") at(route)[ACK_ALL] = { type: \"backlog\" }\n }\n for (const [route, kinds] of Object.entries(legacy.missingKinds ?? {})) {\n if (!Array.isArray(kinds)) continue\n for (const kind of kinds) {\n if (typeof kind === \"string\" && isCoreKind(kind)) {\n at(route)[kind] = { type: \"backlog\" }\n }\n }\n }\n return { version: 2, acknowledge }\n}\n\n/** Serialize a baseline with stable key order, so its diff is reviewable. */\nexport function serializeCoverageBaseline(baseline: CoverageBaseline): string {\n const routes = Object.keys(baseline.acknowledge).sort()\n const ordered: Record<string, AcknowledgeMap> = {}\n for (const route of routes) {\n const scopes = baseline.acknowledge[route]\n const sorted: AcknowledgeMap = {}\n for (const scope of ACK_SCOPES) {\n if (scopes[scope]) sorted[scope] = scopes[scope]\n }\n ordered[route] = sorted\n }\n return JSON.stringify({ version: 2, acknowledge: ordered }, null, 2) + \"\\n\"\n}\n","import { CORE_STATE_KINDS as CORE_KIND_LIST } from \"../../shared/entities\"\nimport {\n ACK_SCOPES,\n AUTHORABLE_ACK_TYPES,\n COMPONENT_ACK_SCOPES,\n} from \"./acknowledge\"\nimport { parseSource, unwrapTsExpression } from \"./ast\"\nimport type { AstNode, ParsedSource } from \"./ast\"\nimport type {\n Diagnostic,\n MetadataExport,\n MetadataExportKind,\n ParsedState,\n ScannedFile,\n Span,\n} from \"./types\"\n\n/**\n * Reads `export const uidex = <literal>` blocks from the shared oxc AST.\n * Only plain literals are accepted (objects / arrays / strings / numbers /\n * booleans / null, with optional `as const` / `satisfies` wrappers); anything\n * computed is rejected with an error diagnostic. Spans are recorded on the\n * extracted metadata so `--fix` codemods and `uidex rename` can edit source.\n */\n\ninterface SourcePos {\n offset: number\n line: number\n column: number\n}\n\ninterface LitEntry {\n key: string\n value: LitValue\n keyPos: SourcePos\n /** whole-property span, extended over one adjacent comma (removal-ready) */\n span: Span\n /** whole-property span WITHOUT the comma extension (replacement-ready) */\n propSpan: Span\n}\n\ntype LitValue =\n | { kind: \"string\"; value: string; pos: SourcePos; span: Span }\n | { kind: \"number\"; value: number; pos: SourcePos; span: Span }\n | { kind: \"boolean\"; value: boolean; pos: SourcePos; span: Span }\n | { kind: \"null\"; pos: SourcePos; span: Span }\n | { kind: \"array\"; items: LitValue[]; pos: SourcePos; span: Span }\n | { kind: \"object\"; entries: LitEntry[]; pos: SourcePos; span: Span }\n\nexport interface UidexExportExtractResult {\n exports: MetadataExport[]\n diagnostics: Diagnostic[]\n}\n\nconst KIND_DISCRIMINATORS = [\n \"page\",\n \"feature\",\n \"primitive\",\n \"widget\",\n \"region\",\n \"flow\",\n \"notFlow\",\n] as const\ntype Discriminator = (typeof KIND_DISCRIMINATORS)[number]\n\nconst ALLOWED_FIELDS: Record<MetadataExportKind, ReadonlySet<string>> = {\n page: new Set([\n \"page\",\n \"name\",\n \"features\",\n \"widgets\",\n \"acceptance\",\n \"states\",\n \"acknowledge\",\n \"capture\",\n \"waivers\",\n \"description\",\n ]),\n // A page's `acknowledge` accepts both scope shapes: `\"*\"` (the whole route)\n // and a core kind (one cell of its matrix). A feature/widget has no route, so\n // the core-kind matrix is meaningless there and only `\"*\"` is accepted —\n // giving a component a scoped opt-out instead of forcing you to delete its\n // whole `states` block. `capture` / `waivers` are REMOVED; they stay parseable\n // only so `--fix` can rewrite them into `acknowledge` (see MIGRATION below).\n feature: new Set([\n \"feature\",\n \"name\",\n \"features\",\n \"acceptance\",\n \"states\",\n \"acknowledge\",\n \"capture\",\n \"description\",\n ]),\n primitive: new Set([\"primitive\", \"name\", \"description\"]),\n widget: new Set([\n \"widget\",\n \"name\",\n \"acceptance\",\n \"states\",\n \"acknowledge\",\n \"capture\",\n \"description\",\n ]),\n region: new Set([\"region\", \"name\", \"description\"]),\n flow: new Set([\"flow\", \"notFlow\", \"name\", \"description\"]),\n}\n\n/** Allowed sub-fields of an `acknowledge` entry. */\nconst ACK_FIELDS: ReadonlySet<string> = new Set([\"type\", \"reason\"])\n\n/** Allowed sub-fields of an object entry in `states`. */\nconst STATE_FIELDS: ReadonlySet<string> = new Set([\n \"name\",\n \"kind\",\n \"acceptance\",\n \"description\",\n])\n\n// Sourced from the shared registry constant so the accepted `kind`/`waiver`\n// values never drift from the kinds the state-matrix gate enforces.\nconst CORE_STATE_KINDS: ReadonlySet<string> = new Set(CORE_KIND_LIST)\nconst STATE_KINDS: ReadonlySet<string> = new Set([...CORE_KIND_LIST, \"variant\"])\n\nconst FALSEABLE: ReadonlySet<MetadataExportKind> = new Set([\n \"page\",\n \"feature\",\n \"primitive\",\n \"region\",\n])\n\n/** Expected `satisfies Uidex.<X>` type name per discriminator. */\nconst SATISFIES_NAMES: Record<Discriminator, string> = {\n page: \"Page\",\n feature: \"Feature\",\n primitive: \"Primitive\",\n widget: \"Widget\",\n region: \"Region\",\n flow: \"Flow\",\n notFlow: \"NotFlow\",\n}\nconst KNOWN_SATISFIES = new Set(Object.values(SATISFIES_NAMES))\n\nclass ExtractError extends Error {\n code: string\n hint?: string\n pos: SourcePos\n constructor(code: string, message: string, pos: SourcePos, hint?: string) {\n super(message)\n this.code = code\n this.pos = pos\n this.hint = hint\n }\n}\n\nexport function extractUidexExports(\n file: ScannedFile,\n parsed?: ParsedSource\n): UidexExportExtractResult {\n const exports: MetadataExport[] = []\n const diagnostics: Diagnostic[] = []\n const { content, displayPath } = file\n const p = parsed ?? parseSource(file)\n if (p.program === null) return { exports, diagnostics }\n\n for (const stmt of p.program.body as unknown as AstNode[]) {\n if (stmt.type !== \"ExportNamedDeclaration\") continue\n const decl = stmt.declaration as AstNode | null | undefined\n if (!isNode(decl) || decl.type !== \"VariableDeclaration\") continue\n if (decl.kind !== \"const\") continue\n for (const declarator of (decl.declarations as AstNode[] | undefined) ??\n []) {\n const id = declarator.id as AstNode | undefined\n if (!id || id.type !== \"Identifier\" || String(id.name) !== \"uidex\") {\n continue\n }\n const headerPos = posAt(content, stmt.start, p)\n try {\n const init = declarator.init as AstNode | null | undefined\n if (!isNode(init)) {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"`export const uidex` must be assigned an object literal.\",\n headerPos\n )\n }\n const value = toLitValue(unwrapTsExpression(init), content, p)\n const metadata = buildMetadata(\n value,\n displayPath,\n file.sourcePath,\n headerPos,\n diagnostics\n )\n metadata.span = statementSpan(stmt, content)\n checkSatisfies(init, metadata, displayPath, p, diagnostics)\n exports.push(metadata)\n } catch (e) {\n if (e instanceof ExtractError) {\n diagnostics.push({\n code: e.code,\n severity: \"error\",\n message: e.message,\n file: displayPath,\n line: e.pos.line,\n hint: e.hint,\n })\n } else {\n throw e\n }\n }\n }\n }\n\n return { exports, diagnostics }\n}\n\n/* ---------- AST → LitValue ---------- */\n\nfunction toLitValue(node: AstNode, content: string, p: ParsedSource): LitValue {\n const unwrapped = unwrapTsExpression(node)\n const pos = posAt(content, unwrapped.start, p)\n const span: Span = { start: unwrapped.start, end: unwrapped.end }\n\n switch (unwrapped.type) {\n case \"Literal\": {\n const v = unwrapped.value\n if (typeof v === \"string\") return { kind: \"string\", value: v, pos, span }\n if (typeof v === \"number\") {\n if (!Number.isFinite(v)) {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n `Invalid numeric literal in \\`export const uidex\\`.`,\n pos\n )\n }\n return { kind: \"number\", value: v, pos, span }\n }\n if (typeof v === \"boolean\") {\n return { kind: \"boolean\", value: v, pos, span }\n }\n if (v === null && unwrapped.raw === \"null\") {\n return { kind: \"null\", pos, span }\n }\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n `Unsupported literal in \\`export const uidex\\`; only strings, numbers, booleans, and null are allowed.`,\n pos\n )\n }\n case \"UnaryExpression\": {\n // Negative numbers parse as unary minus on a numeric literal.\n const arg = unwrapped.argument as AstNode | undefined\n if (\n unwrapped.operator === \"-\" &&\n isNode(arg) &&\n arg.type === \"Literal\" &&\n typeof arg.value === \"number\"\n ) {\n return { kind: \"number\", value: -(arg.value as number), pos, span }\n }\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Unary expressions are not allowed in `export const uidex`.\",\n pos\n )\n }\n case \"TemplateLiteral\": {\n const expressions = (unwrapped.expressions as AstNode[] | undefined) ?? []\n if (expressions.length > 0) {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Template literal with expression parts is not allowed in `export const uidex`; use a plain string literal.\",\n pos\n )\n }\n const quasis = (unwrapped.quasis as AstNode[] | undefined) ?? []\n const cooked =\n (quasis[0]?.value as { cooked?: string } | undefined)?.cooked ?? \"\"\n return { kind: \"string\", value: cooked, pos, span }\n }\n case \"Identifier\": {\n const name = String(unwrapped.name)\n if (name === \"undefined\") {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"`undefined` is not allowed as a value in `export const uidex`; omit the field instead.\",\n pos\n )\n }\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n `Identifier reference \"${name}\" is not allowed in \\`export const uidex\\`; the right-hand side must be a plain literal.`,\n pos\n )\n }\n case \"ObjectExpression\":\n return objectLit(unwrapped, content, p, pos, span)\n case \"ArrayExpression\":\n return arrayLit(unwrapped, content, p, pos, span)\n case \"SpreadElement\":\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Spread (`...`) is not allowed in `export const uidex`; the right-hand side must be a plain literal.\",\n pos\n )\n case \"CallExpression\":\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Function calls are not allowed in `export const uidex`; the right-hand side must be a plain literal.\",\n pos\n )\n case \"ConditionalExpression\":\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Conditional expressions are not allowed in `export const uidex`; the right-hand side must be a plain literal.\",\n pos\n )\n default:\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n `Computed expressions are not allowed in \\`export const uidex\\`; the right-hand side must be a plain literal.`,\n pos\n )\n }\n}\n\nfunction objectLit(\n node: AstNode,\n content: string,\n p: ParsedSource,\n pos: SourcePos,\n span: Span\n): LitValue {\n const entries: LitEntry[] = []\n const seen = new Set<string>()\n for (const prop of (node.properties as AstNode[] | undefined) ?? []) {\n if (prop.type === \"SpreadElement\") {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Spread (`...`) is not allowed inside `export const uidex`.\",\n posAt(content, prop.start, p)\n )\n }\n if (prop.type !== \"Property\") {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Unexpected member inside `export const uidex` object.\",\n posAt(content, prop.start, p)\n )\n }\n const keyNode = prop.key as AstNode\n const keyPos = posAt(content, keyNode.start, p)\n if (prop.shorthand) {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n `Shorthand property \"${String(keyNode.name)}\" is not allowed; write \"${String(keyNode.name)}: ...\" with a literal value.`,\n keyPos\n )\n }\n let key: string\n if (prop.computed) {\n if (keyNode.type !== \"Literal\" || typeof keyNode.value !== \"string\") {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Computed property keys must be string literals in `export const uidex`.\",\n keyPos\n )\n }\n key = keyNode.value\n } else if (keyNode.type === \"Identifier\") {\n key = String(keyNode.name)\n } else if (\n keyNode.type === \"Literal\" &&\n typeof keyNode.value === \"string\"\n ) {\n key = keyNode.value\n } else {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Numeric property keys are not allowed in `export const uidex`.\",\n keyPos\n )\n }\n if (seen.has(key)) {\n throw new ExtractError(\n \"uidex-export-duplicate-field\",\n `Duplicate field \"${key}\" in \\`export const uidex\\`.`,\n keyPos\n )\n }\n seen.add(key)\n const value = toLitValue(prop.value as AstNode, content, p)\n entries.push({\n key,\n value,\n keyPos,\n span: removalSpan(content, prop.start, prop.end),\n propSpan: { start: prop.start, end: prop.end },\n })\n }\n return { kind: \"object\", entries, pos, span }\n}\n\nfunction arrayLit(\n node: AstNode,\n content: string,\n p: ParsedSource,\n pos: SourcePos,\n span: Span\n): LitValue {\n const items: LitValue[] = []\n for (const el of (node.elements as Array<AstNode | null> | undefined) ?? []) {\n if (el === null) {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Array holes are not allowed in `export const uidex`.\",\n pos\n )\n }\n if (el.type === \"SpreadElement\") {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"Spread (`...`) is not allowed inside `export const uidex`.\",\n posAt(content, el.start, p)\n )\n }\n items.push(toLitValue(el, content, p))\n }\n return { kind: \"array\", items, pos, span }\n}\n\n/* ---------- satisfies cross-check ---------- */\n\n/**\n * When the export is written `satisfies Uidex.<X>` and X is one of the known\n * kind names, warn if it contradicts the declared discriminator. Unknown or\n * unqualified type names are left alone — they may be project aliases.\n */\nfunction checkSatisfies(\n init: AstNode,\n metadata: MetadataExport,\n file: string,\n p: ParsedSource,\n diagnostics: Diagnostic[]\n): void {\n let node: AstNode | undefined = init\n let satisfiesType: AstNode | undefined\n while (isNode(node)) {\n if (node.type === \"TSSatisfiesExpression\") {\n satisfiesType = node.typeAnnotation as AstNode | undefined\n break\n }\n if (\n node.type === \"TSAsExpression\" ||\n node.type === \"TSNonNullExpression\" ||\n node.type === \"TSTypeAssertion\" ||\n node.type === \"ParenthesizedExpression\"\n ) {\n node = node.expression as AstNode | undefined\n continue\n }\n break\n }\n if (!isNode(satisfiesType) || satisfiesType.type !== \"TSTypeReference\") return\n const typeName = satisfiesType.typeName as AstNode | undefined\n if (!isNode(typeName) || typeName.type !== \"TSQualifiedName\") return\n const left = typeName.left as AstNode | undefined\n const right = typeName.right as AstNode | undefined\n if (!isNode(left) || left.type !== \"Identifier\" || left.name !== \"Uidex\") {\n return\n }\n if (!isNode(right) || right.type !== \"Identifier\") return\n const actual = String(right.name)\n if (!KNOWN_SATISFIES.has(actual)) return\n\n const discriminator: Discriminator = metadata.notFlow\n ? \"notFlow\"\n : (metadata.kind as Discriminator)\n const expected = SATISFIES_NAMES[discriminator]\n if (actual === expected) return\n diagnostics.push({\n code: \"uidex-export-satisfies-mismatch\",\n severity: \"warning\",\n message: `\\`export const uidex\\` declares kind \"${discriminator}\" but is annotated \\`satisfies Uidex.${actual}\\`; expected \\`Uidex.${expected}\\`.`,\n file,\n line: p.lineAt(satisfiesType.start),\n hint: `Change the annotation to \\`satisfies Uidex.${expected}\\` or fix the kind discriminator.`,\n })\n}\n\n/* ---------- metadata building ---------- */\n\nfunction buildMetadata(\n value: LitValue,\n file: string,\n sourcePath: string,\n headerPos: SourcePos,\n diagnostics: Diagnostic[]\n): MetadataExport {\n if (value.kind !== \"object\") {\n throw new ExtractError(\n \"uidex-export-invalid-literal\",\n \"`export const uidex` must be assigned an object literal.\",\n value.pos\n )\n }\n\n const byKey = new Map<string, LitEntry>()\n for (const entry of value.entries) byKey.set(entry.key, entry)\n\n const presentKinds = KIND_DISCRIMINATORS.filter((k) =>\n byKey.has(k)\n ) as Discriminator[]\n if (presentKinds.length === 0) {\n throw new ExtractError(\n \"uidex-export-missing-kind\",\n \"`export const uidex` must declare one of: \" +\n KIND_DISCRIMINATORS.join(\", \") +\n \".\",\n value.pos\n )\n }\n if (presentKinds.length > 1) {\n throw new ExtractError(\n \"uidex-export-ambiguous-kind\",\n `\\`export const uidex\\` declares multiple kinds (${presentKinds.join(\n \", \"\n )}); exactly one kind discriminator is allowed per module.`,\n value.pos\n )\n }\n\n const discriminator = presentKinds[0]\n // notFlow is the only discriminator that maps to `flow` kind.\n const kind: MetadataExportKind =\n discriminator === \"notFlow\" ? \"flow\" : discriminator\n\n const allowed = ALLOWED_FIELDS[kind]\n for (const entry of value.entries) {\n if (!allowed.has(entry.key)) {\n throw new ExtractError(\n \"uidex-export-unknown-field\",\n `Unknown field \"${entry.key}\" in \\`export const uidex\\` for kind \"${kind}\". Allowed: ${Array.from(\n allowed\n )\n .sort()\n .join(\", \")}.`,\n entry.value.pos\n )\n }\n }\n\n // Parse required id and optional fields.\n const idField: string = discriminator === \"notFlow\" ? \"flow\" : discriminator\n const idValue = byKey.get(discriminator)!.value\n let id: string | false\n if (discriminator === \"notFlow\") {\n if (idValue.kind !== \"boolean\" || idValue.value !== true) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n \"`notFlow` must be `true`.\",\n idValue.pos\n )\n }\n // A flow-kind export with notFlow:true has no id — represent as false.\n id = false\n } else {\n id = readIdField(idValue, kind, idField)\n }\n\n const acceptance = readStringArrayField(byKey, \"acceptance\")?.values\n const description = readStringField(byKey, \"description\")\n const name = readStringField(byKey, \"name\")\n if (name === \"\") {\n const entry = byKey.get(\"name\")!\n diagnostics.push({\n code: \"uidex-export-empty-name\",\n severity: \"info\",\n message: \"`name` is an empty string; treating as unset.\",\n file,\n line: entry.value.pos.line,\n fix: {\n description: \"Remove the empty `name` field\",\n edits: [\n {\n path: sourcePath,\n start: entry.span.start,\n end: entry.span.end,\n replacement: \"\",\n },\n ],\n },\n })\n }\n const featuresField =\n kind === \"page\" || kind === \"feature\"\n ? readStringArrayField(byKey, \"features\")\n : undefined\n const widgetsField =\n kind === \"page\" ? readStringArrayField(byKey, \"widgets\") : undefined\n const states =\n kind === \"page\" || kind === \"feature\" || kind === \"widget\"\n ? readStatesField(byKey)\n : undefined\n const stateBearing =\n kind === \"page\" || kind === \"feature\" || kind === \"widget\"\n const acknowledge = stateBearing\n ? readAcknowledgeField(byKey, kind === \"page\")\n : undefined\n const legacyCapture = stateBearing\n ? readBooleanField(byKey, \"capture\")\n : undefined\n const legacyWaivers = kind === \"page\" ? readWaiversField(byKey) : undefined\n const notFlow =\n kind === \"flow\" && discriminator === \"notFlow\" ? true : undefined\n\n const metadata: MetadataExport = {\n source: \"ts-export\",\n kind,\n id,\n loc: {\n file,\n line: headerPos.line,\n column: headerPos.column,\n },\n }\n if (name) metadata.name = name\n if (acceptance) metadata.acceptance = acceptance\n if (description) metadata.description = description\n if (featuresField) {\n metadata.features = featuresField.values\n metadata.featureSpans = featuresField.spans\n }\n if (widgetsField) {\n metadata.widgets = widgetsField.values\n metadata.widgetSpans = widgetsField.spans\n }\n if (states?.length) metadata.states = states\n if (acknowledge && Object.keys(acknowledge).length > 0) {\n metadata.acknowledge = acknowledge\n }\n if (legacyCapture !== undefined) metadata.legacyCapture = legacyCapture\n if (legacyWaivers && Object.keys(legacyWaivers).length > 0) {\n metadata.legacyWaivers = legacyWaivers\n }\n if (notFlow) metadata.notFlow = true\n if (typeof id === \"string\" && idValue.kind === \"string\") {\n metadata.idSpan = idValue.span\n }\n const fieldSpans: Record<string, Span> = {}\n const fieldPropSpans: Record<string, Span> = {}\n for (const entry of value.entries) {\n fieldSpans[entry.key] = entry.span\n fieldPropSpans[entry.key] = entry.propSpan\n }\n metadata.fieldSpans = fieldSpans\n metadata.fieldPropSpans = fieldPropSpans\n return metadata\n}\n\nfunction readIdField(\n value: LitValue,\n kind: MetadataExportKind,\n fieldName: string\n): string | false {\n if (value.kind === \"string\") {\n if (value.value.length === 0) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `\\`${fieldName}\\` must be a non-empty string.`,\n value.pos\n )\n }\n return value.value\n }\n if (value.kind === \"boolean\" && value.value === false) {\n if (!FALSEABLE.has(kind)) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `\\`${fieldName}: false\\` is only valid for page, feature, and primitive kinds.`,\n value.pos\n )\n }\n return false\n }\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `\\`${fieldName}\\` must be a string${\n FALSEABLE.has(kind) ? \" or `false`\" : \"\"\n }.`,\n value.pos\n )\n}\n\n/**\n * Parse `acknowledge`: `{ <scope>: { type, reason? } }`.\n *\n * The three rules that keep the primitive honest, all enforced here rather than\n * left to review:\n *\n * - SCOPE must be `\"*\"` or a core kind, and core kinds are PAGE-ONLY (a\n * component has no route, so its matrix cell does not exist).\n * - `type: \"impossible\"` REQUIRES a substantive reason. `type: \"backlog\"` does\n * not — so the cheap path is the honest one, and claiming a gap is\n * impossible always costs a sentence somebody can disagree with.\n * - `type: \"captured-elsewhere\"` is REJECTED: the workspace computes it, and\n * hand-writing it would be a way to assert coverage that does not exist.\n */\nfunction readAcknowledgeField(\n byKey: Map<string, LitEntry>,\n isPage: boolean\n):\n | Record<string, { type: \"impossible\" | \"backlog\"; reason?: string }>\n | undefined {\n const entry = byKey.get(\"acknowledge\")\n if (!entry) return undefined\n if (entry.value.kind !== \"object\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n '`acknowledge` must be an object mapping a scope (`\"*\"` or a core kind) to `{ type, reason? }`.',\n entry.value.pos\n )\n }\n const out: Record<\n string,\n { type: \"impossible\" | \"backlog\"; reason?: string }\n > = {}\n for (const e of entry.value.entries) {\n const scopes = isPage ? ACK_SCOPES : COMPONENT_ACK_SCOPES\n if (!scopes.includes(e.key)) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `acknowledge scope \"${e.key}\" is not valid here; expected ${scopes.map((s) => `\"${s}\"`).join(\", \")}${\n isPage\n ? \"\"\n : \" (core-kind scopes are page-only — the state matrix is route-scoped)\"\n }.`,\n e.keyPos\n )\n }\n if (e.value.kind !== \"object\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `acknowledge \"${e.key}\" must be an object \\`{ type, reason? }\\`.`,\n e.value.pos\n )\n }\n const fieldByKey = new Map<string, LitEntry>()\n for (const f of e.value.entries) {\n if (!ACK_FIELDS.has(f.key)) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `Unknown field \"${f.key}\" in an \\`acknowledge\\` entry. Allowed: ${[...ACK_FIELDS].sort().join(\", \")}.`,\n f.value.pos\n )\n }\n fieldByKey.set(f.key, f)\n }\n const type = readStringField(fieldByKey, \"type\")\n if (type === undefined) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `acknowledge \"${e.key}\" needs a \\`type\\`: ${AUTHORABLE_ACK_TYPES.map((t) => `\"${t}\"`).join(\" or \")}.`,\n e.value.pos\n )\n }\n if (type === \"captured-elsewhere\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n '`type: \"captured-elsewhere\"` cannot be authored; the workspace computes it from the sibling app that captured the declaration.',\n fieldByKey.get(\"type\")!.value.pos,\n \"Remove the entry — if a sibling app really captures this, the workspace reports it as `acknowledged-elsewhere` on its own.\"\n )\n }\n if (type !== \"impossible\" && type !== \"backlog\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `acknowledge \\`type\\` must be ${AUTHORABLE_ACK_TYPES.map((t) => `\"${t}\"`).join(\" or \")} (got \"${type}\").`,\n fieldByKey.get(\"type\")!.value.pos\n )\n }\n const reason = readStringField(fieldByKey, \"reason\")\n if (\n type === \"impossible\" &&\n (reason === undefined || reason.length === 0)\n ) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `acknowledge \"${e.key}\" is \\`type: \"impossible\"\\` and needs a non-empty \\`reason\\` (why this can NEVER be rendered/captured).`,\n e.value.pos,\n 'If it merely has not been captured yet, that is `type: \"backlog\"` — which needs no reason.'\n )\n }\n out[e.key] = reason ? { type, reason } : { type }\n }\n return out\n}\n\n/**\n * MIGRATION ONLY — parse the REMOVED `waivers` field so `--fix` can rewrite it\n * as `acknowledge: { <kind>: { type: \"impossible\", reason } }`. No gate reads\n * the result; `audit()` turns its presence into an error with a fix attached.\n */\nfunction readWaiversField(\n byKey: Map<string, LitEntry>\n): Record<string, string> | undefined {\n const entry = byKey.get(\"waivers\")\n if (!entry) return undefined\n if (entry.value.kind !== \"object\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n \"`waivers` must be an object mapping a core kind to a reason.\",\n entry.value.pos\n )\n }\n const waivers: Record<string, string> = {}\n for (const e of entry.value.entries) {\n if (!CORE_STATE_KINDS.has(e.key)) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `waiver key \"${e.key}\" is not a core kind; only ${[...CORE_STATE_KINDS].join(\", \")} participate in the matrix.`,\n e.keyPos\n )\n }\n if (e.value.kind !== \"string\" || e.value.value.length === 0) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `waiver \"${e.key}\" needs a non-empty reason (why the route cannot render this kind).`,\n e.value.pos\n )\n }\n waivers[e.key] = e.value.value\n }\n return waivers\n}\n\nfunction readBooleanField(\n byKey: Map<string, LitEntry>,\n name: string\n): boolean | undefined {\n const entry = byKey.get(name)\n if (!entry) return undefined\n if (entry.value.kind !== \"boolean\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `\\`${name}\\` must be a boolean.`,\n entry.value.pos\n )\n }\n return entry.value.value\n}\n\nfunction readStringField(\n byKey: Map<string, LitEntry>,\n name: string\n): string | undefined {\n const entry = byKey.get(name)\n if (!entry) return undefined\n if (entry.value.kind !== \"string\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `\\`${name}\\` must be a string.`,\n entry.value.pos\n )\n }\n return entry.value.value\n}\n\nfunction readStringArrayField(\n byKey: Map<string, LitEntry>,\n name: string\n): { values: string[]; spans: Span[] } | undefined {\n const entry = byKey.get(name)\n if (!entry) return undefined\n if (entry.value.kind !== \"array\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `\\`${name}\\` must be an array of strings.`,\n entry.value.pos\n )\n }\n const values: string[] = []\n const spans: Span[] = []\n for (const item of entry.value.items) {\n if (item.kind !== \"string\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `\\`${name}\\` must contain only string literals.`,\n item.pos\n )\n }\n values.push(item.value)\n spans.push(item.span)\n }\n return { values, spans }\n}\n\n/**\n * Parse `states`: a mixed array of bare state names (`\"loading\"`) and\n * `{ name, acceptance?, description? }` objects (per-state acceptance). Names\n * must be non-empty and unique within the entity — a duplicate or empty name is\n * an error (a silent dedupe would hide a mis-typed state from the gate).\n */\nfunction readStatesField(\n byKey: Map<string, LitEntry>\n): ParsedState[] | undefined {\n const entry = byKey.get(\"states\")\n if (!entry) return undefined\n if (entry.value.kind !== \"array\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n \"`states` must be an array of state names or `{ name, acceptance?, description? }` objects.\",\n entry.value.pos\n )\n }\n const states: ParsedState[] = []\n const seen = new Set<string>()\n for (const item of entry.value.items) {\n let state: ParsedState\n if (item.kind === \"string\") {\n state = { name: item.value, nameSpan: item.span }\n } else if (item.kind === \"object\") {\n const fieldByKey = new Map<string, LitEntry>()\n for (const e of item.entries) fieldByKey.set(e.key, e)\n for (const e of item.entries) {\n if (!STATE_FIELDS.has(e.key)) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `Unknown field \"${e.key}\" in a \\`states\\` entry. Allowed: ${Array.from(\n STATE_FIELDS\n )\n .sort()\n .join(\", \")}.`,\n e.value.pos\n )\n }\n }\n const nameEntry = fieldByKey.get(\"name\")\n if (!nameEntry || nameEntry.value.kind !== \"string\") {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n \"Each object `states` entry must have a string `name`.\",\n item.pos\n )\n }\n state = { name: nameEntry.value.value, nameSpan: nameEntry.value.span }\n const kind = readStringField(fieldByKey, \"kind\")\n if (kind !== undefined) {\n if (!STATE_KINDS.has(kind)) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n `state \\`kind\\` must be one of ${[...STATE_KINDS].join(\", \")} (got \"${kind}\").`,\n fieldByKey.get(\"kind\")!.value.pos\n )\n }\n state.kind = kind\n }\n const acceptance = readStringArrayField(fieldByKey, \"acceptance\")?.values\n if (acceptance) state.acceptance = acceptance\n const description = readStringField(fieldByKey, \"description\")\n if (description) state.description = description\n } else {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n \"`states` items must be strings or `{ name, ... }` objects.\",\n item.pos\n )\n }\n if (state.name.length === 0) {\n throw new ExtractError(\n \"uidex-export-invalid-field\",\n \"A `states` entry has an empty `name`.\",\n item.pos\n )\n }\n if (seen.has(state.name)) {\n throw new ExtractError(\n \"uidex-export-duplicate-state\",\n `Duplicate state \"${state.name}\" in \\`states\\`; each state name must be unique within the entity.`,\n item.pos\n )\n }\n seen.add(state.name)\n states.push(state)\n }\n return states\n}\n\n/* ---------- utilities ---------- */\n\nfunction posAt(content: string, offset: number, p: ParsedSource): SourcePos {\n const lineStart = content.lastIndexOf(\"\\n\", offset - 1) + 1\n return { offset, line: p.lineAt(offset), column: offset - lineStart + 1 }\n}\n\n/**\n * Extends a property span over one adjacent comma (trailing preferred) so\n * deleting the span removes the property without leaving a dangling comma.\n */\nfunction removalSpan(content: string, start: number, end: number): Span {\n let e = end\n while (e < content.length && /[ \\t]/.test(content[e])) e++\n if (content[e] === \",\") return { start, end: e + 1 }\n let s = start\n while (s > 0 && /[\\s]/.test(content[s - 1])) s--\n if (content[s - 1] === \",\") return { start: s - 1, end }\n return { start, end }\n}\n\n/**\n * Span of the whole export statement, extended over a trailing semicolon and\n * the line break that follows it, so deleting the span removes the line.\n */\nfunction statementSpan(stmt: AstNode, content: string): Span {\n let end = stmt.end\n while (end < content.length && /[ \\t]/.test(content[end])) end++\n if (content[end] === \";\") end++\n while (end < content.length && /[ \\t]/.test(content[end])) end++\n if (content[end] === \"\\r\") end++\n if (content[end] === \"\\n\") end++\n return { start: stmt.start, end }\n}\n\nfunction isNode(value: unknown): value is AstNode {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { type?: unknown }).type === \"string\"\n )\n}\n","import { walkAst } from \"./ast\"\nimport type { AstNode, ParsedSource } from \"./ast\"\nimport type { DynamicFlowCallFact, FlowCallFact, FlowFact } from \"./types\"\n\n/**\n * Extracts tagged flow describes (`test.describe(\"...\", { tag: \"@uidex:flow\" },\n * fn)`) and the `uidex(\"id\")` calls inside them from the parsed AST.\n *\n * Only statically analysable calls are captured: the describe title must be a\n * string literal and `uidex(...)` arguments must be string literals or\n * expressionless template literals. A chained method that is immediately\n * invoked (`uidex(\"x\").fill(...)`) contributes that method name as the call's\n * action.\n */\nexport function collectFlowFacts(\n parsed: ParsedSource,\n content: string\n): FlowFact[] {\n if (parsed.program === null || !content.includes(\"test.describe\")) {\n return []\n }\n\n const facts: FlowFact[] = []\n walkAst(parsed.program, (node) => {\n if (node.type !== \"CallExpression\") return undefined\n const fact = readTaggedDescribe(node, parsed)\n if (fact) facts.push(fact)\n return undefined\n })\n return facts\n}\n\nfunction readTaggedDescribe(\n call: AstNode,\n parsed: ParsedSource\n): FlowFact | null {\n const callee = call.callee as AstNode | undefined\n if (\n !callee ||\n callee.type !== \"MemberExpression\" ||\n !isIdentifier(callee.object, \"test\") ||\n !isIdentifier(callee.property, \"describe\")\n ) {\n return null\n }\n const args = (call.arguments as AstNode[] | undefined) ?? []\n const title = stringLiteralValue(args[0])\n if (title === null) return null\n if (!hasFlowTag(args[1])) return null\n\n const body = args[2]\n const { calls, dynamicCalls } = body\n ? collectUidexCalls(body, parsed)\n : { calls: [], dynamicCalls: [] }\n return {\n title,\n line: parsed.lineAt(call.start),\n calls,\n ...(dynamicCalls.length > 0 ? { dynamicCalls } : {}),\n }\n}\n\nfunction hasFlowTag(node: AstNode | undefined): boolean {\n if (!node || node.type !== \"ObjectExpression\") return false\n for (const prop of (node.properties as AstNode[] | undefined) ?? []) {\n if (prop.type !== \"Property\") continue\n const key = prop.key as AstNode | undefined\n const keyName =\n key?.type === \"Identifier\"\n ? String(key.name)\n : key?.type === \"Literal\"\n ? String(key.value)\n : null\n if (keyName !== \"tag\") continue\n const value = prop.value as AstNode | undefined\n if (!value) return false\n if (stringLiteralValue(value) === \"@uidex:flow\") return true\n if (value.type === \"ArrayExpression\") {\n for (const el of (value.elements as AstNode[] | undefined) ?? []) {\n if (el && stringLiteralValue(el) === \"@uidex:flow\") return true\n }\n }\n return false\n }\n return false\n}\n\nfunction collectUidexCalls(\n body: AstNode,\n parsed: ParsedSource\n): { calls: FlowCallFact[]; dynamicCalls: DynamicFlowCallFact[] } {\n const calls: FlowCallFact[] = []\n const dynamicCalls: DynamicFlowCallFact[] = []\n // Chained calls record the inner uidex(...) node here so the DFS doesn't\n // record it a second time when it reaches it.\n const claimed = new Set<AstNode>()\n\n const record = (node: AstNode, action?: string): void => {\n if (claimed.has(node)) return\n claimed.add(node)\n const resolved = uidexCallId(node)\n if (resolved === null) {\n // A uidex(...) call whose argument is not a static string literal —\n // invisible to the registry, so coverage silently shrinks. Surfaced\n // as a dynamic-flow-reference lint by the audit.\n dynamicCalls.push({ line: parsed.lineAt(node.start) })\n return\n }\n calls.push({\n id: resolved.id,\n ...(action ? { action } : {}),\n line: parsed.lineAt(node.start),\n span: resolved.span,\n })\n }\n\n walkAst(body, (node) => {\n if (node.type !== \"CallExpression\") return undefined\n\n // uidex(\"id\").action(...) — outer call whose callee member chain starts\n // at a uidex(...) call.\n const callee = node.callee as AstNode | undefined\n if (callee?.type === \"MemberExpression\") {\n const inner = callee.object as AstNode | undefined\n if (inner && isUidexCall(inner)) {\n const property = callee.property as AstNode | undefined\n const action =\n property?.type === \"Identifier\" ? String(property.name) : undefined\n record(inner, action)\n }\n return undefined\n }\n\n // Bare uidex(\"id\") call (or one reached before any chain claimed it).\n if (isUidexCall(node)) record(node)\n return undefined\n })\n\n return { calls, dynamicCalls }\n}\n\n/** True when the node is a `uidex(...)` call with at least one argument. */\nfunction isUidexCall(node: AstNode): boolean {\n if (node.type !== \"CallExpression\") return false\n if (!isIdentifier(node.callee, \"uidex\")) return false\n return ((node.arguments as AstNode[] | undefined) ?? []).length >= 1\n}\n\n/** Returns the static id (and its literal span) of a `uidex(\"...\")` call, else null. */\nfunction uidexCallId(\n node: AstNode\n): { id: string; span: { start: number; end: number } } | null {\n const args = (node.arguments as AstNode[] | undefined) ?? []\n const arg = args[0]\n const id = stringLiteralValue(arg)\n if (id === null) return null\n return { id, span: { start: arg.start, end: arg.end } }\n}\n\nfunction stringLiteralValue(node: AstNode | undefined | null): string | null {\n if (!node) return null\n if (node.type === \"Literal\" && typeof node.value === \"string\") {\n return node.value.length > 0 ? node.value : null\n }\n if (node.type === \"TemplateLiteral\") {\n const expressions = (node.expressions as AstNode[] | undefined) ?? []\n if (expressions.length > 0) return null\n const quasis = (node.quasis as AstNode[] | undefined) ?? []\n const cooked = (quasis[0]?.value as { cooked?: string } | undefined)?.cooked\n return cooked && cooked.length > 0 ? cooked : null\n }\n return null\n}\n\nfunction isIdentifier(node: unknown, name: string): boolean {\n return (\n typeof node === \"object\" &&\n node !== null &&\n (node as AstNode).type === \"Identifier\" &&\n String((node as AstNode).name) === name\n )\n}\n","import { unwrapTsExpression, walkAst } from \"./ast\"\nimport type { AstNode, ParsedSource } from \"./ast\"\nimport type {\n AnnotationAncestor,\n DomAttrKind,\n DynamicAttrFact,\n InteractiveElementFact,\n LandmarkFact,\n Span,\n} from \"./types\"\n\n/**\n * Walks the parsed JSX AST and emits each `data-uidex*` attribute occurrence\n * paired with its JSX ancestor chain (outermost to innermost).\n *\n * Ancestry follows the AST: conditional JSX (`{cond && <div/>}`), `.map()`\n * callbacks, fragments, and JSX nested in attribute expressions all\n * contribute correct chains. A file that failed to parse (`program: null`)\n * yields no occurrences — empty ancestry rather than wrong ancestry.\n */\n\nconst ATTR_NAME_RE = /^data-uidex(?:-(region|widget|primitive))?$/\n\nexport interface DataAttrOccurrence {\n kind: DomAttrKind\n id: string\n line: number\n ancestors: AnnotationAncestor[]\n /** span of the value string literal, when the value is a single plain literal */\n span?: Span\n}\n\nexport interface JSXFacts {\n occurrences: DataAttrOccurrence[]\n /** data-uidex* attributes whose value could not be resolved statically */\n dynamicAttrs: DynamicAttrFact[]\n /** interactive host elements with no data-uidex* attribute at all */\n unannotatedInteractive: InteractiveElementFact[]\n /** HTML5 landmark elements (auto-registered as regions by convention) */\n landmarks: LandmarkFact[]\n}\n\n/** Host tags the audit nudges toward `data-uidex` annotation. */\nconst INTERACTIVE_TAGS = new Set([\"button\", \"a\", \"input\", \"select\", \"textarea\"])\n\n/** Host tags that auto-register as regions (HTML5 landmarks). */\nconst LANDMARK_TAGS = new Set([\"header\", \"nav\", \"main\", \"aside\", \"footer\"])\n\ninterface ResolvedAttr {\n kind: DomAttrKind\n id: string\n /** offset of the attribute node, for line reporting */\n start: number\n /** patterns (template-derived ids containing `*`) sort after static ids */\n isPattern: boolean\n /** span of the value literal, when the value is a single plain literal */\n span?: Span\n}\n\nfunction attrKind(node: AstNode): DomAttrKind | null {\n const name = node.name as AstNode | undefined\n if (!name || name.type !== \"JSXIdentifier\") return null\n const m = ATTR_NAME_RE.exec(String(name.name))\n if (!m) return null\n return (m[1] ?? \"element\") as DomAttrKind\n}\n\n/**\n * Same-file `const name = \"literal\"` bindings, used to resolve identifier\n * references in attribute values. Names bound more than once are dropped —\n * the scanner only inlines unambiguous constants.\n */\nfunction collectConstStrings(program: AstNode): Map<string, string> {\n const consts = new Map<string, string>()\n const seen = new Set<string>()\n walkAst(program, (node) => {\n if (node.type !== \"VariableDeclaration\" || node.kind !== \"const\") {\n return undefined\n }\n for (const decl of (node.declarations as AstNode[] | undefined) ?? []) {\n const id = decl.id as AstNode | undefined\n if (!id || id.type !== \"Identifier\") continue\n const name = String(id.name)\n if (seen.has(name)) {\n consts.delete(name)\n continue\n }\n seen.add(name)\n const init = decl.init as AstNode | undefined\n if (!init) continue\n const value = staticString(unwrapTsExpression(init))\n if (value !== null) consts.set(name, value)\n }\n return undefined\n })\n return consts\n}\n\n/** A plain string literal or expressionless template literal, else null. */\nfunction staticString(node: AstNode): string | null {\n if (node.type === \"Literal\" && typeof node.value === \"string\") {\n return node.value\n }\n if (node.type === \"TemplateLiteral\") {\n const expressions = (node.expressions as AstNode[] | undefined) ?? []\n if (expressions.length > 0) return null\n const quasis = (node.quasis as AstNode[] | undefined) ?? []\n return (quasis[0]?.value as { cooked?: string } | undefined)?.cooked ?? \"\"\n }\n return null\n}\n\ntype EvalResult =\n /** every branch resolved; ids may contain `*` wildcards (patterns) */\n { resolved: true; ids: string[] } | { resolved: false }\n\nconst UNRESOLVED: EvalResult = { resolved: false }\n\n/**\n * Static-id evaluator for data-uidex attribute expressions.\n *\n * - string literal / expressionless template → that id\n * - template with expressions → resolvable parts inline, opaque parts\n * become `*`; the result is a pattern id (requires ≥1 static char)\n * - identifier → unambiguous same-file `const name = \"literal\"`\n * - ternary → union of both branches (both must resolve)\n */\nfunction evalIdExpression(\n expr: AstNode,\n consts: Map<string, string>\n): EvalResult {\n const node = unwrapTsExpression(expr)\n\n const literal = staticString(node)\n if (literal !== null) {\n return literal.length > 0 ? { resolved: true, ids: [literal] } : UNRESOLVED\n }\n\n if (node.type === \"TemplateLiteral\") {\n const quasis = (node.quasis as AstNode[] | undefined) ?? []\n const expressions = (node.expressions as AstNode[] | undefined) ?? []\n let out = \"\"\n for (let i = 0; i < quasis.length; i++) {\n out += (quasis[i].value as { cooked?: string } | undefined)?.cooked ?? \"\"\n if (i < expressions.length) {\n const part = evalIdExpression(expressions[i], consts)\n out += part.resolved && part.ids.length === 1 ? part.ids[0] : \"*\"\n }\n }\n out = out.replace(/\\*{2,}/g, \"*\")\n if (!out.includes(\"*\")) {\n return out.length > 0 ? { resolved: true, ids: [out] } : UNRESOLVED\n }\n // A bare `*` (no static text at all) matches everything — useless as a\n // pattern, so it stays a dynamic attribute.\n return out.replace(/\\*/g, \"\").length > 0\n ? { resolved: true, ids: [out] }\n : UNRESOLVED\n }\n\n if (node.type === \"Identifier\") {\n const value = consts.get(String(node.name))\n return value !== undefined && value.length > 0\n ? { resolved: true, ids: [value] }\n : UNRESOLVED\n }\n\n if (node.type === \"ConditionalExpression\") {\n const left = evalIdExpression(node.consequent as AstNode, consts)\n const right = evalIdExpression(node.alternate as AstNode, consts)\n if (!left.resolved || !right.resolved) return UNRESOLVED\n return { resolved: true, ids: [...new Set([...left.ids, ...right.ids])] }\n }\n\n return UNRESOLVED\n}\n\nfunction collectElementAttrs(\n opening: AstNode,\n consts: Map<string, string>,\n dynamicAttrs: DynamicAttrFact[],\n lineAt: (offset: number) => number\n): ResolvedAttr[] {\n const statics: ResolvedAttr[] = []\n const patterns: ResolvedAttr[] = []\n const attributes = (opening.attributes as AstNode[] | undefined) ?? []\n for (const attr of attributes) {\n if (attr.type !== \"JSXAttribute\") continue\n const kind = attrKind(attr)\n if (!kind) continue\n const value = attr.value as AstNode | null | undefined\n if (!value) continue\n\n let result: EvalResult = UNRESOLVED\n let valueSpan: Span | undefined\n if (value.type === \"Literal\") {\n const v = staticString(value)\n result =\n v !== null && v.length > 0 ? { resolved: true, ids: [v] } : UNRESOLVED\n if (result.resolved) valueSpan = { start: value.start, end: value.end }\n } else if (value.type === \"JSXExpressionContainer\") {\n const expr = value.expression as AstNode | undefined\n if (expr && expr.type !== \"JSXEmptyExpression\") {\n result = evalIdExpression(expr, consts)\n const inner = unwrapTsExpression(expr)\n if (result.resolved && staticString(inner) !== null) {\n valueSpan = { start: inner.start, end: inner.end }\n }\n }\n if (!result.resolved) {\n dynamicAttrs.push({\n kind,\n attrName: kind === \"element\" ? \"data-uidex\" : `data-uidex-${kind}`,\n line: lineAt(attr.start),\n })\n continue\n }\n }\n\n if (!result.resolved) continue\n for (const id of result.ids) {\n const resolved: ResolvedAttr = {\n kind,\n id,\n start: attr.start,\n isPattern: id.includes(\"*\"),\n // Only a single plain string literal is renameable in place.\n ...(result.ids.length === 1 && valueSpan ? { span: valueSpan } : {}),\n }\n if (resolved.isPattern) patterns.push(resolved)\n else statics.push(resolved)\n }\n }\n // Static ids before patterns, matching the registration order entities\n // historically appeared in.\n return [...statics, ...patterns]\n}\n\nexport function collectJSXFacts(parsed: ParsedSource): JSXFacts {\n const occurrences: DataAttrOccurrence[] = []\n const dynamicAttrs: DynamicAttrFact[] = []\n const unannotatedInteractive: InteractiveElementFact[] = []\n const landmarks: LandmarkFact[] = []\n // Files with no data-uidex content can still contain unannotated\n // interactive elements, so only a failed parse short-circuits.\n if (parsed.program === null) {\n return { occurrences, dynamicAttrs, unannotatedInteractive, landmarks }\n }\n\n const consts = collectConstStrings(parsed.program as unknown as AstNode)\n const ancestors: AnnotationAncestor[] = []\n\n const visit = (node: unknown): void => {\n if (!isNode(node)) return\n\n if (node.type === \"JSXElement\") {\n const opening = node.openingElement as AstNode\n const attrs = collectElementAttrs(\n opening,\n consts,\n dynamicAttrs,\n parsed.lineAt\n )\n const interactive = readInteractive(node, parsed.lineAt)\n if (interactive) unannotatedInteractive.push(interactive)\n if (attrs.length > 0) {\n const snapshot = ancestors.slice()\n for (const a of attrs) {\n occurrences.push({\n kind: a.kind,\n id: a.id,\n line: parsed.lineAt(a.start),\n ancestors: snapshot,\n ...(a.span ? { span: a.span } : {}),\n })\n }\n }\n let pushed = attrs.length\n for (const a of attrs) ancestors.push({ kind: a.kind, id: a.id })\n // Landmarks register as convention regions; they join the ancestry so\n // child data-uidex elements compose onto them, unless the element also\n // carries an explicit data-uidex-region (which takes precedence and is\n // already on the stack).\n const landmark = readLandmark(opening, parsed.lineAt)\n if (landmark) {\n landmarks.push(landmark)\n if (!attrs.some((a) => a.kind === \"region\")) {\n ancestors.push({ kind: \"region\", id: landmark.tag })\n pushed++\n }\n }\n // Children, plus JSX nested inside attribute expressions (render\n // props), inherit this element's ancestry.\n visitChildren(opening)\n for (const child of (node.children as AstNode[] | undefined) ?? []) {\n visit(child)\n }\n const closing = node.closingElement\n if (isNode(closing)) visitChildren(closing)\n ancestors.length -= pushed\n return\n }\n\n visitChildren(node)\n }\n\n const visitChildren = (node: AstNode): void => {\n for (const key of Object.keys(node)) {\n if (key === \"type\" || key === \"start\" || key === \"end\") continue\n const value = node[key]\n if (Array.isArray(value)) {\n for (const item of value) visit(item)\n } else {\n visit(value)\n }\n }\n }\n\n visit(parsed.program)\n return { occurrences, dynamicAttrs, unannotatedInteractive, landmarks }\n}\n\n/**\n * Returns a fact when the opening element is an HTML5 landmark tag or\n * carries `role=\"region\"`. The fact's `tag` doubles as the convention\n * region id (\"header\", \"nav\", …, or \"region\" for role-based landmarks).\n */\nfunction readLandmark(\n opening: AstNode,\n lineAt: (offset: number) => number\n): LandmarkFact | null {\n const name = opening.name as AstNode | undefined\n if (!name || name.type !== \"JSXIdentifier\") return null\n const tag = String(name.name)\n if (LANDMARK_TAGS.has(tag)) {\n return { tag, line: lineAt(opening.start) }\n }\n for (const attr of (opening.attributes as AstNode[] | undefined) ?? []) {\n if (attr.type !== \"JSXAttribute\") continue\n const attrName = attr.name as AstNode | undefined\n if (!attrName || String(attrName.name) !== \"role\") continue\n const value = attr.value as AstNode | null | undefined\n if (value && value.type === \"Literal\" && value.value === \"region\") {\n return { tag: \"region\", line: lineAt(opening.start) }\n }\n }\n return null\n}\n\n/**\n * Returns a fact when the opening element is an interactive host tag with no\n * data-uidex* attribute of any form (static, pattern, or dynamic). Captures\n * the attribute-insertion offset and a static name hint so `--fix` can\n * deterministically generate a `data-uidex` id.\n */\nfunction readInteractive(\n element: AstNode,\n lineAt: (offset: number) => number\n): InteractiveElementFact | null {\n const opening = element.openingElement as AstNode\n const name = opening.name as AstNode | undefined\n if (!name || name.type !== \"JSXIdentifier\") return null\n const tag = String(name.name)\n if (!INTERACTIVE_TAGS.has(tag)) return null\n let hasSpread = false\n for (const attr of (opening.attributes as AstNode[] | undefined) ?? []) {\n if (attr.type === \"JSXSpreadAttribute\") {\n hasSpread = true\n continue\n }\n if (attr.type === \"JSXAttribute\" && attrKind(attr) !== null) return null\n }\n const nameHint = interactiveNameHint(element, opening)\n return {\n tag,\n line: lineAt(opening.start),\n hasSpread,\n nameEnd: name.end as number,\n ...(nameHint ? { nameHint } : {}),\n }\n}\n\n/** Static string value of a named attribute on the opening element, or null. */\nfunction staticAttrValue(opening: AstNode, attrName: string): string | null {\n for (const attr of (opening.attributes as AstNode[] | undefined) ?? []) {\n if (attr.type !== \"JSXAttribute\") continue\n const n = attr.name as AstNode | undefined\n if (!n || String(n.name) !== attrName) continue\n const value = attr.value as AstNode | null | undefined\n if (!value) return null\n if (value.type === \"Literal\") return staticString(value)\n if (value.type === \"JSXExpressionContainer\") {\n const expr = value.expression as AstNode | undefined\n return expr ? staticString(unwrapTsExpression(expr)) : null\n }\n return null\n }\n return null\n}\n\n/** Concatenated static JSXText children, whitespace-collapsed and trimmed. */\nfunction staticChildText(element: AstNode): string {\n const parts: string[] = []\n for (const child of (element.children as AstNode[] | undefined) ?? []) {\n if (child.type === \"JSXText\") {\n parts.push(String((child as { value?: unknown }).value ?? \"\"))\n }\n }\n return parts.join(\" \").replace(/\\s+/g, \" \").trim()\n}\n\n/**\n * Best static label for an interactive element, used to derive a `data-uidex`\n * id: accessible name first (aria-label), then visible text, then descriptive\n * attributes. Returns undefined when nothing statically usable exists.\n */\nfunction interactiveNameHint(\n element: AstNode,\n opening: AstNode\n): string | undefined {\n const ariaLabel = staticAttrValue(opening, \"aria-label\")\n if (ariaLabel) return ariaLabel\n const text = staticChildText(element)\n if (text) return text\n for (const attr of [\"title\", \"name\", \"placeholder\"]) {\n const v = staticAttrValue(opening, attr)\n if (v) return v\n }\n return undefined\n}\n\nfunction isNode(value: unknown): value is AstNode {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { type?: unknown }).type === \"string\"\n )\n}\n","import { parseSource } from \"./ast\"\nimport type { AstNode, ParsedSource } from \"./ast\"\nimport { extractUidexExports } from \"./extract-uidex-export\"\nimport { collectFlowFacts } from \"./flow-facts\"\nimport { collectJSXFacts } from \"./jsx-ancestry\"\nimport type {\n Annotation,\n Diagnostic,\n ExtractedFile,\n ImportFact,\n ScannedFile,\n} from \"./types\"\n\n/**\n * A fatal oxc failure (throw, or an empty program body alongside reported\n * errors — oxc's signature for unrecoverable input, e.g. a syntax error or a\n * Flow-typed .js file) means every AST-derived fact for the file is silently\n * empty. Surface that instead of letting the file's ids vanish from the gen\n * file with no trace. Recoverable errors keep a usable program and stay quiet.\n */\nfunction parseFailureDiagnostic(\n file: ScannedFile,\n parsed: ParsedSource\n): Diagnostic | null {\n const fatal =\n parsed.program === null ||\n (parsed.hasErrors && parsed.program.body.length === 0)\n if (!fatal) return null\n return {\n code: \"parse-error\",\n severity: \"warning\",\n message:\n \"File could not be parsed — data-uidex attributes and flow facts in it were skipped, and their ids will drop out of the gen file\",\n file: file.displayPath,\n line: 1,\n hint: \"Fix the file's syntax (or exclude it from .uidex.json sources) so the scanner can read its annotations\",\n }\n}\n\nexport function extract(files: ScannedFile[]): ExtractedFile[] {\n return files.map((file) => {\n // One parse per file; every AST-derived fact comes out of this pass and\n // the program itself never leaves the extract phase.\n const parsed = parseSource(file)\n const { exports, diagnostics } = extractUidexExports(file, parsed)\n const parseFailure = parseFailureDiagnostic(file, parsed)\n if (parseFailure) diagnostics.push(parseFailure)\n const out: ExtractedFile = { file, annotations: [] }\n out.annotations = extractOne(file, parsed, out)\n if (exports.length > 0) out.metadata = exports\n if (diagnostics.length > 0) out.diagnostics = diagnostics\n const flows = collectFlowFacts(parsed, file.content)\n if (flows.length > 0) out.flows = flows\n const imports = collectImportFacts(parsed)\n if (imports.length > 0) out.imports = imports\n return out\n })\n}\n\nfunction extractOne(\n file: ScannedFile,\n parsed: ParsedSource,\n out: ExtractedFile\n): Annotation[] {\n const annotations: Annotation[] = []\n const { displayPath } = file\n\n const jsx = collectJSXFacts(parsed)\n if (jsx.dynamicAttrs.length > 0) out.dynamicAttrs = jsx.dynamicAttrs\n if (jsx.unannotatedInteractive.length > 0) {\n out.unannotatedInteractive = jsx.unannotatedInteractive\n }\n if (jsx.landmarks.length > 0) out.landmarks = jsx.landmarks\n for (const occ of jsx.occurrences) {\n annotations.push({\n kind: occ.kind,\n id: occ.id,\n file: displayPath,\n line: occ.line,\n ...(occ.ancestors.length > 0 ? { ancestors: occ.ancestors } : {}),\n ...(occ.span ? { span: occ.span } : {}),\n })\n }\n\n return annotations\n}\n\n/**\n * Static import bindings from the top-level program body: `import` and\n * re-export (`export … from`) statements. Dynamic `import()` and `require()`\n * are intentionally out of scope — the scope-leak check is about module\n * dependency structure, which those don't declare statically.\n */\nfunction collectImportFacts(parsed: ParsedSource): ImportFact[] {\n if (parsed.program === null) return []\n const out: ImportFact[] = []\n for (const stmt of parsed.program.body as unknown as AstNode[]) {\n let source: AstNode | null | undefined\n let isTypeOnly = false\n const names: string[] = []\n if (stmt.type === \"ImportDeclaration\") {\n source = stmt.source as AstNode | undefined\n isTypeOnly = stmt.importKind === \"type\"\n for (const spec of (stmt.specifiers as AstNode[] | undefined) ?? []) {\n const local = spec.local as AstNode | undefined\n if (local && local.type === \"Identifier\") {\n names.push(String(local.name))\n }\n }\n } else if (\n (stmt.type === \"ExportNamedDeclaration\" ||\n stmt.type === \"ExportAllDeclaration\") &&\n stmt.source\n ) {\n source = stmt.source as AstNode\n isTypeOnly = stmt.exportKind === \"type\"\n } else {\n continue\n }\n if (!source || source.type !== \"Literal\") continue\n if (typeof source.value !== \"string\") continue\n out.push({\n specifier: source.value,\n line: parsed.lineAt(stmt.start),\n span: { start: stmt.start, end: stmt.end },\n isTypeOnly,\n names,\n })\n }\n return out\n}\n","import * as path from \"node:path\"\nimport {\n createRegistry,\n type Entity,\n type EntityRef,\n type Feature,\n type Flow,\n type Metadata,\n type Page,\n type Primitive,\n type Region,\n type Registry,\n type StateDecl,\n type Widget,\n type Element as UidexElement,\n} from \"../../shared/entities\"\nimport { DEFAULT_CONVENTIONS, WELL_KNOWN_FILES } from \"./config\"\nimport { detectRoutes } from \"./routes\"\nimport { globToRegExp } from \"./walk\"\nimport type {\n Annotation,\n ConventionsConfig,\n DetectedRoute,\n Diagnostic,\n DomAttrKind,\n ExtractedFile,\n MetadataExport,\n UidexConfig,\n} from \"./types\"\n\nconst DOM_ATTR_KINDS: ReadonlySet<Annotation[\"kind\"]> = new Set([\n \"element\",\n \"region\",\n \"widget\",\n \"primitive\",\n])\n\nexport interface ResolveContext {\n config: UidexConfig\n extracted: ExtractedFile[]\n flowFiles?: ExtractedFile[]\n}\n\nexport interface ResolveOutput {\n registry: Registry\n entities: Entity[]\n routes: DetectedRoute[]\n diagnostics: Diagnostic[]\n}\n\nfunction resolveConventions(c: ConventionsConfig | undefined): {\n primitives: string[] | false\n features: string | false\n pages: \"auto\" | false | { routesDir: string }\n flows: string[] | false\n regions: \"landmarks\" | false\n} {\n return {\n primitives:\n c?.primitives === undefined\n ? DEFAULT_CONVENTIONS.primitives\n : c.primitives,\n features:\n c?.features === undefined ? DEFAULT_CONVENTIONS.features : c.features,\n pages: c?.pages === undefined ? DEFAULT_CONVENTIONS.pages : c.pages,\n flows: c?.flows === undefined ? DEFAULT_CONVENTIONS.flows : c.flows,\n regions: c?.regions === undefined ? DEFAULT_CONVENTIONS.regions : c.regions,\n }\n}\n\nfunction kebab(str: string): string {\n return str\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .replace(/[_\\s]+/g, \"-\")\n .replace(/[^a-zA-Z0-9-]/g, \"\")\n .toLowerCase()\n}\n\nfunction baseName(file: string): string {\n const b = path.posix.basename(file)\n return b.replace(/\\.(tsx|ts|jsx|js|mjs|cjs)$/, \"\")\n}\n\nfunction fileMatchesAny(displayPath: string, patterns: string[]): boolean {\n return patterns.some((g) => globToRegExp(g).test(displayPath))\n}\n\nfunction buildMetaFromExport(exp: MetadataExport): Metadata | undefined {\n const meta: Metadata = {}\n if (exp.name) meta.name = exp.name\n if (exp.description) meta.description = exp.description\n if (exp.acceptance?.length) meta.acceptance = exp.acceptance\n if (exp.features?.length) meta.features = exp.features\n if (exp.widgets?.length) meta.widgets = exp.widgets\n if (exp.states?.length) {\n // Strip parse-only name spans — the emitted Metadata is span-free.\n meta.states = exp.states.map((s) => ({\n name: s.name,\n ...(s.kind ? { kind: s.kind as StateDecl[\"kind\"] } : {}),\n ...(s.acceptance?.length ? { acceptance: s.acceptance } : {}),\n ...(s.description ? { description: s.description } : {}),\n }))\n }\n // The REMOVED `capture` / `waivers` fields deliberately do NOT flow into the\n // registry: an unmigrated declaration must be a loud error with a fix, never\n // a gate that half-works. `audit()` reports them from the extract output.\n if (exp.acknowledge && Object.keys(exp.acknowledge).length > 0) {\n meta.acknowledge = exp.acknowledge as Metadata[\"acknowledge\"]\n }\n return Object.keys(meta).length > 0 ? meta : undefined\n}\n\n/**\n * Resolve annotations + conventions into a typed Registry.\n * Precedence: configuration > `export const uidex` > DOM attribute > convention.\n */\nexport function resolve(ctx: ResolveContext): ResolveOutput {\n const conventions = resolveConventions(ctx.config.conventions)\n const registry = createRegistry()\n const diagnostics: Diagnostic[] = []\n\n // Index per-file exports by kind. Multiple kinds in one file are\n // disallowed by extract, so a file has at most one export per kind.\n const exportsByFile = new Map<string, Map<string, MetadataExport>>()\n for (const ef of ctx.extracted) {\n if (!ef.metadata) continue\n const map = new Map<string, MetadataExport>()\n for (const m of ef.metadata) map.set(m.kind, m)\n exportsByFile.set(ef.file.displayPath, map)\n }\n function exportFor(\n file: string,\n kind: MetadataExport[\"kind\"]\n ): MetadataExport | undefined {\n return exportsByFile.get(file)?.get(kind)\n }\n\n const allAnnotations: Annotation[] = []\n for (const ef of ctx.extracted) {\n for (const a of ef.annotations) allAnnotations.push(a)\n }\n\n // Parent → ordered, deduped direct-child refs. The parent key is\n // `kind:id` of the innermost JSX ancestor carrying a `data-uidex*`\n // attribute. Used to emit `meta.composes` on containers below.\n const directChildren = new Map<string, EntityRef[]>()\n const seenPerParent = new Map<string, Set<string>>()\n for (const ann of allAnnotations) {\n if (!DOM_ATTR_KINDS.has(ann.kind)) continue\n const parent = ann.ancestors?.[ann.ancestors.length - 1]\n if (!parent) continue\n const pk = `${parent.kind}:${parent.id}`\n const childKey = `${ann.kind}:${ann.id}`\n let seen = seenPerParent.get(pk)\n if (!seen) {\n seen = new Set()\n seenPerParent.set(pk, seen)\n }\n if (seen.has(childKey)) continue\n seen.add(childKey)\n let arr = directChildren.get(pk)\n if (!arr) {\n arr = []\n directChildren.set(pk, arr)\n }\n arr.push({ kind: ann.kind as DomAttrKind, id: ann.id })\n }\n\n function metaWithComposes(\n kind: \"widget\" | \"region\" | \"primitive\",\n id: string,\n base?: Metadata\n ): Metadata | undefined {\n const composes = directChildren.get(`${kind}:${id}`)\n if (!composes || composes.length === 0) return base\n return { ...base, composes }\n }\n\n // ---------- pages ----------\n const routes: DetectedRoute[] =\n conventions.pages === false\n ? []\n : detectRoutes(\n ctx.extracted.map((e) => e.file),\n conventions.pages === \"auto\"\n ? {}\n : { routesDir: conventions.pages.routesDir }\n )\n\n const handledPageFiles = new Set<string>()\n for (const route of routes) {\n const routeDir = path.posix.dirname(route.file)\n const wellKnownPath = `${routeDir}/${WELL_KNOWN_FILES.page}`\n const wellKnownExp = exportFor(wellKnownPath, \"page\")\n const routeExp = exportFor(route.file, \"page\")\n\n const exp = wellKnownExp ?? routeExp\n const locFile = wellKnownExp ? wellKnownPath : route.file\n\n if (wellKnownExp) handledPageFiles.add(wellKnownPath)\n handledPageFiles.add(route.file)\n\n if (wellKnownExp && routeExp) {\n diagnostics.push({\n code: \"competing-uidex-export\",\n severity: \"warning\",\n message: `Page metadata declared in both ${wellKnownPath} and ${route.file}; ${wellKnownPath} takes precedence.`,\n file: route.file,\n line: routeExp.loc.line,\n hint: `Remove the export from ${route.file} or delete ${wellKnownPath}.`,\n })\n }\n\n if (exp && exp.id === false) continue\n const effectiveId = exp && typeof exp.id === \"string\" ? exp.id : route.id\n const meta = exp ? buildMetaFromExport(exp) : undefined\n registry.add({ kind: \"route\", path: route.path, page: effectiveId })\n const page: Page = {\n kind: \"page\",\n id: effectiveId,\n loc: { file: locFile, line: exp?.loc.line },\n ...(meta ? { meta } : {}),\n }\n registry.add(page)\n }\n\n // Page exports in non-conventional locations.\n for (const ef of ctx.extracted) {\n const exp = exportFor(ef.file.displayPath, \"page\")\n if (!exp || typeof exp.id !== \"string\") continue\n if (handledPageFiles.has(ef.file.displayPath)) continue\n const meta = buildMetaFromExport(exp)\n registry.add({\n kind: \"page\",\n id: exp.id,\n loc: { file: ef.file.displayPath, line: exp.loc.line },\n ...(meta ? { meta } : {}),\n })\n }\n\n // ---------- features ----------\n const featureGlob =\n typeof conventions.features === \"string\" ? conventions.features : null\n const conventionalFeatureDirs = new Set<string>()\n const featureExportFilesByDir = new Map<\n string,\n Array<{ file: string; exp: MetadataExport }>\n >()\n const wellKnownFeatureFileByDir = new Map<string, string>()\n const suppressedFeatureDirs = new Set<string>()\n\n if (featureGlob) {\n const re = globToRegExp(featureGlob + \"/**\")\n for (const ef of ctx.extracted) {\n if (!re.test(ef.file.displayPath)) continue\n const dir = extractFeatureDir(ef.file.displayPath, featureGlob)\n if (!dir) continue\n conventionalFeatureDirs.add(dir)\n const isWellKnown =\n path.posix.basename(ef.file.displayPath) === WELL_KNOWN_FILES.feature\n if (isWellKnown) wellKnownFeatureFileByDir.set(dir, ef.file.displayPath)\n const exp = exportFor(ef.file.displayPath, \"feature\")\n if (exp) {\n if (exp.id === false) suppressedFeatureDirs.add(dir)\n else {\n let arr = featureExportFilesByDir.get(dir)\n if (!arr) {\n arr = []\n featureExportFilesByDir.set(dir, arr)\n }\n arr.push({ file: ef.file.displayPath, exp })\n }\n }\n }\n for (const dir of conventionalFeatureDirs) {\n if (suppressedFeatureDirs.has(dir)) continue\n const allExports = featureExportFilesByDir.get(dir) ?? []\n const wellKnownPath = wellKnownFeatureFileByDir.get(dir)\n const wellKnownEntry = wellKnownPath\n ? allExports.find((e) => e.file === wellKnownPath)\n : undefined\n\n let exp: MetadataExport | undefined\n if (wellKnownEntry) {\n exp = wellKnownEntry.exp\n for (const other of allExports) {\n if (other.file === wellKnownEntry.file) continue\n diagnostics.push({\n code: \"competing-uidex-export\",\n severity: \"warning\",\n message: `Feature metadata declared in both ${wellKnownEntry.file} and ${other.file}; ${wellKnownEntry.file} takes precedence.`,\n file: other.file,\n line: other.exp.loc.line,\n hint: `Remove the export from ${other.file} or delete ${wellKnownEntry.file}.`,\n })\n }\n } else if (allExports.length > 0) {\n exp = allExports[0].exp\n }\n\n const id =\n exp && typeof exp.id === \"string\" ? exp.id : path.posix.basename(dir)\n const meta = exp ? buildMetaFromExport(exp) : undefined\n const feature: Feature = {\n kind: \"feature\",\n id,\n loc: exp ? { file: exp.loc.file, line: exp.loc.line } : { file: dir },\n ...(meta ? { meta } : {}),\n }\n registry.add(feature)\n }\n }\n\n // Feature exports at non-conventional paths.\n for (const ef of ctx.extracted) {\n const exp = exportFor(ef.file.displayPath, \"feature\")\n if (!exp || typeof exp.id !== \"string\") continue\n if (featureGlob) {\n const dir = extractFeatureDir(ef.file.displayPath, featureGlob)\n if (dir && conventionalFeatureDirs.has(dir)) continue\n }\n const meta = buildMetaFromExport(exp)\n registry.add({\n kind: \"feature\",\n id: exp.id,\n loc: { file: ef.file.displayPath, line: exp.loc.line },\n ...(meta ? { meta } : {}),\n })\n }\n\n // ---------- widgets ----------\n const widgetDomByFile = new Map<string, Annotation[]>()\n for (const a of allAnnotations) {\n if (a.kind !== \"widget\") continue\n const list = widgetDomByFile.get(a.file) ?? []\n list.push(a)\n widgetDomByFile.set(a.file, list)\n }\n const widgetFiles = new Set<string>([\n ...widgetDomByFile.keys(),\n ...[...exportsByFile.entries()]\n .filter(([, kinds]) => kinds.has(\"widget\"))\n .map(([file]) => file),\n ])\n for (const file of widgetFiles) {\n const domAnnotations = widgetDomByFile.get(file) ?? []\n const exp = exportFor(file, \"widget\")\n if (exp && typeof exp.id === \"string\") {\n const exportId = exp.id\n const domIds = domAnnotations.map((a) => a.id)\n if (domAnnotations.length === 0) {\n diagnostics.push({\n code: \"widget-missing-dom\",\n severity: \"error\",\n message: `Widget \"${exportId}\" declared via export const uidex but no data-uidex-widget=\"${exportId}\" attribute found in the same file`,\n file,\n line: exp.loc.line,\n entity: { kind: \"widget\", id: exportId },\n hint: `Add \\`<... data-uidex-widget=\"${exportId}\">\\` at the widget's DOM root`,\n })\n continue\n }\n if (!domIds.includes(exportId)) {\n const domList = domIds.map((i) => `\"${i}\"`).join(\", \")\n diagnostics.push({\n code: \"widget-id-mismatch\",\n severity: \"error\",\n message: `Widget id mismatch in ${file}: export declares \"${exportId}\" but data-uidex-widget attribute(s) are [${domList}]`,\n file,\n line: exp.loc.line,\n entity: { kind: \"widget\", id: exportId },\n hint: `Update either the export or the DOM attribute so both sides use the same id`,\n })\n continue\n }\n const match = domAnnotations.find((a) => a.id === exportId)!\n const meta = metaWithComposes(\n \"widget\",\n exportId,\n buildMetaFromExport(exp)\n )\n const widget: Widget = {\n kind: \"widget\",\n id: exportId,\n loc: { file, line: match.line },\n ...(meta ? { meta } : {}),\n }\n registry.add(widget)\n } else {\n for (const a of domAnnotations) {\n const meta = metaWithComposes(\"widget\", a.id)\n const widget: Widget = {\n kind: \"widget\",\n id: a.id,\n loc: { file: a.file, line: a.line },\n ...(meta ? { meta } : {}),\n }\n registry.add(widget)\n }\n }\n }\n\n // ---------- regions ----------\n // Landmark facts come from the JSX AST (extract phase), so a `<header>`\n // inside a string or comment never registers, and landmark regions\n // participate in ancestry/composes like attribute regions do.\n if (conventions.regions === \"landmarks\") {\n for (const ef of ctx.extracted) {\n for (const lm of ef.landmarks ?? []) {\n const id = lm.tag\n if (!registry.get(\"region\", id)) {\n const meta = metaWithComposes(\"region\", id)\n const region: Region = {\n kind: \"region\",\n id,\n loc: { file: ef.file.displayPath, line: lm.line },\n ...(meta ? { meta } : {}),\n }\n registry.add(region)\n }\n }\n }\n }\n for (const r of allAnnotations.filter((a) => a.kind === \"region\")) {\n const meta = metaWithComposes(\"region\", r.id)\n const region: Region = {\n kind: \"region\",\n id: r.id,\n loc: { file: r.file, line: r.line },\n ...(meta ? { meta } : {}),\n }\n registry.add(region)\n }\n for (const ef of ctx.extracted) {\n const exp = exportFor(ef.file.displayPath, \"region\")\n if (!exp) continue\n if (exp.id === false) continue\n if (typeof exp.id === \"string\" && !registry.get(\"region\", exp.id)) {\n const meta = buildMetaFromExport(exp)\n const region: Region = {\n kind: \"region\",\n id: exp.id,\n loc: { file: ef.file.displayPath, line: exp.loc.line },\n ...(meta ? { meta } : {}),\n }\n registry.add(region)\n }\n }\n\n // ---------- primitives ----------\n const primitiveConventions = conventions.primitives\n for (const ef of ctx.extracted) {\n const file = ef.file.displayPath\n const exp = exportFor(file, \"primitive\")\n if (exp && exp.id === false) continue // suppression\n if (exp && typeof exp.id === \"string\") {\n const meta = metaWithComposes(\n \"primitive\",\n exp.id,\n buildMetaFromExport(exp)\n )\n const scope = computeScope(file)\n const primitive: Primitive = {\n kind: \"primitive\",\n id: exp.id,\n loc: { file, line: exp.loc.line },\n ...(scope ? { scopes: [scope] } : {}),\n ...(meta ? { meta } : {}),\n }\n registry.add(primitive)\n continue\n }\n const domPrimitives = allAnnotations.filter(\n (a) => a.kind === \"primitive\" && a.file === file\n )\n if (domPrimitives.length > 0) {\n for (const p of domPrimitives) {\n const meta = metaWithComposes(\"primitive\", p.id)\n const domScope = computeScope(p.file)\n const primitive: Primitive = {\n kind: \"primitive\",\n id: p.id,\n loc: { file: p.file, line: p.line },\n ...(domScope ? { scopes: [domScope] } : {}),\n ...(meta ? { meta } : {}),\n }\n registry.add(primitive)\n }\n continue\n }\n if (primitiveConventions && fileMatchesAny(file, primitiveConventions)) {\n const name = kebab(baseName(file))\n if (!name) continue\n const convScope = computeScope(file)\n const meta = metaWithComposes(\"primitive\", name)\n const primitive: Primitive = {\n kind: \"primitive\",\n id: name,\n loc: { file },\n ...(convScope ? { scopes: [convScope] } : {}),\n ...(meta ? { meta } : {}),\n }\n registry.add(primitive)\n }\n }\n\n // ---------- elements (annotation-only) ----------\n for (const e of allAnnotations.filter((a) => a.kind === \"element\")) {\n const element: UidexElement = {\n kind: \"element\",\n id: e.id,\n loc: { file: e.file, line: e.line },\n }\n registry.add(element)\n }\n\n // ---------- containment: what a flow IMPLICITLY touches ----------\n //\n // A flow drives ELEMENTS — `uidex(\"product-save-btn\")` — and never names the widget, page or\n // feature that contains them. Coverage (`computeFlowIds`) matches `flow.touches` by EXACT id,\n // so before this, no widget/page/feature was ever linked to any flow: `meta.flows` was empty\n // for every entity in a project, and `acceptance-uncovered` therefore fired for every declared\n // criterion no matter how thoroughly it was driven. A diagnostic that cannot distinguish\n // covered from uncovered is noise, and this one had been silently emitting it.\n //\n // Two containment relations, matching how each kind is actually defined:\n // - widget/region: JSX ancestry. `Annotation.ancestors` already carries the chain, so an\n // element inside a `data-uidex-widget` root links that widget.\n // - feature/page: file ownership. A feature is a DIRECTORY (`src/features/products/**`) and\n // a page is a MODULE, neither of which appears in the DOM, so neither can ever be a JSX\n // ancestor — ownership is the only relation that can express them.\n const ancestorsById = new Map<string, string[]>()\n const fileById = new Map<string, string>()\n for (const a of allAnnotations) {\n if (!fileById.has(a.id)) fileById.set(a.id, a.file)\n if (a.ancestors?.length) {\n const prev = ancestorsById.get(a.id) ?? []\n ancestorsById.set(a.id, [...prev, ...a.ancestors.map((x) => x.id)])\n }\n }\n const ownersByFile = new Map<string, string[]>()\n const addOwner = (file: string, id: string): void => {\n ownersByFile.set(file, [...(ownersByFile.get(file) ?? []), id])\n }\n const featureDirs: { dir: string; id: string }[] = []\n for (const f of registry.list(\"feature\")) {\n const loc = f.loc?.file\n if (!loc) continue\n // A conventional feature's loc is its declaring module; the directory owns the annotations.\n const dir = loc.endsWith(\"/\") ? loc.slice(0, -1) : path.posix.dirname(loc)\n featureDirs.push({ dir, id: f.id })\n }\n for (const p of registry.list(\"page\")) {\n if (p.loc?.file) addOwner(p.loc.file, p.id)\n }\n const ownersFor = (file: string): string[] => {\n const out = [...(ownersByFile.get(file) ?? [])]\n for (const { dir, id } of featureDirs) {\n if (file === dir || file.startsWith(`${dir}/`)) out.push(id)\n }\n return out\n }\n const expandTouches = (ids: string[]): string[] => {\n const out = new Set(ids)\n for (const id of ids) {\n for (const anc of ancestorsById.get(id) ?? []) out.add(anc)\n const file = fileById.get(id)\n if (file) for (const owner of ownersFor(file)) out.add(owner)\n }\n return [...out]\n }\n\n // ---------- flows ----------\n if (ctx.flowFiles && conventions.flows) {\n for (const ff of ctx.flowFiles) {\n const notFlowExport = (ff.metadata ?? []).find(\n (m) => m.kind === \"flow\" && m.notFlow === true\n )\n if (notFlowExport) continue\n const flowExport = (ff.metadata ?? []).find(\n (m) => m.kind === \"flow\" && typeof m.id === \"string\"\n )\n // `steps` stays the literal driven sequence; only `touches` gains the containers, so the\n // devtools timeline still shows what the flow actually did.\n const derived = flowsFromFacts(ff).map((f) => ({\n ...f,\n touches: expandTouches(f.touches),\n }))\n if (\n flowExport &&\n typeof flowExport.id === \"string\" &&\n derived.length === 1\n ) {\n const base = derived[0]\n const flow: Flow = {\n kind: \"flow\",\n id: flowExport.id,\n loc: base.loc,\n touches: base.touches,\n steps: base.steps,\n }\n registry.add(flow)\n } else {\n for (const flow of derived) registry.add(flow)\n }\n }\n }\n\n const entities: Entity[] = []\n for (const kind of [\n \"route\",\n \"page\",\n \"feature\",\n \"widget\",\n \"region\",\n \"element\",\n \"primitive\",\n \"flow\",\n ] as const) {\n entities.push(...registry.list(kind))\n }\n\n return { registry, entities, routes, diagnostics }\n}\n\nfunction extractFeatureDir(\n displayPath: string,\n featureGlob: string\n): string | null {\n // featureGlob like \"src/features/*\"\n const parts = featureGlob.split(\"/\")\n const starIdx = parts.indexOf(\"*\")\n if (starIdx === -1) return null\n const prefixParts = parts.slice(0, starIdx)\n const pathParts = displayPath.split(\"/\")\n for (let i = 0; i < prefixParts.length; i++) {\n if (pathParts[i] !== prefixParts[i]) return null\n }\n if (pathParts.length <= starIdx) return null\n return pathParts.slice(0, starIdx + 1).join(\"/\")\n}\n\nfunction computeScope(displayPath: string): string | null {\n const parts = displayPath.split(\"/\")\n const featureIdx = parts.indexOf(\"features\")\n if (featureIdx !== -1 && parts[featureIdx + 1]) {\n return `feature:${parts[featureIdx + 1]}`\n }\n const pagesIdx = parts.indexOf(\"pages\")\n if (pagesIdx !== -1 && parts[pagesIdx + 1]) {\n return `page:${parts[pagesIdx + 1]}`\n }\n return null\n}\n\n// -------- flow derivation from extract-phase facts --------\n\nfunction flowsFromFacts(ff: ExtractedFile): Flow[] {\n return (ff.flows ?? []).map((fact) => ({\n kind: \"flow\",\n id: kebab(fact.title),\n loc: { file: ff.file.displayPath, line: fact.line },\n touches: dedupe(fact.calls.map((c) => c.id)),\n steps: fact.calls\n .filter((c) => c.action)\n .map((c) => ({ entityId: c.id, action: c.action })),\n }))\n}\n\nfunction dedupe<T>(arr: T[]): T[] {\n return Array.from(new Set(arr))\n}\n","import type { DetectedRoute, ScannedFile } from \"./types\"\n\nconst PAGE_BASENAME = /^page\\.(tsx|ts|jsx|js|mjs|cjs)$/\nconst PAGES_ROUTER_BASENAME = /\\.(tsx|ts|jsx|js|mjs|cjs)$/\nconst ROUTE_BASENAME = /^route\\.(tsx|ts|jsx|js|mjs|cjs)$/\n\n/**\n * Detect framework-aware routes:\n * - Next.js App Router: `**\\/app/**\\/page.tsx` -> `/segments`\n * - Next.js Pages Router: `**\\/pages/**\\/*.tsx` -> `/segments` (excludes _app, _document, api/)\n * - Vite + TanStack Router / React Router: `**\\/routes/**\\/*.tsx` -> `/segments`.\n * Honors TanStack conventions: pathless layouts (`_layout`) and route\n * groups (`(group)`) drop from the path, the folder route file\n * (`route.tsx`) collapses like `index`, `-`-prefixed and `api/` files are\n * excluded, and flat dot-notation filenames (`a.b.$c.tsx`) split into\n * nested segments. Dynamic segments are normalized to the canonical\n * `[param]` form used everywhere else in the pipeline: `$id` -> `[id]`,\n * the splat `$` -> `[...splat]`, and `[.]`-escaped literals are unwrapped.\n */\nexport interface DetectRoutesOptions {\n /**\n * Explicit routes root, as it appears in `displayPath` (relative to the\n * config dir). When set, only files under this dir are routes and the\n * TanStack / React Router `routes/`-style convention is applied — overriding\n * the `app`/`pages`/`routes` directory-name heuristic. Use for a custom\n * TanStack `routesDirectory`.\n */\n routesDir?: string\n}\n\nexport function detectRoutes(\n files: ScannedFile[],\n options: DetectRoutesOptions = {}\n): DetectedRoute[] {\n const out: DetectedRoute[] = []\n const seen = new Set<string>()\n\n const routesDir = options.routesDir\n ? options.routesDir.replace(/^\\.?\\/+/, \"\").replace(/\\/+$/, \"\")\n : null\n const routesDirParts = routesDir ? routesDir.split(\"/\") : null\n\n for (const f of files) {\n const rel = f.displayPath\n const parts = rel.split(\"/\")\n const base = parts[parts.length - 1]\n\n // Explicit routes root (custom TanStack `routesDirectory`): only files under\n // it are routes; the directory-name heuristic below is skipped entirely.\n if (routesDirParts) {\n const end = dirEndIndex(parts, routesDirParts)\n if (end === -1 || end > parts.length - 1) continue\n if (!PAGES_ROUTER_BASENAME.test(base)) continue\n const routePath = routesStylePath(\n parts.slice(end, parts.length - 1),\n base\n )\n if (routePath !== null) push(out, seen, routePath, f.displayPath)\n continue\n }\n\n // Next.js App Router: segments after `app/` including page.tsx\n const appIdx = parts.indexOf(\"app\")\n if (appIdx !== -1 && PAGE_BASENAME.test(base)) {\n const routeSegments = parts.slice(appIdx + 1, parts.length - 1)\n const routePath = formatNextAppPath(routeSegments)\n push(out, seen, routePath, f.displayPath)\n continue\n }\n if (appIdx !== -1 && ROUTE_BASENAME.test(base)) {\n // app router \"route handler\" (API) — skip, not a page\n continue\n }\n\n // Next.js Pages Router\n const pagesIdx = parts.indexOf(\"pages\")\n if (pagesIdx !== -1 && PAGES_ROUTER_BASENAME.test(base)) {\n const segs = parts.slice(pagesIdx + 1)\n // skip pages/api\n if (segs[0] === \"api\") continue\n const last = segs[segs.length - 1]\n if (last.startsWith(\"_\")) continue\n const normalized = [\n ...segs.slice(0, -1),\n base.replace(/\\.[^.]+$/, \"\"),\n ].filter((s) => s !== \"index\")\n const routePath = formatNextAppPath(normalized)\n push(out, seen, routePath, f.displayPath)\n continue\n }\n\n // Vite: TanStack Router / React Router `routes/` directory.\n const routesIdx = parts.indexOf(\"routes\")\n if (routesIdx !== -1 && PAGES_ROUTER_BASENAME.test(base)) {\n const routePath = routesStylePath(\n parts.slice(routesIdx + 1, parts.length - 1),\n base\n )\n if (routePath !== null) push(out, seen, routePath, f.displayPath)\n continue\n }\n }\n\n return out.sort((a, b) => a.path.localeCompare(b.path))\n}\n\nfunction push(\n out: DetectedRoute[],\n seen: Set<string>,\n routePath: string,\n file: string\n): void {\n if (seen.has(routePath)) return\n seen.add(routePath)\n out.push({ id: pathToId(routePath), path: routePath, file })\n}\n\nfunction formatNextAppPath(segments: string[]): string {\n // Drop route groups like \"(marketing)\"\n const kept = segments.filter((s) => !(s.startsWith(\"(\") && s.endsWith(\")\")))\n if (kept.length === 0) return \"/\"\n return \"/\" + kept.join(\"/\")\n}\n\n/**\n * The end index (exclusive) of the first contiguous run of `dirParts` within\n * `parts`, or -1 if not found. Used to locate a multi-segment routes root\n * (e.g. `src/app`) inside a file's path segments.\n */\nfunction dirEndIndex(parts: string[], dirParts: string[]): number {\n if (dirParts.length === 0) return 0\n for (let i = 0; i + dirParts.length <= parts.length; i++) {\n let match = true\n for (let j = 0; j < dirParts.length; j++) {\n if (parts[i + j] !== dirParts[j]) {\n match = false\n break\n }\n }\n if (match) return i + dirParts.length\n }\n return -1\n}\n\n/**\n * Build a route path from the directory segments and filename of a file under a\n * TanStack / React Router routes root, or `null` when the file is not a page\n * (pathless layout file, `-`-prefixed colocation, or an `api/` server route).\n */\nfunction routesStylePath(dirSegs: string[], base: string): string | null {\n // Flat routing encodes nesting in the filename with `.` separators\n // (e.g. `posts.$postId.tsx` -> `posts/$postId`). Dots inside `[...]` are\n // escaped literals (`assetlinks[.]json`), not separators.\n const fileSegs = splitFlatSegments(base.replace(/\\.[^.]+$/, \"\"))\n const leaf = fileSegs[fileSegs.length - 1]\n // A pathless layout file (`_layout.tsx`, `__root.tsx`) has no URL of its own\n // — only its children are pages.\n if (leaf.startsWith(\"_\")) return null\n const rawSegs = [...dirSegs, ...fileSegs]\n // `-`-prefixed files/dirs are colocated code TanStack excludes from routing.\n if (rawSegs.some((s) => s.startsWith(\"-\"))) return null\n // `api/**` are TanStack Start server routes, not pages.\n if (rawSegs[0] === \"api\") return null\n return formatTanStackPath(rawSegs)\n}\n\n/**\n * Split a TanStack flat-route filename (extension already stripped) on `.`\n * separators, treating dots inside `[...]` escapes as literal characters.\n */\nfunction splitFlatSegments(name: string): string[] {\n const segs: string[] = []\n let cur = \"\"\n let depth = 0\n for (const ch of name) {\n if (ch === \"[\") depth++\n else if (ch === \"]\") depth = Math.max(0, depth - 1)\n if (ch === \".\" && depth === 0) {\n segs.push(cur)\n cur = \"\"\n continue\n }\n cur += ch\n }\n segs.push(cur)\n return segs\n}\n\nfunction formatTanStackPath(segments: string[]): string {\n const kept: string[] = []\n for (const seg of segments) {\n if (!seg) continue\n // The folder route file and index routes add no path segment.\n if (seg === \"index\" || seg === \"route\" || seg === \"__root\") continue\n // Pathless layout routes (`_layout`) add no URL segment.\n if (seg.startsWith(\"_\")) continue\n // Route groups (`(group)`) add no URL segment.\n if (seg.startsWith(\"(\") && seg.endsWith(\")\")) continue\n // A trailing `_` opts out of layout nesting but keeps the path segment.\n kept.push(normalizeTanStackSegment(seg.replace(/_$/, \"\")))\n }\n if (kept.length === 0) return \"/\"\n return \"/\" + kept.join(\"/\")\n}\n\n/**\n * Normalize a TanStack path segment to the canonical form the rest of the\n * pipeline speaks (the runtime page matcher, the coverage gate, `pathToId` all\n * assume Next-style `[param]`). TanStack marks dynamic segments with `$` and\n * escapes literals with `[...]`, so `$postId` -> `[postId]`, the bare splat `$`\n * -> `[...splat]`, and an escape like `[.]well-known` -> the literal\n * `.well-known` (matching the URL TanStack actually serves).\n */\nfunction normalizeTanStackSegment(seg: string): string {\n if (seg === \"$\") return \"[...splat]\"\n if (seg.startsWith(\"$\")) return `[${seg.slice(1)}]`\n return seg.replace(/\\[([^\\]]*)\\]/g, \"$1\")\n}\n\nexport function pathToId(routePath: string): string {\n if (routePath === \"/\") return \"root\"\n return routePath\n .replace(/^\\/+/, \"\")\n .replace(/\\[\\.{3}([^\\]]+)\\]/g, \"$1\")\n .replace(/\\[([^\\]]+)\\]/g, \"$1\")\n .replace(/\\//g, \"-\")\n .replace(/[^a-zA-Z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n}\n","import * as path from \"node:path\"\nimport type { Entity, Registry } from \"../../shared/entities\"\nimport { entityKey } from \"../../shared/entities\"\nimport { WELL_KNOWN_FILES } from \"./config\"\nimport { isPlaceholderReason, type CoverageBaseline } from \"./acknowledge\"\nimport { checkComponentCoverage } from \"./component-coverage\"\nimport { migrateLegacyFields } from \"./migrate-acknowledge\"\nimport { checkPageCoverage } from \"./page-coverage\"\nimport {\n checkStateCoverage,\n type CapturedStatesManifest,\n} from \"./state-coverage\"\nimport { checkStateMatrix } from \"./state-matrix\"\nimport type { Workspace } from \"./workspace\"\nimport type {\n AuditSummary,\n Diagnostic,\n ExtractedFile,\n InteractiveElementFact,\n ScannedFile,\n UidexConfig,\n} from \"./types\"\n\nexport interface AuditOptions {\n registry: Registry\n extracted: ExtractedFile[]\n files: ScannedFile[]\n /** Extract output for flow spec files; enables per-call reference checks. */\n flowExtracted?: ExtractedFile[]\n config: UidexConfig\n check?: boolean\n lint?: boolean\n resolveDiagnostics?: Diagnostic[]\n /** Freshly-emitted DATA-file bytes (the entity array), required for --check. */\n generated?: string\n /** On-disk contents of the data file at scan time; `null` if it does not exist. */\n existingOnDisk?: string | null\n /** Relative path of the data file; used in diagnostics. */\n outputPath?: string\n /** Freshly-emitted TYPES-file bytes; enables the types-file --check compare. */\n typesGenerated?: string\n /** On-disk contents of the types file at scan time; `null` if it does not exist. */\n typesOnDisk?: string | null\n /** Relative path of the configured `output` (types) file; used in diagnostics. */\n typesOutputPath?: string\n /** Freshly-emitted LOCS-file bytes; enables the locs-file --check compare. */\n locsGenerated?: string\n /** On-disk contents of the locs file at scan time; `null` if it does not exist. */\n locsOnDisk?: string | null\n /** Relative path of the `.locs` file; used in diagnostics. */\n locsOutputPath?: string\n /** Captured-states manifest for the completeness gate; absent → gate skipped. */\n capturedStates?: CapturedStatesManifest\n /** Coverage baseline (the shrink-only `acknowledge` backlog). */\n coverageBaseline?: CoverageBaseline\n /** Migration diagnostic when the baseline on disk is the removed shape. */\n baselineDiagnostic?: Diagnostic\n /** The resolved workspace; enables `captured-elsewhere`. */\n workspace?: Workspace\n}\n\nexport function audit(opts: AuditOptions): AuditSummary {\n const diagnostics: Diagnostic[] = []\n const { registry, extracted, files, config } = opts\n const check = opts.check ?? false\n const lint = opts.lint ?? false\n const acceptanceEnabled = config.audit?.acceptance ?? true\n const scopeLeakEnabled = config.audit?.scopeLeak ?? true\n const coverageEnabled = config.audit?.coverage ?? true\n const statesEnabled = config.audit?.states ?? true\n const pageCoverageEnabled = config.audit?.pageCoverage ?? true\n const stateMatrixEnabled = config.audit?.stateMatrix ?? true\n\n // Always surface resolve-time diagnostics (widget cross-validation errors\n // etc.) — these are not gated on --check/--lint because they reflect\n // malformed source the scanner cannot silently register.\n if (opts.resolveDiagnostics) diagnostics.push(...opts.resolveDiagnostics)\n\n // Extract-phase diagnostics (malformed `export const uidex` blocks,\n // parse-error files whose annotations were skipped) are equally ungated:\n // each one means source the scanner could not read.\n for (const ef of extracted) {\n if (ef.diagnostics) diagnostics.push(...ef.diagnostics)\n }\n for (const ef of opts.flowExtracted ?? []) {\n if (ef.diagnostics) diagnostics.push(...ef.diagnostics)\n }\n\n // ---- `acknowledge` migration (ungated, like other malformed-source errors) ----\n // The removed `waivers` / `capture` fields and the removed baseline shape mean\n // the declaration no longer says what it used to, so they surface on every run\n // — each with a `--fix` codemod attached.\n for (const ef of extracted) diagnostics.push(...migrateLegacyFields(ef))\n if (opts.baselineDiagnostic) diagnostics.push(opts.baselineDiagnostic)\n\n // A reason the codemod planted for a `capture: false` that carried none. It is\n // non-empty, so it satisfies the `impossible` rule — which is exactly why it\n // has to be reported, or the migration would launder unexplained opt-outs into\n // explained-looking ones.\n for (const ef of extracted) {\n for (const m of ef.metadata ?? []) {\n for (const [scope, ack] of Object.entries(m.acknowledge ?? {})) {\n if (!isPlaceholderReason(ack.reason)) continue\n diagnostics.push({\n code: \"placeholder-reason\",\n severity: \"warning\",\n message: `acknowledge \"${scope}\" still has the migration's placeholder reason (\"${ack.reason}\")`,\n file: ef.file.displayPath,\n line: m.loc.line,\n hint: `Replace it with why this can NEVER be captured — or, if it merely has not been captured yet, change the type to \"backlog\" (which needs no reason).`,\n })\n }\n }\n }\n\n // ---- Stale gen file (--check) ----\n if (check && opts.generated !== undefined) {\n const outRel = opts.outputPath ?? config.output\n const fresh = normalizeForCheck(opts.generated)\n if (opts.existingOnDisk === null || opts.existingOnDisk === undefined) {\n diagnostics.push({\n code: \"gen-missing\",\n severity: \"error\",\n message: `Generated file \"${outRel}\" does not exist on disk; run \\`uidex scan\\` and commit the result`,\n file: outRel,\n hint: \"Run `uidex scan` (without --check) to regenerate\",\n })\n } else {\n const existing = normalizeForCheck(opts.existingOnDisk)\n if (existing !== fresh) {\n const changed = diffEntities(existing, opts.generated, registry)\n const summary = formatChangedSummary(changed)\n diagnostics.push({\n code: \"gen-stale\",\n severity: \"error\",\n message: `Generated file \"${outRel}\" is stale${summary ? `; ${summary}` : \"\"}`,\n file: outRel,\n hint: \"Run `uidex scan` (without --check) to regenerate and commit the result\",\n })\n }\n }\n }\n\n // ---- Stale types file (--check) ----\n // The types file carries no entity array, so a plain content compare (no\n // entity diff). It changes far less often than the data file — only when the\n // id-union set or authoring-shape surface moves.\n if (check && opts.typesGenerated !== undefined) {\n const outRel = opts.typesOutputPath ?? config.output\n const fresh = normalizeForCheck(opts.typesGenerated)\n if (opts.typesOnDisk === null || opts.typesOnDisk === undefined) {\n diagnostics.push({\n code: \"gen-missing\",\n severity: \"error\",\n message: `Generated file \"${outRel}\" does not exist on disk; run \\`uidex scan\\` and commit the result`,\n file: outRel,\n hint: \"Run `uidex scan` (without --check) to regenerate\",\n })\n } else if (normalizeForCheck(opts.typesOnDisk) !== fresh) {\n diagnostics.push({\n code: \"gen-stale\",\n severity: \"error\",\n message: `Generated file \"${outRel}\" is stale`,\n file: outRel,\n hint: \"Run `uidex scan` (without --check) to regenerate and commit the result\",\n })\n }\n }\n\n // ---- Stale locs file (--check) ----\n // The deferred element/region source-location module; plain content compare.\n if (check && opts.locsGenerated !== undefined) {\n const outRel = opts.locsOutputPath ?? config.output\n const fresh = normalizeForCheck(opts.locsGenerated)\n if (opts.locsOnDisk === null || opts.locsOnDisk === undefined) {\n diagnostics.push({\n code: \"gen-missing\",\n severity: \"error\",\n message: `Generated file \"${outRel}\" does not exist on disk; run \\`uidex scan\\` and commit the result`,\n file: outRel,\n hint: \"Run `uidex scan` (without --check) to regenerate\",\n })\n } else if (normalizeForCheck(opts.locsOnDisk) !== fresh) {\n diagnostics.push({\n code: \"gen-stale\",\n severity: \"error\",\n message: `Generated file \"${outRel}\" is stale`,\n file: outRel,\n hint: \"Run `uidex scan` (without --check) to regenerate and commit the result\",\n })\n }\n }\n\n // ---- Acceptance coverage ----\n if (lint && acceptanceEnabled) {\n for (const kind of [\"widget\", \"feature\", \"page\"] as const) {\n for (const e of registry.list(kind)) {\n const criteria = e.meta?.acceptance ?? []\n if (criteria.length === 0) {\n if (kind === \"widget\") {\n diagnostics.push({\n code: \"widget-missing-acceptance\",\n severity: \"warning\",\n message: `Widget \"${e.id}\" has no acceptance metadata; add \\`export const uidex = { widget: \"${e.id}\", acceptance: [...] }\\` at the widget's definition site`,\n file: e.loc?.file,\n line: e.loc?.line,\n entity: { kind, id: e.id },\n hint: `Adding acceptance criteria allows \\`uidex scaffold widget ${e.id}\\` to generate a Playwright spec`,\n })\n }\n continue\n }\n const flowIds = (e.meta?.flows ?? []) as readonly string[]\n if (flowIds.length === 0) {\n const hint =\n kind === \"widget\"\n ? `uidex scaffold widget ${e.id}`\n : `Add a Playwright flow under e2e/** that touches ${kind} \"${e.id}\" (tag the describe with @uidex:flow)`\n for (const c of criteria) {\n diagnostics.push({\n code: \"acceptance-uncovered\",\n severity: \"warning\",\n message: `${kind} \"${e.id}\" has acceptance criterion not covered by any flow: \"${c}\"`,\n file: e.loc?.file,\n line: e.loc?.line,\n entity: { kind, id: e.id },\n hint,\n })\n }\n }\n }\n }\n }\n\n // ---- Prefer well-known file (uidex.page.ts / uidex.feature.ts) ----\n if (lint) {\n const scannedPaths = new Set(files.map((f) => f.displayPath))\n for (const ef of extracted) {\n if (!ef.metadata) continue\n for (const m of ef.metadata) {\n if (m.kind !== \"page\" && m.kind !== \"feature\") continue\n if (typeof m.id !== \"string\") continue\n const filePath = ef.file.displayPath\n const wellKnownName = WELL_KNOWN_FILES[m.kind]\n if (path.posix.basename(filePath) === wellKnownName) continue\n const dir = path.posix.dirname(filePath)\n const wellKnownPath =\n dir === \".\" ? wellKnownName : `${dir}/${wellKnownName}`\n if (scannedPaths.has(wellKnownPath)) continue\n const kindLabel = m.kind === \"page\" ? \"Page\" : \"Feature\"\n diagnostics.push({\n code: \"prefer-well-known-file\",\n severity: \"info\",\n message: `${kindLabel} \"${m.id}\" metadata lives on ${filePath}; prefer ${wellKnownPath}`,\n file: filePath,\n line: m.loc.line,\n entity: { kind: m.kind, id: m.id },\n hint: `Move the \\`export const uidex\\` block to ${wellKnownPath} and remove it from ${filePath}.`,\n })\n }\n }\n }\n\n // ---- Dynamic data-uidex* attribute (expression instead of string literal) ----\n // Extract is the single source of truth for what resolves statically:\n // anything its evaluator could not turn into an id or pattern arrives here\n // as a DynamicAttrFact, so audit can never disagree with registration.\n if (lint) {\n for (const ef of extracted) {\n for (const fact of ef.dynamicAttrs ?? []) {\n diagnostics.push({\n code: \"dynamic-attr\",\n severity: \"warning\",\n message: `\\`${fact.attrName}={…}\\` uses a dynamic expression; the scanner cannot resolve the ${fact.kind} id statically`,\n file: ef.file.displayPath,\n line: fact.line,\n hint: dynamicAttrHint(fact.kind),\n })\n }\n }\n }\n\n // ---- Missing element annotation candidates (interactive elements without data-uidex) ----\n // Each generated id is deterministic (from the element's accessible name or\n // visible text) and deduped against ids already in the registry and ones\n // generated earlier this pass, so `--fix` can annotate the whole tree without\n // collisions. `--fix` only writes the attribute when it is absent, so the id\n // becomes a normal source literal and never churns on re-scan.\n if (lint) {\n const usedElementIds = new Set(registry.list(\"element\").map((e) => e.id))\n for (const ef of extracted) {\n for (const fact of ef.unannotatedInteractive ?? []) {\n if (fact.hasSpread) {\n // The spread may legitimately deliver the annotation via props, so\n // this supersedes missing-element-annotation rather than stacking.\n diagnostics.push({\n code: \"spread-attr\",\n severity: \"info\",\n message: `Interactive <${fact.tag}> spreads dynamic props and has no static data-uidex attribute; if the annotation is forwarded via props the scanner cannot register it`,\n file: ef.file.displayPath,\n line: fact.line,\n hint: \"Prefer a string-literal data-uidex on the element itself, or annotate at the call site.\",\n })\n } else {\n const id = uniqueElementId(fact, usedElementIds)\n usedElementIds.add(id)\n diagnostics.push({\n code: \"missing-element-annotation\",\n severity: \"info\",\n message: `Interactive <${fact.tag}> without data-uidex annotation`,\n file: ef.file.displayPath,\n line: fact.line,\n hint: `Add \\`data-uidex=\"${id}\"\\` (or run \\`uidex scan --fix\\`).`,\n fix: {\n description: `Add data-uidex=\"${id}\" to <${fact.tag}>`,\n edits: [\n {\n path: ef.file.sourcePath,\n start: fact.nameEnd,\n end: fact.nameEnd,\n replacement: ` data-uidex=\"${id}\"`,\n },\n ],\n },\n })\n }\n }\n }\n }\n\n // ---- Scope leak (primitives used outside their scope) ----\n // Import facts come from the AST (extract phase): real import/export-from\n // statements only — nothing inside comments or strings — with type-only\n // imports excluded (a type dependency is not a runtime leak).\n if (lint && scopeLeakEnabled) {\n const primitives = registry.list(\"primitive\")\n const byName = new Map<string, (typeof primitives)[number]>()\n for (const p of primitives) byName.set(p.id, p)\n\n // Build lookup: file displayPath → declared feature cross-references\n const declaredFeatures = new Map<string, ReadonlySet<string>>()\n for (const ef of extracted) {\n if (!ef.metadata) continue\n for (const m of ef.metadata) {\n if (m.features && m.features.length > 0) {\n declaredFeatures.set(ef.file.displayPath, new Set(m.features))\n }\n }\n }\n\n for (const ef of extracted) {\n const displayPath = ef.file.displayPath\n for (const imp of ef.imports ?? []) {\n if (imp.isTypeOnly) continue\n const baseName = imp.specifier.split(\"/\").pop() ?? \"\"\n const primitive = byName.get(\n baseName\n .replace(/\\.(tsx|ts|jsx|js|mjs|cjs)$/, \"\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase()\n )\n if (!primitive) continue\n const scope = primitive.scopes?.[0]\n if (!scope) continue\n const [kind, id] = scope.split(\":\")\n const importerSegments = displayPath.split(\"/\")\n\n // Same scope directory — not a leak\n if (\n importerSegments.includes(id) &&\n importerSegments.includes(kind + \"s\")\n ) {\n continue\n }\n\n // Route-feature affinity: a page whose path contains the feature\n // id is the feature's UI surface (e.g. app/editor/page-config/page.tsx\n // importing from feature:page-config)\n if (kind === \"feature\" && importerSegments.includes(id)) continue\n\n // Declared cross-reference: the importer's `export const uidex`\n // lists this feature in its `features` array\n if (kind === \"feature\" && declaredFeatures.get(displayPath)?.has(id)) {\n continue\n }\n\n diagnostics.push({\n code: \"scope-leak\",\n severity: \"warning\",\n message: `Primitive \"${primitive.id}\" is scoped to ${scope} but is imported from ${displayPath}`,\n file: displayPath,\n line: imp.line,\n })\n }\n }\n }\n\n // ---- Coverage (entities referenced in flows must exist) ----\n if (lint && coverageEnabled) {\n // Per-call lines from the flow specs' extract facts, keyed by the\n // describe location (id-independent, so flowExport renames still match).\n const factsByLoc = new Map<string, Map<string, number>>()\n for (const ef of opts.flowExtracted ?? []) {\n for (const fact of ef.flows ?? []) {\n const lines = new Map<string, number>()\n for (const call of fact.calls) {\n if (!lines.has(call.id)) lines.set(call.id, call.line)\n }\n factsByLoc.set(`${ef.file.displayPath}:${fact.line}`, lines)\n }\n }\n\n for (const flow of registry.list(\"flow\")) {\n const callLines = factsByLoc.get(`${flow.loc.file}:${flow.loc.line}`)\n for (const touchedId of flow.touches) {\n const found =\n registry.get(\"element\", touchedId) ??\n registry.get(\"widget\", touchedId) ??\n registry.get(\"region\", touchedId) ??\n registry.matchPattern(\"element\", touchedId) ??\n registry.matchPattern(\"widget\", touchedId) ??\n registry.matchPattern(\"region\", touchedId)\n if (!found) {\n diagnostics.push({\n code: \"unknown-reference\",\n severity: \"warning\",\n message: `Flow \"${flow.id}\" references unknown entity \"${touchedId}\"`,\n file: flow.loc.file,\n // Point at the uidex() call itself when the spec facts are\n // available; the describe line is the fallback.\n line: callLines?.get(touchedId) ?? flow.loc.line,\n })\n }\n }\n }\n }\n\n // ---- Duplicate ids (same kind+id annotated in more than one file) ----\n // The registry is last-writer-wins, so a cross-file duplicate silently\n // collapses to one entity while the runtime has two DOM matches. Widget and\n // primitive duplicates are definition collisions (warning); element/region\n // duplicates are sometimes intentional (responsive variants), so info.\n if (lint) {\n const occurrences = new Map<string, Array<{ file: string; line: number }>>()\n for (const ef of extracted) {\n for (const a of ef.annotations) {\n if (\n a.kind !== \"element\" &&\n a.kind !== \"region\" &&\n a.kind !== \"widget\" &&\n a.kind !== \"primitive\"\n ) {\n continue\n }\n const key = `${a.kind}:${a.id}`\n let list = occurrences.get(key)\n if (!list) {\n list = []\n occurrences.set(key, list)\n }\n list.push({ file: a.file, line: a.line })\n }\n }\n for (const [key, list] of occurrences) {\n const filesSeen = new Set(list.map((o) => o.file))\n if (filesSeen.size < 2) continue\n const [kind, id] = key.split(/:(.*)/s) as [string, string]\n const others = list\n .slice(1)\n .map((o) => `${o.file}:${o.line}`)\n .join(\", \")\n diagnostics.push({\n code: \"duplicate-id\",\n severity:\n kind === \"widget\" || kind === \"primitive\" ? \"warning\" : \"info\",\n message: `${kind} id \"${id}\" is declared in ${filesSeen.size} files (also at ${others}); the registry keeps only one entry`,\n file: list[0].file,\n line: list[0].line,\n entity: { kind: kind as \"element\", id },\n hint:\n kind === \"element\" || kind === \"region\"\n ? \"If these are variants of the same logical element this is fine; otherwise rename one (`uidex rename` updates flow references too).\"\n : \"Rename one of the definitions; two definitions with the same id silently merge.\",\n })\n }\n }\n\n // ---- Dynamic uidex() references in tagged flows ----\n // Flow ids must be string literals; a dynamic argument silently drops out\n // of `touches`, shrinking coverage with no trace. Mirror of dynamic-attr.\n if (lint && coverageEnabled) {\n for (const ef of opts.flowExtracted ?? []) {\n for (const fact of ef.flows ?? []) {\n for (const dyn of fact.dynamicCalls ?? []) {\n diagnostics.push({\n code: \"dynamic-flow-reference\",\n severity: \"warning\",\n message: `\\`uidex(…)\\` call in flow \"${fact.title}\" uses a dynamic expression; the id is invisible to coverage and registry validation`,\n file: ef.file.displayPath,\n line: dyn.line,\n hint: \"Use a string-literal id (component ids inside uidex() must be statically analysable).\",\n })\n }\n }\n }\n }\n\n // ---- Declared cross-references must exist ----\n // `features:` / `widgets:` arrays are tsc-checked at the `satisfies` site,\n // but a runtime audit still catches refs the author never typechecked.\n // Mirror the flow unknown-reference check for metadata exports.\n if (lint && coverageEnabled) {\n for (const ef of extracted) {\n if (!ef.metadata) continue\n for (const m of ef.metadata) {\n const check = (\n refKind: \"feature\" | \"widget\",\n ids: readonly string[] | undefined,\n spans: ReadonlyArray<{ start: number }> | undefined\n ) => {\n for (let i = 0; i < (ids?.length ?? 0); i++) {\n const refId = ids![i]\n const found =\n registry.get(refKind, refId) ??\n registry.matchPattern(refKind, refId)\n if (found) continue\n diagnostics.push({\n code: \"unknown-reference\",\n severity: \"warning\",\n message: `\\`export const uidex\\` in ${ef.file.displayPath} references unknown ${refKind} \"${refId}\"`,\n file: ef.file.displayPath,\n line: spans?.[i]\n ? lineOfOffset(ef.file.content, spans[i].start)\n : m.loc.line,\n hint: `No ${refKind} with id \"${refId}\" exists in the registry; fix the reference or add the ${refKind}.`,\n })\n }\n }\n check(\"feature\", m.features, m.featureSpans)\n check(\"widget\", m.widgets, m.widgetSpans)\n }\n }\n }\n\n // ---- State-capture completeness gate ----\n // Cross-checks declared `states` against a capture run's manifest. Skipped\n // when no manifest is supplied, so a plain scan (no capture run) never fails.\n if (lint && statesEnabled && opts.capturedStates) {\n // An entity's `loc.file` is a DISPLAY path (a source `prefix` rewrites it),\n // so the workspace needs the real path to test against a sibling's roots.\n const sourceByDisplay = new Map(\n files.map((f) => [f.displayPath, f.sourcePath])\n )\n diagnostics.push(\n ...checkStateCoverage(registry, opts.capturedStates, {\n workspace: opts.workspace,\n resolveSourcePath: (displayPath) => sourceByDisplay.get(displayPath),\n })\n )\n }\n\n // ---- Page-capture coverage gate ----\n // Every derived route must be captured or acknowledged at `\"*\"` scope. Runs\n // only when a capture manifest is present.\n if (lint && pageCoverageEnabled && opts.capturedStates) {\n diagnostics.push(\n ...checkPageCoverage(registry, opts.capturedStates, opts.coverageBaseline)\n )\n }\n\n // ---- Component coverage per route ----\n // The integration view: which routes compose a component whose declared states\n // nobody captured. Info-severity; escalate via `audit.severity`.\n if (lint && statesEnabled && opts.capturedStates) {\n diagnostics.push(...checkComponentCoverage(registry, opts.capturedStates))\n }\n\n // ---- State-matrix gate ----\n // Every captured route renders the four core kinds, or acknowledges the gap.\n // Shares one `acknowledge` axis with the page gate above.\n if (lint && stateMatrixEnabled && opts.capturedStates) {\n diagnostics.push(\n ...checkStateMatrix(registry, opts.capturedStates, opts.coverageBaseline)\n )\n }\n\n // Per-code severity overrides (`audit.severity`). Applied LAST so it governs\n // every diagnostic regardless of which check produced it — that is the point:\n // a code's built-in severity is a sensible default, not a policy. `\"off\"`\n // drops the diagnostic entirely. Escalating a warning to `\"error\"` is how a\n // repo turns an advisory gate (e.g. `missing-state-capture`) into a ratchet.\n const overrides = config.audit?.severity ?? {}\n const governed = diagnostics.flatMap((d) => {\n const level = overrides[d.code]\n if (level === undefined) return [d]\n if (level === \"off\") return []\n return [{ ...d, severity: level }]\n })\n\n const summary = {\n errors: governed.filter((d) => d.severity === \"error\").length,\n warnings: governed.filter((d) => d.severity === \"warning\").length,\n }\n\n return { diagnostics: governed, summary }\n}\n\nfunction lineOfOffset(content: string, offset: number): number {\n let line = 1\n for (let i = 0; i < offset && i < content.length; i++) {\n if (content[i] === \"\\n\") line++\n }\n return line\n}\n\n/** Fallback ids by tag when the element carries no static name hint. */\nconst TAG_FALLBACK_ID: Record<string, string> = {\n a: \"link\",\n button: \"button\",\n input: \"input\",\n select: \"select\",\n textarea: \"textarea\",\n}\n\nfunction kebabId(str: string): string {\n return str\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .replace(/[^a-zA-Z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .toLowerCase()\n}\n\n/** Deterministic kebab id from an element's name hint, capped at five words. */\nfunction deriveElementId(fact: InteractiveElementFact): string {\n const fromHint = fact.nameHint ? kebabId(fact.nameHint) : \"\"\n const capped = fromHint.split(\"-\").filter(Boolean).slice(0, 5).join(\"-\")\n return capped || TAG_FALLBACK_ID[fact.tag] || fact.tag\n}\n\n/** `deriveElementId`, made unique by suffixing `-2`, `-3`, … on collision. */\nfunction uniqueElementId(\n fact: InteractiveElementFact,\n used: ReadonlySet<string>\n): string {\n const base = deriveElementId(fact)\n if (!used.has(base)) return base\n for (let n = 2; ; n++) {\n const candidate = `${base}-${n}`\n if (!used.has(candidate)) return candidate\n }\n}\n\nfunction normalizeLineEndings(s: string): string {\n return s.replace(/\\r\\n/g, \"\\n\")\n}\n\n/**\n * Normalization for the staleness comparison. Besides line endings, the\n * embedded `gitContext` block is neutralized: it records the commit the file\n * was generated at, which is by construction one commit behind once the file\n * itself is committed — comparing it would make `--check` fail on every\n * freshly committed gen file.\n */\nfunction normalizeForCheck(s: string): string {\n return normalizeLineEndings(s).replace(\n /export const gitContext = \\{[\\s\\S]*?\\} as const/,\n \"export const gitContext = {} as const\"\n )\n}\n\ninterface EntityChange {\n added: string[]\n removed: string[]\n modified: string[]\n}\n\nfunction formatChangedSummary(change: EntityChange): string {\n const parts: string[] = []\n const fmt = (kind: string, names: string[]) => {\n if (names.length === 0) return\n const preview = names.slice(0, 3).join(\", \")\n const suffix = names.length > 3 ? ` (+${names.length - 3} more)` : \"\"\n parts.push(`${kind}: ${preview}${suffix}`)\n }\n fmt(\"added\", change.added)\n fmt(\"removed\", change.removed)\n fmt(\"modified\", change.modified)\n return parts.join(\"; \")\n}\n\nfunction diffEntities(\n existing: string,\n generated: string,\n registry: Registry\n): EntityChange {\n const oldEntities = extractEntitiesArray(existing)\n const newEntities = extractEntitiesArray(generated) ?? freshEntities(registry)\n\n const added: string[] = []\n const removed: string[] = []\n const modified: string[] = []\n\n if (!oldEntities) {\n for (const e of newEntities) added.push(labelFor(e))\n return { added, removed, modified }\n }\n\n const oldByKey = new Map<string, Entity>()\n for (const e of oldEntities) oldByKey.set(entityKey(e) + \"@\" + e.kind, e)\n const newByKey = new Map<string, Entity>()\n for (const e of newEntities) newByKey.set(entityKey(e) + \"@\" + e.kind, e)\n\n for (const [k, e] of newByKey) {\n const prev = oldByKey.get(k)\n if (!prev) {\n added.push(labelFor(e))\n } else if (stableStringify(prev) !== stableStringify(e)) {\n modified.push(labelFor(e))\n }\n }\n for (const [k, e] of oldByKey) {\n if (!newByKey.has(k)) removed.push(labelFor(e))\n }\n\n return { added, removed, modified }\n}\n\nfunction labelFor(e: Entity): string {\n return `${e.kind} \"${entityKey(e)}\"`\n}\n\nfunction freshEntities(registry: Registry): Entity[] {\n const kinds = [\n \"route\",\n \"page\",\n \"feature\",\n \"widget\",\n \"region\",\n \"element\",\n \"primitive\",\n \"flow\",\n ] as const\n const out: Entity[] = []\n for (const k of kinds) out.push(...(registry.list(k) as Entity[]))\n return out\n}\n\nfunction extractEntitiesArray(source: string): Entity[] | null {\n const marker = \"export const entities: ReadonlyArray<Entity> = \"\n const idx = source.indexOf(marker)\n if (idx === -1) return null\n const start = source.indexOf(\"[\", idx)\n if (start === -1) return null\n let depth = 0\n let inStr: string | null = null\n let escaped = false\n for (let i = start; i < source.length; i++) {\n const c = source[i]\n if (inStr) {\n if (escaped) {\n escaped = false\n } else if (c === \"\\\\\") {\n escaped = true\n } else if (c === inStr) {\n inStr = null\n }\n continue\n }\n if (c === '\"' || c === \"'\") {\n inStr = c\n continue\n }\n if (c === \"[\") depth++\n else if (c === \"]\") {\n depth--\n if (depth === 0) {\n const json = source.slice(start, i + 1)\n try {\n return JSON.parse(json) as Entity[]\n } catch {\n return null\n }\n }\n }\n }\n return null\n}\n\nfunction dynamicAttrHint(kind: string): string {\n if (kind === \"region\") {\n return (\n `Use a string literal: \\`data-uidex-region=\"id\"\\`, or declare the ` +\n `region via \\`export const uidex = { region: \"id\" } as const satisfies ` +\n `Uidex.Region\\` on the file that passes the region value`\n )\n }\n return (\n `The scanner resolves string literals, same-file const references, ` +\n `ternaries with literal branches, and template literals with static ` +\n `text (dynamic parts become \\`*\\` patterns). If this component forwards ` +\n `the annotation via a prop, restructure so the caller provides the ` +\n `annotated element directly (e.g. via a slot or render prop)`\n )\n}\n\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(value, stableReplacer)\n}\n\nfunction stableReplacer(_key: string, value: unknown): unknown {\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[k] = (value as Record<string, unknown>)[k]\n }\n return sorted\n }\n return value\n}\n","import type { Registry } from \"../../shared/entities\"\nimport { ACK_ALL } from \"./acknowledge\"\nimport type { CapturedState, CapturedStatesManifest } from \"./state-coverage\"\nimport type { Diagnostic } from \"./types\"\n\n/**\n * Component coverage PER ROUTE — the integration view a component-level capture\n * inherently lacks.\n *\n * A widget/feature capture is deliberately routeless: it mounts the component in\n * isolation, so it proves the component renders its states and nothing about the\n * page that hosts it (wrong props, a parent's `overflow` clipping it, the wrong\n * container width). Meanwhile `page.widgets` / `page.features` already record\n * which components a page composes, so the registry can answer \"which routes\n * host this component, and are its states captured?\" without any new authoring.\n *\n * Emitted at `info`: an uncaptured component state on a route is a coverage\n * observation, not a defect. Repos that want it enforced escalate it via\n * `audit.severity: { \"component-state-uncaptured\": \"error\" }`.\n */\n\nconst COMPOSED_KINDS = [\"widget\", \"feature\"] as const\n\n/** Declared-state components a page composes, via its `widgets`/`features`. */\nfunction composedStateEntities(\n registry: Registry,\n page: string\n): { kind: (typeof COMPOSED_KINDS)[number]; id: string }[] {\n const meta = registry.get(\"page\", page)?.meta\n if (!meta) return []\n const out: { kind: (typeof COMPOSED_KINDS)[number]; id: string }[] = []\n for (const kind of COMPOSED_KINDS) {\n const ids = (kind === \"widget\" ? meta.widgets : meta.features) ?? []\n for (const id of ids as readonly string[]) {\n const e = registry.get(kind, id)\n if (!e?.meta?.states?.length) continue\n if (e.meta.acknowledge?.[ACK_ALL]) continue\n out.push({ kind, id })\n }\n }\n return out\n}\n\nfunction capturedStatesFor(\n captured: CapturedState[],\n kind: string,\n id: string\n): ReadonlySet<string> {\n const out = new Set<string>()\n for (const c of captured) {\n if (c.entity !== id) continue\n if (c.kind !== undefined && c.kind !== kind && c.kind !== \"page\") continue\n out.add(c.state)\n }\n return out\n}\n\nexport function checkComponentCoverage(\n registry: Registry,\n manifest: CapturedStatesManifest\n): Diagnostic[] {\n const routes = registry.list(\"route\")\n if (routes.length === 0) return []\n const captured = manifest.captured ?? []\n const diagnostics: Diagnostic[] = []\n\n for (const route of routes) {\n // A route acknowledged at `\"*\"` scope is out of every capture gate.\n // Note this gate deliberately does NOT honor `captured-elsewhere`: a sibling\n // capturing the component in ISOLATION says nothing about whether it renders\n // correctly inside THIS route, which is the whole point of this view.\n if (registry.get(\"page\", route.page)?.meta?.acknowledge?.[ACK_ALL]) continue\n for (const { kind, id } of composedStateEntities(registry, route.page)) {\n const entity = registry.get(kind, id)!\n const declared = entity.meta!.states!.map((s) => s.name)\n const shot = capturedStatesFor(captured, kind, id)\n const missing = declared.filter((s) => !shot.has(s))\n if (missing.length === 0) continue\n diagnostics.push({\n code: \"component-state-uncaptured\",\n severity: \"info\",\n message: `route \"${route.path}\" composes ${kind} \"${id}\", whose state(s) [${missing.join(\", \")}] no capture produced`,\n file: entity.loc?.file,\n line: entity.loc?.line,\n entity: { kind, id },\n hint: `Capture the missing state(s) for \"${id}\", or drop them from its \\`states\\` if they no longer exist. This is the integration view: an isolated component capture never proves the state renders correctly INSIDE \"${route.path}\".`,\n })\n }\n }\n\n return diagnostics\n}\n","import { CORE_STATE_KINDS } from \"../../shared/entities\"\nimport {\n ACK_ALL,\n PLACEHOLDER_REASON,\n isLegacyBaseline,\n migrateBaseline,\n serializeCoverageBaseline,\n type Acknowledgment,\n} from \"./acknowledge\"\nimport type {\n Diagnostic,\n ExtractedFile,\n FixEdit,\n MetadataExport,\n} from \"./types\"\n\n/**\n * The `acknowledge` codemod.\n *\n * `waivers` and `capture` are removed, but a repo can have hundreds of\n * declarations using them, so migration cannot be \"go edit 62 files\". It runs on\n * the SAME span-rewrite infrastructure as `uidex rename` and the other `--fix`\n * codemods: the extractor keeps parsing the removed fields purely to record\n * their spans and values, this module turns each occurrence into an error\n * carrying a machine-applicable fix, and `uidex scan --fix` applies them.\n *\n * No gate reads the legacy fields, so an unmigrated repo gets a loud error and a\n * one-command fix — never a gate that silently half-works.\n *\n * The one place the rewrite cannot be purely mechanical is `capture: false`,\n * which carried NO reason (the model only asked for one on a waiver). Becoming\n * `{ type: \"impossible\", reason }` it now needs one, and the codemod cannot\n * invent it — so it plants a TODO placeholder and `placeholder-reason` reports\n * every one. That is deliberate: those opt-outs were the least justified thing\n * in the old model (a boolean that silenced a hard error with no explanation),\n * and the migration surfaces them all instead of laundering them into the new\n * shape.\n */\n\nconst CORE: readonly string[] = CORE_STATE_KINDS\n\n/** `\"*\"` first (broadest), then core kinds in matrix order — deterministic. */\nfunction orderScopes(scopes: string[]): string[] {\n const rank = (s: string) => (s === ACK_ALL ? -1 : CORE.indexOf(s))\n return [...scopes].sort((a, b) => rank(a) - rank(b))\n}\n\nfunction renderKey(scope: string): string {\n return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(scope)\n ? scope\n : JSON.stringify(scope)\n}\n\nfunction renderAck(a: Acknowledgment): string {\n const parts = [`type: ${JSON.stringify(a.type)}`]\n if (a.reason) parts.push(`reason: ${JSON.stringify(a.reason)}`)\n return `{ ${parts.join(\", \")} }`\n}\n\n/** The `acknowledge: { … }` property text, indented to sit where the old one did. */\nfunction renderAcknowledge(\n entries: Record<string, Acknowledgment>,\n indent: string\n): string {\n const inner = indent + \" \"\n const lines = orderScopes(Object.keys(entries)).map(\n (scope) => `${inner}${renderKey(scope)}: ${renderAck(entries[scope])},`\n )\n return [\"acknowledge: {\", ...lines, `${indent}}`].join(\"\\n\")\n}\n\n/** Leading whitespace of the line `offset` sits on. */\nfunction indentAt(content: string, offset: number): string {\n const lineStart = content.lastIndexOf(\"\\n\", offset - 1) + 1\n const m = /^[ \\t]*/.exec(content.slice(lineStart, offset))\n return m ? m[0] : \"\"\n}\n\n/** The legacy fields → the `acknowledge` map that replaces them. */\nfunction plannedEntries(m: MetadataExport): Record<string, Acknowledgment> {\n const entries: Record<string, Acknowledgment> = {}\n // `capture: false` was an unexplained, all-axes opt-out. It becomes an\n // `\"*\"`-scoped `impossible` — which now has to say why.\n if (m.legacyCapture === false) {\n entries[ACK_ALL] = {\n type: \"impossible\",\n reason: m.description || PLACEHOLDER_REASON,\n }\n }\n // A waiver already carried its reason, so this half is 1:1 and lossless.\n for (const kind of CORE) {\n const reason = m.legacyWaivers?.[kind]\n if (reason) entries[kind] = { type: \"impossible\", reason }\n }\n return entries\n}\n\n/**\n * Migration diagnostics for one file's `export const uidex` blocks. Emitted as\n * errors: the fields are gone, so the declaration means nothing until rewritten.\n */\nexport function migrateLegacyFields(ef: ExtractedFile): Diagnostic[] {\n const out: Diagnostic[] = []\n const { content, sourcePath, displayPath } = ef.file\n\n for (const m of ef.metadata ?? []) {\n const legacy: string[] = []\n if (m.legacyWaivers) legacy.push(\"waivers\")\n if (m.legacyCapture !== undefined) legacy.push(\"capture\")\n if (legacy.length === 0) continue\n\n const fields = legacy.join(\" and \")\n const base = {\n severity: \"error\" as const,\n code: \"legacy-acknowledge-field\",\n file: displayPath,\n line: m.loc.line,\n }\n\n // Already partly migrated by hand — merging two hand-written maps is not a\n // mechanical edit, so report it and let a human do it.\n if (m.acknowledge) {\n out.push({\n ...base,\n message: `\\`${fields}\\` was replaced by \\`acknowledge\\`, and this declaration already has an \\`acknowledge\\` field`,\n hint: `Merge the remaining \\`${fields}\\` entries into \\`acknowledge\\` by hand and delete them; --fix will not merge two maps for you.`,\n })\n continue\n }\n\n const entries = plannedEntries(m)\n const edits: FixEdit[] = []\n // Anchor on the FIRST legacy field in source order, so the replacement lands\n // where the author was already looking; the other is deleted.\n const present = legacy\n .map((f) => ({ f, prop: m.fieldPropSpans?.[f], del: m.fieldSpans?.[f] }))\n .filter((x) => x.prop && x.del)\n .sort((a, b) => a.prop!.start - b.prop!.start)\n if (present.length !== legacy.length) {\n out.push({\n ...base,\n message: `\\`${fields}\\` was replaced by \\`acknowledge\\`, but the field spans needed to rewrite it are unavailable`,\n hint: \"Rewrite the declaration by hand: `acknowledge: { <scope>: { type, reason? } }`.\",\n })\n continue\n }\n const [anchor, ...rest] = present\n if (Object.keys(entries).length === 0) {\n // `capture: true` was the default — it acknowledged nothing, so drop it.\n edits.push({\n path: sourcePath,\n start: anchor.del!.start,\n end: anchor.del!.end,\n replacement: \"\",\n })\n } else {\n edits.push({\n path: sourcePath,\n start: anchor.prop!.start,\n end: anchor.prop!.end,\n replacement: renderAcknowledge(\n entries,\n indentAt(content, anchor.prop!.start)\n ),\n })\n }\n for (const r of rest) {\n edits.push({\n path: sourcePath,\n start: r.del!.start,\n end: r.del!.end,\n replacement: \"\",\n })\n }\n\n out.push({\n ...base,\n message: `\\`${fields}\\` was replaced by the unified \\`acknowledge\\` field`,\n hint: `Run \\`uidex scan --fix\\` to rewrite it${m.legacyCapture === false && !m.description ? \", then replace the TODO reason it plants — `capture: false` carried no explanation and `impossible` requires one\" : \"\"}.`,\n fix: {\n description: `Rewrite \\`${fields}\\` as \\`acknowledge\\``,\n edits,\n },\n })\n }\n\n return out\n}\n\n/**\n * Migration diagnostic for a pre-`acknowledge` coverage baseline. The whole file\n * is replaced, which is safe because the baseline is a generated artifact: the\n * same content `--update-baseline` would produce, just without needing a capture\n * run to regenerate it.\n */\nexport function migrateLegacyBaseline(opts: {\n path: string\n raw: string\n parsed: unknown\n displayPath: string\n}): Diagnostic | undefined {\n if (!isLegacyBaseline(opts.parsed)) return undefined\n return {\n code: \"legacy-coverage-baseline\",\n severity: \"error\",\n message: `coverage baseline \"${opts.displayPath}\" uses the removed \\`uncapturedPages\\` / \\`missingKinds\\` shape`,\n file: opts.displayPath,\n hint: \"Run `uidex scan --fix` to rewrite it as `acknowledge` entries of type `backlog` (identical content, new shape — no capture run needed).\",\n fix: {\n description: `Rewrite ${opts.displayPath} as an \\`acknowledge\\` baseline`,\n edits: [\n {\n path: opts.path,\n start: 0,\n end: opts.raw.length,\n replacement: serializeCoverageBaseline(migrateBaseline(opts.parsed)),\n },\n ],\n },\n }\n}\n","import type { Registry } from \"../../shared/entities\"\nimport {\n ACK_ALL,\n describeAck,\n originHint,\n routeAcknowledge,\n type AcknowledgeMap,\n type CoverageBaseline,\n} from \"./acknowledge\"\nimport type { CapturedState, CapturedStatesManifest } from \"./state-coverage\"\nimport type { Diagnostic } from \"./types\"\n\n/**\n * Page-capture coverage — the coarse gate above the per-state gate. Every\n * derived route must be accounted for: captured (a run drove it), or\n * ACKNOWLEDGED at `\"*\"` scope — either `impossible` (a redirect, a static\n * notice, an internal target — the old `capture: false`, which now has to say\n * WHY) or `backlog` (tool-managed, shrink-only). A route in none of those is a\n * *new* uncaptured page and fails hard — the ratchet that keeps debt growing.\n *\n * uidex derives the route set (route groups stripped, dynamic segments kept), so\n * unlike a hand-rolled `src/app/**` walk there is no page list to enumerate or\n * keep from rotting: a route exists in the registry or it doesn't. And captures\n * observe the URL they ran against, so which route a capture covers is matched,\n * never hand-declared.\n */\n\n/**\n * Turn a Next-style route pattern into an anchored matcher.\n * `/[scope]/products/[productId]/edit` → matches `/acme/products/p1/edit`\n * `/[...slug]` (catch-all) → matches one or more segments\n * Returns the literal-segment count as a specificity score, so the most literal\n * matching pattern wins when several match (e.g. `/x/new` beats `/x/[id]`).\n */\nexport function compileRoute(pattern: string): {\n test: (url: string) => boolean\n specificity: number\n} {\n const segs = pattern.split(\"/\").filter(Boolean)\n let specificity = 0\n // A trailing optional catch-all `[[...x]]` matches ZERO or more segments, so it\n // is dropped from the joined body and re-added as an optional tail below.\n const optionalTail =\n segs.length > 0 && /^\\[\\[\\.{3}.+\\]\\]$/.test(segs[segs.length - 1])\n const effective = optionalTail ? segs.slice(0, -1) : segs\n const parts = effective.map((seg) => {\n const catchAll = /^\\[\\.{3}.+\\]$/.test(seg) // required `[...x]` — one or more\n const dynamic = /^\\[.+\\]$/.test(seg)\n if (catchAll) return \"(?:[^/]+)(?:/[^/]+)*\"\n if (dynamic) return \"[^/]+\"\n specificity++\n return seg.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n })\n let body = parts.length === 0 ? \"\" : \"/\" + parts.join(\"/\")\n if (optionalTail) body += \"(?:/[^/]+)*\"\n if (body === \"\") body = \"/\"\n const re = new RegExp(`^${body}/?$`)\n return { test: (url) => re.test(url), specificity }\n}\n\n/** The route pattern (from the given set) that most-specifically matches a URL. */\nexport function matchUrlToRoute(\n url: string,\n routePaths: string[]\n): string | null {\n const path = stripQuery(url)\n let best: { path: string; specificity: number } | null = null\n for (const rp of routePaths) {\n const { test, specificity } = compileRoute(rp)\n if (!test(path)) continue\n if (!best || specificity > best.specificity)\n best = { path: rp, specificity }\n }\n return best?.path ?? null\n}\n\nfunction stripQuery(url: string): string {\n const q = url.indexOf(\"?\")\n const h = url.indexOf(\"#\")\n let end = url.length\n if (q !== -1) end = Math.min(end, q)\n if (h !== -1) end = Math.min(end, h)\n return url.slice(0, end)\n}\n\n/**\n * The single route a captured state exercised, shared by both coverage gates so\n * they can never disagree about attribution:\n * - an explicit `route` (if it names a real route), else\n * - the observed `url` matched to its most-specific route pattern, else\n * - only for an explicit `kind: \"page\"` capture, the route whose page id is the\n * entity (ids are unique per kind, so a same-id widget/feature must not\n * silently cover a page — it needs a URL or explicit route).\n * Returns null when nothing resolves (e.g. a `/shots/*` harness URL).\n */\nexport function routeForCapture(\n c: CapturedState,\n routes: ReadonlyArray<{ path: string; page: string }>,\n routePaths: string[]\n): string | null {\n if (c.route && routePaths.includes(c.route)) return c.route\n if (c.url) {\n const m = matchUrlToRoute(c.url, routePaths)\n if (m) return m\n }\n if (c.kind === \"page\") {\n const r = routes.find((r) => r.page === c.entity)\n if (r) return r.path\n }\n return null\n}\n\nexport function checkPageCoverage(\n registry: Registry,\n manifest: CapturedStatesManifest,\n baseline?: CoverageBaseline\n): Diagnostic[] {\n const routes = registry.list(\"route\")\n if (routes.length === 0) return []\n const routePaths = routes.map((r) => r.path)\n const captured = manifest.captured ?? []\n\n // Which routes a run actually covered (see routeForCapture).\n const covered = new Set<string>()\n for (const c of captured) {\n const route = routeForCapture(c, routes, routePaths)\n if (route) covered.add(route)\n }\n\n const diagnostics: Diagnostic[] = []\n\n for (const r of routes) {\n const ack = routeAcknowledge(registry, baseline, r.path, r.page).get(\n ACK_ALL\n )\n const loc = registry.get(\"page\", r.page)?.loc\n if (covered.has(r.path)) {\n // Hygiene: a capture contradicts the acknowledgment. An `impossible`\n // claim on a route a run just drove is exactly the rot the primitive is\n // meant to expose; a `backlog` entry is simply debt that got paid.\n if (ack?.type === \"impossible\") {\n diagnostics.push({\n code: \"stale-acknowledgment\",\n severity: \"warning\",\n message: `page \"${r.page}\" acknowledges \"*\" as ${describeAck(ack)}, but route \"${r.path}\" is captured`,\n file: loc?.file,\n line: loc?.line,\n entity: { kind: \"page\", id: r.page },\n hint: originHint(ack, r.page),\n })\n } else if (ack?.type === \"backlog\") {\n diagnostics.push({\n code: \"page-captured\",\n severity: \"warning\",\n message: `route \"${r.path}\" is now captured but is still acknowledged as backlog`,\n file: loc?.file,\n line: loc?.line,\n hint: originHint(ack, r.page),\n })\n }\n continue\n }\n if (ack?.type === \"impossible\") continue\n if (ack?.type === \"backlog\") {\n diagnostics.push({\n code: \"page-backlog\",\n severity: \"info\",\n message: `route \"${r.path}\" has no visual-states capture (acknowledged backlog)`,\n file: loc?.file,\n line: loc?.line,\n hint: `Capture it (drive the route in a states spec) and it drops off the baseline, or — if it can NEVER be captured — say so with \\`acknowledge: { \"*\": { type: \"impossible\", reason: \"…\" } }\\` on page \"${r.page}\".`,\n })\n continue\n }\n diagnostics.push({\n code: \"page-no-capture\",\n severity: \"error\",\n message: `route \"${r.path}\" has no visual-states capture and is not accounted for`,\n file: loc?.file,\n line: loc?.line,\n entity: { kind: \"route\", id: r.path },\n hint: `Capture the route in a states spec; or if it can NEVER be captured add \\`acknowledge: { \"*\": { type: \"impossible\", reason: \"why\" } }\\` to page \"${r.page}\"; or record it as debt with \\`uidex scan --update-baseline\\` (which writes \\`{ type: \"backlog\" }\\`, visible in the diff for review).`,\n })\n }\n\n // Baseline hygiene: an entry that no longer names a real route, so the\n // backlog can't rot into a list of routes nobody has.\n for (const b of Object.keys(baseline?.acknowledge ?? {})) {\n if (routePaths.includes(b)) continue\n diagnostics.push({\n code: \"stale-page-baseline\",\n severity: \"warning\",\n message: `coverage baseline acknowledges \"${b}\", which is not a route in the registry`,\n hint: `Remove it from the baseline (\\`uidex scan --update-baseline\\`); the route no longer exists.`,\n })\n }\n\n return diagnostics\n}\n\n/**\n * The page half of the shrink-only baseline for `--update-baseline`: every route\n * with no capture and no SOURCE acknowledgment. Seeds on first run and prunes on\n * later runs; growth only ever happens through this explicit command, visible in\n * the file's diff.\n */\nexport function computePageBacklog(\n registry: Registry,\n manifest: CapturedStatesManifest\n): Record<string, AcknowledgeMap> {\n const out: Record<string, AcknowledgeMap> = {}\n // Re-run the gate against an EMPTY baseline: anything that comes back as a\n // hard `page-no-capture` has no capture and no source acknowledgment.\n for (const d of checkPageCoverage(registry, manifest, {\n version: 2,\n acknowledge: {},\n })) {\n if (d.code === \"page-no-capture\" && d.entity) {\n out[d.entity.id] = { [ACK_ALL]: { type: \"backlog\" } }\n }\n }\n return out\n}\n","import * as fs from \"node:fs\"\nimport * as path from \"node:path\"\nimport { CONFIG_FILENAME, discover } from \"./discover\"\nimport { createSourceMatcher } from \"./walk\"\nimport type { CapturedState, CapturedStatesManifest } from \"./state-coverage\"\nimport type { DiscoveredConfig, UidexConfig } from \"./types\"\n\n/**\n * WORKSPACE — the level above one app.\n *\n * A monorepo app registers not only its own source but shared packages (a\n * `sources[]` entry pointing outside the app). A component declaring `states` in\n * `@acme/ui` therefore lands in EVERY app that sources it, while only one of them\n * captures it. Each scan used to be a closed world that could not see a sibling's\n * manifest, so \"captured elsewhere\" had to be GUESSED — the borrowed-entity\n * heuristic: \"this declaration came from a shared root and this app captured\n * nothing for it, so presumably somebody else did.\"\n *\n * That guess is now a computation. The workspace resolves the sibling apps and\n * answers exactly:\n *\n * 1. Does sibling B's configured source set CONTAIN this declaration's file?\n * Same rootDir/include/exclude rules as the walker (`createSourceMatcher`),\n * so \"B registers this same declaration\" is a fact read off B's config —\n * not an inference from THIS app's `prefix` strings.\n * 2. Does B's captured-states manifest contain a capture for it?\n *\n * Both true → `captured-elsewhere`, naming B. That kills the heuristic's\n * false-negative too: a page id that merely COLLIDES with an unrelated sibling\n * page fails test 1, because an app-local file is not inside the sibling's roots.\n *\n * Deliberately cheap: sibling `.uidex.json` files and their manifests are plain\n * JSON reads. Answering the question needs no sibling source walk, no sibling\n * parse, and no sibling registry — so making this the default costs a handful of\n * file reads rather than an N-times-slower scan.\n */\n\n/** Files/dirs that mark a directory as the root of a workspace. */\nconst WORKSPACE_MARKERS = [\n \"pnpm-workspace.yaml\",\n \"pnpm-workspace.yml\",\n \"turbo.json\",\n \"lerna.json\",\n \"nx.json\",\n \".git\",\n]\n\n/** How far up from the config dir the auto-detect looks for a marker. */\nconst MAX_ASCENT = 8\n\nconst DEFAULT_STATES_MANIFEST = \"uidex-states.json\"\n\n/**\n * Lookup key for \"this app captured entity X of kind K\". `|` is legal in\n * neither an entity kind nor a kebab-case id, so the two parts can never run\n * together. A capture that recorded NO kind gets its own key, matched\n * separately, so an unlabeled capture still counts — mirroring how the\n * state-coverage gate treats one.\n *\n * Exported because `WorkspaceApp.captured` is a public field: anyone building a\n * Workspace by hand (tests, embedders) has to produce keys in this exact shape.\n */\nexport function captureKey(kind: string | undefined, entity: string): string {\n return `${kind ?? \"\"}|${entity}`\n}\n\nexport interface WorkspaceApp {\n /** Display name — the config dir's basename (e.g. \"platform-web\"). */\n name: string\n configDir: string\n configPath: string\n /** Whether this app's configured sources would register `absFile`. */\n registers: (absFile: string) => boolean\n /** `captureKey` values this app's manifest captured. */\n captured: ReadonlySet<string>\n}\n\nexport interface Workspace {\n root: string\n /** Every OTHER app in the workspace; the scanning app is excluded. */\n siblings: WorkspaceApp[]\n}\n\nexport interface ResolveWorkspaceOptions {\n configDir: string\n config: UidexConfig\n /** Overrides discovery; used by tests to avoid touching the real filesystem. */\n configs?: DiscoveredConfig[]\n}\n\nfunction hasMarker(dir: string): boolean {\n return WORKSPACE_MARKERS.some((m) => fs.existsSync(path.join(dir, m)))\n}\n\n/**\n * Walk up from the app looking for a workspace marker. Returns `undefined` when\n * there is none — a standalone app then keeps today's closed-world behavior\n * rather than silently treating its parent directory as a workspace.\n */\nexport function findWorkspaceRoot(configDir: string): string | undefined {\n let dir = path.resolve(configDir)\n for (let i = 0; i < MAX_ASCENT; i++) {\n const parent = path.dirname(dir)\n if (parent === dir) return undefined\n dir = parent\n if (hasMarker(dir)) return dir\n }\n return undefined\n}\n\nfunction captureKeys(\n manifest: CapturedStatesManifest | undefined\n): Set<string> {\n const out = new Set<string>()\n for (const c of manifest?.captured ?? []) {\n out.add(captureKey(c.kind, c.entity))\n }\n return out\n}\n\nfunction readManifest(\n configDir: string,\n config: UidexConfig\n): CapturedStatesManifest | undefined {\n const rel = config.statesManifest ?? DEFAULT_STATES_MANIFEST\n let raw: string\n try {\n raw = fs.readFileSync(path.resolve(configDir, rel), \"utf8\")\n } catch {\n return undefined\n }\n try {\n const parsed = JSON.parse(raw) as Partial<CapturedStatesManifest>\n if (!parsed || !Array.isArray(parsed.captured)) return undefined\n const captured: CapturedState[] = []\n for (const entry of parsed.captured as unknown[]) {\n if (!entry || typeof entry !== \"object\") continue\n const c = entry as Record<string, unknown>\n if (typeof c.entity !== \"string\" || typeof c.state !== \"string\") continue\n const rec: CapturedState = { entity: c.entity, state: c.state }\n if (typeof c.kind === \"string\") rec.kind = c.kind as CapturedState[\"kind\"]\n captured.push(rec)\n }\n return { captured }\n } catch {\n return undefined\n }\n}\n\nfunction toApp(dc: DiscoveredConfig): WorkspaceApp {\n return {\n name: path.basename(dc.configDir),\n configDir: dc.configDir,\n configPath: dc.configPath,\n registers: createSourceMatcher(dc.config.sources, {\n cwd: dc.configDir,\n globalExcludes: dc.config.exclude,\n }),\n captured: captureKeys(readManifest(dc.configDir, dc.config)),\n }\n}\n\n/**\n * Resolve the workspace an app participates in.\n *\n * `config.workspace` selects the root: a path (relative to the config dir),\n * `false` for an explicit closed world, or omitted for auto-detect via\n * `findWorkspaceRoot`. Returns `undefined` when there is no workspace or no\n * sibling in it — callers then behave exactly as a single-app scan does.\n */\nexport function resolveWorkspace(\n opts: ResolveWorkspaceOptions\n): Workspace | undefined {\n const { configDir, config } = opts\n if (config.workspace === false) return undefined\n\n const root =\n typeof config.workspace === \"string\"\n ? path.resolve(configDir, config.workspace)\n : findWorkspaceRoot(configDir)\n if (!root) return undefined\n\n const configs = opts.configs ?? discover({ cwd: root, all: true })\n const self = path.resolve(configDir, CONFIG_FILENAME)\n const siblings = configs\n .filter((dc) => path.resolve(dc.configPath) !== self)\n .map(toApp)\n if (siblings.length === 0) return undefined\n return { root, siblings }\n}\n\n/**\n * The sibling app that already captured this declaration, if any — the exact\n * answer that replaces the borrowed-entity guess. `absFile` is the declaring\n * file's real path (a display path cannot be resolved back across a `prefix`).\n *\n * A capture recording no `kind` matches on id alone, mirroring how the\n * state-coverage gate treats an unlabeled capture.\n */\nexport function capturedElsewhere(\n workspace: Workspace | undefined,\n absFile: string | undefined,\n kind: string,\n id: string\n): string | undefined {\n if (!workspace || !absFile) return undefined\n for (const app of workspace.siblings) {\n if (!app.registers(absFile)) continue\n if (\n app.captured.has(captureKey(kind, id)) ||\n app.captured.has(captureKey(undefined, id))\n ) {\n return app.name\n }\n }\n return undefined\n}\n","import type { MetaEntityKind, Registry } from \"../../shared/entities\"\nimport { describeAck, entityAcknowledge } from \"./acknowledge\"\nimport { capturedElsewhere, type Workspace } from \"./workspace\"\nimport type { Diagnostic } from \"./types\"\n\n/**\n * State-capture completeness — the deterministic replacement for a bespoke\n * `check-states.mjs`. Cross-checks the states DECLARED on registry entities\n * (`export const uidex = { states: [...] }`) against the states a capture run\n * actually produced (a `uidex-states.json` manifest written by the Playwright\n * states reporter):\n *\n * - `missing-state-capture` — a declared state no run captured. The gap the\n * acceptance-grounded analysis surfaces (a promised behavior with no pixel\n * evidence) becomes a mechanical audit failure.\n * - `orphan-state-capture` — a run captured a state the entity never declared,\n * so the contact sheet shows a state the registry doesn't know about.\n *\n * Two things take an entity out of the gate, and both are acknowledgments:\n * a SOURCE `acknowledge: { \"*\": … }`, or the WORKSPACE observing that a sibling\n * app which registers this same declaration captured it (`captured-elsewhere`).\n *\n * The workspace answer replaces a heuristic this module used to carry: a\n * \"borrowed\" entity (one declared under a shared source `prefix`) that this app\n * captured nothing for was ASSUMED to be a sibling's responsibility. That guess\n * could not tell a genuinely shared component from an id that merely collided\n * with a sibling's, and it silenced real gaps whenever an app captured nothing.\n * The workspace checks the sibling's actual source set and actual manifest, so\n * the answer is exact and the guess is gone.\n */\n\n/** One `entity/state` a capture run recorded. */\nexport interface CapturedState {\n /** Registry entity id the capture rendered (e.g. \"products\"). */\n entity: string\n /** Entity kind, when the capture recorded it (page/feature/widget). */\n kind?: MetaEntityKind\n /** The declared state name captured (e.g. \"new-filled\"). */\n state: string\n /** Canonical matrix kind (loading/empty/populated/error/variant). */\n stateKind?: string\n /** URL pathname the capture ran against (page-coverage gate matches it to a route). */\n url?: string\n /** Explicit route pattern the capture covers, when supplied. */\n route?: string\n}\n\nexport interface CapturedStatesManifest {\n captured: CapturedState[]\n /** ISO timestamp the reporter stamped; drives the staleness check. */\n generatedAt?: string\n}\n\nconst STATE_KINDS: readonly MetaEntityKind[] = [\"page\", \"feature\", \"widget\"]\n\ninterface DeclaredEntity {\n kind: MetaEntityKind\n id: string\n states: string[]\n loc?: { file?: string; line?: number }\n}\n\nexport interface StateCoverageOptions {\n /** The workspace, when one is resolved; enables `captured-elsewhere`. */\n workspace?: Workspace\n /**\n * Maps an entity's `loc.file` (a DISPLAY path, which a `prefix` makes\n * unresolvable on its own) back to its real path on disk. Supplied by\n * `audit()` from the scanned-file list, so the workspace can test the file\n * against a sibling's source roots.\n */\n resolveSourcePath?: (displayPath: string) => string | undefined\n}\n\nfunction declaredStateEntities(\n registry: Registry,\n opts: StateCoverageOptions,\n ungated: Diagnostic[]\n): DeclaredEntity[] {\n const out: DeclaredEntity[] = []\n for (const kind of STATE_KINDS) {\n for (const e of registry.list(kind)) {\n const states = e.meta?.states\n if (!states || states.length === 0) continue\n const absFile = e.loc?.file\n ? opts.resolveSourcePath?.(e.loc.file)\n : undefined\n const ack = entityAcknowledge(\n e.meta,\n capturedElsewhere(opts.workspace, absFile, kind, e.id)\n )\n if (ack) {\n // A COMPUTED acknowledgment is invisible in the source, so it is\n // reported; an authored one is already right there in the file.\n if (ack.origin === \"workspace\") {\n ungated.push({\n code: \"acknowledged-elsewhere\",\n severity: \"info\",\n message: `${kind} \"${e.id}\" declares states that no capture here produced, but sibling app \"${ack.by}\" registers the same declaration and captured it (${describeAck(ack)})`,\n file: e.loc?.file,\n line: e.loc?.line,\n entity: { kind, id: e.id },\n hint: `This is the workspace answering, not a guess: \"${ack.by}\" sources the declaring file and its manifest has a capture for \"${e.id}\". Set \\`workspace: false\\` in .uidex.json to gate it here anyway.`,\n })\n }\n continue\n }\n out.push({\n kind,\n id: e.id,\n states: states.map((s) => s.name),\n loc: e.loc,\n })\n }\n }\n return out\n}\n\n/**\n * Ids some capture recorded as `kind: \"page\"` that no PAGE entity claims.\n *\n * A capture harness that DEFAULTS `kind` to `\"page\"` (rather than leaving it\n * unset) makes every component capture unmatchable: the recorded kind is wrong,\n * not merely absent, so strict matching rejects it and the entity's declared\n * states read as never captured. Treating `\"page\"` as unreliable ONLY when no\n * page owns that id recovers those captures while leaving genuine page captures\n * matched exactly — an id owned by a real page never lands in this set.\n */\nfunction unreliablePageKinds(\n registry: Registry,\n captured: CapturedState[]\n): ReadonlySet<string> {\n const out = new Set<string>()\n for (const c of captured) {\n if (c.kind !== \"page\") continue\n if (registry.get(\"page\", c.entity)) continue\n out.add(c.entity)\n }\n return out\n}\n\n/** Whether a captured entry can refer to this declared entity. */\nfunction captureMatchesEntity(\n cap: CapturedState,\n ent: DeclaredEntity,\n unreliable: ReadonlySet<string> = EMPTY\n): boolean {\n if (cap.entity !== ent.id) return false\n if (cap.kind === undefined) return true\n if (cap.kind === ent.kind) return true\n // A defaulted-but-wrong `\"page\"` kind no page claims: match on id alone.\n return cap.kind === \"page\" && unreliable.has(cap.entity)\n}\n\nconst EMPTY: ReadonlySet<string> = new Set<string>()\n\nexport function checkStateCoverage(\n registry: Registry,\n manifest: CapturedStatesManifest,\n opts: StateCoverageOptions = {}\n): Diagnostic[] {\n const diagnostics: Diagnostic[] = []\n const captured = manifest.captured ?? []\n const unreliable = unreliablePageKinds(registry, captured)\n const declared = declaredStateEntities(registry, opts, diagnostics)\n\n // ---- missing: declared but never captured ----\n for (const ent of declared) {\n for (const state of ent.states) {\n const hit = captured.some(\n (c) => captureMatchesEntity(c, ent, unreliable) && c.state === state\n )\n if (hit) continue\n diagnostics.push({\n code: \"missing-state-capture\",\n severity: \"warning\",\n message: `${ent.kind} \"${ent.id}\" declares state \"${state}\" but no capture produced it`,\n file: ent.loc?.file,\n line: ent.loc?.line,\n entity: { kind: ent.kind, id: ent.id },\n hint: `Add a capture for \"${ent.id}/${state}\" to the states matrix, or remove the state from \\`export const uidex = { states: [...] }\\` if it no longer exists.`,\n })\n }\n }\n\n // ---- orphan: captured a state the entity never declared ----\n // Only flag when the entity DECLARES states (an entity with no `states` block\n // opts out of the gate, so extra captures for it are fine).\n for (const cap of captured) {\n const candidates = declared.filter((ent) =>\n captureMatchesEntity(cap, ent, unreliable)\n )\n if (candidates.length === 0) continue // entity declares no states → not gated\n const declaredSomewhere = candidates.some((ent) =>\n ent.states.includes(cap.state)\n )\n if (declaredSomewhere) continue\n const ent = candidates[0]\n diagnostics.push({\n code: \"orphan-state-capture\",\n severity: \"warning\",\n message: `Capture produced state \"${cap.state}\" for ${ent.kind} \"${ent.id}\", which is not in its declared states [${ent.states.join(\", \")}]`,\n file: ent.loc?.file,\n line: ent.loc?.line,\n entity: { kind: ent.kind, id: ent.id },\n hint: `Declare \"${cap.state}\" in \\`export const uidex = { states: [...] }\\` for \"${ent.id}\", or rename the capture to a declared state.`,\n })\n }\n\n return diagnostics\n}\n","import { CORE_STATE_KINDS, type Registry } from \"../../shared/entities\"\nimport {\n ACK_ALL,\n describeAck,\n originHint,\n routeAcknowledge,\n type AcknowledgeMap,\n type CoverageBaseline,\n type ResolvedAcknowledgment,\n} from \"./acknowledge\"\nimport { routeForCapture } from \"./page-coverage\"\nimport type { CapturedState, CapturedStatesManifest } from \"./state-coverage\"\nimport type { Diagnostic } from \"./types\"\n\n/**\n * State-matrix coverage — the second completeness axis. A capture that only ever\n * shoots the happy path leaves most of the harness's value on the table, so\n * every *captured* route must render each of the four core kinds\n * (loading / empty / populated / error), or ACKNOWLEDGE the gap:\n *\n * acknowledge: { empty: { type: \"impossible\", reason: \"a create form…\" } }\n * acknowledge: { empty: { type: \"backlog\" } }\n *\n * Those two used to be a page-level `waivers` map and a `missingKinds` block in\n * a separate baseline file — different shapes, different homes, and only prose\n * to explain which was correct. They are now sibling values of one field, so\n * calling capturable debt \"impossible\" is a one-token edit a reviewer can see.\n *\n * Only *captured* routes are in scope: a route with no capture at all is a\n * page-coverage concern, not a matrix hole.\n */\n\nconst CORE_KINDS: readonly string[] = CORE_STATE_KINDS\nconst STATE_ENTITY_KINDS = [\"page\", \"feature\", \"widget\"] as const\n\n/**\n * The canonical matrix kind of a captured state: the recorded `stateKind`, else\n * the `kind` declared on the entity's `states: [{ name, kind }]`, else inferred\n * from the state name (a core-kind name → that kind, otherwise `variant`). So a\n * declared kind is honored even when the capture (e.g. `recordStates`) recorded\n * none, and a non-core-named state that declares a core kind still fills its cell.\n */\nfunction resolveMatrixKind(registry: Registry, c: CapturedState): string {\n if (c.stateKind) return c.stateKind\n for (const kind of STATE_ENTITY_KINDS) {\n const declared = registry\n .get(kind, c.entity)\n ?.meta?.states?.find((s) => s.name === c.state)?.kind\n if (declared) return declared\n }\n return CORE_KINDS.includes(c.state) ? c.state : \"variant\"\n}\n\n/** route → the core kinds a run actually captured for it. */\nfunction coreKindsByRoute(\n registry: Registry,\n manifest: CapturedStatesManifest\n): Map<string, Set<string>> {\n const routes = registry.list(\"route\")\n const routePaths = routes.map((r) => r.path)\n const byRoute = new Map<string, Set<string>>()\n for (const c of manifest.captured ?? []) {\n const route = routeForCapture(c, routes, routePaths)\n if (!route) continue\n // Every capture marks the route as \"captured\" (so the matrix applies), but\n // only core kinds fill the matrix cells.\n if (!byRoute.has(route)) byRoute.set(route, new Set())\n const kind = resolveMatrixKind(registry, c)\n if (CORE_KINDS.includes(kind)) byRoute.get(route)!.add(kind)\n }\n return byRoute\n}\n\nexport function checkStateMatrix(\n registry: Registry,\n manifest: CapturedStatesManifest,\n baseline?: CoverageBaseline\n): Diagnostic[] {\n const routes = registry.list(\"route\")\n if (routes.length === 0) return []\n const pageOf = new Map(routes.map((r) => [r.path, r.page]))\n const captured = coreKindsByRoute(registry, manifest)\n const diagnostics: Diagnostic[] = []\n\n for (const [route, kinds] of captured) {\n const page = pageOf.get(route)\n const ack = routeAcknowledge(registry, baseline, route, page)\n const loc = page ? registry.get(\"page\", page)?.loc : undefined\n\n // An entity-scoped acknowledgment takes the whole route out of the matrix,\n // mirroring the page-coverage gate — otherwise a capture that incidentally\n // hits a redirect / static page would be forced to render all four kinds.\n const all = ack.get(ACK_ALL)\n if (all) {\n // …but if it claims the route can NEVER be captured and a run just\n // captured it, that is the claim rotting, and it must be visible.\n if (all.type === \"impossible\") {\n diagnostics.push(staleDiagnostic(all, route, page, loc))\n }\n continue\n }\n\n for (const kind of CORE_KINDS) {\n if (kinds.has(kind)) continue\n const entry = ack.get(kind)\n if (entry?.type === \"impossible\") continue // the route CANNOT render it\n if (entry?.type === \"backlog\") {\n diagnostics.push({\n code: \"matrix-backlog\",\n severity: \"info\",\n message: `route \"${route}\" does not render core kind \"${kind}\" (acknowledged backlog)`,\n file: loc?.file,\n line: loc?.line,\n hint: `Capture the \"${kind}\" state for \"${route}\", or if the route CANNOT render it change the acknowledgment to \\`{ type: \"impossible\", reason: \"why it can't\" }\\`.`,\n })\n continue\n }\n diagnostics.push({\n code: \"core-kind\",\n severity: \"error\",\n message: `route \"${route}\" is captured but never renders core kind \"${kind}\"`,\n file: loc?.file,\n line: loc?.line,\n entity: { kind: \"route\", id: route },\n hint: `Capture the \"${kind}\" state; or if the route CANNOT render it, add \\`acknowledge: { ${kind}: { type: \"impossible\", reason: \"why it can't\" } }\\` to page \"${page}\"; or record it as debt with \\`uidex scan --update-baseline\\` (which writes \\`{ type: \"backlog\" }\\`, visible in the diff for review).`,\n })\n }\n\n // Hygiene: an acknowledgment for a kind the route DOES render hides a real\n // capture and rots its reason.\n for (const [scope, entry] of ack) {\n if (scope === ACK_ALL || !kinds.has(scope)) continue\n diagnostics.push(staleDiagnostic(entry, route, page, loc))\n }\n }\n\n return diagnostics\n}\n\nfunction staleDiagnostic(\n entry: ResolvedAcknowledgment,\n route: string,\n page: string | undefined,\n loc: { file?: string; line?: number } | undefined\n): Diagnostic {\n const what =\n entry.scope === ACK_ALL\n ? `route \"${route}\" is captured`\n : `route \"${route}\" does render core kind \"${entry.scope}\"`\n return {\n code: \"stale-acknowledgment\",\n severity: \"warning\",\n message: `${page ? `page \"${page}\"` : `route \"${route}\"`} acknowledges \"${entry.scope}\" as ${describeAck(entry)}, but ${what}`,\n file: loc?.file,\n line: loc?.line,\n ...(page ? { entity: { kind: \"page\" as const, id: page } } : {}),\n hint: originHint(entry, page),\n }\n}\n\n/**\n * The matrix half of the shrink-only baseline for `--update-baseline`: every\n * (captured route, core kind) that is neither captured nor already acknowledged\n * in SOURCE. Source acknowledgments are excluded so the same gap is never\n * recorded twice, in two files, saying two things.\n */\nexport function computeMatrixBacklog(\n registry: Registry,\n manifest: CapturedStatesManifest\n): Record<string, AcknowledgeMap> {\n const routes = registry.list(\"route\")\n const pageOf = new Map(routes.map((r) => [r.path, r.page]))\n const captured = coreKindsByRoute(registry, manifest)\n const out: Record<string, AcknowledgeMap> = {}\n for (const [route, kinds] of captured) {\n const page = pageOf.get(route)\n // Recompute against NO baseline: only source acknowledgments count here.\n const ack = routeAcknowledge(registry, undefined, route, page)\n if (ack.has(ACK_ALL)) continue\n const scopes: AcknowledgeMap = {}\n for (const kind of CORE_KINDS) {\n if (kinds.has(kind) || ack.has(kind)) continue\n scopes[kind] = { type: \"backlog\" }\n }\n if (Object.keys(scopes).length > 0) out[route] = scopes\n }\n return out\n}\n","import type { Entity, Registry } from \"../../shared/entities\"\nimport type { GitContext } from \"./types\"\n\nexport interface EmitOptions {\n registry: Registry\n gitContext?: GitContext\n /** The import source for `createUidex` in the generated preconfigured export. */\n uidexImport?: string\n}\n\n/**\n * The scanner emits THREE artifacts, split by consumer:\n *\n * - `types` — the id unions + the `Uidex` authoring-shape namespace. Pure types,\n * no runtime, no `@ts-nocheck`. This is the file the ~dozens of\n * `import type { Uidex } from \"@/uidex.gen\"` sites resolve, so it must stay\n * small: an `import type` still forces tsc/tsserver to fully parse the target\n * module, so keeping the runtime entity data out of it is what keeps the editor\n * and type-checker responsive across every consumer file.\n * - `data` — the AUTHORED registry (route/page/feature/widget/primitive/flow) +\n * `gitContext` + `loadRegistry` + the preconfigured `uidex` instance. Runtime,\n * `@ts-nocheck`. Loaded eagerly by the devtools on mount.\n * - `locs` — the thin element/region `{ id, loc }` entities, emitted as positional\n * tuples (see `emitLocsModule`). Loaded lazily by the devtools (idle / first\n * inspect) via `loadLocs`, so ~90% of the entity count stays out of the initial\n * devtools chunk.\n */\nexport interface EmitResult {\n types: string\n /** Authored-metadata registry (pages/features/widgets/flows/…). */\n data: string\n /** Deferred `id → loc` module for the thin element/region entities. */\n locs: string\n}\n\n/**\n * Kinds shipped in the main (eagerly-loaded) registry: they carry authored\n * metadata (acceptance/states/flows/descriptions) the devtools renders. The thin\n * kinds (`element`, `region`) are just `{ id, loc }` and exist only so the\n * inspector can show a clicked node's source path — so they move to a SEPARATE\n * `.locs` module the devtools loads lazily (after mount / on first inspect),\n * keeping ~90% of the entity count out of the initial devtools chunk.\n */\nconst AUTHORED_KINDS = new Set([\n \"route\",\n \"page\",\n \"feature\",\n \"widget\",\n \"primitive\",\n \"flow\",\n])\n\n/**\n * Intern `loc.file` paths into a shared string table and serialize as a MINIFIED\n * `JSON.parse(\"…\")` payload (cheaper for a bundler to transform — a trivial AST —\n * and `tsc` sees `any`, not a giant literal). Returns the `files` declaration and\n * the `JSON.parse(...).map(hydrate)` expression; the caller emits a module-local\n * `hydrate()` that reverses the interning at load.\n */\nfunction internedPayload(entities: readonly Entity[]): {\n filesDecl: string\n parseExpr: string\n} {\n const fileIndex = new Map<string, number>()\n const files: string[] = []\n const compact = entities.map((e) => {\n const loc = (e as { loc?: { file?: unknown } }).loc\n if (!loc || typeof loc.file !== \"string\") return e\n let idx = fileIndex.get(loc.file)\n if (idx === undefined) {\n idx = files.length\n files.push(loc.file)\n fileIndex.set(loc.file, idx)\n }\n const rest = { ...(loc as Record<string, unknown>) }\n delete rest.file\n return { ...e, loc: { f: idx, ...rest } }\n })\n return {\n filesDecl: `const files: readonly string[] = ${jsonStable(files)}`,\n parseExpr: `(JSON.parse(${JSON.stringify(\n JSON.stringify(compact, replacerSorted)\n )}) as any[]).map(hydrate)`,\n }\n}\n\nconst HYDRATE_FN = [\n \"function hydrate(e: any): any {\",\n ' if (e.loc && typeof e.loc.f === \"number\") {',\n \" const { f, ...rest } = e.loc\",\n \" e.loc = { file: files[f], ...rest }\",\n \" }\",\n \" return e\",\n \"}\",\n].join(\"\\n\")\n\n/**\n * The `.locs` module holds thousands of thin element/region entities that are\n * almost all just `{ kind, id, loc }`. Rather than the generic object payload,\n * emit those as positional TUPLES `[kindIdx, id, fileIdx, line?, col?]` — which\n * drops every repeated JSON key (`\"kind\"`, `\"id\"`, `\"loc\"`, `\"line\"`, …) across\n * every row — and keep the handful of metadata-bearing entities (e.g. regions\n * with `composes`) as compact objects with an interned `loc`. `loadLocs`\n * reconstitutes the full `{ kind, id, loc, meta? }` entities.\n */\n/**\n * Shrink a rich thin-entity's `meta` for the `.locs` payload: collapse\n * `composes: [{ id, kind: \"element\" }]` → `[\"id\"]` (the common case — a region\n * composing elements; `loadLocs` re-wraps string entries as element refs).\n * Non-element refs keep their `{ id, kind }` object form. Every other field\n * (including `flows`) is preserved verbatim, so the reconstructed entity matches\n * the scanner's exactly.\n */\nfunction compactMeta(meta: unknown): unknown {\n if (!meta || typeof meta !== \"object\") return meta\n const composes = (meta as { composes?: unknown }).composes\n if (!Array.isArray(composes)) return meta\n return {\n ...(meta as Record<string, unknown>),\n composes: composes.map((c) =>\n c &&\n typeof c === \"object\" &&\n (c as { kind?: unknown }).kind === \"element\" &&\n Object.keys(c).length === 2 &&\n typeof (c as { id?: unknown }).id === \"string\"\n ? (c as { id: string }).id\n : c\n ),\n }\n}\n\nfunction emitLocsModule(thin: readonly Entity[], uidexImport: string): string {\n const kinds = [...new Set(thin.map((e) => e.kind))].sort()\n const kindIdx = new Map(kinds.map((k, i) => [k, i]))\n const fileIndex = new Map<string, number>()\n const files: string[] = []\n const fi = (f: string): number => {\n let i = fileIndex.get(f)\n if (i === undefined) {\n i = files.length\n files.push(f)\n fileIndex.set(f, i)\n }\n return i\n }\n\n const bare: Array<Array<string | number>> = []\n const rich: unknown[] = []\n for (const e of thin) {\n const loc = (e as { loc?: Record<string, unknown> }).loc\n const topOnlyKindIdLoc = Object.keys(e).every(\n (k) => k === \"kind\" || k === \"id\" || k === \"loc\"\n )\n const locOnlyKnown =\n !!loc &&\n typeof loc.file === \"string\" &&\n Object.keys(loc).every(\n (k) => k === \"file\" || k === \"line\" || k === \"column\"\n )\n if (topOnlyKindIdLoc && locOnlyKnown) {\n const row: Array<string | number> = [\n kindIdx.get(e.kind)!,\n (e as { id: string }).id,\n fi(loc.file as string),\n ]\n if (loc.line != null || loc.column != null)\n row.push(Number(loc.line ?? 0))\n if (loc.column != null) row.push(Number(loc.column))\n bare.push(row)\n } else {\n const richEntity: Record<string, unknown> = { ...e }\n if (loc && typeof loc.file === \"string\") {\n const { file, ...rest } = loc as { file: string } & Record<\n string,\n unknown\n >\n richEntity.loc = { f: fi(file), ...rest }\n }\n if (richEntity.meta) richEntity.meta = compactMeta(richEntity.meta)\n rich.push(richEntity)\n }\n }\n\n const str = (v: unknown): string =>\n JSON.stringify(JSON.stringify(v, replacerSorted))\n const l: string[] = []\n l.push(\"// THIS FILE IS AUTO-GENERATED BY `uidex scan`. DO NOT EDIT.\")\n l.push(\n \"// Deferred element/region source locations for the inspector's copy-path.\"\n )\n l.push(\"// @ts-nocheck\")\n l.push(\"/* eslint-disable */\")\n l.push(`import type { Entity, Registry } from ${JSON.stringify(uidexImport)}`)\n l.push(\"\")\n l.push(`const files: readonly string[] = ${jsonStable(files)}`)\n l.push(`const kinds: readonly string[] = ${jsonStable(kinds)}`)\n l.push(\"function loc(fi: number, line?: number, col?: number) {\")\n l.push(\" const o: any = { file: files[fi] }\")\n // Truthy (not `!= null`): a 0 is the placeholder for an absent line/column\n // (source positions are 1-based), so `[k,id,fi,0,col]` — a column with no line\n // — reconstructs without a spurious `line: 0`.\n l.push(\" if (line) o.line = line\")\n l.push(\" if (col) o.column = col\")\n l.push(\" return o\")\n l.push(\"}\")\n l.push(`const bare: any[] = JSON.parse(${str(bare)})`)\n l.push(`const rich: any[] = JSON.parse(${str(rich)})`)\n l.push(\"\")\n l.push(\n \"/** Add the thin element/region entities (source locations) to a registry. */\"\n )\n l.push(\"export function loadLocs(target: Registry): Registry {\")\n l.push(\" for (const r of bare)\")\n l.push(\n \" target.add({ kind: kinds[r[0]], id: r[1], loc: loc(r[2], r[3], r[4]) } as Entity)\"\n )\n // Build a fresh entity per call (don't mutate the shared module-level `rich`\n // objects), re-hydrating the interned loc and re-expanding string composes back\n // to `{ id, kind: \"element\" }` element refs.\n l.push(\" for (const e of rich) {\")\n l.push(\" const out: any = { ...e }\")\n l.push(' if (e.loc && typeof e.loc.f === \"number\") {')\n l.push(\" const { f, ...rest } = e.loc\")\n l.push(\" out.loc = { file: files[f], ...rest }\")\n l.push(\" }\")\n l.push(\" if (e.meta && Array.isArray(e.meta.composes)) {\")\n l.push(\n ' out.meta = { ...e.meta, composes: e.meta.composes.map((c: any) => typeof c === \"string\" ? { id: c, kind: \"element\" } : c) }'\n )\n l.push(\" }\")\n l.push(\" target.add(out)\")\n l.push(\" }\")\n l.push(\" return target\")\n l.push(\"}\")\n l.push(\"\")\n return l.join(\"\\n\")\n}\n\nfunction sortById<T extends { id: string }>(arr: readonly T[]): T[] {\n return [...arr].sort((a, b) => a.id.localeCompare(b.id))\n}\n\nfunction jsonStable(value: unknown, indent = 2): string {\n return JSON.stringify(value, replacerSorted, indent)\n}\n\nfunction replacerSorted(_key: string, value: unknown): unknown {\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[k] = (value as Record<string, unknown>)[k]\n }\n return sorted\n }\n return value\n}\n\nfunction emitIdUnion(name: string, ids: string[]): string {\n if (ids.length === 0) return `export type ${name} = never\\n`\n const sorted = [...ids].sort()\n const body = sorted.map((id) => ` | ${JSON.stringify(id)}`).join(\"\\n\")\n return `export type ${name} =\\n${body}\\n`\n}\n\n/**\n * Id kinds emitted as an opaque branded `string` instead of a literal union.\n * `element` ids number in the thousands, yet no `Uidex.*` authoring shape\n * references `ElementId`, so a multi-thousand-member literal union is pure\n * type-checker cost (parse + the quadratic union comparisons the TS Performance\n * guide warns about, and eventual TS2590 risk) for zero authoring value. A\n * branded string collapses the union to a single type while keeping the exported\n * name usable by any consumer that references it. The smaller, *referenced*\n * unions (PageId/FeatureId/WidgetId/RegionId/…) stay literal so `satisfies\n * Uidex.Page` etc. keep their id autocomplete.\n */\nconst OPAQUE_ID_UNIONS = new Set([\"ElementId\"])\n\n/**\n * `UidexStates` — the declared state space, as a TYPE.\n *\n * `StateId` flattens every state name into one union, which cannot express that\n * `\"01-variants\"` belongs to the widget `gate-badge` and nowhere else. This\n * emits the actual shape — kind → entity id → its own state names — so a capture\n * helper bound to it rejects a wrong entity, a wrong kind, or a state that entity\n * never declared, at COMPILE time. `missing-state-capture` / `orphan-state-capture`\n * become the fallback for what types cannot see (a capture that never ran),\n * rather than the primary defence against a typo.\n *\n * Type-only, so `uidex.gen.ts` stays free of any runtime import: the e2e side\n * binds it via `createStateCapture<UidexStates>()` from `uidex/playwright`,\n * keeping Playwright out of the app bundle.\n */\n/** `{ id, states }` for every entity of a kind, for the state-map emission. */\nfunction stateEntities(\n list: readonly { id: string; meta?: { states?: { name: string }[] } }[]\n): { id: string; states: string[] }[] {\n return list.map((e) => ({\n id: e.id,\n states: (e.meta?.states ?? []).map((s) => s.name),\n }))\n}\n\nfunction emitStateMap(\n groups: { kind: string; entities: { id: string; states: string[] }[] }[]\n): string {\n const lines: string[] = [\"export interface UidexStates {\"]\n for (const g of groups) {\n const withStates = g.entities.filter((e) => e.states.length > 0)\n if (withStates.length === 0) {\n // `never` (not `{}`) so binding a kind that declares nothing is an error,\n // not a silently-permissive `Record<string, never>`.\n lines.push(` ${g.kind}: never`)\n continue\n }\n lines.push(` ${g.kind}: {`)\n for (const e of [...withStates].sort((a, b) => a.id.localeCompare(b.id))) {\n const states = [...new Set(e.states)]\n .sort()\n .map((s) => JSON.stringify(s))\n .join(\" | \")\n lines.push(` ${JSON.stringify(e.id)}: ${states}`)\n }\n lines.push(\" }\")\n }\n lines.push(\"}\")\n return lines.join(\"\\n\") + \"\\n\"\n}\n\nfunction emitId(name: string, ids: string[]): string {\n if (OPAQUE_ID_UNIONS.has(name)) {\n return `export type ${name} = string & { readonly __uidex?: ${JSON.stringify(name)} }\\n`\n }\n return emitIdUnion(name, ids)\n}\n\n/** The default suffix that derives the runtime-data module path from `output`. */\nexport function dataOutputPath(output: string): string {\n return output.replace(/\\.(d\\.ts|ts|tsx|mts|cts|js|mjs|cjs)$/, \".data.$1\")\n}\n\n/** The default suffix that derives the deferred `.locs` module path from `output`. */\nexport function locsOutputPath(output: string): string {\n return output.replace(/\\.(d\\.ts|ts|tsx|mts|cts|js|mjs|cjs)$/, \".locs.$1\")\n}\n\nexport function emit(opts: EmitOptions): EmitResult {\n const { registry, gitContext, uidexImport = \"uidex\" } = opts\n\n const routes = [...registry.list(\"route\")].sort((a, b) =>\n a.path.localeCompare(b.path)\n )\n const pages = sortById(registry.list(\"page\"))\n const features = sortById(registry.list(\"feature\"))\n const widgets = sortById(registry.list(\"widget\"))\n\n // Distinct declared render-state names across every state-bearing entity.\n const stateNames = new Set<string>()\n for (const e of [...pages, ...features, ...widgets]) {\n for (const s of e.meta?.states ?? []) stateNames.add(s.name)\n }\n const regions = sortById(registry.list(\"region\"))\n const elements = sortById(registry.list(\"element\"))\n const primitives = sortById(registry.list(\"primitive\"))\n const flows = sortById(registry.list(\"flow\"))\n\n // ---------------------------------------------------------------------------\n // Types file — pure types, no runtime, no `@ts-nocheck`. Kept small so the\n // `import type { Uidex }` sites (and tsserver, on every keystroke in them) parse\n // only this, never the entity data.\n // ---------------------------------------------------------------------------\n const t: string[] = []\n t.push(\"// THIS FILE IS AUTO-GENERATED BY `uidex scan`. DO NOT EDIT.\")\n t.push(\n \"// Types only — the runtime registry lives in the sibling `.data` module.\"\n )\n t.push(\"/* eslint-disable */\")\n t.push(\"\")\n t.push(\"// ---- id unions ----\")\n t.push(\n emitId(\n \"PageId\",\n pages.map((e) => e.id)\n )\n )\n t.push(\n emitId(\n \"FeatureId\",\n features.map((e) => e.id)\n )\n )\n t.push(\n emitId(\n \"WidgetId\",\n widgets.map((e) => e.id)\n )\n )\n t.push(\n emitId(\n \"RegionId\",\n regions.map((e) => e.id)\n )\n )\n t.push(\n emitId(\n \"ElementId\",\n elements.map((e) => e.id)\n )\n )\n t.push(\n emitId(\n \"PrimitiveId\",\n primitives.map((e) => e.id)\n )\n )\n t.push(\n emitId(\n \"FlowId\",\n flows.map((e) => e.id)\n )\n )\n t.push(\n emitId(\n \"RouteId\",\n routes.map((e) => e.path)\n )\n )\n t.push(emitId(\"StateId\", [...stateNames]))\n t.push(\"\")\n t.push(\"// ---- declared state space (kind → entity → its own states) ----\")\n t.push(\n emitStateMap([\n { kind: \"page\", entities: stateEntities(pages) },\n { kind: \"feature\", entities: stateEntities(features) },\n { kind: \"widget\", entities: stateEntities(widgets) },\n ])\n )\n t.push(\"// ---- authoring-surface shape types ----\")\n t.push(\"export namespace Uidex {\")\n t.push(\n ' export type CoreStateKind = \"loading\" | \"empty\" | \"populated\" | \"error\"'\n )\n t.push(' export type StateKind = CoreStateKind | \"variant\"')\n t.push(\" export interface State {\")\n t.push(\" name: string\")\n t.push(\" kind?: StateKind\")\n t.push(\" acceptance?: readonly string[]\")\n t.push(\" description?: string\")\n t.push(\" }\")\n // `Impossible` REQUIRES a reason and `Backlog` does not, so `tsc` refuses an\n // unexplained permanent opt-out at the literal site — the type-level half of\n // the rule that keeps capturable debt from being relabelled \"impossible\".\n t.push(' export type AcknowledgeScope = CoreStateKind | \"*\"')\n t.push(\" export interface Impossible {\")\n t.push(' type: \"impossible\"')\n t.push(\" reason: string\")\n t.push(\" }\")\n t.push(\" export interface Backlog {\")\n t.push(' type: \"backlog\"')\n t.push(\" reason?: string\")\n t.push(\" }\")\n t.push(\" export type Acknowledgment = Impossible | Backlog\")\n t.push(\n \" export type Acknowledge = Partial<Record<AcknowledgeScope, Acknowledgment>>\"\n )\n // A component has no route, so only the `\"*\"` scope is meaningful on one.\n t.push(' export type ComponentAcknowledge = { \"*\"?: Acknowledgment }')\n t.push(\" export interface Page {\")\n t.push(\" page: PageId | false\")\n t.push(\" name?: string\")\n t.push(\" features?: readonly FeatureId[]\")\n t.push(\" widgets?: readonly WidgetId[]\")\n t.push(\" acceptance?: readonly string[]\")\n t.push(\" states?: readonly (string | State)[]\")\n t.push(\" acknowledge?: Acknowledge\")\n t.push(\" description?: string\")\n t.push(\" }\")\n t.push(\" export interface Feature {\")\n t.push(\" feature: FeatureId | false\")\n t.push(\" name?: string\")\n t.push(\" features?: readonly FeatureId[]\")\n t.push(\" acceptance?: readonly string[]\")\n t.push(\" states?: readonly (string | State)[]\")\n t.push(\" acknowledge?: ComponentAcknowledge\")\n t.push(\" description?: string\")\n t.push(\" }\")\n t.push(\" export interface Primitive {\")\n t.push(\" primitive: PrimitiveId\")\n t.push(\" name?: string\")\n t.push(\" description?: string\")\n t.push(\" }\")\n t.push(\" export interface Widget {\")\n t.push(\" widget: WidgetId\")\n t.push(\" name?: string\")\n t.push(\" acceptance?: readonly string[]\")\n t.push(\" states?: readonly (string | State)[]\")\n t.push(\" acknowledge?: ComponentAcknowledge\")\n t.push(\" description?: string\")\n t.push(\" }\")\n t.push(\" export interface Region {\")\n t.push(\" region: RegionId | false\")\n t.push(\" name?: string\")\n t.push(\" description?: string\")\n t.push(\" }\")\n t.push(\" export interface Flow {\")\n t.push(\" flow: FlowId\")\n t.push(\" name?: string\")\n t.push(\" description?: string\")\n t.push(\" }\")\n t.push(\" export interface NotFlow {\")\n t.push(\" notFlow: true\")\n t.push(\" }\")\n t.push(\"}\")\n t.push(\"\")\n\n const allEntities: Entity[] = [\n ...routes,\n ...pages,\n ...features,\n ...widgets,\n ...regions,\n ...elements,\n ...primitives,\n ...flows,\n ]\n const authored = allEntities.filter((e) => AUTHORED_KINDS.has(e.kind))\n const thin = allEntities.filter((e) => !AUTHORED_KINDS.has(e.kind))\n const gc: GitContext = gitContext ?? { branch: null, commit: null, pr: null }\n\n // ---------------------------------------------------------------------------\n // Data module — the AUTHORED registry (metadata-bearing kinds). Eagerly loaded\n // by the devtools on mount. `@ts-nocheck` (machine-generated data).\n // ---------------------------------------------------------------------------\n const authoredPayload = internedPayload(authored)\n const d: string[] = []\n d.push(\"// THIS FILE IS AUTO-GENERATED BY `uidex scan`. DO NOT EDIT.\")\n d.push(\n \"// Authored-metadata registry. The thin element/region entities (source\"\n )\n d.push(\n \"// locations only) live in the sibling `.locs` module, loaded lazily.\"\n )\n d.push(\"// @ts-nocheck\")\n d.push(\"/* eslint-disable */\")\n d.push(`import { createUidex } from ${JSON.stringify(uidexImport)}`)\n d.push(`import type { Registry } from ${JSON.stringify(uidexImport)}`)\n d.push(\"\")\n d.push(authoredPayload.filesDecl)\n d.push(HYDRATE_FN)\n d.push(`export const entities = ${authoredPayload.parseExpr}`)\n d.push(\"\")\n d.push(`export const gitContext = ${jsonStable(gc)} as const`)\n d.push(\"\")\n d.push(\"export function loadRegistry(target: Registry): Registry {\")\n d.push(\" for (const entity of entities) target.add(entity)\")\n d.push(\" return target\")\n d.push(\"}\")\n d.push(\"\")\n d.push(\"export const uidex = createUidex()\")\n d.push(\"for (const entity of entities) uidex.registry.add(entity)\")\n d.push(\"\")\n\n // ---------------------------------------------------------------------------\n // Locs module — the thin `{ id, loc }` element/region entities, split out so\n // the devtools loads them lazily (after mount / on first inspect). Keeping them\n // out of the main data module keeps ~90% of the entity count out of the initial\n // devtools chunk. Emitted as positional tuples (see emitLocsModule). `@ts-nocheck`.\n // ---------------------------------------------------------------------------\n const locs = emitLocsModule(thin, uidexImport)\n\n return { types: t.join(\"\\n\"), data: d.join(\"\\n\"), locs }\n}\n","import { execSync } from \"node:child_process\"\nimport type { GitContext } from \"./types\"\n\nexport interface GitResolveOptions {\n cwd?: string\n env?: NodeJS.ProcessEnv\n}\n\nfunction runGit(args: string[], cwd: string): string | null {\n try {\n const out = execSync(`git ${args.join(\" \")}`, {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n encoding: \"utf8\",\n })\n return out.trim() || null\n } catch {\n return null\n }\n}\n\nexport function resolveGitContext(opts: GitResolveOptions = {}): GitContext {\n const cwd = opts.cwd ?? process.cwd()\n const env = opts.env ?? process.env\n\n const branch =\n env.GITHUB_HEAD_REF ||\n env.GITHUB_REF_NAME ||\n env.BUILDKITE_BRANCH ||\n env.CI_COMMIT_REF_NAME ||\n env.BITBUCKET_BRANCH ||\n runGit([\"rev-parse\", \"--abbrev-ref\", \"HEAD\"], cwd) ||\n null\n\n const commit =\n env.GITHUB_SHA ||\n env.BUILDKITE_COMMIT ||\n env.CI_COMMIT_SHA ||\n env.BITBUCKET_COMMIT ||\n runGit([\"rev-parse\", \"HEAD\"], cwd) ||\n null\n\n const pr =\n env.PR_NUMBER ||\n env.GITHUB_PR_NUMBER ||\n parseGitHubRef(env.GITHUB_REF) ||\n env.BUILDKITE_PULL_REQUEST ||\n env.CI_MERGE_REQUEST_IID ||\n env.BITBUCKET_PR_ID ||\n null\n\n return {\n branch: branch || null,\n commit: commit || null,\n pr: pr && pr !== \"false\" ? String(pr) : null,\n }\n}\n\nfunction parseGitHubRef(ref: string | undefined): string | null {\n if (!ref) return null\n const m = ref.match(/^refs\\/pull\\/(\\d+)\\/merge$/)\n return m ? m[1] : null\n}\n","import * as fs from \"node:fs\"\nimport * as path from \"node:path\"\nimport type { Registry } from \"../../shared/entities\"\n\nexport type ScaffoldKind = \"widget\" | \"page\" | \"feature\"\n\nexport interface ScaffoldSpecOptions {\n registry: Registry\n kind: ScaffoldKind\n id: string\n outDir: string\n force?: boolean\n fixtureImport?: string\n}\n\nexport interface ScaffoldOptions {\n registry: Registry\n widgetId: string\n outDir: string\n force?: boolean\n fixtureImport?: string\n}\n\nexport interface ScaffoldResult {\n outputPath: string\n written: boolean\n skipped: boolean\n reason?: string\n}\n\nexport function scaffoldWidgetSpec(opts: ScaffoldOptions): ScaffoldResult {\n return scaffoldSpec({\n registry: opts.registry,\n kind: \"widget\",\n id: opts.widgetId,\n outDir: opts.outDir,\n force: opts.force,\n fixtureImport: opts.fixtureImport,\n })\n}\n\n/**\n * Emits a tagged Playwright stub from an entity's declared acceptance\n * criteria — one `test()` per criterion. Widgets keep the historical\n * `widget-<id>.spec.ts` name; pages and features emit `flow-<id>.spec.ts`\n * per the one-tagged-describe-per-flow-spec convention.\n */\nexport function scaffoldSpec(opts: ScaffoldSpecOptions): ScaffoldResult {\n const {\n registry,\n kind,\n id,\n outDir,\n force = false,\n fixtureImport = \"./fixtures\",\n } = opts\n const entity = registry.get(kind, id)\n if (!entity) {\n throw new Error(`${capitalize(kind)} \"${id}\" not found in registry`)\n }\n\n const criteria = entity.meta?.acceptance ?? []\n const filename =\n kind === \"widget\" ? `widget-${id}.spec.ts` : `flow-${id}.spec.ts`\n const outputPath = path.resolve(outDir, filename)\n\n if (fs.existsSync(outputPath) && !force) {\n return {\n outputPath,\n written: false,\n skipped: true,\n reason: `spec already exists at ${outputPath}; pass --force to overwrite`,\n }\n }\n\n const content = renderSpec({ id, criteria, fixtureImport })\n\n fs.mkdirSync(path.dirname(outputPath), { recursive: true })\n fs.writeFileSync(outputPath, content, \"utf8\")\n\n return { outputPath, written: true, skipped: false }\n}\n\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1)\n}\n\nfunction renderSpec(args: {\n id: string\n criteria: readonly string[]\n fixtureImport: string\n}): string {\n const lines: string[] = []\n // No `expect` import: a scaffolded stub asserts nothing, so importing it only invites\n // `expect(true).toBe(true)`. The implementer adds the import along with the first real\n // assertion.\n lines.push(`import { test } from ${JSON.stringify(args.fixtureImport)}`)\n lines.push(\"\")\n lines.push(\n `test.describe(${JSON.stringify(args.id)}, { tag: \"@uidex:flow\" }, () => {`\n )\n // `test.fixme`, never a passing stub.\n //\n // A scaffold emitting `expect(true).toBe(true)` produces a suite that is GREEN while proving\n // nothing — and because acceptance coverage is all-or-nothing per entity, one such stub marks\n // EVERY criterion on that entity as covered. Scaffolding would then be a one-command way to\n // manufacture the appearance of coverage, which is worse than having no criteria at all.\n //\n // `fixme` reports as skipped-and-expected-to-fail: visible in the run, never counted as a\n // pass, and removing the marker is the deliberate act that says \"I implemented this\".\n const stub = (title: string, body: string[]): void => {\n lines.push(` test.fixme(${JSON.stringify(title)}, async ({ uidex }) => {`)\n for (const l of body) lines.push(` ${l}`)\n lines.push(` void uidex`)\n lines.push(` })`)\n lines.push(\"\")\n }\n if (args.criteria.length === 0) {\n stub(\"TODO: add acceptance criteria\", [\n \"// Declare `acceptance: [...]` on the entity, then re-run scaffold.\",\n ])\n } else {\n for (const criterion of args.criteria) {\n stub(criterion, [\n \"// TODO: drive this criterion, then remove `.fixme` to arm the test.\",\n ])\n }\n }\n lines.push(\"})\")\n lines.push(\"\")\n return lines.join(\"\\n\")\n}\n","import * as fs from \"node:fs\"\nimport * as path from \"node:path\"\nimport type { Registry } from \"../../shared/entities\"\nimport { audit } from \"./audit\"\nimport { discover } from \"./discover\"\nimport { emit, dataOutputPath, locsOutputPath } from \"./emit\"\nimport { extract } from \"./extract\"\nimport { resolveGitContext } from \"./git\"\nimport { resolve } from \"./resolve\"\nimport { parseCoverageBaseline, type CoverageBaseline } from \"./acknowledge\"\nimport { migrateLegacyBaseline } from \"./migrate-acknowledge\"\nimport { resolveWorkspace, type Workspace } from \"./workspace\"\nimport type { CapturedState, CapturedStatesManifest } from \"./state-coverage\"\nimport type {\n AuditSummary,\n Diagnostic,\n DiscoveredConfig,\n GitContext,\n UidexConfig,\n} from \"./types\"\nimport { walk } from \"./walk\"\n\nexport interface RunScanOptions {\n cwd?: string\n check?: boolean\n lint?: boolean\n configs?: DiscoveredConfig[]\n /** Captured-states manifest for the completeness gate; overrides on-disk load. */\n capturedStates?: CapturedStatesManifest\n /** Coverage baseline (the shrink-only backlog); overrides on-disk load. */\n coverageBaseline?: CoverageBaseline\n /** Workspace override; skips auto-detection (used by tests). */\n workspace?: Workspace\n}\n\nconst DEFAULT_STATES_MANIFEST = \"uidex-states.json\"\nconst DEFAULT_COVERAGE_BASELINE = \"uidex-coverage-baseline.json\"\n\nexport interface LoadedBaseline {\n baseline?: CoverageBaseline\n /** Present when the file on disk is the pre-`acknowledge` shape. */\n legacy?: Diagnostic\n}\n\n/**\n * Load the coverage baseline from disk. A file in the REMOVED shape does not\n * silently read as \"no baseline\" — that would turn every acknowledged-backlog\n * route into a hard error — it comes back as a migration diagnostic with a fix.\n */\nexport function loadCoverageBaseline(\n configDir: string,\n config: UidexConfig\n): LoadedBaseline {\n const rel = config.coverageBaseline ?? DEFAULT_COVERAGE_BASELINE\n const abs = path.resolve(configDir, rel)\n let raw: string\n try {\n raw = fs.readFileSync(abs, \"utf8\")\n } catch {\n return {}\n }\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch {\n return {}\n }\n const legacy = migrateLegacyBaseline({\n path: abs,\n raw,\n parsed,\n displayPath: rel,\n })\n if (legacy) return { legacy }\n return { baseline: parseCoverageBaseline(parsed) ?? undefined }\n}\n\n/** Load the captured-states manifest from disk, if present + well-formed. */\nfunction loadCapturedStates(\n configDir: string,\n config: UidexConfig\n): CapturedStatesManifest | undefined {\n const rel = config.statesManifest ?? DEFAULT_STATES_MANIFEST\n const abs = path.resolve(configDir, rel)\n let raw: string\n try {\n raw = fs.readFileSync(abs, \"utf8\")\n } catch {\n return undefined\n }\n try {\n const parsed = JSON.parse(raw) as Partial<CapturedStatesManifest>\n if (!parsed || !Array.isArray(parsed.captured)) return undefined\n // Sanitize each entry: a malformed one (null, missing/non-string fields)\n // would otherwise crash the gates that read `.entity` / `.url`.\n const captured: CapturedState[] = []\n for (const entry of parsed.captured as unknown[]) {\n if (!entry || typeof entry !== \"object\") continue\n const c = entry as Record<string, unknown>\n if (typeof c.entity !== \"string\" || typeof c.state !== \"string\") continue\n const rec: CapturedState = { entity: c.entity, state: c.state }\n if (typeof c.kind === \"string\") rec.kind = c.kind as CapturedState[\"kind\"]\n if (typeof c.stateKind === \"string\") rec.stateKind = c.stateKind\n if (typeof c.url === \"string\") rec.url = c.url\n if (typeof c.route === \"string\") rec.route = c.route\n captured.push(rec)\n }\n return typeof parsed.generatedAt === \"string\"\n ? { captured, generatedAt: parsed.generatedAt }\n : { captured }\n } catch {\n return undefined\n }\n}\n\n/** One generated artifact: its bytes plus where it lands (abs + repo-relative). */\nexport interface ScanArtifact {\n generated: string\n /** Absolute path on disk. */\n outputPath: string\n /** Path relative to the config dir, for diagnostics. */\n outputRel: string\n}\n\nexport interface ScanResult {\n config: UidexConfig\n configDir: string\n registry: Registry\n gitContext: GitContext\n audit?: AuditSummary\n /** Pure-types artifact (`config.output`, e.g. `uidex.gen.ts`). */\n types: ScanArtifact\n /** Authored-registry artifact (the sibling `.data` module). */\n data: ScanArtifact\n /** Deferred element/region source-location artifact (the sibling `.locs` module). */\n locs: ScanArtifact\n /** The captured-states manifest in effect this run, if any (for --update-baseline). */\n capturedStates?: CapturedStatesManifest\n}\n\nexport function runScan(opts: RunScanOptions = {}): ScanResult[] {\n const cwd = opts.cwd ?? process.cwd()\n const configs = opts.configs ?? discover({ cwd })\n if (configs.length === 0) {\n throw new Error(`No .uidex.json found starting from ${cwd}`)\n }\n\n return configs.map((dc) => runOne(dc, opts))\n}\n\nfunction runOne(dc: DiscoveredConfig, opts: RunScanOptions): ScanResult {\n const { config, configDir } = dc\n\n const sourceFiles = walk(config.sources, {\n cwd: configDir,\n globalExcludes: config.exclude,\n })\n\n const extracted = extract(sourceFiles)\n\n const flowFiles = config.flows\n ? walk(\n config.flows.map((glob) => ({ rootDir: \".\", include: [glob] })),\n { cwd: configDir, includeTests: true }\n )\n : []\n const extractedFlows = extract(flowFiles)\n\n const resolved = resolve({\n config,\n extracted,\n flowFiles: extractedFlows,\n })\n\n const gitContext = resolveGitContext({ cwd: configDir })\n\n const emitted = emit({\n registry: resolved.registry,\n gitContext,\n })\n\n const typesRel = config.output\n const typesPath = path.resolve(configDir, typesRel)\n const dataRel = dataOutputPath(config.output)\n const dataPath = path.resolve(configDir, dataRel)\n const locsRel = locsOutputPath(config.output)\n const locsPath = path.resolve(configDir, locsRel)\n\n let typesOnDisk: string | null = null\n let dataOnDisk: string | null = null\n let locsOnDisk: string | null = null\n if (opts.check) {\n typesOnDisk = readOrNull(typesPath)\n dataOnDisk = readOrNull(dataPath)\n locsOnDisk = readOrNull(locsPath)\n }\n\n const hasExtractDiagnostics = [...extracted, ...extractedFlows].some(\n (ef) => (ef.diagnostics?.length ?? 0) > 0\n )\n const capturedStates =\n opts.capturedStates ?? loadCapturedStates(configDir, config)\n const loadedBaseline = opts.coverageBaseline\n ? { baseline: opts.coverageBaseline }\n : loadCoverageBaseline(configDir, config)\n const coverageBaseline = loadedBaseline.baseline\n const workspace = opts.workspace ?? resolveWorkspace({ configDir, config })\n\n let auditResult: AuditSummary | undefined\n if (\n opts.check ||\n opts.lint ||\n resolved.diagnostics.length > 0 ||\n hasExtractDiagnostics ||\n loadedBaseline.legacy\n ) {\n auditResult = audit({\n registry: resolved.registry,\n extracted,\n files: sourceFiles,\n flowExtracted: extractedFlows,\n config,\n check: opts.check,\n lint: opts.lint,\n resolveDiagnostics: resolved.diagnostics,\n // The entity array (and thus the meaningful drift) lives in the data file,\n // so the entity-aware gen-stale diff runs against it; the types file gets a\n // plain content compare (see audit()).\n generated: emitted.data,\n existingOnDisk: dataOnDisk,\n outputPath: dataRel,\n typesGenerated: emitted.types,\n typesOnDisk,\n typesOutputPath: typesRel,\n locsGenerated: emitted.locs,\n locsOnDisk,\n locsOutputPath: locsRel,\n capturedStates,\n coverageBaseline,\n baselineDiagnostic: loadedBaseline.legacy,\n workspace,\n })\n }\n\n return {\n config,\n configDir,\n registry: resolved.registry,\n gitContext,\n audit: auditResult,\n types: {\n generated: emitted.types,\n outputPath: typesPath,\n outputRel: typesRel,\n },\n data: { generated: emitted.data, outputPath: dataPath, outputRel: dataRel },\n locs: { generated: emitted.locs, outputPath: locsPath, outputRel: locsRel },\n capturedStates,\n }\n}\n\n/** Read a file's contents, or `null` if it does not exist. */\nfunction readOrNull(p: string): string | null {\n try {\n return fs.readFileSync(p, \"utf8\")\n } catch {\n return null\n }\n}\n\n/**\n * Write one artifact, but ONLY when its contents actually changed.\n *\n * A `uidex scan` runs on every edit (pre-commit + editor/agent hooks), yet most\n * edits touch no `data-uidex*` annotation, so the freshly-emitted file is\n * byte-identical to what is already on disk. An unconditional `writeFileSync`\n * still bumps the file's mtime, which a dev-server file watcher (Next/Turbopack,\n * Vite) treats as a change — forcing an HMR recompile of the (large, generated)\n * module for no reason. Comparing first makes a no-op scan a genuine no-op.\n *\n * Returns `true` if the file was written, `false` if it was already up to date.\n */\nexport function writeArtifact(artifact: ScanArtifact): boolean {\n if (readOrNull(artifact.outputPath) === artifact.generated) return false\n fs.mkdirSync(path.dirname(artifact.outputPath), { recursive: true })\n fs.writeFileSync(artifact.outputPath, artifact.generated, \"utf8\")\n return true\n}\n\n/**\n * Write all three generated artifacts (types + data + locs), each only if\n * changed. Splitting them means a change confined to one (e.g. adding an element\n * only touches `.locs`) never rewrites the others, so watchers recompile only what\n * actually moved. Returns `true` if any file was written.\n */\nexport function writeScanResult(result: ScanResult): boolean {\n const wroteTypes = writeArtifact(result.types)\n const wroteData = writeArtifact(result.data)\n const wroteLocs = writeArtifact(result.locs)\n return wroteTypes || wroteData || wroteLocs\n}\n\n/** Absolute path of the coverage baseline for a scan result. */\nexport function coverageBaselinePath(result: ScanResult): string {\n const rel = result.config.coverageBaseline ?? DEFAULT_COVERAGE_BASELINE\n return path.resolve(result.configDir, rel)\n}\n","import type { CapturedState, CapturedStatesManifest } from \"./state-coverage\"\n\n/**\n * Fold a PARTIAL capture manifest into the committed one.\n *\n * A filtered run (`--grep`) legitimately captures a subset, so the reporter's\n * shrink guard diverts it to `<name>.partial.json` rather than overwriting a\n * fuller manifest. Without a merge path the only ways forward are re-running the\n * FULL suite or hand-editing JSON — both of which make scoped re-capture\n * expensive enough that people skip it and let the manifest drift.\n *\n * Merge is by `(kind, entity, state)`: rows in the partial REPLACE their\n * counterparts (that run is the newer evidence) and rows absent from it are\n * preserved (it never claimed to cover them). So merging is purely additive to\n * coverage — it can never drop a state, which is what makes it safe to run\n * without re-reading the whole manifest.\n */\n\nexport interface MergeResult {\n manifest: CapturedStatesManifest\n /** `(kind, entity, state)` keys the partial replaced. */\n updated: string[]\n /** Keys the partial contributed that the committed manifest lacked. */\n added: string[]\n}\n\nfunction keyOf(c: CapturedState): string {\n return `${c.kind ?? \"page\"} ${c.entity} ${c.state}`\n}\n\nexport function mergeStates(\n committed: CapturedStatesManifest,\n partial: CapturedStatesManifest\n): MergeResult {\n const byKey = new Map<string, CapturedState>()\n for (const c of committed.captured ?? []) byKey.set(keyOf(c), c)\n\n const updated: string[] = []\n const added: string[] = []\n for (const c of partial.captured ?? []) {\n const k = keyOf(c)\n ;(byKey.has(k) ? updated : added).push(k)\n byKey.set(k, c)\n }\n\n const captured = [...byKey.values()].sort(\n (a, b) => a.entity.localeCompare(b.entity) || a.state.localeCompare(b.state)\n )\n\n return {\n manifest: {\n ...committed,\n captured,\n // The merged file is only as fresh as its OLDEST evidence: rows carried\n // over from the committed manifest were not re-verified by this run, so\n // claiming the partial's newer stamp would defeat the staleness check.\n ...(committed.generatedAt ? { generatedAt: committed.generatedAt } : {}),\n },\n updated: updated.sort(),\n added: added.sort(),\n }\n}\n","import * as fs from \"node:fs\"\nimport * as path from \"node:path\"\nimport type { Diagnostic, FixEdit } from \"./types\"\n\n/**\n * Applies the machine-generated fixes attached to diagnostics.\n *\n * Edits are offset-based against the content the scanner read, so this must\n * run before anything else touches the files. Within a file, edits apply\n * last-to-first; an edit overlapping one already applied is skipped. Identical\n * edits are deduped — two fixes in one file emitting the same edit collapse to\n * one application.\n */\n\nexport interface AppliedFix {\n code: string\n description: string\n file?: string\n}\n\nexport interface ApplyFixesResult {\n applied: AppliedFix[]\n /** fixes skipped because of overlapping edits or existing target files */\n skipped: Array<AppliedFix & { reason: string }>\n}\n\ninterface FixEntry {\n code: string\n description: string\n file?: string\n edits: FixEdit[]\n createFiles: Array<{ path: string; content: string }>\n deleteFiles: string[]\n skippedReason?: string\n}\n\nexport function applyFixes(diagnostics: Diagnostic[]): ApplyFixesResult {\n const entries: FixEntry[] = []\n for (const d of diagnostics) {\n if (!d.fix) continue\n entries.push({\n code: d.code,\n description: d.fix.description,\n file: d.file,\n edits: d.fix.edits ?? [],\n createFiles: d.fix.createFiles ?? [],\n deleteFiles: d.fix.deleteFiles ?? [],\n })\n }\n if (entries.length === 0) return { applied: [], skipped: [] }\n\n // Collect edits per file, deduping identical ones across fixes.\n const seenEdits = new Set<string>()\n const editsByFile = new Map<string, Array<FixEdit & { entry: FixEntry }>>()\n for (const entry of entries) {\n for (const edit of entry.edits) {\n const key = `${edit.path}:${edit.start}:${edit.end}:${edit.replacement}`\n if (seenEdits.has(key)) continue\n seenEdits.add(key)\n let list = editsByFile.get(edit.path)\n if (!list) {\n list = []\n editsByFile.set(edit.path, list)\n }\n list.push({ ...edit, entry })\n }\n }\n\n for (const [filePath, edits] of editsByFile) {\n let content: string\n try {\n content = fs.readFileSync(filePath, \"utf8\")\n } catch {\n for (const e of edits) e.entry.skippedReason ??= \"file is unreadable\"\n continue\n }\n // Resolve overlaps first-in-file-wins, then apply last-to-first so\n // earlier offsets stay valid.\n edits.sort((a, b) => a.start - b.start || a.end - b.end)\n const kept: typeof edits = []\n let prevEnd = -1\n for (const edit of edits) {\n if (edit.start < prevEnd) {\n edit.entry.skippedReason ??= \"overlapping edit\"\n continue\n }\n kept.push(edit)\n prevEnd = edit.end\n }\n for (let i = kept.length - 1; i >= 0; i--) {\n const edit = kept[i]\n content =\n content.slice(0, edit.start) +\n edit.replacement +\n content.slice(edit.end)\n }\n if (kept.length > 0) fs.writeFileSync(filePath, content, \"utf8\")\n }\n\n for (const entry of entries) {\n if (entry.skippedReason) continue\n for (const create of entry.createFiles) {\n if (fs.existsSync(create.path)) {\n entry.skippedReason = `${path.basename(create.path)} already exists`\n continue\n }\n fs.mkdirSync(path.dirname(create.path), { recursive: true })\n fs.writeFileSync(create.path, create.content, \"utf8\")\n }\n if (entry.skippedReason) continue\n for (const del of entry.deleteFiles) {\n try {\n fs.unlinkSync(del)\n } catch {\n // already gone — the goal state is reached\n }\n }\n }\n\n const applied: AppliedFix[] = []\n const skipped: Array<AppliedFix & { reason: string }> = []\n for (const entry of entries) {\n const summary: AppliedFix = {\n code: entry.code,\n description: entry.description,\n file: entry.file,\n }\n if (entry.skippedReason) {\n skipped.push({ ...summary, reason: entry.skippedReason })\n } else {\n applied.push(summary)\n }\n }\n return { applied, skipped }\n}\n","import { discover } from \"./discover\"\nimport { extract } from \"./extract\"\nimport { applyFixes } from \"./fix\"\nimport { runScan, writeScanResult } from \"./pipeline\"\nimport { walk } from \"./walk\"\nimport type { FixEdit } from \"./types\"\n\n/**\n * Cross-file id rename. The registry knows every reference surface for an\n * id — the DOM attribute, `uidex(\"…\")` calls in flow specs, the widget\n * export's discriminator, and `widgets:` arrays — so the rename rewrites all\n * of them in one pass and regenerates the gen file. Occurrences the scanner\n * can't edit mechanically (const indirection, ternaries, patterns) are\n * reported for manual follow-up instead of being guessed at.\n */\n\nexport type RenameKind = \"element\" | \"widget\" | \"region\"\n\nexport interface RenameOptions {\n cwd: string\n kind: RenameKind\n oldId: string\n newId: string\n /** allow renaming onto an id that already exists */\n force?: boolean\n}\n\nexport interface RenameResult {\n /** number of source edits applied */\n edits: number\n /** occurrences that need a human (no static literal to rewrite) */\n manual: Array<{ file: string; line: number; reason: string }>\n errors: string[]\n}\n\nconst ID_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/\n\nexport function renameEntity(opts: RenameOptions): RenameResult {\n const { cwd, kind, oldId, newId, force = false } = opts\n const manual: RenameResult[\"manual\"] = []\n const errors: string[] = []\n\n if (!ID_RE.test(newId)) {\n return {\n edits: 0,\n manual,\n errors: [`New id \"${newId}\" is not kebab-case`],\n }\n }\n\n const configs = discover({ cwd })\n if (configs.length === 0) {\n return { edits: 0, manual, errors: [`No .uidex.json found under ${cwd}`] }\n }\n\n const edits: FixEdit[] = []\n\n for (const dc of configs) {\n const { config, configDir } = dc\n const sourceFiles = walk(config.sources, {\n cwd: configDir,\n globalExcludes: config.exclude,\n })\n const extracted = extract(sourceFiles)\n const flowFiles = config.flows\n ? walk(\n config.flows.map((glob) => ({ rootDir: \".\", include: [glob] })),\n { cwd: configDir, includeTests: true }\n )\n : []\n const extractedFlows = extract(flowFiles)\n\n // Existence / collision checks against the live registry.\n const scan = runScan({ cwd: configDir, configs: [dc] })[0]\n const registry = scan.registry\n if (!registry.get(kind, oldId)) {\n if (registry.matchPattern(kind, oldId)) {\n errors.push(\n `${kind} \"${oldId}\" only matches via a pattern id; pattern-backed ids cannot be renamed mechanically`\n )\n } else {\n errors.push(`${kind} \"${oldId}\" not found in registry`)\n }\n continue\n }\n if (registry.get(kind, newId) && !force) {\n errors.push(\n `${kind} \"${newId}\" already exists; pass --force to merge the ids`\n )\n continue\n }\n\n const quoteAs = (content: string, start: number): string => {\n const q = content[start]\n return q === '\"' || q === \"'\" || q === \"`\"\n ? `${q}${newId}${q}`\n : `\"${newId}\"`\n }\n\n // 1. DOM attribute occurrences.\n for (const ef of extracted) {\n for (const a of ef.annotations) {\n if (a.kind !== kind || a.id !== oldId) continue\n if (a.span) {\n edits.push({\n path: ef.file.sourcePath,\n start: a.span.start,\n end: a.span.end,\n replacement: quoteAs(ef.file.content, a.span.start),\n })\n } else {\n manual.push({\n file: a.file,\n line: a.line,\n reason:\n \"attribute value is not a plain string literal (const reference, ternary, or template)\",\n })\n }\n }\n\n // 2. Metadata exports: the widget discriminator and widgets: arrays.\n for (const m of ef.metadata ?? []) {\n if (kind === \"widget\" && m.kind === \"widget\" && m.id === oldId) {\n if (m.idSpan) {\n edits.push({\n path: ef.file.sourcePath,\n start: m.idSpan.start,\n end: m.idSpan.end,\n replacement: quoteAs(ef.file.content, m.idSpan.start),\n })\n } else {\n manual.push({\n file: ef.file.displayPath,\n line: m.loc.line ?? 1,\n reason: \"widget export id is not a plain string literal\",\n })\n }\n }\n if (kind === \"widget\" && m.widgets) {\n for (let i = 0; i < m.widgets.length; i++) {\n if (m.widgets[i] !== oldId) continue\n const span = m.widgetSpans?.[i]\n if (span) {\n edits.push({\n path: ef.file.sourcePath,\n start: span.start,\n end: span.end,\n replacement: quoteAs(ef.file.content, span.start),\n })\n }\n }\n }\n }\n }\n\n // 3. uidex(\"…\") calls in flow specs.\n for (const ef of extractedFlows) {\n for (const fact of ef.flows ?? []) {\n for (const call of fact.calls) {\n if (call.id !== oldId) continue\n if (call.span) {\n edits.push({\n path: ef.file.sourcePath,\n start: call.span.start,\n end: call.span.end,\n replacement: quoteAs(ef.file.content, call.span.start),\n })\n } else {\n manual.push({\n file: ef.file.displayPath,\n line: call.line,\n reason: \"uidex() argument is not a plain string literal\",\n })\n }\n }\n }\n }\n }\n\n if (errors.length > 0) {\n return { edits: 0, manual, errors }\n }\n if (edits.length === 0 && manual.length === 0) {\n return {\n edits: 0,\n manual,\n errors: [\n `${kind} \"${oldId}\" has no editable occurrences (convention-derived ids like landmarks cannot be renamed)`,\n ],\n }\n }\n\n const result = applyFixes([\n {\n code: \"rename\",\n severity: \"info\",\n message: \"\",\n fix: {\n description: `Rename ${kind} \"${oldId}\" to \"${newId}\"`,\n edits,\n },\n },\n ])\n if (result.skipped.length > 0) {\n errors.push(`Some edits were skipped: ${result.skipped[0].reason}`)\n }\n\n // Regenerate the gen file on the renamed tree.\n for (const r of runScan({ cwd })) writeScanResult(r)\n\n return { edits: edits.length, manual, errors }\n}\n","import * as fs from \"node:fs\"\nimport * as path from \"node:path\"\nimport { runAiCommand } from \"./ai\"\nimport { discover, CONFIG_FILENAME } from \"./discover\"\nimport { applyFixes } from \"./fix\"\nimport type { AppliedFix } from \"./fix\"\nimport { runScan, writeArtifact, coverageBaselinePath } from \"./pipeline\"\nimport type { ScanArtifact } from \"./pipeline\"\nimport {\n serializeCoverageBaseline,\n type AcknowledgeMap,\n type CoverageBaseline,\n} from \"./acknowledge\"\nimport { computePageBacklog } from \"./page-coverage\"\nimport { computeMatrixBacklog } from \"./state-matrix\"\nimport { renameEntity } from \"./rename\"\nimport type { RenameKind } from \"./rename\"\nimport { scaffoldSpec } from \"./scaffold\"\nimport { mergeStates } from \"./states-merge\"\nimport type { CapturedStatesManifest } from \"./state-coverage\"\nimport type { ScaffoldKind } from \"./scaffold\"\nimport type { Diagnostic, UidexConfig } from \"./types\"\n\nexport interface CliResult {\n exitCode: number\n stdout: string\n stderr: string\n}\n\nexport interface CliOptions {\n argv: string[]\n cwd?: string\n}\n\nimport { parseArgs } from \"../cli/parse-args\"\n\ntype Flags = Record<string, string | boolean>\n\nexport async function run(opts: CliOptions): Promise<CliResult> {\n const cwd = opts.cwd ?? process.cwd()\n const { positional, flags } = parseArgs(opts.argv)\n const command = positional[0] ?? \"help\"\n\n const writer = createWriter()\n\n try {\n switch (command) {\n case \"help\":\n case \"--help\":\n case \"-h\":\n writer.out(helpText())\n return writer.result(0)\n\n case \"init\":\n return runInit(cwd, writer)\n\n case \"scan\":\n return runScanCommand(cwd, flags, writer)\n\n case \"scaffold\":\n return runScaffold(cwd, positional.slice(1), flags, writer)\n\n case \"rename\":\n return runRename(cwd, positional.slice(1), flags, writer)\n\n case \"states\":\n return runStates(cwd, positional.slice(1), writer)\n\n case \"ai\": {\n const result = await runAiCommand({\n cwd,\n argv: opts.argv.slice(1),\n })\n if (result.stdout) writer.out(result.stdout.replace(/\\n$/, \"\"))\n if (result.stderr) writer.err(result.stderr.replace(/\\n$/, \"\"))\n return writer.result(result.exitCode)\n }\n\n default:\n writer.err(`Unknown command: ${command}`)\n writer.err(helpText())\n return writer.result(1)\n }\n } catch (e) {\n writer.err(e instanceof Error ? e.message : String(e))\n return writer.result(1)\n }\n}\n\nfunction helpText(): string {\n return [\n \"uidex — scanner CLI\",\n \"\",\n \"Commands:\",\n \" init Create a .uidex.json\",\n \" scan [flags] Run the scanner pipeline\",\n \" scaffold <widget|page|feature> <id> Emit a Playwright spec from declared acceptance\",\n \" rename <element|widget|region> <old-id> <new-id> Rename an id everywhere (DOM attr, flows, exports)\",\n \" states merge [partial] Fold a filtered run's *.partial.json into the committed manifest\",\n \" ai <install|uninstall|providers> Manage AI assistant integrations\",\n \"\",\n \"Flags:\",\n \" --check Verify the on-disk gen file matches a fresh scan; exit non-zero on drift (read-only)\",\n \" --lint Run lint diagnostics (missing annotations, scope leak, duplicate ids, coverage)\",\n \" --audit Equivalent to --check --lint (read-only)\",\n \" --fix Apply machine-generated fixes (add data-uidex to unannotated interactive elements, drop empty names, migrate waivers/capture to acknowledge), then rescan and write\",\n \" --update-baseline Regenerate the coverage baseline (uidex-coverage-baseline.json) as `acknowledge` backlog entries\",\n \" --json Emit JSON diagnostics on stdout\",\n \" --force (scaffold) overwrite existing spec\",\n \"\",\n ].join(\"\\n\")\n}\n\nfunction runInit(cwd: string, w: ReturnType<typeof createWriter>): CliResult {\n const configPath = path.join(cwd, CONFIG_FILENAME)\n if (fs.existsSync(configPath)) {\n w.err(`.uidex.json already exists at ${configPath}`)\n return w.result(1)\n }\n const config: UidexConfig = {\n $schema: \"https://uidex.dev/schema/v2.json\",\n sources: [{ rootDir: \"src\" }],\n output: \"src/uidex.gen.ts\",\n }\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + \"\\n\", \"utf8\")\n w.out(`Created ${configPath}`)\n\n const gitignorePath = path.join(cwd, \".gitignore\")\n // `*.gen.*` covers both generated artifacts: the types file (`*.gen.ts`) and\n // the runtime data module (`*.gen.data.ts`).\n const entry = \"*.gen.*\"\n if (fs.existsSync(gitignorePath)) {\n const existing = fs.readFileSync(gitignorePath, \"utf8\")\n const hasEntry = existing.split(\"\\n\").some((line) => line.trim() === entry)\n if (!hasEntry) {\n const needsNewline = existing.length > 0 && !existing.endsWith(\"\\n\")\n fs.appendFileSync(\n gitignorePath,\n `${needsNewline ? \"\\n\" : \"\"}${entry}\\n`,\n \"utf8\"\n )\n w.out(`Appended ${entry} to ${gitignorePath}`)\n }\n } else {\n fs.writeFileSync(gitignorePath, `${entry}\\n`, \"utf8\")\n w.out(`Created ${gitignorePath} with ${entry}`)\n }\n return w.result(0)\n}\n\nfunction runScanCommand(\n cwd: string,\n flags: Flags,\n w: ReturnType<typeof createWriter>\n): CliResult {\n const fix = Boolean(flags.fix)\n const updateBaseline = Boolean(flags[\"update-baseline\"])\n // --fix re-scans and writes the gen file after applying fixes, so the\n // read-only --check pass is meaningless alongside it.\n const check = !fix && !updateBaseline && Boolean(flags.check || flags.audit)\n const lint = Boolean(flags.lint || flags.audit || fix || updateBaseline)\n const asJson = Boolean(flags.json)\n\n let configs = discover({ cwd })\n if (configs.length === 0) {\n w.err(`No ${CONFIG_FILENAME} found under ${cwd}`)\n return w.result(1)\n }\n\n let fixed: AppliedFix[] = []\n let fixSkipped: Array<AppliedFix & { reason: string }> = []\n if (fix) {\n // Discovery pass: check+lint so every fixable diagnostic is produced.\n const discovery = runScan({ cwd, check: true, lint: true, configs })\n const result = applyFixes(\n discovery.flatMap((r) => r.audit?.diagnostics ?? [])\n )\n fixed = result.applied\n fixSkipped = result.skipped\n // Fixes may create or delete files; re-discover before the real pass.\n configs = discover({ cwd })\n }\n\n const results = runScan({ cwd, check, lint, configs })\n\n const artifacts = results.flatMap((r) => [r.types, r.data, r.locs])\n const wrote = new Set<ScanArtifact>()\n if (!check) {\n for (const a of artifacts) {\n if (writeArtifact(a)) wrote.add(a)\n }\n }\n\n // --update-baseline: regenerate the shrink-only page-coverage backlog from the\n // current uncaptured set and exit. Growth only ever happens here, so it lands\n // in the file's diff for review; the default gate errors on new uncaptured\n // pages that were not deliberately baselined.\n if (updateBaseline) {\n for (const r of results) {\n const manifest = r.capturedStates ?? { captured: [] }\n // Both axes write the SAME `{ type: \"backlog\" }` shape into one map — the\n // whole point of the unification. Route-scoped (`\"*\"`) and kind-scoped\n // entries for the same route merge rather than living in two blocks.\n const acknowledge: Record<string, AcknowledgeMap> = {}\n const merge = (from: Record<string, AcknowledgeMap>) => {\n for (const [route, scopes] of Object.entries(from)) {\n acknowledge[route] = { ...(acknowledge[route] ?? {}), ...scopes }\n }\n }\n merge(computePageBacklog(r.registry, manifest))\n merge(computeMatrixBacklog(r.registry, manifest))\n const baseline: CoverageBaseline = { version: 2, acknowledge }\n const p = coverageBaselinePath(r)\n fs.writeFileSync(p, serializeCoverageBaseline(baseline))\n const entries = Object.values(acknowledge)\n const pages = entries.filter((s) => s[\"*\"]).length\n const kindGaps = entries.reduce(\n (n, s) => n + Object.keys(s).filter((k) => k !== \"*\").length,\n 0\n )\n w.out(\n `Wrote ${p} — ${pages} uncaptured page(s), ${kindGaps} missing core-kind(s) acknowledged as backlog`\n )\n }\n return w.result(0)\n }\n\n const allDiagnostics = results.flatMap((r) => r.audit?.diagnostics ?? [])\n const summary = results.reduce(\n (acc, r) => {\n acc.errors += r.audit?.summary.errors ?? 0\n acc.warnings += r.audit?.summary.warnings ?? 0\n return acc\n },\n { errors: 0, warnings: 0 }\n )\n\n if (asJson) {\n const out = {\n diagnostics: allDiagnostics.map(jsonDiagnostic),\n summary,\n ...(fix ? { fixed, fixSkipped } : {}),\n }\n w.out(JSON.stringify(out, null, 2))\n } else {\n for (const f of fixed) {\n w.out(`FIXED [${f.code}] ${f.file ?? \"\"} ${f.description}`)\n }\n for (const s of fixSkipped) {\n w.out(\n `SKIPPED [${s.code}] ${s.file ?? \"\"} ${s.description} (${s.reason})`\n )\n }\n for (const r of results) {\n for (const art of [r.types, r.data, r.locs]) {\n if (check) {\n w.out(`Checked ${art.outputPath}`)\n } else if (wrote.has(art)) {\n w.out(`Wrote ${art.outputPath}`)\n } else {\n w.out(`Unchanged ${art.outputPath}`)\n }\n }\n for (const d of r.audit?.diagnostics ?? []) {\n const loc = d.file ? `${d.file}${d.line ? `:${d.line}` : \"\"}` : \"\"\n const stream = d.severity === \"error\" ? w.err : w.out\n const fixable = d.fix && !fix ? \" [fixable: run with --fix]\" : \"\"\n stream(\n `${d.severity.toUpperCase()} [${d.code}] ${loc} ${d.message}${fixable}`\n )\n if (d.hint) stream(` hint: ${d.hint}`)\n }\n }\n if (check || lint) {\n w.out(`${summary.errors} error(s), ${summary.warnings} warning(s)`)\n }\n }\n\n const exit = summary.errors > 0 ? 1 : 0\n return w.result(exit)\n}\n\n/** Diagnostics serialized for --json: `fix` (absolute paths) → `fixable`. */\nfunction jsonDiagnostic(d: Diagnostic): Omit<Diagnostic, \"fix\"> & {\n fixable?: boolean\n} {\n const { fix, ...rest } = d\n return fix ? { ...rest, fixable: true } : rest\n}\n\nconst SCAFFOLD_KINDS = new Set<string>([\"widget\", \"page\", \"feature\"])\n\nfunction runScaffold(\n cwd: string,\n args: string[],\n flags: Flags,\n w: ReturnType<typeof createWriter>\n): CliResult {\n const [kind, id] = args\n if (!kind || !SCAFFOLD_KINDS.has(kind) || !id) {\n w.err(\"Usage: uidex scaffold <widget|page|feature> <id> [--force]\")\n return w.result(1)\n }\n const scaffoldKind = kind as ScaffoldKind\n\n const results = runScan({ cwd })\n for (const r of results) {\n const entity = r.registry.get(scaffoldKind, id)\n if (!entity) continue\n const outDir = path.resolve(r.configDir, \"e2e\")\n const result = scaffoldSpec({\n registry: r.registry,\n kind: scaffoldKind,\n id,\n outDir,\n force: Boolean(flags.force),\n })\n if (result.skipped) {\n w.err(result.reason ?? \"skipped\")\n return w.result(1)\n }\n w.out(`Wrote ${result.outputPath}`)\n return w.result(0)\n }\n\n w.err(\n `${scaffoldKind.charAt(0).toUpperCase() + scaffoldKind.slice(1)} \"${id}\" not found in registry`\n )\n return w.result(1)\n}\n\nconst RENAME_KINDS = new Set<string>([\"element\", \"widget\", \"region\"])\n\n/**\n * `uidex states merge [partial]` — fold a filtered run's partial manifest into\n * the committed one. Runs per discovered config, so a monorepo merges every\n * app's partial in one invocation. Merge is additive by `(kind, entity, state)`,\n * so it can never drop coverage; a partial with nothing new is a no-op.\n */\nfunction runStates(\n cwd: string,\n args: string[],\n w: ReturnType<typeof createWriter>\n): CliResult {\n const [sub, explicitPartial] = args\n if (sub !== \"merge\") {\n w.err(\"Usage: uidex states merge [partial-manifest]\")\n return w.result(1)\n }\n\n const configs = discover({ cwd })\n if (configs.length === 0) {\n w.err(`No ${CONFIG_FILENAME} found under ${cwd}`)\n return w.result(1)\n }\n\n let merged = 0\n for (const { configDir, config } of configs) {\n const rel = config.statesManifest ?? \"uidex-states.json\"\n const target = path.resolve(configDir, rel)\n const partial = explicitPartial\n ? path.resolve(cwd, explicitPartial)\n : target.replace(/\\.json$/i, \"\") + \".partial.json\"\n\n const committedRaw = readJson(target)\n const partialRaw = readJson(partial)\n if (!partialRaw) continue // nothing to fold in for this app\n if (!committedRaw) {\n w.err(`No committed manifest at ${rel}; nothing to merge into`)\n return w.result(1)\n }\n\n const result = mergeStates(committedRaw, partialRaw)\n fs.writeFileSync(target, JSON.stringify(result.manifest, null, 2) + \"\\n\")\n merged++\n w.out(\n `Merged ${path.basename(partial)} → ${rel}: ${result.added.length} added, ${result.updated.length} updated, ${result.manifest.captured.length} total`\n )\n for (const k of result.added) w.out(` + ${k}`)\n for (const k of result.updated) w.out(` ~ ${k}`)\n }\n\n if (merged === 0) {\n w.out(\"No partial manifest found; nothing to merge.\")\n }\n return w.result(0)\n}\n\nfunction readJson(p: string): CapturedStatesManifest | null {\n try {\n const parsed = JSON.parse(fs.readFileSync(p, \"utf8\")) as unknown\n if (!parsed || typeof parsed !== \"object\") return null\n const m = parsed as Partial<CapturedStatesManifest>\n return Array.isArray(m.captured) ? (m as CapturedStatesManifest) : null\n } catch {\n return null\n }\n}\n\nfunction runRename(\n cwd: string,\n args: string[],\n flags: Flags,\n w: ReturnType<typeof createWriter>\n): CliResult {\n const [kind, oldId, newId] = args\n if (!kind || !RENAME_KINDS.has(kind) || !oldId || !newId) {\n w.err(\n \"Usage: uidex rename <element|widget|region> <old-id> <new-id> [--force]\"\n )\n return w.result(1)\n }\n\n const result = renameEntity({\n cwd,\n kind: kind as RenameKind,\n oldId,\n newId,\n force: Boolean(flags.force),\n })\n\n for (const e of result.errors) w.err(e)\n for (const m of result.manual) {\n w.err(`MANUAL ${m.file}:${m.line} — ${m.reason}`)\n }\n if (result.errors.length > 0) return w.result(1)\n\n w.out(\n `Renamed ${kind} \"${oldId}\" → \"${newId}\" (${result.edits} edit(s)); gen file regenerated`\n )\n if (result.manual.length > 0) {\n w.err(\n `${result.manual.length} occurrence(s) need manual follow-up (listed above)`\n )\n return w.result(1)\n }\n return w.result(0)\n}\n\nfunction createWriter() {\n let stdout = \"\"\n let stderr = \"\"\n return {\n out(msg: string) {\n stdout += msg + \"\\n\"\n },\n err(msg: string) {\n stderr += msg + \"\\n\"\n },\n result(exitCode: number): CliResult {\n return { exitCode, stdout, stderr }\n },\n }\n}\n","import * as p from \"@clack/prompts\"\nimport { PROVIDERS, getProvider } from \"./providers\"\nimport type { AiProvider, FileChange, InstallResult } from \"./types\"\n\nexport interface AiCommandOptions {\n cwd: string\n argv: string[]\n /**\n * Optional non-interactive mode. When set, prompts are skipped and the\n * provider id must come from `--provider` (or be the only registered one).\n */\n nonInteractive?: boolean\n /** Hooks for tests / programmatic use. Replaces clack prompts. */\n prompt?: {\n selectProvider?: (providers: AiProvider[]) => Promise<string | null>\n }\n}\n\nexport interface AiCommandResult {\n exitCode: number\n stdout: string\n stderr: string\n}\n\nexport async function runAiCommand(\n opts: AiCommandOptions\n): Promise<AiCommandResult> {\n const { cwd, argv } = opts\n const sub = argv[0]\n\n if (!sub || sub === \"--help\" || sub === \"-h\" || sub === \"help\") {\n return out(0, helpText())\n }\n\n if (sub === \"providers\") {\n return out(\n 0,\n PROVIDERS.map((pr) => ` ${pr.id.padEnd(10)} ${pr.label}`).join(\"\\n\") +\n \"\\n\"\n )\n }\n\n if (sub !== \"install\" && sub !== \"uninstall\") {\n return err(1, `Unknown ai subcommand: ${sub}\\n\\n${helpText()}`)\n }\n\n const flags = parseFlags(argv.slice(1))\n const provider = await selectProvider(opts, flags.provider)\n if (!provider) return out(0, \"Cancelled.\\n\")\n\n if (sub === \"install\") {\n const result = await provider.install({\n cwd,\n force: flags.force === true,\n })\n return out(0, formatChanges(provider, \"Installed\", result))\n }\n\n // uninstall\n const result = await provider.uninstall({ cwd })\n return out(0, formatChanges(provider, \"Uninstalled\", result))\n}\n\nasync function selectProvider(\n opts: AiCommandOptions,\n explicit: string | undefined\n): Promise<AiProvider | null> {\n if (explicit) {\n const found = getProvider(explicit)\n if (!found) {\n throw new Error(\n `Unknown provider: ${explicit}. Run 'uidex ai providers' to list.`\n )\n }\n return found\n }\n\n if (PROVIDERS.length === 1) return PROVIDERS[0]\n\n if (opts.nonInteractive) {\n throw new Error(\n \"Multiple providers available; pass --provider <id> in non-interactive mode.\"\n )\n }\n\n if (opts.prompt?.selectProvider) {\n const id = await opts.prompt.selectProvider(PROVIDERS)\n return id ? (getProvider(id) ?? null) : null\n }\n\n const choice = await p.select({\n message: \"Which AI assistant?\",\n options: PROVIDERS.map((pr) => ({\n value: pr.id,\n label: pr.label,\n hint: pr.description,\n })),\n })\n if (p.isCancel(choice)) return null\n return getProvider(choice as string) ?? null\n}\n\ninterface Flags {\n provider?: string\n force?: boolean\n}\n\nfunction parseFlags(args: string[]): Flags {\n const flags: Flags = {}\n for (let i = 0; i < args.length; i++) {\n const a = args[i]\n if (a === \"--force\") flags.force = true\n else if (a === \"--provider\" || a === \"-p\") flags.provider = args[++i]\n else if (a.startsWith(\"--provider=\")) flags.provider = a.slice(11)\n }\n return flags\n}\n\nfunction formatChanges(\n provider: AiProvider,\n verb: string,\n result: InstallResult\n): string {\n const lines: string[] = [`${verb} ${provider.label}:`]\n for (const c of result.changes) lines.push(` ${describe(c)}`)\n return lines.join(\"\\n\") + \"\\n\"\n}\n\nfunction describe(c: FileChange): string {\n switch (c.action) {\n case \"created\":\n return `+ ${c.path}`\n case \"overwritten\":\n return `~ ${c.path}`\n case \"removed\":\n return `- ${c.path}`\n case \"skipped\":\n return `· ${c.path}${c.reason ? ` (${c.reason})` : \"\"}`\n }\n}\n\nfunction helpText(): string {\n return [\n \"uidex ai — install AI assistant integrations\",\n \"\",\n \"Subcommands:\",\n \" install Install an AI integration into the current repo\",\n \" uninstall Remove an AI integration from the current repo\",\n \" providers List available providers\",\n \"\",\n \"Flags:\",\n \" --provider <id>, -p Skip the prompt and pick a provider by id\",\n \" --force (install) overwrite existing files\",\n \"\",\n ].join(\"\\n\")\n}\n\nfunction out(exitCode: number, stdout: string): AiCommandResult {\n return { exitCode, stdout, stderr: \"\" }\n}\n\nfunction err(exitCode: number, stderr: string): AiCommandResult {\n return { exitCode, stdout: \"\", stderr }\n}\n","import * as fs from \"node:fs\"\nimport * as path from \"node:path\"\nimport { readTemplate } from \"../templates\"\nimport type {\n AiProvider,\n FileChange,\n InstallOptions,\n InstallResult,\n UninstallOptions,\n UninstallResult,\n} from \"../types\"\n\nconst SKILL_FILES: { dest: string; template: string }[] = [\n { dest: \".claude/skills/uidex/SKILL.md\", template: \"claude/SKILL.md\" },\n {\n dest: \".claude/skills/uidex/references/conventions.md\",\n template: \"claude/references/conventions.md\",\n },\n {\n dest: \".claude/skills/uidex/references/audit.md\",\n template: \"claude/references/audit.md\",\n },\n {\n dest: \".claude/skills/uidex/references/api.md\",\n template: \"claude/references/api.md\",\n },\n]\n\nconst LEGACY_FILES = [\n \".claude/rules/uidex.md\",\n \".claude/commands/uidex/audit.md\",\n \".claude/commands/uidex/api.md\",\n]\n\nexport const claudeProvider: AiProvider = {\n id: \"claude\",\n label: \"Claude Code\",\n description:\n \"Adds .claude/skills/uidex/ skill with conventions, audit, and API references.\",\n\n async install({ cwd, force }: InstallOptions): Promise<InstallResult> {\n const changes: FileChange[] = []\n\n for (const file of SKILL_FILES) {\n const dest = path.join(cwd, file.dest)\n const exists = fs.existsSync(dest)\n\n if (exists && !force) {\n changes.push({\n path: file.dest,\n action: \"skipped\",\n reason: \"exists (use --force to overwrite)\",\n })\n continue\n }\n\n fs.mkdirSync(path.dirname(dest), { recursive: true })\n fs.writeFileSync(dest, readTemplate(file.template))\n changes.push({\n path: file.dest,\n action: exists ? \"overwritten\" : \"created\",\n })\n }\n\n for (const rel of LEGACY_FILES) {\n const dest = path.join(cwd, rel)\n if (fs.existsSync(dest)) {\n fs.unlinkSync(dest)\n changes.push({ path: rel, action: \"removed\" })\n }\n }\n cleanupEmpty(path.join(cwd, \".claude/commands/uidex\"))\n cleanupEmpty(path.join(cwd, \".claude/commands\"))\n cleanupEmpty(path.join(cwd, \".claude/rules\"))\n\n return { changes }\n },\n\n async uninstall({ cwd }: UninstallOptions): Promise<UninstallResult> {\n const changes: FileChange[] = []\n\n for (const file of SKILL_FILES) {\n const dest = path.join(cwd, file.dest)\n if (!fs.existsSync(dest)) {\n changes.push({ path: file.dest, action: \"skipped\", reason: \"absent\" })\n continue\n }\n fs.unlinkSync(dest)\n changes.push({ path: file.dest, action: \"removed\" })\n }\n\n cleanupEmpty(path.join(cwd, \".claude/skills/uidex/references\"))\n cleanupEmpty(path.join(cwd, \".claude/skills/uidex\"))\n cleanupEmpty(path.join(cwd, \".claude/skills\"))\n\n for (const rel of LEGACY_FILES) {\n const dest = path.join(cwd, rel)\n if (fs.existsSync(dest)) {\n fs.unlinkSync(dest)\n changes.push({ path: rel, action: \"removed\" })\n }\n }\n cleanupEmpty(path.join(cwd, \".claude/commands/uidex\"))\n cleanupEmpty(path.join(cwd, \".claude/commands\"))\n cleanupEmpty(path.join(cwd, \".claude/rules\"))\n\n return { changes }\n },\n}\n\nfunction cleanupEmpty(dir: string): void {\n try {\n const entries = fs.readdirSync(dir)\n if (entries.length === 0) fs.rmdirSync(dir)\n } catch {\n /* directory missing or non-empty — ignore */\n }\n}\n","import * as fs from \"node:fs\"\nimport * as path from \"node:path\"\n\n/**\n * Resolves a path inside the package's templates/ directory.\n *\n * In production the bin runs from `dist/cli/cli.cjs`, so templates live\n * at `../../templates/<rel>`. In tests we run via tsx from\n * `src/scan/ai/`, which resolves through `../../../templates`.\n */\nexport function templatePath(rel: string): string {\n const candidates = [\n path.resolve(__dirname, \"../../templates\", rel), // dist/cli/cli.cjs → ../../templates\n path.resolve(__dirname, \"../../../../templates\", rel), // src/scanner/scan/ai → ../../../../templates\n ]\n for (const c of candidates) {\n try {\n fs.accessSync(c, fs.constants.R_OK)\n return c\n } catch {\n continue\n }\n }\n throw new Error(\n `uidex: template not found: ${rel}. Looked in:\\n ${candidates.join(\"\\n \")}`\n )\n}\n\nexport function readTemplate(rel: string): string {\n return fs.readFileSync(templatePath(rel), \"utf8\")\n}\n","import type { AiProvider } from \"../types\"\nimport { claudeProvider } from \"./claude\"\n\nexport const PROVIDERS: AiProvider[] = [claudeProvider]\n\nexport function getProvider(id: string): AiProvider | undefined {\n return PROVIDERS.find((p) => p.id === id)\n}\n","export function parseArgs(args: string[]): {\n positional: string[]\n flags: Record<string, string | boolean>\n} {\n const positional: string[] = []\n const flags: Record<string, string | boolean> = {}\n for (let i = 0; i < args.length; i++) {\n const a = args[i]\n if (a.startsWith(\"--\")) {\n const eq = a.indexOf(\"=\")\n if (eq !== -1) {\n flags[a.slice(2, eq)] = a.slice(eq + 1)\n } else {\n const next = args[i + 1]\n if (next && !next.startsWith(\"--\")) {\n flags[a.slice(2)] = next\n i++\n } else {\n flags[a.slice(2)] = true\n }\n }\n } else {\n positional.push(a)\n }\n }\n return { positional, flags }\n}\n"],"mappings":"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","names":["path","p","fs","path","out","p","path","out","CORE_STATE_KINDS","p","isNode","out","out","isNode","out","path","out","resolve","p","out","path","out","out","path","r","out","fs","path","out","STATE_KINDS","out","ent","out","summary","p","baseName","check","out","out","fs","path","fs","path","DEFAULT_STATES_MANIFEST","resolve","p","fs","path","fs","path","fs","path","fs","path","p","result","helpText","p","out"]}