uidex 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +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/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 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 }\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 | { 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 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 === 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 // ---------- 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 + 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 { 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","p","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"]}