ui-image-to-code

Convert UI screenshots, website URLs, screen recordings, mockups, and design images into editable React/Vue/HTML/CSS frontend code with browser-validated visual parity and Studio fine-tuning. Use for

SKILL.md

GitHub

UI Image to Code

Turn visual references into maintainable, runnable UI. Treat the image as evidence, preserve the host project's conventions, and validate the implementation in a browser before calling it complete.

Orchestration contract

Act as the coordinator for the entire screenshot-to-UI job. Do not start by guessing components or writing decorative code.

Use this hard order. This gate sequence is authoritative if any older paragraph below is less strict:

  1. Mandatory project contract: before capture or source generation, run python scripts/prepare_ui_contract.py <target-project> --page <id:label> --journey <id:label> .... Declare every required page, interaction journey, viewport, source-blind boundary, browser replay, Studio, roundtrip, and design-signoff requirement. A job without .ui-job/job-contract.json is invalid, not merely incomplete. The three companion Skill sign-offs are additive and cannot be replaced by passing another --companion-skill. Disabling browser replay, design review, Studio, or roundtrip is an exceptional user-approved scope reduction and requires --exception-reason; never disable a gate merely to make validation pass.
  2. Contract-complete acquisition: for URL jobs initialize python scripts/prepare_website_capture.py <url> <target-project>. Every contract journey needs a distinct observed or confirmed action edge ending in a distinct settled, approved state. Every approved state needs an evidenceId. QingLu/video is supplemental evidence for pointer, timing, transition, or destination details; it never replaces deterministic state and action records.
  3. Position and atomic evidence: run python scripts/prepare_ui_job.py <screenshot> <target-project> --id <evidence-id> --viewport <width>x<height> for every approved state. Split every visible icon, label, title/subtitle, and control from its container. A merged navigation row is not sufficient icon evidence.
  4. Evidence and compile gates: validate every map with validate_evidence_map.py, compile every map with compile_ui_spec.py, validate capture with validate_website_capture.py, and compile interactions with compile_interaction_spec.py. All approved states and required journeys must be covered before source generation.
  5. Source generation and provenance: generate semantic responsive source with stable data-ui-id and data-ui-action bindings from all covered specs, then run python scripts/record_source_generation.py <target-project> --spec <compiled-spec> ... --interaction-spec <compiled-interaction-spec> .... Any later source or spec change makes the marker stale.
  6. Mandatory design sign-offs: frontend-skill signs hierarchy, composition, responsive structure, and restraint; emil-design-eng signs icon precision, control feedback, timing, drag/resize feel, and reduced motion; qinglu-ui-parity signs the observed interaction paths and motion evidence. Store the result in .ui-job/design-review.json. Every named Skill needs its own passed review record, timestamp, and project-local evidence files; a bare Skill name is not a sign-off. P0 issues must be zero.
  7. Icon asset hard gate: product icons must be atomic SVG or one consistent licensed/open icon-library system. Final source must not use Emoji or decorative Unicode glyphs as icons. Missing icons are explicit approximate replacements, never silent characters. Mixed fill/stroke languages, inconsistent optical size, and untracked assets block delivery. Run python scripts/audit_icon_assets.py <target-project> --source <source-file> ...; .ui-job/icon-inventory.json must pass before design review or delivery.
  8. Real-browser correction: replay every contract journey at every required viewport against the actual project URL, store screenshots and action evidence in .ui-job/browser-qa.json, and correct geometry before typography, assets, color, motion, and responsive details.
  9. Mandatory latest-project menu scan: in every authorized source-aware job, Codex must inspect the latest working tree and the live loopback application before Studio import. Start the real production project on loopback, then run python scripts/scan_project_menu.py <target-project> --url <loopback-production-url>; do not hand-author the manifest. The scanner discovers real menus, routes, nested entries, tabs, dialogs, drawers, and tool workspaces, replays safe entries in an isolated browser, measures real production UI roots, and atomically writes .ui-job/project-menu.json. Validate it with python scripts/validate_project_menu.py <target-project>. Stable menu identity must bind trigger → destination → production page/state root. Stale source files or hashes block Studio import. This is a default foundation, never an optional feature the user must request. Re-scan after route/menu source changes. In source-blind Mode A, do not inspect hidden source or DOM; build only from supplied pixels and explicitly performed visible interactions.
  10. Mandatory real-UI Studio import: immediately after source generation, browser correction, and the latest-project menu scan, run python scripts/finalize_ui_to_studio.py <target-project>. This must preserve the generated source, attach the real production DOM to Studio, initialize UI Document V4, source map, identity registry, sync state, project-menu drilldown, and .ui-job/studio-installation.json, and expose every stable visible object for direct adjustment. A copied template, studio.html, empty .ui-studio directory, screenshot layer, or starter page is not an import. Studio may be omitted only through the explicit contract exception described in step 0. Project-menu rows must report truth-sourced live layer counts. The active page updates from production-DOM mutations; inactive pages are measured in an isolated renderer that cannot move the main canvas. Dynamic actions are labeled dynamic until executed. Layer-row visibility and lock are separate 30 × 30 SVG controls with accessible state; dots, Emoji, Unicode icons, guessed counts, and permanent “pending recognition” labels fail the Studio contract.
  11. Real source roundtrip: save a Studio revision, run sync:context and sync:changes, apply it to production source, verify the real project preview, mark the revision clean, refresh Studio, and prove rollback in .ui-job/roundtrip-qa.json.
  12. Final delivery hard gate: run python scripts/validate_delivery_gate.py <target-project>. It must verify contract coverage, approved-state evidence, compiled specs, source hashes, browser E2E, design sign-offs, icon quality, latest project-menu coverage, Studio contract, identities, clean sync, real preview, and rollback. Do not hand off while it fails.

The detailed legacy stages below add implementation detail but may not weaken these gates:

  1. Codex website acquisition (when the input is a URL): treat Codex as the controller and the browser as the primary actuator, screenshot surface, and action observer. Initialize the run with python scripts/prepare_website_capture.py <url> <target-project>, then follow references/codex-website-capture.md. Explore only authorized visible UI. Record every relevant trigger and its observed menu, route, dialog, workspace, toggle, download, or external destination with stable identities. Attach QingLu or browser video spans only when they add pointer, timing, transition, or destination evidence. Validate with python scripts/validate_website_capture.py <manifest>, compile with python scripts/compile_interaction_spec.py <manifest>, and feed each approved stable screenshot into step 1. Do not ask the user to manually screenshot every page.
  2. Position evidence: run python scripts/prepare_ui_job.py <screenshot> <target-project> --viewport <width>x<height>, then inspect the persisted original-resolution reference and record the page frame, regions, bounds, anchors, hierarchy, typography boxes, icons, controls, and confidence.
  3. Evidence gate: complete the generated artifacts/ui-evidence/<reference-id>.json using references/evidence-map-schema.md, change its status from draft to ready, then run python scripts/validate_evidence_map.py <map>. Do not generate UI source until it passes.
  4. Generation-spec compile: run python scripts/compile_ui_spec.py <map>. Read the generated artifacts/ui-spec/<reference-id>.json before writing source. It preserves factual geometry while compiling parent trees, normalized coordinates, layout hints, responsive anchors, generation order, and missing-content warnings.
  5. Source generation: translate the compiled UI generation spec and, for URL jobs, the compiled interaction generation spec into semantic, responsive, maintainable components with stable data-ui-id nodes and data-ui-action bindings. Geometry comes before styling polish. Implement the observed destination and settled state before adding evidenced motion. Treat inferred Flex/Grid and responsive fields as implementation guidance, not new screenshot facts.
  6. Design-skill pass: apply only the relevant available companion skills according to references/orchestration-workflow.md. Companion skills may improve composition, assets, motion, or parity, but must not silently contradict observed screenshot evidence.
  7. Browser correction: render at the reference viewport, compare, correct page frame and geometry first, then typography, assets, color, and interactions.
  8. Human final 5%: open Studio when small position, size, proportion, text, icon, or spacing adjustments remain. Let the user make those adjustments directly; never require them to describe every pixel change to Codex.
  9. Studio save: persist the next revision, semantic operations, source-base hash, and stable data-ui-id targets to project files. Unsaved browser state is not a Codex handoff.
  10. Codex latest-UI ingestion: on the next turn run npm run sync:context, require a valid identity registry, read pending operations, and continue from the latest saved revision rather than chat memory.
  11. Source reconciliation: apply the revision, verify the browser, mark it clean, and refresh Studio onto the new source baseline. Repeat steps 7–10 as many times as needed.

Keep this skill as the workflow owner when companion design skills are used. Source accuracy, evidence boundaries, stable IDs, safe export, and browser verification take precedence over optional stylistic invention.

Read references/orchestration-workflow.md before processing a screenshot. Read references/delivery-hard-gate-v1.md before declaring a multi-state website reconstruction complete. Read references/project-menu-scan.md before Studio import or resuming an authorized project.

Natural-language website replica entry

When the user says something equivalent to 复刻这个网站:<URL>, accept that as a complete normal entry command. Do not require them to enumerate pages, click every menu, record video, or take screenshots first. Codex owns discovery, safe browser operation, capture coordination, evidence compilation, generation, replay, and parity reporting.

Before control begins, infer a conservative same-origin scope from the supplied URL and state it briefly. Proceed without another planning interview for public or otherwise authorized read-only UI. Pause only when the next action would authenticate, purchase, pay, delete, publish, submit a real form, upload private data, send a message, change an account, cross to an unapproved origin, defeat an access control, or exceed the agreed exploration budget.

Use a state graph rather than a flat page list. Give every run, journey, screen, state, action, frame, and generated node a stable identity. Capture before-action, pressed/open, transition, and settled evidence when those states are visible. A state is settled only after two consecutive observations are visually stable; do not capture arbitrary timer frames and call them states. Deduplicate equivalent states, preserve route and viewport provenance, mask dynamic/private regions, and produce an explicit coverage report so Codex can resume without repeating the whole website.

Use two acquisition profiles:

  • blind-visual is the default for competitor, benchmark, AI-generated, or source-blind work. Drive only the visible UI using screenshots, coordinates, and user-visible labels. Do not inspect DOM, CSS, JavaScript, network payloads, source maps, hidden accessibility content, or downloadable site assets.
  • authorized-semantic may use visible roles and accessible names to make navigation more reliable when the user explicitly authorizes semantic browser assistance. It still must not inspect or copy implementation source unless source-aware integration is separately authorized.

QingLu is an optional motion observer, not the coordinator and not a prerequisite for normal website capture. Deterministic browser screenshots and browser action records are the primary geometry and destination evidence. Use QingLu video only to supplement pointer cues, timing, transition tracks, or proof that a trigger opened a specific destination. A supported manual or automated recording is acceptable; a dedicated QingLu control bridge is not required. If video is absent or cannot be aligned confidently, continue and mark the related evidence inferred or unknown rather than inventing motion. Read references/interaction-motion-evidence-v1.md and references/codex-website-capture.md. Read references/capture-control-protocol-v1.md only when the user explicitly requests a separate programmable capture bridge.

Source-blind evaluation mode A

When the user is testing screenshot-to-UI ability, explicitly asks not to scan source, or supplies an AI-generated/competitor screenshot without authorizing project inspection, run Mode A: source-blind reconstruction. This is a hard evaluation boundary, not a preference.

Allowed inputs are limited to the supplied image files, their dimensions, the user-visible prompt, the requested viewport, an explicitly supplied reference URL, an explicitly requested framework, and generic Skill templates or public dependencies. For screenshot-only tests, do not open a hidden implementation in a browser. For URL-driven blind-visual capture, the rendered pixels and explicitly performed visible interactions are allowed reference evidence, but DOM, HTML, CSS, JavaScript/TypeScript, network payloads, hidden accessibility content, components, routes discovered from source, downloaded site assets, design tokens, source maps, build output, prior generated answers, UI Documents, Studio revisions, identity registries, and hidden-project baselines remain forbidden. Do not use Use project reference, same-origin DOM calibration, repository search, or project-aware companion skills.

Generate into a new empty evaluation directory outside the hidden project's tree. Record a short provenance manifest containing the allowed image paths, viewport, requested stack, tools used, and a declaration that project source was not inspected. Complete evidence extraction, UI-spec compilation, source generation, browser rendering, screenshot comparison, and correction using only the supplied visual references. The generated source may be compared against those same supplied screenshots; it must not be compared against a render, DOM snapshot, or asset taken from the hidden implementation.

Freeze the generated source, rendered screenshots, metrics, and manifest before revealing or opening the hidden project. Only after that freeze may a separate evaluation phase inspect ground truth, calculate parity, or diagnose misses. Never repair the frozen Mode A result with leaked ground-truth facts and still report it as the same blind test.

Mode A ends when the user explicitly authorizes integration. At that point start a separately labeled integration phase; do not retroactively treat project-derived improvements as blind reconstruction performance.

Resume protocol

When the user says “continue”, “继续”, “sync Studio”, or otherwise resumes an existing UI job, do not restart or ask them to repeat visual adjustments. Run python scripts/ui_job_status.py <target-project> first, then continue from its nextAction:

  • prepare-ui-contract: declare the mandatory page, journey, viewport, browser, design, Studio, and roundtrip contract.
  • complete-position-evidence: finish and validate the existing draft map.
  • compile-ui-spec: compile ready position evidence into the deterministic generation contract.
  • complete-approved-state-evidence: create a ready map and compiled UI spec for every approved state.
  • generate-and-record-source: generate source from every covered UI/interaction spec and record hashes.
  • scan-project-menu: start the current production project on loopback and run python scripts/scan_project_menu.py <target-project> --url <loopback-production-url>; do not manually create or repair the menu tree.
  • finalize-ui-to-studio: run python scripts/finalize_ui_to_studio.py <target-project> so the current generated UI and its stable identities become the actual editable Studio document without replacing production source.
  • apply-studio-revision: read and apply saved Studio semantic operations.
  • refresh-studio-base: bring Studio forward after direct source changes.
  • run-browser-journey-qa: replay every contract journey and required viewport on the real project.
  • run-design-director-review: finish hierarchy, icon, responsive, interaction-polish, and parity sign-offs with zero P0 issues.
  • verify-studio-roundtrip: prove Studio save, Codex apply, real preview, clean sync, and rollback.
  • run-delivery-gate: execute the aggregate hard gate before handoff.

Read project files, not chat memory or browser local storage, to determine the current state.

For a Studio-enabled project, ui_job_status.py chooses the phase, while npm run sync:context is the authoritative latest-UI intake. Never apply a pending Studio revision if its identity status is invalid, it contains duplicate IDs, its target IDs no longer resolve, or its source hash conflicts.

Outcome contract

Deliver working source code, not a prose-only design specification or a screenshot embedded as the page.

  • Reuse the existing framework, component library, tokens, assets, routing, and package manager when a project exists, except in source-blind Mode A.
  • Make the visible page accurate at the supplied viewport and make nearby widths behave sensibly.
  • Implement visible interactions and states when they can be inferred; mark genuinely unobserved behavior as an assumption.
  • Run the relevant build, typecheck, lint, and tests available in the repository.
  • Render the page, compare it with the reference, and complete at least one correction pass unless a technical blocker prevents rendering.
  • Do not claim pixel-perfect parity without browser screenshots at matching viewport dimensions.

Source-first hard rule

Treat source as the product and screenshots as evidence only.

  • Always create real HTML/CSS/JavaScript, framework source, components, assets, and configuration in the target project.
  • Never present a PNG/JPG, editor screenshot, or screenshot-backed page as the primary deliverable.
  • In a projectless task, also provide a source archive; provide a self-contained HTML file when the result can run without a build step.
  • Put source links, the runnable entry point, and the run command before any preview image in the handoff.
  • Make Studio save/export produce a source patch, source files, or a versioned UI document consumed by production components. Browser-local state alone is not a completed export.
  • Reopen the exported clean page and verify that it works without editor chrome or the reference image.

Choose the delivery mode

Use code mode by default: generate maintainable UI source with centralized tokens and editable component props.

Use professional studio mode when the user asks to drag, resize, change proportions, tune visual parameters, edit layers, finish the last 5%, or work like Photoshop/Figma/Pixso/MasterGo. Deliver both clean production source and a development-only editing workspace. Read references/visual-editor-mode.md and references/ui-document-schema.md before planning it.

When the goal is “generate accurately, then let me fix small offsets myself,” use both modes in sequence: code mode produces the first runnable reconstruction; Studio mode is the adjustment surface over real generated nodes. Studio is not a screenshot tracer and must not be the only deliverable.

Keep the Studio sidebars human-centered. The left workspace should present the current task, searchable real objects, and meaningful context; hide stable IDs and HTML tags behind an optional developer toggle. Preserve each feature's selection and scroll position, and use hover to reveal the corresponding canvas object without changing selection. Track one deepest semantic hover target explicitly; never style every matching :hover ancestor, because nested parent/child outlines create misleading double borders. The right inspector must adapt to the selected object, prioritize typography for text and replacement for icons, keep advanced sections collapsed, and move source details into a Developer section. Do not expose every generic CSS control at once.

scripts/scaffold_studio.py is an engine installer for maintainers and empty prototypes; it is not the generated-UI handoff. For a real reconstruction, first record the current generated source, then run scripts/finalize_ui_to_studio.py <target>. The finalizer refuses stale source hashes, duplicate or dynamic identities, empty imports, starter substitution, source mutation during installation, incomplete identity coverage, or unclean initial sync. It writes .ui-job/studio-installation.json only after the actual generated UI is connected. Treat --force-template as an editor-engine refresh only: it must never overwrite production index.html, styles.css, app.js, package.json, ui-studio-overrides.css, or ui-studio-structure.js. Compare protected source files byte-for-byte before and after forced installation, and fail the handoff if any changes. reference.png is optional: overlay comparison stays unavailable until a reference is supplied, while the Recognition workspace can still accept PNG/JPG/WebP uploads.

When the user expects a new screenshot to become editable structure automatically, read references/screenshot-recognition-v4.md. Start with the bundled recognition workspace: upload the screenshot, review evidence-backed candidates, auto-triage high-confidence structure only as a proposal, and keep ambiguous items in the human queue. Auto-triage is never Human approval. Before writing UI Document V4, every accepted node—including page and exact-DOM candidates—must have explicit humanConfirmed evidence, the review queue must be empty, the accepted-only graph must pass, and the user must confirm the final summary. Treat screenshot intake as a quality gate: persist source dimensions, viewport compatibility, low-detail/blur and compression risk, likely browser chrome, and later OCR-detected system overlays. Known activation watermarks and top-edge address-bar URLs must be recorded and excluded from editable text layers rather than silently becoming production UI. Pixel structure detection is a first pass, not proof of 95% fidelity. Evidence-aware noise suppression may exclude tiny Pixel-only edge fragments, but DOM, OCR, or Human evidence must override that hint. After explicit same-origin DOM fusion, it may also absorb a long thin Pixel-only border fragment only when one exact DOM edge or a union of collinear exact DOM edges covers at least 72% of its long axis within a 12px source-space tolerance; record the target IDs, direction, overlap, and distance, and never suppress a thin line merely because of geometry. Precise analysis must automatically attempt an available bounded OCR adapter and report its running/ready/unavailable state. Use the browser adapter first, then the loopback-only local cascade: Windows Media OCR on Windows and an already-installed Tesseract CLI elsewhere. Process only a short-lived local PNG, remove it after recognition, do not silently call a remote OCR service, and do not auto-download large OCR models. OCR JSON is an Advanced fallback, never the primary consumer workflow. The bundled semantic layer can import bounded OCR JSON, infer Flex/Grid and repeated structures, and—when a same-origin production page already exists—calibrate visible screenshot candidates against real data-ui-id DOM nodes. Choosing Use project reference is explicit provenance confirmation and permits Precise analysis to auto-fuse compatible DOM, text, and layout evidence; arbitrary same-size uploads must not auto-calibrate. DOM calibration requires both explicit provenance and a matching canonical pixel fingerprint; dimensions alone only make the adapter eligible. DOM calibration is strong evidence for that known page, not a substitute for screenshot-only recognition. Recognition commits must use schema-valid lowercase kebab-case operation types such as analysis.generate-editable-layers; reject unknown or legacy camelCase operation names before writing a revision.

Evidence fusion must preserve one stable candidate identity across Pixel, OCR, Layout, DOM, and Human inputs. A repeated generation of the same screenshot identity must update the same generated node IDs instead of appending timestamp-derived duplicates; keep new reference/run IDs for audit while persisting a stable sourceKey and candidate-to-node identity record. Never replace the whole pixel result with DOM nodes or label every detected rectangle as layout-supported. Add Layout provenance only when a real layout or repetition hint exists, merge exact DOM facts into matching candidates, deduplicate only high-overlap compatible objects, repair child parents, and run an accepted-only parent/cycle audit before enabling Generate editable layers.

Normalize OCR into semantic lines before fusion: merge only close baseline-aligned horizontal fragments, preserve vertically distinct title/subtitle layers, and allow one OCR line to consume at most one pixel text candidate per pass. Record raw blocks, coalesced lines, matches, and newly created text nodes. Tighten non-authoritative parents to the smallest geometrically valid container while preserving explicit Human and exact DOM parent choices. Detect repeated siblings from parent, type, shape similarity, and row/column alignment, including repeated frames and controls. Human merge must redirect removed-node children to the retained stable candidate; Human split must use deterministic candidate-derived IDs, prefer real child-content gaps, redistribute children spatially, and keep both results in review. Never use timestamps as generated layer identity.

Diagnose same-parent overlap as an explainable conflict, not a bare count. Record both identities, IoU, semantic compatibility, evidence strength, Human protection, severity, reason, and a conservative recommendation. The inspector must let the user locate the other candidate, merge probable duplicates, keep both, or exclude a clearly weaker Pixel-only candidate. Persist keep-both and explicit exclusion resolutions so re-analysis does not reopen them. Human-confirmed candidates are never auto-merged or auto-excluded, Smart triage never auto-merges, and unresolved duplicate/weak-evidence blockers must prevent editable-layer generation.

The editor must manipulate real DOM components and layout parameters. It must not edit a flattened screenshot or ship editor chrome in the production bundle.

The professional canvas must use a separate, persistent camera over an infinite-feeling workspace. Empty-workspace drag, Space + primary drag, and middle-button drag move only that camera, allowing the page frame to be placed anywhere around the visual center without changing production coordinates or creating a source revision. Mouse middle-button drag is direct one-to-one movement with no release inertia; momentum is reserved for touch input so modifier keys cannot make the frame fly away. Keep cursor-centered zoom, selection overlays, rulers, guides, snapping, and saved UI state aligned after every camera move.

Make the camera feel like a professional design tool rather than a scroll container. Unmodified wheel/touchpad input pans the camera, Shift-wheel pans horizontally, and Alt+wheel zooms around the cursor. Never intercept Ctrl/Cmd+wheel because the browser owns that gesture. While a pointer pan is active, lock out wheel zoom until release. Show a compact transient camera HUD only while manipulating or locating the view; include zoom and frame offset, then fade it quickly. Programmatic “locate selection” movement may use a 160–180ms ease-out transition, but it must be canceled immediately by pointer, wheel, Space-pan, or another camera command. Keyboard-initiated camera actions remain instant. Use the actual rendered iframe scale for wheel coordinates. Provide a persistent compact “return to canvas” toolbar action, Ctrl/Cmd+0, and double-click on black empty workspace as equivalent recovery paths; do not rely on a range slider as the only zoom control.

Normalize every iframe-origin pointer sample into parent viewport coordinates before applying middle-button or hand-tool panning. The iframe moves under the pointer while the canvas scrolls, so using iframe-local clientX/clientY directly creates a feedback loop and runaway drift. Pointer capture must belong to the document where the gesture started, Alt state changes during an active middle-button gesture must not restart or reinterpret the gesture, and mouse panning must never add momentum. Keep panel collapse controls as 44px seam-attached chevron targets rather than floating glass blocks, and preserve the current canvas camera when either side panel or feature workspace changes.

Treat rulers and guides as one persistent visibility system. Rulers remain fixed to the top and left of the canvas viewport while their ticks track the rendered UI scale. Render interactive guide hit areas in the parent canvas overlay, not inside the preview iframe, so guides remain grabbable across document boundaries. Use an invisible 9–12px hit corridor around a one-pixel guide, show position feedback on hover or drag, and delete a guide when the user drags it back into its originating ruler; retain double-click deletion as a secondary shortcut.

Keep rulers fixed to the top and left edges of the canvas viewport, outside the scrollable world. Tick spacing and tick origin must update from the same camera zoom and scroll state on every animation frame. Dragging down from the top ruler creates a horizontal guide; dragging right from the left ruler creates a vertical guide. The ruler/guide visibility command hides the complete ruler overlay without changing document coordinates. Axis snap lines may appear during alignment, but do not draw a permanent crosshair over the selected UI.

Treat the left shell as two independent regions: a persistent feature rail and a collapsible contextual workspace. Collapsing the left content must keep the feature rail visible and clickable; choosing another feature while collapsed reopens the contextual workspace and switches its content. Use quiet split-view buttons with a familiar pane glyph, compact fixed hit area, delayed tooltip, and restrained state color rather than oversized protruding arrows.

In Studio, require semantic two-way correspondence between the rendered page and the layer tree. Visible menus, icons, labels, title/subtitle pairs, and controls need human-readable names plus stable IDs; clicking the page must reveal the exact matching tree node. Include whole/section/atomic selection scopes and overlapping type filters so a menu icon can be found as both a menu child and an icon.

Treat every route/page adapter bundled with the Studio template as optional metadata, never as a layer filter gate. A newly generated project may use any safe stable data-ui-id namespace. On every iframe load, rebuild the tree from the current production DOM; when no recognized route adapter applies, fall back to the complete real parent/child identity hierarchy and keep orphaned-but-valid identities visible at the root. The visible tree count must equal the current identity coverage before search/type filtering. Clear stale selection IDs after a page swap, derive the page label from current page metadata/title, and fail the Studio gate if a non-empty identity registry produces an empty unfiltered tree. Never display an old task's page name or a successful editable state when the preview and identity registry do not match.

Localize the layer tree from the imported UI, not from Studio's own locale and never from raw generator metadata. Detect the rendered page language from lang and visible text, then name each layer in this priority: visible direct text, accessible name/alt/title/placeholder, nearest labeled control context, meaningful same-language data-ui-name, and finally a localized semantic kind. Generic technical names such as Root, Icon, Container, Header, HTML tags, and stable IDs must never be the primary consumer-facing label on a non-English page. An icon without its own label inherits the nearest visible control or menu label plus the localized icon suffix; unresolved repeated generic layers receive stable human numbering. Preserve brand text and mixed-language copy when it is actually visible. Keep the stable ID and tag only in optional Developer information. Rebuild these labels after every iframe page swap, and fail the Studio contract if a page dominated by CJK text still exposes generic English tree labels.

Treat typography and frames as design-system objects. Text edits must include content, reusable font stacks, weight, size, line height, letter spacing, alignment, and export; frame edits must include fill, stroke, radii, opacity, rotation, and shadows. If providing free fonts, record the upstream source and exact open license, detect local availability, and keep safe fallbacks rather than embedding unverified binaries.

For the Studio shell, prefer a single-row professional command bar with functional zoning and visible priority. Keep viewport/zoom, core selection tools, snapping, preview, save, and main source export directly accessible; make save/export and the primary snap mode larger than secondary tools. Consolidate low-frequency CAD, reference comparison, resources, reset, focus/fullscreen, and secondary export commands into labeled popovers. At 1024 desktop width, compact controls without page-level overflow or lost functions.

Treat feature switching as a context change, not a camera-navigation command. It may update selection, the object list, and the inspector, but it must preserve zoom, pan, scroll position, and the world point currently visible on screen. If reopening a collapsed context pane changes the canvas viewport bounds, compensate for that screen-space shift instead of refitting or recentering the canvas. Only an explicit object-row activation, Locate action, or Return to canvas command may move the camera.

Before Studio is generated or reopened, Codex MUST start the latest real project on loopback and run scripts/scan_project_menu.py. The scanner uses isolated Playwright safe replay, visible localized labels, stable project identities, and real production DOM counts. It writes atomically and preserves the last valid manifest when scanning fails. Never replace this scan with remembered chat labels, placeholder cards, or a hand-written menu list.

For applications with several kinds of editable objects, add a feature-driven split view in front of the raw layer tree. Use a narrow, always-visible left rail with consistent line icons and short labels such as Screenshot to UI, Structure, Icons, Text, Frames, Compare, and Deliver; keep primary editing domains together and pin diagnostics/delivery to the end of the rail. Before Studio is generated or reopened, Codex MUST scan the latest real project navigation, routes, nested menus, and reachable states; stale menu manifests are a blocking error, not an optional follow-up. Do not create separate competing “Menu” and “Layers” workspaces, page cards, tabs, or a second page switcher. Structure MUST remain one persistent, localized, recursive project tree: page/menu rows stay visible and their real editable layers expand inline beneath the owning row. A single click on the row body activates only that real application page/state, updates the center UI, preserves the canvas camera, and does not enter layers, select the route trigger/page root, draw a whole-page frame, or create an undo entry. A double-click on the row body, or a single click on its dedicated live layer-count/chevron disclosure, activates the page if needed and expands or collapses its layers in place. Nested submenus obey the same interaction recursively. Never replace the menu directory with a separate layer page and never require a back-to-directory control. Page activation, menu expansion, and child-layer selection are three independent states. Show live counts from the current production DOM; background scans may show an explicit scanning state, but placeholder, stale, or invented counts are forbidden. Restore only a still-valid remembered child selection, page-local expansion state, and tree scroll; reopen its ancestors so the selected row cannot remain hidden. Mark routes as current, bound, unbound, or loading rather than inventing unavailable screens, and surface a binding error without destroying the persistent tree when activation fails. Switching pages must rebuild that branch from the page's current production DOM while leaving unrelated branches and the canvas camera stable. The adjacent context pane must have one clear title, search, compact labeled settings, and a dominant object/tree list. Do not stack several equal-weight segmented controls above the tree: selection scope and content filtering are different concepts and should be separate labeled pop-up/select controls. Each feature must automatically select or reveal a sensible real DOM object on the center canvas and switch the right inspector to the matching contextual tools. Make the split view collapsible and width-resizable with bounded responsive defaults and a recoverable reset. Icon mode must expose the safe icon-site/import/restore workflow; text mode must elevate content and licensed open fonts; compare and delivery modes must have dedicated controls. Preserve the accepted canvas-core contract while changing this shell information architecture.

The bundled Studio also includes a safe icon-name/JSON/SVG importer. When a user wants icons from Iconify, Icônes, or a compatible catalog, keep each icon as an atomic svg[data-ui-id] layer. The primary path must accept a copied Iconify name such as tdesign:abstract-filled, including extraction from noisy whole-page copied text; JSON and raw SVG are advanced fallbacks. Show a contextual three-step flow—confirm target, paste name, inspect and replace—with automatic preview, actionable inline failure recovery, and no prerequisite knowledge of JSON. Persist the sanitized SVG replacement through undo, drafts, JSON, and clean source export. Follow the icon-library requirements in references/visual-editor-mode.md; never paste untrusted SVG into production without the allowlist sanitizer.

When users expect repeated Studio edits and Codex source edits to stay synchronized, read references/codex-studio-roundtrip.md. Require project-file revisions, stable IDs, source hashes, constrained writes, preflight checks, and explicit conflict handling. Safe visual parameters may update the single generated ui-studio-overrides.css preview patch immediately, but previewRevision and canonical appliedRevision must remain distinct until Codex absorbs the change. Never imply that browser localStorage, a downloaded file, or a changed preview automatically wakes a Codex task.

Exact real-project preview must propagate the saved preview revision into the nested production-entry URL, reload from the loopback project server, and label previewRevision separately from canonical appliedRevision. It may include the saved generated preview patch, but never unsaved browser state; describe that boundary accurately in the UI so the user knows what Codex still needs to formalize.

If sync:context reports a conflict, inspect sync:changes; use npm run sync:resolve-safe only for a current, previewed, stable-ID-resolved visual-only revision. The command must reject newly pending text, icon, or structural changes. Run npm run sync:refresh-generated after changing the override generator so a clean document can rebuild its generated assets without inventing a revision. Generated Studio declarations must win over host component selectors; verify the resulting computed styles in the clean production page, not only the generated CSS text.

The bundled Studio template includes the loopback-only project bridge, UI Document V4 migration, screenshot evidence storage, semantic operation history, stable identity registry, canvas-core and shell regression contracts, a dedicated visual-diff workspace, a weighted 95% acceptance gate, exact and responsive real-project previews, append-only revision restore, a frame-coalesced direct-manipulation engine, and Codex apply commands. The canvas overlay must use actual rendered iframe scale plus canvas scroll, not a cached zoom multiplier. Treat all four visible selection borders as forgiving 20–28px fixed-screen-space resize hit zones in addition to the eight handles: top/bottom resize height, left/right resize width, opposite edges remain anchored, corner handles keep higher hit priority, and an 18px proximity fallback resolves near-border gestures to resize even when a transparent child surface wins the event target. This must remain usable above 120% zoom when the opposite handle is outside the viewport. Selected form controls remain directly draggable in design mode; selected descendants route to their active ancestor, and one separated name pill replaces overlapping move labels. The exact edge or handle that receives pointer-down must retain pointer capture until release, keep its native directional cursor locked across the editor, remain visibly active during every redraw, and preserve the selection chrome mode until the gesture ends. Gesture completion must be idempotent and must finalize on pointerup, pointercancel, lostpointercapture, window mouseup, window blur, or a mouse move reporting buttons === 0; every exit path must remove transient classes and listeners, commit at most one history entry, and repaint from one authoritative rendered DOM measurement. Keep live width and height state in the gesture's shared scope so move-only and resize-only branches cannot lose geometry before the animation frame paints. At small rendered sizes, hide inactive midpoint handles but retain corners and non-collapsing full-edge resize zones. Reject non-finite overlay snapshots so the UI never shows NaN × NaN. During move or resize, approaching a canvas edge must progressively auto-pan the camera in that direction while adding the real camera distance back into the geometry delta; use a fixed screen-space activation zone, a capped quadratic speed curve, requestAnimationFrame coalescing, and pointer capture. Each animation frame must be a layout-read-free transaction: apply camera scroll, compute the fractional document delta, mutate only the real DOM geometry properties needed by the gesture, predict the selection rectangle from the immutable pointer-down snapshot, and paint it immediately. Do not round live X/Y/W/H to whole document pixels at low zoom. Suppress the normal scroll-triggered overlay scheduler during manipulation, and update only the five geometry inputs rather than rebuilding the full inspector, tree, sync status, style sections, or clearing and reapplying unrelated styles. Perform exactly one authoritative rendered-bound measurement and opposite-edge correction on release. Auto-pan changes camera state but must not create a source revision or a second undo entry. Exact preview renders the real project at the editor's CSS viewport; responsive live preview is a separate mode and must not be used as matching-dimension parity evidence. After scaffolding, start it with npm run studio:start. Before Codex edits a Studio-enabled project, run npm run sync:context, then npm run sync:changes; apply a reviewed pending revision with npm run sync:apply; after direct source edits, run npm run sync:source-updated. Verify it with npm run studio:check, npm run studio:check-canvas, npm run studio:check-sidebars, npm run studio:check-multi, npm run studio:check-history, npm run studio:check-foundation, npm run studio:check-document, npm run studio:check-analysis, npm run studio:check-fidelity, npm run studio:check-controls, npm run studio:check-motion, npm run studio:check-preview, and npm run studio:check-sync.

The bundled shortcut layer supports undoable Delete/Backspace, Ctrl/Cmd+Z and redo variants, stable-ID copy/cut/paste, appearance-only paste, F2 semantic rename, visibility/lock commands, Ctrl/Cmd+J true duplication, and Alt-drag true duplication. Alt-drag must create the duplicate before the move, preserve fresh IDs for every descendant, and commit insertion plus geometry as one undoable gesture. Shift-dragging empty canvas performs marquee selection. Ctrl/Cmd+[ or ] changes stacking by one level, Shift sends the selection to the back/front, Ctrl/Cmd+Alt+Arrow aligns selected objects to an edge, and Ctrl/Cmd+Alt+H/V distributes them. Ctrl/Cmd temporarily bypasses snapping during a move, while resize retains its existing modifier behavior. True duplicates must persist as validated structuralEdits.insertions, replay before application code binds interactions, update the live project preview, and remain in clean source export; never substitute an editor-only DOM clone.

Workflow

1. Inspect every reference

Use the highest-detail local image inspection available. Record the source dimensions and, when known, the intended viewport. If the input is a contact sheet or contains multiple screens, separate the screens conceptually before implementation.

Read references/ui-analysis.md and build its evidence map. Distinguish visible facts from inferences. Do not invent hidden screens, interactions, breakpoints, or assets.

Persist the screenshot and initialize its evidence map with scripts/prepare_ui_job.py before implementation. Use source-space coordinates, validate the completed ready map with scripts/validate_evidence_map.py, then compile it with scripts/compile_ui_spec.py. Read references/ui-generation-spec.md before generating source. Do not rely on temporary clipboard paths or chat-only measurements that disappear between turns.

If an image is inaccessible or too low-resolution to identify essential content, ask for the missing image or state the limited assumption. Do not silently ignore a reference.

2. Choose the isolated target or inspect the authorized project

In source-blind Mode A, do not inspect the target project. Create a clean sibling evaluation directory, confirm it contains no copied project files, select the user-requested stack or the lightest viable default, and continue using only the compiled screenshot evidence.

Outside Mode A, inspect an authorized target project as follows.

Before editing, inspect repository instructions, the current tree, package scripts, routes, reusable components, design tokens, fonts, and public assets. Preserve user changes and avoid replacing working infrastructure.

Choose the implementation target in this order:

  1. The user's explicitly requested stack.
  2. The existing project's stack and patterns.
  3. For a new project, React + TypeScript with the lightest viable local setup.
  4. If dependencies cannot be installed, portable HTML, CSS, and JavaScript with no external runtime dependency.

Read references/implementation-and-qa.md when choosing a new stack, planning responsive behavior, or beginning visual validation.

3. Plan the visual system

Extract a small token set for colors, typography, spacing, radii, shadows, borders, and content width. Identify repeated UI structures and implement them as components. Map each supplied screen to a route, viewport, or state before coding.

Prioritize fidelity in this order:

  1. Page frame, major regions, alignment, and proportions.
  2. Typography, line wrapping, density, and spacing rhythm.
  3. Colors, borders, shadows, radii, and imagery.
  4. Micro-interactions and decorative polish.

In studio mode, also assign stable element IDs and express editable values through a structured UI model, component props, or centralized design tokens. Keep the final production components readable; do not turn the entire page into an unstructured list of absolute coordinates.

Map every major evidence item to a planned source node before coding. Split menu icons from labels, titles from subtitles, and controls from their containers so later Studio adjustments target the correct atomic object.

When the user asks for 95% automation, read references/fidelity-95-gate.md. Treat 95 as a weighted acceptance gate at the observed viewports, not an unsupported promise of universal pixel identity. Use the bundled Compare workspace for matching-dimension reference/render pairs, overlay, side-by-side, heatmap, blink, and ranked mismatch diagnosis. Its same-image self-test validates only the comparison engine; it is never project fidelity evidence.

Treat the editing-canvas reference image as a named, read-only calibration layer, never as an ambiguous toolbar action. Its compact control must expose an explicit checked visibility switch, a two-state layer-order choice (Reference above UI / UI above reference), a live reference-visibility percentage, and a short statement that calibration does not enter saves or exports. Default to Reference above UI because it is the clearest mode for checking position and dimensions. When UI above reference is chosen, use real reverse compositing by reducing only the editor iframe opacity while keeping the reference underneath; changing z-index alone is invalid because an opaque page would hide the reference. Disable layer and visibility-strength controls while the reference is hidden, persist all three settings locally, and keep selection chrome, guides, rulers, and exported production content above and independent of the calibration layer. Maintain one canonical writable control only: dedicated Compare panels may show its current state and link back to it, but must not duplicate legacy visibility buttons or opacity sliders. Visibility, layer-order, and strength adjustments are continuous calibration, so their popover stays open until the user clicks outside or closes it explicitly.

4. Implement maintainable UI

Use semantic HTML and accessible controls. Use CSS variables or the project's token system instead of scattering unexplained constants. Keep repeated data in arrays or structured objects and repeated visuals in components.

  • Reuse supplied and repository assets before creating substitutes.
  • Preserve legible reference text; use concise placeholders only for unreadable or user-specific content.
  • Avoid tracing the entire screenshot with absolute positioning. Reserve absolute positioning for genuine overlays or anchored decoration.
  • Do not crop the reference screenshot into large slices to fake components.
  • Do not add fashionable gradients, cards, icons, animations, or copy that are absent from the evidence.
  • Add focus, hover, pressed, selected, disabled, loading, empty, and error states only where the visible UI or normal function requires them.
  • Keep the first pass visually faithful before making optional product improvements.

5. Infer responsive behavior conservatively

Use supplied breakpoint images as primary evidence. With only one viewport, infer fluid behavior from constraints: fixed navigation, max-width containers, wrapping groups, intrinsic control sizes, and likely content priority.

Prefer a small number of evidence-based breakpoints. Do not shrink desktop UI uniformly. Reflow, wrap, collapse, or hide lower-priority content while preserving usable touch targets and readable text.

6. Run and verify

Use the repository's own commands. Fix errors introduced by the implementation. Start the page locally and capture screenshots at the reference dimensions; include mobile and desktop captures when both are in scope.

Compare reference and implementation using the loop in references/implementation-and-qa.md. Correct geometry before cosmetic details. Repeat until no material mismatch remains or further progress needs missing assets or user input.

When images have matching dimensions, run scripts/score_visual_fidelity.py to create diagnostic metrics and a heatmap. Do not use its numeric result as the only acceptance signal; complete the weighted gate in references/fidelity-95-gate.md.

In studio mode, verify selection, drag/resize, numeric property editing, aspect locking, undo/redo, responsive viewport switching, persistence, and clean export. At both fit zoom and above 120% zoom, drag a selected form control by its body, then drag each complete border near—but not exactly on—the visible 1px outline. Confirm that north/south change height while anchoring the opposite edge, east/west change width, the operation is recorded as resize rather than move, and no selection label ever shows non-finite dimensions. Move the opposite resize handle outside the viewport and confirm the currently visible border remains usable. Continue dragging that border into each canvas-edge activation zone and confirm the camera follows without breaking the anchored document geometry; one undo must restore the object edit without rewinding the camera. Confirm that an exported UI runs without the editor.

If the browser result still has small geometry differences, move the task into Studio instead of asking the user to explain offsets in prose. A saved Studio revision becomes the next source of truth for those adjustments.

After finalizing or materially changing Studio, run scripts/verify_studio_contract.py <target>. The verifier must fail when the production page, its local CSS/JS, or all stable data-ui-id nodes are missing. A structural pass is still insufficient for delivery: .ui-job/studio-installation.json must match the current source-generation marker and identity registry, and the browser roundtrip must prove selection, adjustment, save, actual-project preview, source application, and rollback. Still perform the browser interaction checks in references/visual-editor-mode.md.

7. Hand off a usable result

Before handoff, run python scripts/validate_delivery_gate.py <target-project>. A build, a homepage screenshot, or a passing Studio structural check cannot substitute for this gate. If it fails, continue from python scripts/ui_job_status.py <target-project> and report the exact missing contract deliverable rather than claiming completion.

Report:

  • What was implemented and where.
  • Direct links to source files or a source archive before screenshots.
  • The exact command to run it.
  • Which checks passed.
  • Which viewport screenshots were compared.
  • In studio mode, how to open the editor and how to export/apply adjustments.
  • Any assumptions, missing assets, or known visual differences.

Keep the handoff concise. Link to the runnable entry point and verification images when the environment supports file links.

If the handoff contains only an image, screenshot, mockup, or localStorage-only editor state, the task is not complete.

Stop conditions

Pause and ask for direction only when a choice would materially change the product, such as selecting among incompatible target frameworks, replacing an unavailable paid/proprietary asset, or inventing navigation and behavior not shown by the references. For minor ambiguity, make the smallest reversible assumption and continue.

Precision snapping rule

Snapping must be a low-force fixed-screen-space aid: acquire explicit guides only inside 3 screen pixels, structure edges inside 4 pixels, and dense grid points inside 2.5 pixels, then release within a small 4.5–6 pixel hysteresis band. Rank physical distance first and use semantic priority only for sub-pixel ties, deduplicate coincident targets, allow a clearly nearer target to break the sticky snap immediately, pass the real rendered scale for each axis, and retain Alt as a temporary bypass.