diff --git a/eval/package.json b/eval/package.json index b57e1d6..ac10c9d 100644 --- a/eval/package.json +++ b/eval/package.json @@ -1,6 +1,6 @@ { "name": "@coderadar/eval", - "version": "0.1.0", + "version": "0.2.0", "private": true, "description": "CodeRadar eval harness — scans failure-mode fixtures, diffs against golden outputs, emits the scorecard that gates every phase.", "license": "MIT", diff --git a/package.json b/package.json index a120629..e6d7162 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "coderadar", "private": true, - "version": "0.1.0", + "version": "0.2.0", "description": "Static analysis toolkit that maps UI components to their data sources (APIs, state, events) — enabling AI agents to trace any screenshot back to the code and data behind it.", "license": "MIT", "packageManager": "pnpm@11.2.2", diff --git a/packages/cli/README.md b/packages/cli/README.md index 2738278..1c46933 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -1,12 +1,12 @@ # ui-lineage -**Map UI components to their data sources and user journeys** — trace any screenshot or ticket back to the code, APIs, state, and navigation behind it. Deterministic static analysis for React/TSX. No LLM, no network calls. +**Map UI components to their data, journeys, and behavior** — trace any screenshot or ticket back to the code, APIs, state, events, and navigation behind it. Deterministic static analysis for React/TSX. No LLM in the core, no network calls. -`ui-lineage` scans a React codebase into a **lineage graph** and lets you query it three ways: +`ui-lineage` scans a React codebase into a **lineage graph** and answers three questions: -- **match** — text seen on screen → the component(s) that render it -- **trace** — a component → every API, state slice, and event that feeds it (attributed *per instance*, so a shared `` on the Users page reports `/api/users` while the same component on Invoices reports `/api/invoices`) -- **journeys** — a page → the user-action paths leading out of it (click → navigate → click…), lazily expanded and cycle-safe +1. **match** — text or structure seen on screen → the component(s) that render it (rarity-weighted, fuzzy/OCR-tolerant, structure-aware, with business-vocab aliases and human corrections, and *calibrated* confidence). +2. **trace** — a component → every API, state slice, and event that feeds it, *attributed per instance* (a shared `` reports `/api/users` on the Users page and `/api/invoices` on Invoices). +3. **journeys** — a page → the user-action paths out of it (click → navigate → click…), lazily expanded and cycle-safe, with flag/role conditions. ## Install @@ -20,47 +20,58 @@ Requires Node ≥ 20. ## CLI ```bash -# 1. Scan a React app into a graph -ui-lineage scan ./src -o app.graph.json - -# 2. Find a component from on-screen text -ui-lineage find "All invoices" -g app.graph.json - -# 3. Trace a component (or an instance id) to its data -ui-lineage trace InvoicesPage -g app.graph.json - -# 4. Walk the user journeys from a page or route -ui-lineage journeys /users -g app.graph.json +ui-lineage scan ./src -o app.graph.json # scan a React app into a graph +ui-lineage find "All invoices" -g app.graph.json # text → component +ui-lineage find "invoice widget" -a aliases.yaml # resolve business vocabulary +ui-lineage trace InvoicesPage -g app.graph.json # component → data/state/events +ui-lineage journeys /users -g app.graph.json # user-journey paths from a page +ui-lineage correct BillingCard "amount owed" # record a correction for next time ``` -`journeys` output reads left-to-right, with `↩ cycle` where a list ⇄ detail loop closes: +`journeys` reads left-to-right, with `↩ cycle` where a list ⇄ detail loop closes: ``` - ▸ /users • onClick() → /users/:userId ▸ /users/:userId • onClick() → /users ▸ /users ↩ cycle + ▸ /users • onClick() → /users/:id ▸ /users/:id • onClick() → /users ▸ /users ↩ cycle ▸ /users • onClick() ⇢ fetch /api/users ``` ## Library ```ts -import { scanReact, resolveHookEdges, journeys, traceLineage, matchComponentsByText } from "ui-lineage"; +import { + scanReact, resolveHookEdges, + matchComponents, traceLineage, journeys, + recordCorrection, loadCorrections, +} from "ui-lineage"; const graph = resolveHookEdges(scanReact({ root: "./src" })); -const match = matchComponentsByText(graph, ["All invoices"]); +const match = matchComponents(graph, { terms: ["All invoices"] }); const lineage = traceLineage(graph, match.candidates[0].value.component.id); const paths = journeys(graph, "/users", { depth: 3 }); ``` -Every query returns a `QueryResult` envelope — ranked `candidates` with evidence and confidence, or an honest `ambiguous` / `declined`. +Every query returns a `QueryResult` envelope — ranked `candidates` with evidence and confidence, or an honest `ambiguous` (with a disambiguation question built from the candidates' differences) / `declined` (machine-readable reason). + +### Screenshots (`ui-lineage/vision`) + +```ts +import { StubVisionAdapter, matchFromVision } from "ui-lineage/vision"; +``` + +Turn a screenshot into `{ terms, structure, annotations }` and match it — terms the user circled are weighted 3×; a non-app image declines. The Claude-vision adapter needs `@anthropic-ai/sdk` installed separately; the stub and matching helpers do not. Images are processed in memory, never persisted. ## What it understands -Endpoints (constants, templates, API wrappers, react-query/SWR), i18n text, cross-file instance trees and per-instance prop-flow, Redux/Zustand stores, portals/modals/toasts, React Router & Next.js routes, and action effects (navigate / fetch / dispatch / setState) mined from event handlers. +Endpoints (constants, templates, API wrappers, react-query/SWR), i18n text, cross-file instance trees & per-instance prop-flow, Redux/Zustand stores, portals/modals/toasts, React Router & Next.js routes, action effects (navigate/fetch/dispatch/setState), form libraries & non-JSX events (react-hook-form, `addEventListener`, hotkeys), and feature-flag/role conditions. + +## New in 0.2.0 + +User journeys · action effects · form & non-JSX events · flag/role conditions · a real matching engine (rarity + fuzzy/OCR + structural + most-specific-subtree) · screenshot/vision adapter · alias glossary + corrections store · calibrated confidence with honesty metrics. ## Status -Early (v0.1). The matching engine, screenshot adapter, and MCP server are on the roadmap. Output is deterministic and language-agnostic (plain JSON graph), designed to feed AI agents as a context provider — not to be one. +Pre-1.0. The context-bundle orchestrator and MCP server are next. Output is deterministic and language-agnostic (a plain JSON graph), designed to feed AI agents as a context provider — not to be one. ## License diff --git a/packages/cli/package.json b/packages/cli/package.json index c868b1a..1d34e0a 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "ui-lineage", - "version": "0.1.0", + "version": "0.2.0", "description": "Map UI components to their data sources and user journeys — trace any screenshot back to the code, APIs, state, and navigation behind it. Deterministic static analysis for React/TSX.", "license": "MIT", "type": "module", @@ -18,7 +18,8 @@ "./vision": { "types": "./dist/vision.d.ts", "default": "./dist/vision.js" - } + }, + "./package.json": "./package.json" }, "files": [ "dist", diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 1fbcc65..ebf31d6 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -27,7 +27,7 @@ program .description( "Map UI components to their data sources and user journeys — trace any screenshot back to the code, APIs, state, and navigation behind it.", ) - .version("0.1.0"); + .version("0.2.0"); program .command("scan") diff --git a/packages/core/package.json b/packages/core/package.json index 1a9060b..1f7d90b 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@coderadar/core", - "version": "0.1.0", + "version": "0.2.0", "private": true, "description": "CodeRadar lineage graph schema — the language-agnostic contract every parser emits and every agent consumes. Bundled into the published `ui-lineage` package.", "license": "MIT", diff --git a/packages/parser-react/package.json b/packages/parser-react/package.json index 6f6b753..5dddf6b 100644 --- a/packages/parser-react/package.json +++ b/packages/parser-react/package.json @@ -1,6 +1,6 @@ { "name": "@coderadar/parser-react", - "version": "0.1.0", + "version": "0.2.0", "private": true, "description": "React/TSX parser for CodeRadar — extracts components, hooks, data sources, state, and events into a lineage graph. Bundled into the published `ui-lineage` package.", "license": "MIT", diff --git a/packages/parser-react/src/scan.ts b/packages/parser-react/src/scan.ts index 2908ddb..4161809 100644 --- a/packages/parser-react/src/scan.ts +++ b/packages/parser-react/src/scan.ts @@ -243,7 +243,7 @@ export function scanReact(options: ScanOptions): LineageGraph { version: 2, root, generatedAt: new Date().toISOString(), - generator: "@coderadar/parser-react@0.1.0", + generator: "ui-lineage@0.2.0", nodes: [...nodes.values()], edges, }; diff --git a/packages/vision/package.json b/packages/vision/package.json index 3814588..9f21882 100644 --- a/packages/vision/package.json +++ b/packages/vision/package.json @@ -1,6 +1,6 @@ { "name": "@coderadar/vision", - "version": "0.1.0", + "version": "0.2.0", "private": true, "description": "Screenshot → { terms, structure, annotations } vision adapter for ui-lineage. Images are processed in memory and never persisted (G7). Bundled into the published ui-lineage package.", "license": "MIT",