AI Code2WF — Overview
Code2WF converts one completed Page Import into one low-fidelity wireframe specification. Page Import owns codebase execution and browser capture. Code2WF receives only a pageImportId; it does not accept a repository, public URL, HTML, CSS, or executable JavaScript.
The Figma plugin materializes the completed specification into native Figma nodes. If generation completes while the plugin is closed, the row stays discoverable and the plugin materializes it the next time it is opened in the target file.
The MVP supports:
- one imported route, query/state, and viewport per Code2WF job;
- one generated screen in one Figma file;
- visible structure, copy, controls, media placeholders, and evidence-based annotations;
- status values shared with the existing WF2Des Figma-generation lifecycle; and
- row-level placement completion following the existing WF2Des convention.
The MVP does not crawl routes, build a page graph, create navigation/prototype links, generate responsive variants, or recreate a high-fidelity visual design.
Tech Stack
| Layer | Technology |
|---|---|
| Conversion runtime | Python 3.12 container worker |
| Queue | Backend-produced Code2WF SQS queue and DLQ |
| Input | Immutable completed Page Import result in S3 |
| Output | Immutable result artifact using WF2Des envelope naming and containing the existing WF2Des DesignSpecModel in S3 |
| Product state | Backend-owned PostgreSQL code2wf row |
| Status notification | Shared POST /v1/webhooks/ai-status with type: "code2wf" |
| Figma write path | Authenticated Figma plugin |
Responsibility Boundary
flowchart LR
SRC["Codebase page"] --> PI["Page Import"]
PI -->|"completed pageImportId"| API["Backend Code2WF API"]
API --> Q["Code2WF queue"]
Q --> W["Code2WF worker"]
W --> SPEC["Result artifact with DesignSpecModel in S3"]
SPEC --> PL["Figma plugin"]
PL ==>|"native nodes"| FIG["Figma file"]
PL -->|"placement"| API
Page Import owns
- repository/runtime provenance and the selected page entry;
- route, query/state, viewport, build/start, and post-JavaScript capture;
- normalized visible hierarchy, geometry, semantics, screenshot, and assets; and
- its own import lifecycle and immutable result.
Code2WF owns
- validating a completed Page Import in the same organization/project;
- converting its immutable result into a bounded low-fi node tree;
- generating deterministic evidence-based annotations as ordinary layout/text nodes;
- storing and reporting an immutable result artifact with the existing nested
DesignSpecModel; and - exposing the result for plugin materialization.
The Figma plugin owns
- discovering completed rows for the open Figma file where
materializedAtis null; - building a staging root through the planned Code2WF plugin path and applying the existing WF2Des swap-on-success
pluginDatacontract; - reporting the generated screen's
placedNodeId; and - retrying unfinished materialization on a later plugin session or explicit user action.
Code2WF has no server-side materialization state machine or retry scheduler.
Lifecycle
Code2WF reuses the existing wf2des_status type for Figma generation rows. The MVP uses only this subset:
status |
Meaning |
|---|---|
"0" |
processing |
"1" |
completed |
"2" |
failed |
attempt is always 1 in the MVP and Code2WF has no phase. To run generation again, the client submits another trigger and the backend creates another UUIDv7 job.
Generation completion and Figma materialization are separate:
- The client submits a completed
pageImportIdand the Figma destination fields. - The backend generates
code2wfIdas UUIDv7, inserts the row, resolves the Page Import's immutable result, and dispatches attempt1. - The worker writes a result artifact using the WF2Des
job_id/status/generated_atconvention and containing the existingDesignSpecModel, then reports completed or failed. - The plugin discovers a completed, unmaterialized row and builds native nodes.
- The placement endpoint stamps
materialized_at, following the same row-level convention as WF2Des.
Every valid trigger creates a new row and worker job. Code2WF does not accept a caller-provided ID and does not deduplicate identical trigger bodies.
Generation Rules
- Preserve visible grouping, relative geometry, copy, and control semantics across the Page Import's full document height; use a visible existing-schema placeholder when a relationship cannot be represented by the shared auto-layout tree.
- Replace page-specific presentation with a neutral wireframe palette and typography.
- Create annotations only from observable links, forms, controls, ARIA state, or capture warnings, and render them as ordinary
layout_frame/textsubtrees with a sibling marker that does not modify the captured control label. - Do not invent hidden screens or behavior.
- Generate annotation wording deterministically; Code2WF adds no annotation-only model or schema.
- Validate the shared spec shape, known node union, and locked V1 limits before writing the result.
The exact worker and result contracts are defined in Code2WF I/O Definition.
Figma Materialization
The plugin must add Code2WF discovery, result fetching, and placement wiring, then pass the existing DesignSpecModel through the WF2Des planner/materializer. That path builds a new staging root before touching prior output, stores root.setPluginData("wf2des", JSON.stringify({jobId, specVersion, role: "root"})), records {[jobId]: rootId} under document-root key wf2des_index, and removes the prior root only after the replacement succeeds. The shared builder also needs to finish support for already-defined text fallback and layout sizing/wrap fields; no Code2WF-only fields are introduced. Its existing placeRoot path receives the resolved current-page rectangle for placementTarget and places the root at that rectangle's x/y without changing the target; absent, stale, or other-page targets use the existing viewport-center fallback. The Code2WF discovery/API wiring and those shared-field options do not exist yet; a second node schema or renderer is not required. The MVP retains the existing wf2des · 1.0 root label and plugin-data namespace.
After the native screen is complete, the plugin calls the Code2WF placement endpoint with its placedNodeId. The backend stamps materialized_at on the completed row, following the existing WF2Des placement convention. Repeating placement after the timestamp exists returns the existing timestamp.
On a caught build failure, the current materializer removes its staging tree; an ungraceful plugin shutdown still needs an integration test. PostgreSQL remains unchanged until placement succeeds. On reopen, the planned discovery flow fetches the immutable result and rebuilds; the existing swap-on-success path replaces a prior root after the replacement completes instead of intentionally retaining duplicate output.