---
id: 05-runner-scan-and-preview-adapter
epic: walking-skeleton
title: runner scan stage + embedded-Vite preview adapter + canvas agent v0
type: technical-story
status: todo
feature: runner
depends-on: [04-runner-app-protocol-clone-install]
blocks: [07-runner-lifecycle-events-and-realtime]
created: 2026-07-12T10:24:14Z
---

## Goal

Complete `apps/runner`: a minimal react-docgen-typescript scan that returns ≥1 component (name + props) from the fixture, and an embedded-Vite preview adapter rooted at the clone that serves a Veect frame-host page — importing the component requested via `render-frame` and mounting the injected, Veect-authored canvas agent script v0.

## Why

This is invariant #1 made real: the component renders through the repo's own toolchain, not a Veect re-implementation (ADR-028 — no NodeRenderer on the board path). The agent script is the editor's only eyes inside the cross-origin iframe; it must be adapter-injected and never sourced from the repo (ADR-028 consequences — security floor even at fixture scale).

## Done when

- Scan stage runs react-docgen-typescript over the fixture's component glob and emits a scan-result message with ≥1 component carrying name + props (skeleton fidelity; full `ComponentMeta` comes with `discovery-and-library`).
- Preview adapter starts embedded Vite rooted at the clone on a dedicated port = dedicated origin (spec §9), serving a frame-host entry that imports the requested component with default props (`render-frame`) and mounts the agent script.
- Canvas agent v0 reports `runtime.ready`, component bounding boxes (post `fonts.loaded`), and click-target resolution; `targetOrigin` pinned in both directions (ADR-028).
- Agent script is Veect-authored and adapter-injected — never sourced from the repo.
- Protocol integration suite extends to: scan returns ≥1 component → adapter serves the frame host with the agent script → adapter origin liveness (PRD Success criteria).
- `pnpm typecheck && pnpm lint && pnpm test && pnpm conformance && pnpm fallow:audit && pnpm coverage:diff` all pass after each task.

## In scope

- Scan stage (react-docgen-typescript, minimal glob) + scan-result message.
- Embedded-Vite adapter, frame-host entry, `render-frame` handling, adapter-ready/status events.
- Canvas agent script v0 (ready, geometry, click-target resolution; pinned `targetOrigin`).
- Integration tests for scan payload, adapter origin liveness, and agent-script presence.

## Out of scope

- The editor-side canvas-protocol client (story 09).
- Watch/HMR, perf-500 budgets (`discovery-and-library`); Next.js adapter (`preview-and-nextjs-depth`).
- Multi-view frames, isolation, code panel (later PRDs).

## Tasks

- [ ] Add the scan stage: minimal react-docgen-typescript scan over the fixture's component glob → scan-result message with ≥1 component (name + props); integration test asserts the `Button` payload arrives over real WS.
- [ ] Add the preview adapter: embedded Vite rooted at the clone on a dedicated port/origin (spec §9), frame-host entry importing the component requested via `render-frame` (default props) and mounting the injected Veect-authored canvas agent script v0 (`runtime.ready`, bounding boxes post `fonts.loaded`, click-target resolution; pinned `targetOrigin` both directions; never sourced from the repo); adapter-ready/status events; integration test asserts adapter origin liveness and that the frame host serves with the agent script.
