@agent-native/core 0.80.9 → 0.80.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +13 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/production-agent.ts +108 -15
- package/corpus/core/src/cli/design-connect.ts +28 -2
- package/corpus/core/src/cli/skills.ts +45 -24
- package/corpus/core/src/client/AssistantChat.tsx +123 -26
- package/corpus/core/src/client/sse-event-processor.ts +9 -0
- package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +9 -2
- package/corpus/templates/assets/AGENTS.md +4 -0
- package/corpus/templates/assets/actions/_tool-activity.ts +46 -0
- package/corpus/templates/assets/actions/generate-image-batch.ts +26 -5
- package/corpus/templates/assets/actions/generate-image.ts +118 -67
- package/corpus/templates/assets/actions/list-draft-assets.ts +50 -0
- package/corpus/templates/assets/actions/rerun-generation-run.ts +52 -31
- package/corpus/templates/assets/app/components/create/RecentDraftsSection.tsx +100 -0
- package/corpus/templates/assets/app/i18n/zh-TW.ts +7 -0
- package/corpus/templates/assets/app/i18n-data.ts +61 -0
- package/corpus/templates/assets/app/routes/_index.tsx +4 -0
- package/corpus/templates/assets/app/routes/library.tsx +145 -38
- package/corpus/templates/assets/changelog/2026-06-29-image-generation-can-now-render-requested-text-and-respect-b.md +6 -0
- package/corpus/templates/assets/changelog/2026-06-30-image-generation-no-longer-looks-stuck-while-the-provider-is-still-working.md +6 -0
- package/corpus/templates/assets/changelog/2026-06-30-tagged-presets-now-control-the-image-aspect-ratio.md +6 -0
- package/corpus/templates/assets/server/lib/generation.ts +135 -11
- package/corpus/templates/assets/shared/api.ts +4 -0
- package/corpus/templates/clips/actions/list-ai-requests.ts +60 -0
- package/corpus/templates/clips/app/hooks/use-auto-title.ts +24 -25
- package/corpus/templates/design/DESIGN-STUDIO-PLAN.md +717 -0
- package/corpus/templates/design/actions/add-breakpoint.ts +143 -0
- package/corpus/templates/design/actions/add-localhost-screens.ts +5 -0
- package/corpus/templates/design/actions/apply-a11y-fix.ts +317 -0
- package/corpus/templates/design/actions/apply-component-prop-edit.ts +441 -0
- package/corpus/templates/design/actions/apply-design-state.ts +213 -0
- package/corpus/templates/design/actions/apply-design-token-edit.ts +202 -0
- package/corpus/templates/design/actions/apply-motion-edit.ts +413 -0
- package/corpus/templates/design/actions/apply-shader-fill.ts +404 -0
- package/corpus/templates/design/actions/apply-visual-edit.ts +191 -5
- package/corpus/templates/design/actions/capture-design-state.ts +224 -0
- package/corpus/templates/design/actions/connect-builder-app.ts +162 -0
- package/corpus/templates/design/actions/create-component.ts +447 -0
- package/corpus/templates/design/actions/create-design-branch.ts +263 -0
- package/corpus/templates/design/actions/create-design-state.ts +162 -0
- package/corpus/templates/design/actions/delete-design-state.ts +55 -0
- package/corpus/templates/design/actions/delete-design.ts +20 -0
- package/corpus/templates/design/actions/deploy-design-preview.ts +275 -0
- package/corpus/templates/design/actions/get-component-details.ts +251 -0
- package/corpus/templates/design/actions/get-design-branch-diff.ts +362 -0
- package/corpus/templates/design/actions/get-design-review.ts +314 -0
- package/corpus/templates/design/actions/get-design-surface-index.ts +582 -0
- package/corpus/templates/design/actions/get-motion-timeline.ts +99 -0
- package/corpus/templates/design/actions/index-components.ts +258 -0
- package/corpus/templates/design/actions/index-design-tokens.ts +277 -0
- package/corpus/templates/design/actions/list-design-extensions.ts +309 -0
- package/corpus/templates/design/actions/list-design-source-capabilities.ts +153 -0
- package/corpus/templates/design/actions/list-design-states.ts +90 -0
- package/corpus/templates/design/actions/migrate-inline-design-to-app.ts +298 -0
- package/corpus/templates/design/actions/open-component-source.ts +242 -0
- package/corpus/templates/design/actions/preview-component-prop-edit.ts +260 -0
- package/corpus/templates/design/actions/preview-design-token-edit.ts +113 -0
- package/corpus/templates/design/actions/preview-shader-fill.ts +187 -0
- package/corpus/templates/design/actions/remove-breakpoint.ts +103 -0
- package/corpus/templates/design/actions/remove-motion-timeline.ts +196 -0
- package/corpus/templates/design/actions/run-design-audit.ts +436 -0
- package/corpus/templates/design/actions/run-design-extension-action.ts +284 -0
- package/corpus/templates/design/actions/set-active-breakpoint.ts +39 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +1550 -82
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +649 -43
- package/corpus/templates/design/app/components/design/DrawOverlay.tsx +1 -1
- package/corpus/templates/design/app/components/design/EditPanel.tsx +1788 -52
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +114 -33
- package/corpus/templates/design/app/components/design/LocalSourceEditBanner.tsx +157 -0
- package/corpus/templates/design/app/components/design/MotionDock.tsx +1071 -0
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1053 -99
- package/corpus/templates/design/app/components/design/ReviewPanel.tsx +766 -0
- package/corpus/templates/design/app/components/design/StatesPanel.tsx +581 -0
- package/corpus/templates/design/app/components/design/TokensPanel.tsx +578 -0
- package/corpus/templates/design/app/components/design/canvas-primitive-style.ts +241 -0
- package/corpus/templates/design/app/components/design/index.ts +16 -0
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +15 -6
- package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +66 -3
- package/corpus/templates/design/app/components/design/inspector/InspectorAiActions.tsx +145 -0
- package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +42 -12
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +1 -1
- package/corpus/templates/design/app/hooks/useAgentEditRequest.ts +131 -0
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +3 -1
- package/corpus/templates/design/app/i18n/zh-TW.ts +32 -0
- package/corpus/templates/design/app/i18n-data.ts +280 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +3087 -490
- package/corpus/templates/design/changelog/2026-06-29-added-a-review-panel-in-the-design-editor-s-inspector-with-a.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-copying-and-pasting-layers-no-longer-shows-success-notificat.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-device-presets-in-all-screens-view-resize-the-selected-previ.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-layer-and-canvas-drags-keep-the-layer-list-stable-while-chan.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-layer-moves-can-be-undone-and-redone-without-flashing-the-ca.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-previews-use-a-single-blue-hover-border-in-all-screen.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-selected-containers-show-draggable-padding-and-gap-guides-on.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-the-design-editor-adds-a-studio-layer-with-tokens-respon.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-accessibility-findings-now-offer-a-one-click-fix.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-component-instances-now-have-editable-props-in-the-inspe.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-design-token-edits-now-stay-visible-in-previews-and-token-li.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-inspect-code-now-shows-the-elements-opening-tag-at-a-gla.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-shader-fill-presets-can-now-be-applied-to-an-element.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-the-motion-timeline-can-now-add-a-track-to-any-element-a.md +6 -0
- package/corpus/templates/design/changelog/2026-06-30-visual-editor-selection-layer-paint-and-drawing-controls-are-more-reliable.md +6 -0
- package/corpus/templates/design/e2e/global-setup.ts +94 -2
- package/corpus/templates/design/e2e/helpers.ts +10 -4
- package/corpus/templates/design/server/db/schema.ts +123 -0
- package/corpus/templates/design/server/plugins/db.ts +90 -0
- package/corpus/templates/design/shared/builder-app.ts +297 -0
- package/corpus/templates/design/shared/capability-resolver.ts +123 -0
- package/corpus/templates/design/shared/capture-sanitize.ts +70 -0
- package/corpus/templates/design/shared/code-layer.ts +1016 -71
- package/corpus/templates/design/shared/component-model.ts +274 -0
- package/corpus/templates/design/shared/design-review.ts +275 -0
- package/corpus/templates/design/shared/design-source-capabilities.ts +286 -0
- package/corpus/templates/design/shared/design-state.ts +112 -0
- package/corpus/templates/design/shared/design-surface-index.ts +258 -0
- package/corpus/templates/design/shared/motion-compiler.ts +349 -0
- package/corpus/templates/design/shared/motion-timeline.ts +193 -0
- package/corpus/templates/design/shared/resolve-tweaks.ts +32 -9
- package/corpus/templates/design/shared/responsive-classes.ts +452 -0
- package/corpus/templates/design/shared/shader-fill.ts +323 -0
- package/corpus/templates/design/shared/source-mode.ts +245 -0
- package/corpus/templates/plan/app/components/plan/CanvasArea.tsx +6 -2
- package/corpus/templates/plan/changelog/2026-06-29-plan-canvases-open-without-an-initial-pan-and-zoom-flicker.md +6 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +94 -10
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +28 -2
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +37 -21
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +14 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +115 -22
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +10 -0
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +8 -8
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,717 @@
|
|
|
1
|
+
# Code-Native Design Studio — Canonical Implementation Plan
|
|
2
|
+
|
|
3
|
+
> Converged plan, merged from two independent passes (Claude + Codex) and their
|
|
4
|
+
> cross-reviews. This is the single source of truth; implement from this doc.
|
|
5
|
+
>
|
|
6
|
+
> - **Product / runtime-tier spine** (the organizing principle).
|
|
7
|
+
> - **Capability matrix + preview/apply actions + application-state shape +
|
|
8
|
+
> atomic-motion guardrail + screenshot acceptance criteria** (the contract).
|
|
9
|
+
> - **Builder-hosted branch + `fusion` first; our own durable container later.**
|
|
10
|
+
> - **First cheap win: Tokens on the existing Tweaks loop + CSS-first motion on
|
|
11
|
+
> inline designs.**
|
|
12
|
+
>
|
|
13
|
+
> Visual source of truth: the published visual plan
|
|
14
|
+
> <https://plan.agent-native.com/plans/plan-88dc4a09fb0c46bc> (workbench, motion
|
|
15
|
+
> dock, tokens, states, review, extensions). Its artboards are the acceptance
|
|
16
|
+
> references for the panels below.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 0. Goal & thesis
|
|
21
|
+
|
|
22
|
+
Turn the Design template into a Figma-class editor where the canvas and the
|
|
23
|
+
codebase are two views of the same product. The thesis: **when a source can
|
|
24
|
+
safely support it, a visual edit writes real code, and a source edit shows up on
|
|
25
|
+
the canvas.** Keep the editor minimal and Figma-esque — left pages/layers,
|
|
26
|
+
central canvas, right inspector, and a bottom dock only when motion or review
|
|
27
|
+
needs it — and add code-backed components, tokens, motion, states/captures,
|
|
28
|
+
accessibility review, visual diffs, assets/shaders/plugins, and a real-app path.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 1. Runtime tiers (the organizing principle)
|
|
33
|
+
|
|
34
|
+
The editor already has a `sourceType` contract — `inline | localhost | fusion`
|
|
35
|
+
(`templates/design/shared/source-mode.ts`). Treat those as **two capability
|
|
36
|
+
tiers**:
|
|
37
|
+
|
|
38
|
+
### Tier A — Inline (HTML + Alpine), zero-setup
|
|
39
|
+
|
|
40
|
+
A design is a sandboxed iframe of semantic HTML + Tailwind + a little Alpine,
|
|
41
|
+
stored in SQL (`designs.data`, `design_files`, rendered via `srcdoc`). No build,
|
|
42
|
+
no module graph, no TypeScript, no real routes/server. This is the instant,
|
|
43
|
+
shareable, "open a URL and design" on-ramp and the default.
|
|
44
|
+
|
|
45
|
+
### Tier B — Real app (localhost **or** fusion / Builder)
|
|
46
|
+
|
|
47
|
+
A design is backed by a real React/TS codebase.
|
|
48
|
+
|
|
49
|
+
- **`localhost`** — the bridge talks to a dev server on the user's machine
|
|
50
|
+
(`designLocalhostConnections`, `connect-localhost.ts`).
|
|
51
|
+
- **`fusion`** _(the new hosted tier)_ — connect Builder.io and run the app as a
|
|
52
|
+
Builder-hosted branch (today) or, later, our own durable container. Same
|
|
53
|
+
capabilities as localhost but hosted, collaborative, and deployable.
|
|
54
|
+
|
|
55
|
+
> `localhost` and `fusion` are the **same "real app" capability tier** seen
|
|
56
|
+
> through two transports. Everything gated to "real apps" works in both; the only
|
|
57
|
+
> difference is where the code lives.
|
|
58
|
+
|
|
59
|
+
### 1.1 Tiers are coarse; capabilities are the real gate
|
|
60
|
+
|
|
61
|
+
The UI must **never infer write ability from `sourceType` alone.** Each source
|
|
62
|
+
advertises an explicit capability set, and every control reads it. A control is
|
|
63
|
+
**enabled**, **preview-only / read-only**, or a **migration CTA** purely as a
|
|
64
|
+
function of capabilities. This is what stops the agent or UI from ever promising
|
|
65
|
+
a write the bridge can't perform (localhost can read but not write _yet_; `fusion`
|
|
66
|
+
starts preview-only until its bridge is real). The tier table in §2 is the
|
|
67
|
+
_consequence_ of these capability sets, not a parallel switch. The capability
|
|
68
|
+
matrix is defined in §5.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 2. Feature tiering — Alpine vs. real app
|
|
73
|
+
|
|
74
|
+
| Capability | Inline / Alpine | Real app (localhost / fusion) | Why |
|
|
75
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | ----------------------------- | ------------------------------------------------ |
|
|
76
|
+
| Reusable blocks / Alpine "components" — annotate a DOM subtree or `Alpine.data()` island; simple `x-data` variants | ✅ (kept deliberately **light**) | ✅ (superset) | Pure markup |
|
|
77
|
+
| **Full code components** — prop tables from TS / `cva` / `tailwind-variants`, Storybook variants, instance outlines, **jump to source**, edit canonical component, detach | **Real app** → CTA | ✅ | Needs module graph + TS types + multi-file edits |
|
|
78
|
+
| Tokens — live CSS-var editing (friendly swatches for the design's own `:root` vars) | ✅ | ✅ | Design owns its CSS vars |
|
|
79
|
+
| **Tokens-as-code** — parse `globals.css` / `tailwind.config` and **write back to source** | **Real app** → CTA | ✅ | Auto-parse + source write-back needs real files |
|
|
80
|
+
| **Motion** — multi-layer keyframe timeline → managed `<style data-agent-native-motion>` block | ✅ | ✅ | CSS is the runtime truth; works on any HTML |
|
|
81
|
+
| Motion source export — write to real CSS modules / `motion`-react two-way / Dev Mode export | **Real app** → CTA | ✅ | Two-way code round-trip needs real files |
|
|
82
|
+
| Responsive / breakpoints | ✅ | ✅ | CSS media queries |
|
|
83
|
+
| Simple design states (logged out, empty, loading, error) as alternate `x-data` / DOM | ✅ | ✅ | Markup snapshots |
|
|
84
|
+
| **Data fixtures & live captures** (real running-app data, route, props, API) | **Real app** → CTA | ✅ | No live data on a static design |
|
|
85
|
+
| Accessibility audit (contrast, tap targets, roles, alt) | ✅ | ✅ | Reads the rendered DOM |
|
|
86
|
+
| Version diff (`design_versions`) | ✅ | ✅ | SQL versions already exist |
|
|
87
|
+
| **Real branches + PRs + deploy** | **Real app** → CTA | ✅ | Needs git + branch + deploy |
|
|
88
|
+
| Extensions / shaders / asset library | ✅ | ✅ | Extensions are the Alpine substrate |
|
|
89
|
+
| Semantic a11y fixes in code; plugins needing the app's own APIs/build | **Real app** → CTA | ✅ | Needs real source / build |
|
|
90
|
+
|
|
91
|
+
**The one-line rule:** if a feature only needs the **rendered DOM or the design's
|
|
92
|
+
own HTML/CSS+SQL**, it ships in Alpine. If it needs the **module graph, TS types,
|
|
93
|
+
a real build, real routes, server data, or git/deploy**, it's a **real-app**
|
|
94
|
+
feature behind a Connect-Builder CTA. _Motion crosses into Alpine because we make
|
|
95
|
+
it CSS-first._
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 3. The "Make it real" upgrade flow (Connect Builder)
|
|
100
|
+
|
|
101
|
+
Advanced panels are never dead ends; they are CTAs. On an inline design, the
|
|
102
|
+
gated controls render an inline upgrade card (progressive disclosure — only when
|
|
103
|
+
the user reaches for a real-app feature):
|
|
104
|
+
|
|
105
|
+
> **Make this a real app** — connect Builder.io to unlock components, props, data
|
|
106
|
+
> states, branches, and deploys.
|
|
107
|
+
|
|
108
|
+
### 3.1 What already exists vs. what's new
|
|
109
|
+
|
|
110
|
+
Most of the backend exists. The genuinely-new pieces are small:
|
|
111
|
+
|
|
112
|
+
1. **Connect** _(exists)_ — the `connect-builder` card
|
|
113
|
+
(`packages/core/src/server/agent-chat-plugin.ts`, `kind:
|
|
114
|
+
"connect-builder-card"`, `{ configured, builderEnabled, connectUrl }`) runs the
|
|
115
|
+
Builder OAuth / `cli-auth` flow and stores a scoped credential
|
|
116
|
+
(`credential-provider.ts`). `builderEnabled` flips true once a branch project is
|
|
117
|
+
configured (`resolveBuilderBranchProjectId()`). Vault owns the secret; the app
|
|
118
|
+
owns a scoped reader.
|
|
119
|
+
2. **Migrate** _(NEW)_ — there is no inline→React migration today. Feed the
|
|
120
|
+
design's semantic HTML **plus** its `:root` CSS vars / Brand Kit tokens as the
|
|
121
|
+
seed to the existing Builder cloud agent (`runBuilderAgent()` via
|
|
122
|
+
`startWorkspaceAppCreation()`, `packages/dispatch/.../app-creation-store.ts`),
|
|
123
|
+
producing a real React + Tailwind app. Tokens carry over 1:1 by seeding the
|
|
124
|
+
app's token config from the Brand Kit; annotated Alpine "components" map to real
|
|
125
|
+
components where possible (`implementWithDesignSystem` / `planWithDesignSystem`
|
|
126
|
+
from builder-mcp assist).
|
|
127
|
+
3. **Provision** _(exists; today = Builder-hosted branch)_ —
|
|
128
|
+
`startWorkspaceAppCreation()` returns `{ branchName, url, status }`: a GitHub
|
|
129
|
+
branch in Builder's hosting running as a full React app, tracked pending until
|
|
130
|
+
merged. **No per-user container is required for v1.** _Our own isolated dev
|
|
131
|
+
containers are the `SandboxAdapter` Docker adapter — a blueprint
|
|
132
|
+
(`packages/core/blueprints/sandbox/docker.md`); only the local child-process
|
|
133
|
+
adapter is built. Treat self-hosted containers as an optional, heavier
|
|
134
|
+
follow-on._
|
|
135
|
+
4. **Reconnect** _(NEW — implement `fusion`)_ — flip the design's `sourceType`
|
|
136
|
+
from `inline` to `fusion` (the enum + i18n exist; the bridge/rendering is the
|
|
137
|
+
stub to fill in). `fusion` points the editor at the Builder-hosted app's dev URL
|
|
138
|
+
and uses the bridge for snapshot + code context. Gated panels light up.
|
|
139
|
+
5. **Deploy** _(exists)_ — merge the Builder branch → the existing template deploy
|
|
140
|
+
path (`packages/core/src/deploy/build.ts`, Netlify / CF Pages).
|
|
141
|
+
|
|
142
|
+
### 3.2 The three genuinely-new pieces (everything else is reuse)
|
|
143
|
+
|
|
144
|
+
1. **Migration**: inline HTML/Alpine + tokens → a real React seed for the Builder
|
|
145
|
+
cloud agent.
|
|
146
|
+
2. **`fusion` source mode**: bridge + rendering so the editor drives a
|
|
147
|
+
Builder-hosted app the same way it drives an inline iframe.
|
|
148
|
+
3. **Bridge write hardening**: promote `readFile` / `applyEdit` / `writeFile` from
|
|
149
|
+
`planned` → `available` behind the bridge permission model.
|
|
150
|
+
|
|
151
|
+
### 3.3 Reversibility
|
|
152
|
+
|
|
153
|
+
Migration is additive and non-destructive: the original inline design is kept as a
|
|
154
|
+
`design_version` snapshot so "make it real" can be previewed/rolled back. The user
|
|
155
|
+
approves the generated app before cutover.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## 4. Architecture
|
|
160
|
+
|
|
161
|
+
### 4.1 Foundations we reuse (do not rebuild)
|
|
162
|
+
|
|
163
|
+
- **Source modes & bridge** — `source-mode.ts` defines `inline | localhost |
|
|
164
|
+
fusion` plus the `DesignBridgeRequest` op set: `select`, `resolveNodeToFile`,
|
|
165
|
+
`readFile`, `applyEdit`, `writeFile`, `captureSnapshot`, `captureState`.
|
|
166
|
+
`select` / `resolveNodeToFile` / `captureSnapshot` / `captureState` are
|
|
167
|
+
**`available`**; `readFile` / `applyEdit` / `writeFile` are **`planned`**
|
|
168
|
+
(`connect-localhost.ts` — _"Local file writes require the next bridge hardening
|
|
169
|
+
pass"_). The iframe postMessage bridge in `DesignCanvas.tsx` already carries
|
|
170
|
+
parent→iframe (`tweak-values`, `style-change`, `replace-document-content`,
|
|
171
|
+
`select-element`, `layer-states`, `delete-element`) and iframe→parent
|
|
172
|
+
(`element-select`, `visual-style-change`, `visual-structure-change`,
|
|
173
|
+
`text-content-change`, …). New writes add **named** messages (e.g.
|
|
174
|
+
`motion-preview`), never ad-hoc ones.
|
|
175
|
+
- **Code-layer projection** — `code-layer.ts` (+ `get-code-layer-projection.ts`)
|
|
176
|
+
models nodes, selectors, and `CodeLayerSourceSpan` byte offsets, mapping
|
|
177
|
+
elements to source via `data-agent-native-node-id` (stamped by
|
|
178
|
+
`ensureCodeLayerNodeIdsInHtml`; rename target `data-agent-native-layer-name`).
|
|
179
|
+
- **Deterministic edit path** — `apply-visual-edit.ts` + the
|
|
180
|
+
`replace-document-content` bridge message already do inline HTML writes
|
|
181
|
+
(preview + persist via the Yjs/collab path, `applyLocalContentUpdate`).
|
|
182
|
+
- **Tweaks (CSS-var write path)** — a `TweakDefinition` (`shared/api.ts`) carries a
|
|
183
|
+
`cssVar`; `resolveTweaksToCssVars` (`resolve-tweaks.ts`, byte-identical
|
|
184
|
+
client/server) → `{ "--var": value }`; `apply-tweaks` persists to
|
|
185
|
+
`designs.data.tweakSelections`; the injected `TWEAK_BRIDGE_SCRIPT` applies
|
|
186
|
+
`tweak-values` live via `documentElement.style.setProperty`. **This is the
|
|
187
|
+
Tier-A Tokens write path.**
|
|
188
|
+
- **Brand Kit & token parsing** — `packages/core/src/brand-kit/types.ts`
|
|
189
|
+
(`BrandKitData`) is the shared shape; `DesignSystemData` extends it.
|
|
190
|
+
`design-token-utils.ts` parses CSS vars (`extractCssVars`), Tailwind
|
|
191
|
+
(`parseTailwindConfig`), CSS/SCSS (`parseCss`), JSON/theme files, HTML URLs,
|
|
192
|
+
GitHub (≤10 files), uploads — **import/read-only today** (no write-back).
|
|
193
|
+
`import-code.ts` is the import entry. `design_systems` rows store a `data` JSON
|
|
194
|
+
blob; the current UI edits metadata + shows a read-only token preview.
|
|
195
|
+
- **Versions** — `design_versions` exists; reused for diff + migration snapshots.
|
|
196
|
+
- **Canvas frames** — `canvas-frames.ts` + `MultiScreenCanvas.tsx` for overview
|
|
197
|
+
geometry; reused by states/responsive.
|
|
198
|
+
- **Extensions** — the sandboxed Alpine mini-app substrate +
|
|
199
|
+
`DesignExtensionsPanel.tsx` inspector slot; shaders/plugins are extensions.
|
|
200
|
+
- **Builder & app-creation** — `connect-builder` card, `runBuilderAgent()`,
|
|
201
|
+
`startWorkspaceAppCreation()`, `create_workspace_app` (scaffold), `build.ts`
|
|
202
|
+
(deploy) all exist; the real-app tier wires these, it does not invent them.
|
|
203
|
+
|
|
204
|
+
### 4.2 Design Surface Index — a lazy read-model, not an up-front cache
|
|
205
|
+
|
|
206
|
+
Normalize what already exists (nodes, components, tokens, motion, states, review,
|
|
207
|
+
extension contributions) into **one queryable surface** that both UI panels and
|
|
208
|
+
agent actions read. **Grow it lazily from the existing `code-layer.ts` projection
|
|
209
|
+
and per-feature needs; do not build a normalized cache table up front.** Add a
|
|
210
|
+
cache (`design_surface_indexes`) only if/when re-parsing proves to be a real
|
|
211
|
+
performance problem, with incremental rebuilds keyed by file/source hash and an
|
|
212
|
+
initial scope limited to the active route/screen. Shared types live under
|
|
213
|
+
`templates/design/shared/`: `design-surface-index.ts`,
|
|
214
|
+
`design-source-capabilities.ts`, `motion-timeline.ts`, `design-state.ts`,
|
|
215
|
+
`design-review.ts`.
|
|
216
|
+
|
|
217
|
+
### 4.3 New durable data (additive only)
|
|
218
|
+
|
|
219
|
+
Additive — never drop/rename/retype. All tables use `ownableColumns()` and are
|
|
220
|
+
read/written through `accessFilter` / `assertAccess`.
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
component_index # real-app component metadata
|
|
224
|
+
id (pk); design_id -> designs.id; source_ref
|
|
225
|
+
name; file_path; export_name
|
|
226
|
+
props jsonb # parsed prop types / cva variants
|
|
227
|
+
variants jsonb; stories jsonb
|
|
228
|
+
runtime_selectors jsonb; created_at; updated_at
|
|
229
|
+
|
|
230
|
+
motion_timeline # scoped to design + source + screen/file (MANY per design)
|
|
231
|
+
id (pk); design_id -> designs.id; source_ref
|
|
232
|
+
file_path # null for inline (lives in the managed <style> block)
|
|
233
|
+
tracks jsonb # [{ target_node_id, property, keyframes:[{t,value,ease}] }]
|
|
234
|
+
# -- multiple target layers, each with property tracks
|
|
235
|
+
duration_ms; default_ease
|
|
236
|
+
compiled_hash # keep timeline JSON and compiled CSS in lockstep
|
|
237
|
+
created_at; updated_at
|
|
238
|
+
|
|
239
|
+
design_state # states, fixtures, captures
|
|
240
|
+
id (pk); design_id -> designs.id; source_ref
|
|
241
|
+
name; kind # 'state' | 'fixture' | 'capture'
|
|
242
|
+
breakpoint # 'auto' | 'desktop' | 'tablet' | 'mobile'
|
|
243
|
+
route; fixture_data jsonb; capture_data jsonb; preview_ref
|
|
244
|
+
created_at; updated_at
|
|
245
|
+
|
|
246
|
+
design_review_snapshot # cache a11y + visual-diff results (add when needed)
|
|
247
|
+
id (pk); design_id -> designs.id
|
|
248
|
+
base_version_id; compare_version_id; source_ref
|
|
249
|
+
a11y_findings jsonb; visual_diff jsonb; status
|
|
250
|
+
created_at; updated_at
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
`designs.source_type` already exists; migration flips `inline` → `fusion`.
|
|
254
|
+
`design_versions` is reused for diff + snapshots.
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## 5. Source capabilities (the contract)
|
|
259
|
+
|
|
260
|
+
Every source advertises what it can safely do; the UI gates on this, never on
|
|
261
|
+
`sourceType`.
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
readFile writeFile applyEdit resolveNodeToFile previewPatch diffPatch
|
|
265
|
+
captureSnapshot captureState indexComponents indexTokens writeTokens
|
|
266
|
+
previewMotion writeMotion branch deployPreview deploy
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Behavior:
|
|
270
|
+
|
|
271
|
+
- **Inline / design-file** — HTML/CSS preview + controlled writes through the
|
|
272
|
+
existing deterministic path (`replace-document-content` / `apply-tweaks`);
|
|
273
|
+
`previewMotion` + Tier-A `writeMotion` (managed `<style>` block) and CSS-var
|
|
274
|
+
token edits are available without the file-write bridge.
|
|
275
|
+
- **localhost** — starts read-only/preview-only; `readFile` / `applyEdit` /
|
|
276
|
+
`writeFile` become available only after bridge hardening.
|
|
277
|
+
- **fusion (Builder)** — starts preview-only; unlocks the full set
|
|
278
|
+
(`indexComponents`, `writeTokens`, `writeMotion`, `branch`, `deploy`) once the
|
|
279
|
+
bridge proves capabilities.
|
|
280
|
+
- A control reads the matrix and renders **enabled**, **preview-only**, or
|
|
281
|
+
**migration CTA**. The agent reads the same matrix and never claims an
|
|
282
|
+
unsupported write.
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## 6. Feature workstreams
|
|
287
|
+
|
|
288
|
+
Each workstream touches the four required areas — **UI, actions,
|
|
289
|
+
skills/instructions, application state** — and names its Alpine vs. real-app
|
|
290
|
+
behavior. UI binds through `useActionQuery` / `useActionMutation`; never raw fetch.
|
|
291
|
+
|
|
292
|
+
### 6.1 Editor workbench & components
|
|
293
|
+
|
|
294
|
+
**UI (matches the workbench artboard):** quiet top toolbar (title, segmented
|
|
295
|
+
`Edit / Interact / Annotate`, device dropdown, zoom dropdown, avatar, Share); left
|
|
296
|
+
rail (search → Screens → Layers, component rows marked with an accent diamond,
|
|
297
|
+
selected instance in a soft accent row); canvas (central frame, selected-instance
|
|
298
|
+
accent outline, a source-aware tag like `PrimaryButton →`, a small bottom local
|
|
299
|
+
toolbar, a compact Motion disclosure); right inspector keeps `Design / Tweaks /
|
|
300
|
+
Extensions` compact, with component details shown **contextually inside Design**
|
|
301
|
+
(no permanent Components tab unless real usage proves the need).
|
|
302
|
+
|
|
303
|
+
**Alpine:** annotate a DOM subtree with `data-agent-native-component="Name"` (or an
|
|
304
|
+
`Alpine.data()` island); code-layer marks instances; canvas outlines them; the
|
|
305
|
+
Design tab shows the simple `x-data` variants. **Deliberately light — a bridge to
|
|
306
|
+
real apps, not a fake component system.**
|
|
307
|
+
|
|
308
|
+
**Real app:** `index-components` runs a build-time index (TS prop types, `cva` /
|
|
309
|
+
`tailwind-variants`, Storybook stories) and injects dev metadata
|
|
310
|
+
(`data-agent-native-component`, `data-agent-native-prop-*`, source span) via a
|
|
311
|
+
Vite/Babel transform; canvas outlines real instances; jump-to-source reuses the
|
|
312
|
+
bridge `resolveNodeToFile` op keyed off `data-agent-native-node-id`; the inspector
|
|
313
|
+
renders prop controls from the prop types; detach/instance edits write through the
|
|
314
|
+
bridge. Indexing modes: static AST parse on connect first, dev transform later for
|
|
315
|
+
runtime-variant fidelity; config/annotation escape hatches (`agent-native.design.ts`).
|
|
316
|
+
|
|
317
|
+
**Acceptance:** selecting a component instance outlines it in the accent color; in
|
|
318
|
+
a real app the inspector shows name, source file, variant/size/state controls,
|
|
319
|
+
token usage, and an **Edit component** action; in Alpine the user gets lightweight
|
|
320
|
+
region hints + the real-app CTA; the agent sees selected-component context via
|
|
321
|
+
`view-screen`.
|
|
322
|
+
|
|
323
|
+
### 6.2 Tokens / design systems
|
|
324
|
+
|
|
325
|
+
**UI (matches the tokens artboard):** friendly token names + swatches, CSS-var
|
|
326
|
+
name on the right, type-scale section, radius input, a source chip (e.g.
|
|
327
|
+
`globals.css`), a **New token** action; grouped by color / type / spacing-radius /
|
|
328
|
+
shadows-effects.
|
|
329
|
+
|
|
330
|
+
**Alpine:** the panel is a first-class face on the **Tweaks** loop — edits go
|
|
331
|
+
through `apply-tweaks` (live `tweak-values` preview, persisted in
|
|
332
|
+
`designs.data.tweakSelections`).
|
|
333
|
+
|
|
334
|
+
**Real app:** additionally auto-parses `globals.css` / `tailwind.config` / theme
|
|
335
|
+
JSON (`design-token-utils.ts`) and **writes back to source** via `apply-design-token-edit`
|
|
336
|
+
through the hardened write bridge; tokens become tokens-as-code; the Brand Kit is
|
|
337
|
+
the shared shape across Design / Slides / Assets.
|
|
338
|
+
|
|
339
|
+
**Acceptance:** editing a token previews immediately; writing patches the source
|
|
340
|
+
only through a capability-gated action.
|
|
341
|
+
|
|
342
|
+
### 6.3 Motion dock (CSS-first; the headline)
|
|
343
|
+
|
|
344
|
+
**Both tiers.** A `MotionTimeline` compiles into a managed `<style
|
|
345
|
+
data-agent-native-motion>` block targeting layers by `data-agent-native-node-id`.
|
|
346
|
+
The CSS is the runtime truth; the JSON `tracks` only aid editing.
|
|
347
|
+
|
|
348
|
+
- **UI (matches the motion artboard):** a full-width, collapsible **Motion dock**
|
|
349
|
+
at the bottom of `DesignEditor.tsx` (animated layer rows, property tracks, time
|
|
350
|
+
ruler, diamond keyframes, play/scrub, auto-keyframe toggle, **Write to CSS**),
|
|
351
|
+
with the canvas still visible above; a compact **Motion section** in the
|
|
352
|
+
inspector for the selected keyframe (numeric + easing + transform/opacity).
|
|
353
|
+
- **Preview:** scrubbing sends preview-only bridge messages (`motion-preview` /
|
|
354
|
+
playhead); it **never** writes to DB / Yjs / source.
|
|
355
|
+
- **Apply (atomic, non-negotiable):** `apply-motion-edit` updates timeline
|
|
356
|
+
metadata, compiled CSS, Yjs/collab state, revision check, diff + rollback proof,
|
|
357
|
+
and iframe refresh **together**; `compiled_hash` guards drift. Include a
|
|
358
|
+
reduced-motion strategy in both preview and output.
|
|
359
|
+
|
|
360
|
+
**Real-app superset:** write keyframes into real CSS modules, optional
|
|
361
|
+
`motion`-react round-trip, Dev Mode export.
|
|
362
|
+
|
|
363
|
+
**Acceptance:** scrubbing never writes; **Write to CSS** is one atomic action with
|
|
364
|
+
diff/rollback proof; multiple layers and tracks animate.
|
|
365
|
+
|
|
366
|
+
### 6.4 States, responsive & captures
|
|
367
|
+
|
|
368
|
+
#### Responsive — multi-breakpoint editing (Framer / Figma-Sites style)
|
|
369
|
+
|
|
370
|
+
Show one screen at several breakpoints **side by side** in the overview and edit
|
|
371
|
+
each independently. Researched models we borrow from:
|
|
372
|
+
|
|
373
|
+
- **Framer** — Desktop (the parent) + Tablet **810** + Phone **390** as
|
|
374
|
+
side-by-side frames; added via a **Breakpoint button** on the page selection
|
|
375
|
+
(infinite, resizable). Desktop-first: a frame drawn on Desktop propagates down to
|
|
376
|
+
smaller breakpoints; a smaller-breakpoint edit overrides only that frame.
|
|
377
|
+
- **Figma Sites** — Desktop **1280** / Tablet **800** / Mobile **375**; a **`+` in
|
|
378
|
+
the webpage header on the canvas** adds a predefined or custom width; primary →
|
|
379
|
+
secondary cascade (default primary = Desktop ⇒ desktop-first); **"Set as primary
|
|
380
|
+
breakpoint"** flips to mobile-first; per-property, per-breakpoint overrides;
|
|
381
|
+
**"Reset all changes"** reverts a layer to the inherited (primary) value;
|
|
382
|
+
responsive components auto-match variants by breakpoint name.
|
|
383
|
+
|
|
384
|
+
**Our model — mobile-first by default, because the output is Tailwind.** Unlike
|
|
385
|
+
Framer/Figma (desktop-first), we make the **base = mobile** and let larger
|
|
386
|
+
breakpoints layer overrides upward — which is exactly Tailwind's min-width cascade
|
|
387
|
+
(`base` → `md:` → `lg:`). This matches the requested preference and makes "edit on
|
|
388
|
+
screen → responsive class" deterministic.
|
|
389
|
+
|
|
390
|
+
- **Overview:** a screen carries a **breakpoint set**; `MultiScreenCanvas` renders
|
|
391
|
+
one iframe **per breakpoint at its width**, laid left→right (Mobile → Tablet →
|
|
392
|
+
Desktop), all bound to the **same source** (same `srcdoc` for inline, same URL for
|
|
393
|
+
localhost/fusion). A **`+` at the right edge** adds the next device size
|
|
394
|
+
(Mobile 390 / Tablet 768 / Desktop 1280, or a custom width). Store the set by
|
|
395
|
+
extending `canvas-frames.ts` geometry to a per-breakpoint frame list (not a fixed
|
|
396
|
+
single geometry per file). Frames **snap to Tailwind breakpoint min-widths**
|
|
397
|
+
(`md` 768, `lg` 1024, `xl` 1280) so each frame maps 1:1 to a prefix.
|
|
398
|
+
- **Per-breakpoint editing = the active frame is the edit scope.** Editing a layer in
|
|
399
|
+
the **Mobile** frame writes the **unprefixed** class (the base); the same edit in
|
|
400
|
+
**Tablet** writes `md:…`; in **Desktop** writes `lg:`/`xl:…`. Inherited values
|
|
401
|
+
cascade up from base unless a prefixed override exists. For non-Tailwind / inline
|
|
402
|
+
CSS, the edit writes into a `@media (min-width: …)` block in the managed style.
|
|
403
|
+
- **This is the main new code-layer work.** Today the projection **detects but
|
|
404
|
+
strips** Tailwind `sm:`/`md:`/`lg:` prefixes and all class edits are global
|
|
405
|
+
(`code-layer.ts`; `EditCapability` has no responsive kind). Add a
|
|
406
|
+
**responsive-aware class model**: parse class tokens grouped by breakpoint
|
|
407
|
+
(base, `sm:`, `md:`, `lg:`, `xl:`, `2xl:`), expose each property's value _per
|
|
408
|
+
breakpoint_, and add an `EditCapability` of `kind: "responsive-class"` whose
|
|
409
|
+
add/replace targets the active breakpoint's prefix. Surface **override indicators**
|
|
410
|
+
(which properties differ from base at this breakpoint) with a **Reset to base**
|
|
411
|
+
affordance (cf. Figma's "Reset all changes").
|
|
412
|
+
- **Tiering:** the multi-frame overview + base/Tailwind-prefix editing works in
|
|
413
|
+
**Alpine today** — inline designs already load Tailwind CDN + use `sm:/md:/lg:`,
|
|
414
|
+
the device frame already sets the iframe width, and class edits already flow
|
|
415
|
+
through the deterministic `replace-document-content` path (no bridge write). For
|
|
416
|
+
**real apps**, the same per-breakpoint edit writes prefixed classes / media rules
|
|
417
|
+
to the real source (needs the bridge write hardening, phase 5).
|
|
418
|
+
|
|
419
|
+
#### States
|
|
420
|
+
|
|
421
|
+
Design states (Default / Logged out / Empty / Loading / Error and pseudo-states) as
|
|
422
|
+
alternate `x-data` / DOM snapshots in `design_state`. Breakpoint and state are
|
|
423
|
+
**orthogonal axes** — any state can be viewed at any breakpoint.
|
|
424
|
+
|
|
425
|
+
#### Captures (real app)
|
|
426
|
+
|
|
427
|
+
`capture-design-state` snaps the running app's route + props + data into a
|
|
428
|
+
`design_state` row (the bridge `captureState` op is **already `available`**).
|
|
429
|
+
|
|
430
|
+
Selected **breakpoint + state** persist in application state (`breakpoint` already
|
|
431
|
+
in the §8 shape; add `breakpointSetId` / `activeBreakpointId`) and are agent-visible
|
|
432
|
+
via `view-screen`. New actions (§7): `add-breakpoint`, `remove-breakpoint`,
|
|
433
|
+
`set-active-breakpoint`, `reset-breakpoint-overrides`.
|
|
434
|
+
|
|
435
|
+
#### `visual-edit` skill upgrade
|
|
436
|
+
|
|
437
|
+
Today `/visual-edit` opens one URL at one size. Upgrade a screen from a single
|
|
438
|
+
URL+size to a **route × breakpoint matrix** — the same URL (or inline design)
|
|
439
|
+
rendered at Mobile/Tablet/Desktop side by side, editing only the frame that needs
|
|
440
|
+
fixing. Identical mechanism for inline (Alpine) and real (React) apps: same source,
|
|
441
|
+
N widths. Flow states (`?step=…`) and breakpoints compose as two axes.
|
|
442
|
+
|
|
443
|
+
**Acceptance:** a screen shows Mobile/Tablet/Desktop side by side with a `+` to add a
|
|
444
|
+
width; editing a layer in one frame writes a breakpoint-scoped class and the other
|
|
445
|
+
frames reflect the cascade; overridden properties show a reset-to-base control; real
|
|
446
|
+
apps additionally capture running state; the agent sees the selected
|
|
447
|
+
breakpoint/state/route via `view-screen`.
|
|
448
|
+
|
|
449
|
+
### 6.5 Accessibility & review (read-only first)
|
|
450
|
+
|
|
451
|
+
`run-design-audit` over the rendered DOM (contrast, tap targets, focus
|
|
452
|
+
visibility, missing names/labels, reduced-motion). The **Review** panel (matches
|
|
453
|
+
the review artboard) shows severity-dot findings with optional **Fix** + a visual
|
|
454
|
+
diff over `design_versions` (base/compare selector, changed-surface rows, before/
|
|
455
|
+
after). Findings navigate to the affected canvas/source node. Fix actions are
|
|
456
|
+
**capability-gated** (semantic code fixes are real-app only).
|
|
457
|
+
|
|
458
|
+
### 6.6 Branches, Builder & deploy
|
|
459
|
+
|
|
460
|
+
**Alpine:** version diff between two `design_versions`.
|
|
461
|
+
**Real app:** `connect-builder-app` / `migrate-inline-design-to-app` /
|
|
462
|
+
`create-design-branch` (Builder-hosted branch today via `runBuilderAgent`) /
|
|
463
|
+
`get-design-branch-diff` / `deploy-design-preview`, with rollback. (Our own durable
|
|
464
|
+
container is the later `SandboxAdapter` path.)
|
|
465
|
+
|
|
466
|
+
### 6.7 Extensions, shaders & assets
|
|
467
|
+
|
|
468
|
+
Extensions are the substrate (both tiers), inline via `DesignExtensionsPanel`.
|
|
469
|
+
First-party: **asset library** (selection-aware insertion — can ship early),
|
|
470
|
+
**shader fills**, **token auditor**, **motion presets**. **Shaders: preview-first;
|
|
471
|
+
`apply-shader-fill` stays disabled until runtime rendering + a real source-write
|
|
472
|
+
path + a generated fallback + diff proof all exist.** No permanent chrome.
|
|
473
|
+
|
|
474
|
+
---
|
|
475
|
+
|
|
476
|
+
## 7. Action surface
|
|
477
|
+
|
|
478
|
+
Actions are the shared UI/agent contract; every editable surface splits into a
|
|
479
|
+
cheap ephemeral **preview** and a deliberate atomic **apply**.
|
|
480
|
+
|
|
481
|
+
- **Foundation:** `get-design-surface-index` (read), `refresh-design-surface-index`,
|
|
482
|
+
`list-design-source-capabilities` (read).
|
|
483
|
+
- **Components:** `index-components`, `get-component-details` (read),
|
|
484
|
+
`preview-component-prop-edit`, `apply-component-prop-edit`, `open-component-source`.
|
|
485
|
+
- **Tokens:** `index-design-tokens`, `preview-design-token-edit`,
|
|
486
|
+
`apply-design-token-edit`, `create-design-token`.
|
|
487
|
+
- **Motion:** `get-motion-timeline` (read), `preview-motion-frame`,
|
|
488
|
+
`apply-motion-edit` (atomic), `remove-motion-timeline`.
|
|
489
|
+
- **States/captures:** `list-design-states` (read), `create-design-state`,
|
|
490
|
+
`capture-design-state`, `apply-design-state`, `delete-design-state`.
|
|
491
|
+
- **Responsive/breakpoints:** `add-breakpoint`, `remove-breakpoint`,
|
|
492
|
+
`set-active-breakpoint`, `reset-breakpoint-overrides`. Per-breakpoint style edits
|
|
493
|
+
reuse `preview-component-prop-edit` / `apply-visual-edit` with an `EditCapability`
|
|
494
|
+
of `kind: "responsive-class"` scoped to the active breakpoint's Tailwind prefix.
|
|
495
|
+
- **Review:** `run-design-audit`, `get-design-review` (read), `preview-a11y-fix`,
|
|
496
|
+
`apply-a11y-fix` (gated), `create-design-review-snapshot`.
|
|
497
|
+
- **Builder/branch:** `connect-builder-app`, `migrate-inline-design-to-app`,
|
|
498
|
+
`create-design-branch`, `get-design-branch-diff`, `deploy-design-preview`.
|
|
499
|
+
- **Extensions/assets/shaders:** `list-design-extensions`,
|
|
500
|
+
`run-design-extension-action`, `insert-design-asset`, `preview-shader-fill`,
|
|
501
|
+
`apply-shader-fill` _(stays disabled until contracts are real)_.
|
|
502
|
+
|
|
503
|
+
Every write action declares its `accessTarget` for the audit log and re-checks
|
|
504
|
+
source capabilities server-side.
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
## 8. Application state
|
|
509
|
+
|
|
510
|
+
Publish the exact design context so the agent sees what the user sees. `view-screen`
|
|
511
|
+
returns selected component/source metadata, current capabilities, selected token/
|
|
512
|
+
state/motion context, current panel/dock, recent audit/diff summary, and CTA
|
|
513
|
+
availability.
|
|
514
|
+
|
|
515
|
+
```ts
|
|
516
|
+
type DesignNavigationState = {
|
|
517
|
+
view: "design-editor" | "design-overview" | "design-review";
|
|
518
|
+
designId: string;
|
|
519
|
+
sourceType: "inline" | "localhost" | "fusion"; // Builder is a flavor of fusion
|
|
520
|
+
screenId?: string;
|
|
521
|
+
fileId?: string;
|
|
522
|
+
route?: string;
|
|
523
|
+
mode: "edit" | "interact" | "annotate";
|
|
524
|
+
selectedNodeIds: string[];
|
|
525
|
+
selectedComponentId?: string;
|
|
526
|
+
selectedTokenId?: string;
|
|
527
|
+
selectedStateId?: string;
|
|
528
|
+
inspectorTab: "design" | "tweaks" | "extensions";
|
|
529
|
+
inspectorSection?:
|
|
530
|
+
| "component"
|
|
531
|
+
| "tokens"
|
|
532
|
+
| "motion"
|
|
533
|
+
| "states"
|
|
534
|
+
| "review"
|
|
535
|
+
| "extension";
|
|
536
|
+
dock?: { kind: "motion" | "review" | null; open: boolean };
|
|
537
|
+
motion?: {
|
|
538
|
+
timelineId?: string;
|
|
539
|
+
playheadMs: number;
|
|
540
|
+
selectedTrackId?: string;
|
|
541
|
+
selectedKeyframeId?: string;
|
|
542
|
+
previewing: boolean;
|
|
543
|
+
};
|
|
544
|
+
breakpoint?: "auto" | "desktop" | "tablet" | "mobile"; // active breakpoint
|
|
545
|
+
breakpointSetId?: string; // the screen's side-by-side breakpoint set
|
|
546
|
+
activeBreakpointId?: string; // which frame is the current edit scope
|
|
547
|
+
sourceCapabilities: string[];
|
|
548
|
+
};
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
Wire writes through `navigate` / `view-screen` plus selection, motion-dock,
|
|
552
|
+
state, and review state writes.
|
|
553
|
+
|
|
554
|
+
---
|
|
555
|
+
|
|
556
|
+
## 9. Agent instructions & skills
|
|
557
|
+
|
|
558
|
+
Update `templates/design/AGENTS.md`:
|
|
559
|
+
|
|
560
|
+
- **Mode boundary** — Alpine is lightweight; full components, data states, branches,
|
|
561
|
+
deploys, and deep token writes are real-app features.
|
|
562
|
+
- **Capability gate rule** — never claim a write unless capabilities advertise it.
|
|
563
|
+
- **Action map** — index/read, component, token, motion, state/capture, review,
|
|
564
|
+
Builder/branch/deploy.
|
|
565
|
+
- **Motion rule** — preview-only scrubbing; atomic `apply-motion-edit` to commit.
|
|
566
|
+
- **Shader rule** — keep writes gated until runtime/write seams are real.
|
|
567
|
+
- **Visual rule** — preserve the minimal Figma-esque shell and the screenshot
|
|
568
|
+
acceptance criteria.
|
|
569
|
+
|
|
570
|
+
Add `.agents/skills/design-studio/SKILL.md`: how to inspect capabilities, index a
|
|
571
|
+
surface before editing, choose Alpine vs real-app behavior, apply token/component/
|
|
572
|
+
motion edits safely, use review outputs, and offer Builder migration CTAs.
|
|
573
|
+
|
|
574
|
+
---
|
|
575
|
+
|
|
576
|
+
## 10. Cross-cutting
|
|
577
|
+
|
|
578
|
+
- **Four areas** — every feature touches UI + actions + skills/instructions + app
|
|
579
|
+
state.
|
|
580
|
+
- **Preview vs apply** — cheap ephemeral preview (bridge message) vs deliberate,
|
|
581
|
+
atomic, revision-checked, diffable apply. Scrub/drag/nudge previews; commit writes.
|
|
582
|
+
- **Security** — Builder credentials via Vault + scoped reader (never copied into
|
|
583
|
+
app rows); all new tables `ownableColumns()` + access-checked; source writes only
|
|
584
|
+
in capability-advertising modes behind bridge auth.
|
|
585
|
+
- **Reliability** — writes are single atomic actions, never per-frame loops;
|
|
586
|
+
migration reports proof-of-done.
|
|
587
|
+
|
|
588
|
+
---
|
|
589
|
+
|
|
590
|
+
## 11. Rollout phases
|
|
591
|
+
|
|
592
|
+
0. **Capability gates + CTA skeleton (thin honesty layer).** Sources advertise
|
|
593
|
+
capabilities; controls gate to enabled / preview-only / migration-CTA; the "Make
|
|
594
|
+
it real" CTA renders wherever a control is gated. No new _feature_ yet. Cheap;
|
|
595
|
+
unblocks everything. **Not blocked on bridge write-hardening** — inline writes
|
|
596
|
+
already work through `replace-document-content` / `apply-tweaks`; hardening lands
|
|
597
|
+
with the real-app lane (phase 5). Add screenshot visual-regression coverage of
|
|
598
|
+
the editor shell + panel primitives.
|
|
599
|
+
1. **Tokens + CSS-keyframe Motion on inline (first user-visible win).** Tokens panel
|
|
600
|
+
on the Tweaks loop; Motion dock with managed-keyframes `apply-motion-edit`. Zero
|
|
601
|
+
new infra; proves "visual edit → code" at small scale. Ship the cheap half of
|
|
602
|
+
responsive here too: the **multi-breakpoint preview** — render the same inline
|
|
603
|
+
source at Mobile/Tablet/Desktop side by side with a `+` to add a width (the device
|
|
604
|
+
frame already width-controls the iframe; this is just N iframes + a button).
|
|
605
|
+
2. **Components.** Light annotated Alpine components + the real-app component index +
|
|
606
|
+
prop controls behind the CTA.
|
|
607
|
+
3. **States, responsive & captures.** Design states; the **responsive-aware
|
|
608
|
+
code-layer** (per-breakpoint Tailwind-prefix editing with override / reset-to-base,
|
|
609
|
+
the new `kind: "responsive-class"` edit capability) so editing one frame writes a
|
|
610
|
+
scoped class; then real-app data captures.
|
|
611
|
+
4. **Accessibility + version diff (read-only Review panel).**
|
|
612
|
+
5. **Connect Builder / real-app tier.** Harden bridge writes, implement `fusion`,
|
|
613
|
+
wire migration; unlock full components / tokens-as-code / branches / deploy.
|
|
614
|
+
6. **Shaders & plugins (gated, last).** Preview-first; apply/export only after
|
|
615
|
+
runtime + source-write + fallback + diff proof.
|
|
616
|
+
|
|
617
|
+
**First user-visible milestone:** on an inline design, edit a token (live, persisted)
|
|
618
|
+
and add a keyframe animation that **Write to CSS** commits with a visible diff —
|
|
619
|
+
"visual edit becomes persisted code/CSS" without the whole real-app stack.
|
|
620
|
+
|
|
621
|
+
---
|
|
622
|
+
|
|
623
|
+
## 12. Parallel workstreams (clear ownership)
|
|
624
|
+
|
|
625
|
+
1. Capability gates + surface index (shared types, source-mode contract, index
|
|
626
|
+
actions, app-state/`view-screen`).
|
|
627
|
+
2. UI shell + visual primitives (chrome, compact rows, swatches, segmented
|
|
628
|
+
controls, severity rows, property groups, CTA rows; screenshot-matching states).
|
|
629
|
+
3. Components + real-app CTA.
|
|
630
|
+
4. Tokens (parser/indexer, panel, preview/apply).
|
|
631
|
+
5. Motion (timeline model, compiler/parser, dock UI, preview messages, atomic apply).
|
|
632
|
+
6. States/captures.
|
|
633
|
+
7. Review/diff/a11y.
|
|
634
|
+
8. Builder/branches/deploy.
|
|
635
|
+
9. Extensions/assets/shaders.
|
|
636
|
+
|
|
637
|
+
---
|
|
638
|
+
|
|
639
|
+
## 13. Verification
|
|
640
|
+
|
|
641
|
+
- **Unit/action:** surface index builds for inline files; capability gates disable
|
|
642
|
+
unsupported writes; token parser handles CSS vars + Tailwind; motion compiler
|
|
643
|
+
emits deterministic CSS and the parser reads the managed block back;
|
|
644
|
+
`apply-motion-edit` is atomic + revision-checked; component index handles
|
|
645
|
+
representative React/`cva`; state/capture actions persist + are app-state-visible;
|
|
646
|
+
audit returns stable findings.
|
|
647
|
+
- **UI (screenshot-driven Playwright):** component-selected workbench, motion dock
|
|
648
|
+
open, tokens panel, states panel, review panel, extensions panel, the Alpine
|
|
649
|
+
real-app CTA.
|
|
650
|
+
- **Agent parity:** agent can inspect the selected component via `view-screen`,
|
|
651
|
+
refresh the index, preview+apply a token edit where supported, add motion
|
|
652
|
+
keyframes via the action path, create/select a state, run review, and navigate to
|
|
653
|
+
an affected surface.
|
|
654
|
+
- **Real-app smoke (Builder/React fixture):** select a React component → props +
|
|
655
|
+
variants → preview a prop edit → apply a safe source edit → parse tokens → apply a
|
|
656
|
+
token change → capture a route state → run review → produce a branch/visual diff.
|
|
657
|
+
- **Responsive smoke:** a screen renders at Mobile/Tablet/Desktop side by side; a `+`
|
|
658
|
+
adds a width; editing a layer in the Tablet frame writes a `md:` class while base
|
|
659
|
+
(Mobile) is untouched; the Desktop frame reflects the cascade; reset-to-base clears
|
|
660
|
+
the override; the same flow works on an inline design and a real-app URL.
|
|
661
|
+
- **Alpine smoke:** edit layout/styles; preview + persist a CSS-var token change;
|
|
662
|
+
add simple keyframes and Write to CSS; run a basic a11y scan; see the real-app CTA
|
|
663
|
+
for full component controls.
|
|
664
|
+
|
|
665
|
+
---
|
|
666
|
+
|
|
667
|
+
## 14. Risks & mitigations
|
|
668
|
+
|
|
669
|
+
- **Split motion source of truth** — CSS is truth, JSON is metadata,
|
|
670
|
+
`apply-motion-edit` updates both atomically, store `compiled_hash` + revision,
|
|
671
|
+
provide rollback/diff proof.
|
|
672
|
+
- **Overclaiming localhost/React writes** — strict capability matrix; read-only /
|
|
673
|
+
preview-only fallback; CTA when the source lacks fidelity. (`readFile` /
|
|
674
|
+
`applyEdit` / `writeFile` are `planned` today.)
|
|
675
|
+
- **Inspector sprawl** — contextual sections inside the existing inspector; one
|
|
676
|
+
bottom dock for motion/review; extension-contributed panels; no new top-level tab
|
|
677
|
+
without usage proof.
|
|
678
|
+
- **Building-the-framework-first** — grow the Surface Index lazily; add cache tables
|
|
679
|
+
only when re-parsing is a measured problem; first cheap win (Tokens) ships before
|
|
680
|
+
any framework phase completes.
|
|
681
|
+
- **Over-investing in Alpine components** — keep them annotated regions, not a fake
|
|
682
|
+
component system; they are a bridge to real apps.
|
|
683
|
+
- **Shader prematurity** — preview-first; apply disabled until runtime + fallback +
|
|
684
|
+
source write + diff exist.
|
|
685
|
+
- **Component index accuracy** — static AST + config/annotation overrides first;
|
|
686
|
+
Vite/Babel dev transform later; tie controls to confidence/capability metadata.
|
|
687
|
+
- **Performance** — cache indexes when needed; incremental rebuilds by file/source
|
|
688
|
+
hash; initial scope = active route/screen; show freshness in UI + actions.
|
|
689
|
+
- **Container assumption** — the real-app tier is a Builder-hosted branch today, not
|
|
690
|
+
our own container; the Docker `SandboxAdapter` is a later, optional path.
|
|
691
|
+
|
|
692
|
+
---
|
|
693
|
+
|
|
694
|
+
## 15. Open decisions
|
|
695
|
+
|
|
696
|
+
1. **Component indexing transport (real apps)** — Vite/Babel dev transform injecting
|
|
697
|
+
`data-agent-native-*` metadata (most accurate; needs the dev server wired through
|
|
698
|
+
the bridge) **[recommended]** vs. static TS/AST parse on connect (no runtime hook,
|
|
699
|
+
misses runtime-only variants). _Mitigation: ship static first, add the transform
|
|
700
|
+
for fidelity._
|
|
701
|
+
2. **Motion source format (real apps)** — managed CSS keyframes block **[recommended;
|
|
702
|
+
one mental model with Alpine]** vs. a `motion`-react representation (richer
|
|
703
|
+
springs, ties output to the library).
|
|
704
|
+
3. **Real-app hosting** — Builder-hosted branch **[recommended for v1; exists]** vs.
|
|
705
|
+
our own durable container (`SandboxAdapter` Docker; not built). Affects deploy +
|
|
706
|
+
data residency.
|
|
707
|
+
4. **Migration fidelity** — pixel-match gate vs. "good enough + agent cleanup"
|
|
708
|
+
before cutover. Affects how aggressive the Connect-Builder CTA can be.
|
|
709
|
+
5. **Breakpoint defaults & cascade** — mobile-first base + Tailwind min-width prefixes
|
|
710
|
+
**[recommended; deterministic with our output]** vs. also offering a per-design
|
|
711
|
+
desktop-first / "set as primary breakpoint" flip like Figma Sites. Default frame
|
|
712
|
+
widths (390 / 768 / 1280, snapped to Tailwind `md` / `lg` / `xl`) and whether to
|
|
713
|
+
allow fully custom widths.
|
|
714
|
+
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
```
|