Lookbook · Amplifier Research
Lookbook
A dataset for UI convergence.
Collecting (prompt → component tree) pairs
to make AI-assisted UI generation predictable.
Experimental · April 2, 2026 · kenotron-ms/lookbook · Ken Chau
The Problem
UI generation is powerful.
But it's unpredictable.

No structural preview

You can't know what components will be generated before running generation. The output — the tree, the depth, the node count — is a surprise every time, even from the same prompt.

The topology is invisible

You see the rendered UI. You don't see the component hierarchy that produced it. There's no intermediate representation between "prompt" and "compiled pixels" to reason about.

Reuse is hard to predict

Without knowing which components will appear, you can't predict cross-app reusability or check design system coverage before generating. You discover the architecture after the fact.

The pattern exists — it's just uncaptured

AI-assisted UI generation isn't random. Similar prompts tend to produce similar component topologies. This convergence pattern has never been systematically collected or studied.

The Hypothesis
prompt → component tree
is a learnable function.
f : PromptSpace ComponentTreeSpace
Given enough (prompt, tree) pairs, derive the mapping between them.
f("Build Claude.ai chat with artifacts, thinking blocks, Projects sidebar")
{ root: SageLayout, nodes: 9, depth: 3, loc: 1665 }
g : ComponentTreeSpace PromptSpace (the reverse)
g({ root: SageLayout, children: [Sidebar, ChatArea, ArtifactsPanel] })
"Build a Claude.ai-style agentic chat interface with..."

Forward: f(prompt) → tree

Predict the component hierarchy before any code is generated. Use for prompt engineering, complexity estimation, and design system planning.

Reverse: g(tree) → prompt

Given an existing component hierarchy, reconstruct the prompt space it belongs to. Enables reverse-engineering of existing apps and identifying shared architectures.

The prerequisite: data

Neither function can be derived without a corpus of (prompt, component_tree) pairs. Lookbook is the collection infrastructure for that corpus.

The Method
Build a corpus of
(prompt, component_tree) pairs.
Take a prompt
Generate iteratively
via UI Studio
Capture component hierarchy
Store the pair
as a dataset entry
Each dataset entry records:
{ "id" : "sage" // app slug "prompt" : "Build Claude.ai chat with artifacts, thinking, Projects" "component_tree" : { "root" : "SageLayout" // entry component "nodes" : 9 // .jsx file count "depth" : 3 // nesting levels "loc_total": 1665 // lines of code } "iterations" : 3 // v1, v2, v3 "pipeline" : "amplifier-ui-studio" "author" : "Ken Chau" "date" : "2026-03-29" }

What makes this a dataset, not a gallery

A typical lookbook is a visual showcase. This one captures the structure behind the visuals — the component tree with nesting depth, node count, and iteration history.


The goal isn't to demonstrate quality. It's to record what topology a given prompt produces, so we can study the mapping over many examples.

Iteration snapshots are first-class data

Capturing v1, v2, and v3 of each app isn't just documentation — it shows how the component tree evolves as prompts become more specific. That evolution path is itself a data signal.

Data Point #001 · Sage
The prompt. The tree.
Source prompt
"Build a Claude.ai-style chat interface with artifacts panel, thinking blocks, tool call displays, Projects sidebar."
9 components (.jsx files)
1,665 LOC (total)
3 iterations
depth 3
9 .jsx files verified: Layout, Sidebar, ChatArea, MessageBubble, ThinkingBlock, ToolCallCard, ArtifactsPanel, InputBar, ComposeModal. LOC: 358 + 341 + 312 + 237 + 203 + 113 + 63 + 33 + 5 = 1,665.
Resultant component hierarchy
<SageLayout> ← Layout.jsx ├── <Sidebar> ← Sidebar.jsx (358 LOC) │ ├── ProjectsList │ └── NewConversation ├── <ChatArea> ← ChatArea.jsx (113 LOC) │ ├── <MessageBubble> ← MessageBubble.jsx │ │ ├── ThinkingBlock ← ThinkingBlock.jsx │ │ └── ToolCallCard ← ToolCallCard.jsx │ ├── <ArtifactsPanel> ← ArtifactsPanel.jsx │ │ ├── ArtifactViewer │ │ └── ArtifactTabs │ └── <InputBar> ← InputBar.jsx (341 LOC) │ ├── TextArea │ ├── AttachButton │ └── SendButton └── <ComposeModal> ← ComposeModal.jsx (5 LOC)
Convergence · Sage v1 → v2 → v3
How the tree stabilizes with iteration.
v1 First interpretation
App ├── Sidebar │ └── ConversationList ├── ChatArea │ ├── Messages │ ├── Artifacts │ └── InputBar └── ...
~6 regions · shallow structure · no agentic nodes · visual-reference only · 7,566 lines added (26 files)
v2 Agentic layer added
SageLayout ├── Sidebar │ ├── ProjectsList │ └── ConversationList ├── ChatWindow │ ├── MessageList │ │ ├── MessageBubble │ │ ├── ThinkingBlock ← │ │ └── ToolCallCard ← │ ├── ArtifactsPanel │ └── InputBar
+ThinkingBlock, +ToolCallCard · hierarchy deepens · Projects sidebar added · +2,924 ins / −1,964 del
v3 Converged (pixel-accurate)
SageLayout ├── Sidebar │ ├── ProjectsList │ └── NewConversation ← ├── ChatArea │ ├── MessageBubble │ │ ├── ThinkingBlock │ │ └── ToolCallCard │ ├── ArtifactsPanel │ │ ├── ArtifactViewer ← │ │ └── ArtifactTabs ← │ └── InputBar
Structure stable · leaf nodes specified · 9 .jsx files · 1,665 LOC · +2,355 ins / −2,319 del (visual corrections only)
The convergence signal: By v2, the structural skeleton is established — the major nodes are all present. v3 doesn't restructure; it specifies. The topology converges before the visual fidelity does. This ordering — structure first, pixels second — may be a generalizable pattern.
The Dataset
Early stage.
One confirmed data point.
1
confirmed
data point
(Sage · 2026-03-29)

What Sage contributes to the corpus

  • 1 source prompt → 1 component tree mapping
  • 3 iteration snapshots showing the convergence path
  • 9 named components with exact LOC per file
  • Full git provenance: 4 commits over 1h 54min
  • Convergence observation: structure stable by v2
Status: collection phase. The convergence function is not yet derived. One data point establishes the schema and proves the collection workflow — it does not validate the hypothesis.
Sage — dataset entry (proposed format)
{ "id" : "sage" "prompt" : "Build Claude.ai chat with artifacts, thinking, tools, Projects sidebar" "component_tree" : { "root" : "SageLayout" "nodes" : 9 // .jsx file count "depth" : 3 "loc_total" : 1665 "components" : ["SageLayout", "Sidebar", "ChatArea", "MessageBubble", "ThinkingBlock", "ToolCallCard", "ArtifactsPanel", "InputBar", "ComposeModal"] } "iterations" : 3 "convergence_at" : "v2" // qualitative observation "pipeline" : "amplifier-ui-studio" "date" : "2026-03-29" "author" : "Ken Chau" }
The Convergence Function
What f(prompt) → component_tree
would enable.
Forward function · f(prompt) → tree

🔍 Pre-generation topology preview

Know the component tree before generating code. Predict complexity, node count, and nesting depth from the prompt alone. Use to flag over-engineering before it happens.

🧭 Prompt engineering feedback loop

Modify your prompt → see the predicted tree change → iterate on the prompt until the topology matches intent. Iterate on the map, not the territory.

📐 Design system coverage analysis

Given a set of prompts you plan to run, predict which component nodes will be needed. Check design system coverage before generation, not after.

Reverse function · g(tree) → prompt

🔄 Tree → prompt reconstruction

Given an existing component hierarchy (from any codebase), reconstruct the prompt space it belongs to. Useful for understanding legacy apps built with AI generation.

🧩 Component reuse prediction

Identify when two different prompts would produce the same component topology — and therefore which components could be shared across apps without duplication.

⚠️ None of this exists yet

All applications above require a trained or derived function. That function requires a corpus. We have 1 data point. The collection phase must precede the analysis phase.

Next Steps
How to grow the dataset.

1. Contribute data points

Build an app with Amplifier's UI Studio pipeline. Capture the component hierarchy. Add the (prompt, tree) pair to lookbook. The workflow takes one afternoon.


No minimum LOC. No minimum quality. Any generated app with a documented prompt and captured tree structure counts as a valid data point.

2. Canonicalize the schema

The dataset entry format above is a draft. It needs: formal JSON Schema, a standard component tree serialization format, and a convention for iteration snapshots.


Open question: what's the right representation for a component tree that enables topology comparison across apps built with different frameworks?

3. Analyze at 10+ entries

With 10 or more data points, begin asking: which nodes appear most frequently? What tree structures cluster together? Do prompt patterns predict topologies?


Target milestone: 10 apps before any function derivation attempt. Patterns need minimum density before they're visible.

Planned tooling

  • Automated tree extractor — parse .jsx source → JSON tree
  • Iteration diff tool — compare tree snapshots across v1/v2/v3
  • Topology similarity metric — edit distance between component trees
  • Prompt cluster visualizer — group prompts by the trees they produce

Open research questions

  • How many data points before convergence patterns emerge?
  • Does tree depth correlate with prompt specificity?
  • Are there universal "attractor" topologies for common UI patterns?
  • Is the structure-before-pixels ordering consistent across apps?
Sources & Methodology
How this data was gathered.
Component inventory (Sage) — Verified via wc -l apps/sage/src/components/*.jsx. All 9 files confirmed: Layout.jsx (33), Sidebar.jsx (358), ChatArea.jsx (113), MessageBubble.jsx (203), ThinkingBlock.jsx (63), ToolCallCard.jsx (237), ArtifactsPanel.jsx (312), InputBar.jsx (341), ComposeModal.jsx (5). Sum: 1,665 LOC.
Iteration evidence — v1/v2/v3 story sourced from git history: git log --oneline apps/sage/. Four commits on 2026-03-29 (98cd7ea, e1eca21, 1a16e15, 5ce6877). Timestamps from git log --format="%h %ai %s". Build duration (1h 54min 22s) is the exact diff between commits 98cd7ea (20:22:35) and 5ce6877 (22:16:57).
Convergence observation — The claim "topology converges by v2" is a qualitative observation from comparing v2 and v3 commit messages, not a computed result. The v3 commit (5ce6877) records ~2,355 insertions and ~2,319 deletions — but these are pixel-level visual corrections, not structural changes. No automated tool currently measures this. The "convergence_at": "v2" field in the dataset schema is inferred, not derived.
Convergence function hypothesis — f(prompt) → component_tree and g(component_tree) → prompt are hypotheses. No function has been trained, derived, or validated. All described applications are potential applications, not demonstrated capabilities. The lookbook project is in the data collection phase only.
Dataset schema — The JSON schema shown is a proposed draft format, not a finalized specification. The component tree naming in slides follows the conceptual hierarchy from the project brief; actual .jsx filenames differ slightly (e.g., the brief uses "SageLayout" and "ChatWindow" where the files are "Layout.jsx" and "ChatArea.jsx").
Data as of: April 2, 2026 · Repository: kenotron-ms/lookbook (/Users/ken/workspace/ms/lookbook) · Status: Experimental · Single author: Ken Chau
Contribute
Add your app to the dataset.
⚗️

Build with UI Studio

Take any prompt and run it through Amplifier's iterative generation pipeline. Three iterations — v1 to v3 — is the target format for each data point.

🌳

Capture the component tree

Document the hierarchy: root node, nesting, leaf components. wc -l src/components/*.jsx gives you LOC per node. Record the tree at each iteration.

📦

Add to lookbook

Create a new app directory under apps/. Add a dataset.json entry with your (prompt, component_tree) pair using the schema from Sage.

📖

Tell the story

Use Amplifier's storyteller to create a deck for your app. Each story documents the pipeline run, adds a data point to the corpus, and makes the convergence pattern visible.

Repository: kenotron-ms/lookbook · Status: Experimental · Dataset entries: 1 (Sage · March 2026) · Goal: 10 entries before analysis
More Amplifier Stories