visual-edit
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseVisual Edit
可视化编辑
Use when the user wants to inspect or edit a real local app
visually instead of generating standalone Alpine HTML. The source of truth is
the running localhost app plus its route URLs. Design shows those routes as
iframe-backed screens on the infinite canvas.
/visual-edit当用户希望以可视化方式检查或编辑真实本地应用,而非生成独立的Alpine HTML时,使用。数据源是运行中的localhost应用及其路由URL。Design会在无限画布上以基于iframe的屏幕形式展示这些路由。
/visual-editInstalling this skill for an external MCP host
为外部MCP主机安装此技能
The hosted install path
(, or for the
full Design bundle) installs the exported instructions and registers the
hosted Design MCP connector together. The open Skills CLI path
() installs
exported instructions only, with no MCP connector registration.
npx @agent-native/core@latest skills add visual-editdesignnpx skills@latest add BuilderIO/agent-native --skill visual-edit托管安装路径(,或使用安装完整的Design包)会同时安装导出的指令并注册托管的Design MCP连接器。开放式Skills CLI路径()仅安装导出的指令,不注册MCP连接器。
npx @agent-native/core@latest skills add visual-editdesignnpx skills@latest add BuilderIO/agent-native --skill visual-editPut Design Beside The Chat
将Design置于聊天窗口旁
Prefer the interactive MCP App returned by when the coding
host renders it. The user gets the Design canvas beside the conversation, and
Apply design updates can submit the bounded source-edit handoff back to the
current host conversation through the standard MCP Apps message bridge. The
host may ask the user to confirm the current conversation or choose a new one.
open-visual-editOtherwise, is a credential-free, read-only fallback that is safe to
show in model text or retain in logs. Do not claim that fallback is editable:
the edit capability is intentionally available only to the host-managed MCP App
launcher, where it is hidden from the model and redeemed once.
openUrl- In Codex Desktop, prefer the rendered MCP App. Use the in-app Browser for the
credential-free only when a read-only fallback is acceptable.
openUrl - In Claude Code Desktop's Code tab, prefer the rendered MCP App. Preview
in the Browser pane only as the read-only fallback.
openUrl - In VS Code, use the Agent Native Design webview/deep link described below.
- Inline browser availability is host-dependent. CLI, remote, or restricted sessions may not expose one. If the inline surface is unavailable or disabled, return the normal Open design link instead of claiming it opened.
Prefer the MCP App surface for a connected Design plugin, then the host's
browser/preview tool as the universal fallback. Keep the canvas beside chat
when the host supports rearrangeable panes.
Inside Design, use Show/Hide UI from the menu or press Figma's
shortcut to toggle all editing chrome so only the canvas remains.
The same action is available from Design's empty-canvas context menu.
Cmd KShift \当编码主机渲染时,优先选择返回的交互式MCP App。用户可在对话旁看到Design画布,且应用设计更新可通过标准MCP Apps消息桥将受限的源码编辑交接回当前主机对话。主机可能会要求用户确认当前对话或选择新对话。
open-visual-edit否则,是无需凭证的只读回退方案,可安全地在模型文本中展示或保留在日志中。不要声称回退方案支持编辑:编辑功能仅对主机管理的MCP App启动器开放,该功能对模型隐藏且仅可使用一次。
openUrl- 在Codex Desktop中,优先选择渲染后的MCP App。仅当只读回退方案可接受时,才使用应用内浏览器打开无需凭证的。
openUrl - 在Claude Code Desktop的代码标签页中,优先选择渲染后的MCP App。仅将作为只读回退方案在浏览器窗格中预览。
openUrl - 在VS Code中,使用下文所述的Agent Native Design webview/深度链接。
- 内嵌浏览器的可用性取决于主机。CLI、远程或受限会话可能不会提供内嵌浏览器。如果内嵌界面不可用或已禁用,请返回常规的打开设计链接,而非声称已打开。
优先选择连接的Design插件的MCP App界面,然后将主机的浏览器/预览工具作为通用回退方案。当主机支持可重排窗格时,将画布置于聊天窗口旁。
在Design内,从菜单中选择显示/隐藏UI,或按下Figma的快捷键,可切换所有编辑控件,仅保留画布。同样的操作也可从Design的空白画布上下文菜单中执行。
Cmd KShift \Core Model
核心模型
- Each screen is a URL-backed iframe, not copied HTML.
- Each screen keeps URL metadata: ,
connectionId,routeId,path,url, title, and viewport size.bridgeUrl - Localhost Edit mode renders the running app through the local bridge as a live
iframe with the same editor bridge used by HTML designs. It is never a frozen
static DOM snapshot. Editing is direct DOM manipulation against that live
document; the parallel fetch feeds the editable source model only and must never be rendered in the frame.
/snapshot - The skill needs no Design account sign-in.
/visual-editmints a five-minute, single-use capability for the exactopen-visual-editlocal-editor route. The MCP host redeems it outside model-visible text, then opens the existing editor with localhost edit access. This capability is not an account session:/visual-edit/:designIdremains signed out, and account-backed save/share/generate actions remain denied./_agent-native/session - The skill enters through local . When that CLI has no account session, the action uses a stable, workspace-scoped local principal to register the bridge, create/reuse the local design, and place screens. That principal exists only inside the in-process CLI call; it is not a browser login and cannot be selected by an HTTP, MCP, or tunneled caller.
pnpm action open-visual-edit - Public links are always read-only, including on loopback. Loopback peer
identity is not an authentication boundary because a tunnel or reverse proxy
can make a remote request appear local. A bare or
/visual-edit/:designIdURL carries no capability and must never release the connection's/design/:designId.previewToken - The live editor is same-origin through the local bridge proxy. This boots CSR apps and root-relative assets, but it is still a localhost editing proxy: app-origin cookies, WebSockets/HMR, SSE, and non-GET app API calls may need a future dev-server/plugin integration for perfect parity with the app's own origin.
- There are exactly two views. The infinite canvas is where all editing happens, and the responsive interactive view (Interact) is where the app runs for real. There is no third "full view"/focused-edit state — clicking a screen in the Screens list, or the view toggle, opens the responsive view, and closing it returns to the canvas.
- Interact keeps the left and right rails and adds a device bar above the canvas (device preset, editable width/height, zoom, close). It renders the app's normal URL so navigation, scrolling, links, and form controls behave as they would in the browser, and the wheel scrolls the app rather than panning the canvas. The canvas view is the opposite: the wheel pans and zooms it, and native interaction inside the frame is suppressed.
- While a localhost screen has pending live visual edits, do not switch back to Interact until the user either applies the edits to source or explicitly aborts/discards the preview.
- Alt-drag duplicates a screen. For localhost screens, duplication copies the iframe frame and URL metadata; change the copy's path/query for a new state.
- Flow visualization is multiple URL states: ,
/checkout?step=shipping,/checkout?step=payment, etc./checkout?step=done - When the user gives a named flow or numbered screen list, preserve that order
and create one screen per URL/path. Shorthand like
means
localhost:1234/onboarding/1.http://localhost:1234/onboarding/1
- 每个屏幕都是基于URL的iframe,而非复制的HTML。
- 每个屏幕都保留URL元数据:、
connectionId、routeId、path、url、标题和视口大小。bridgeUrl - Localhost编辑模式通过本地桥接器将运行中的应用渲染为实时iframe,使用与HTML设计相同的编辑器桥接器。它永远不会是冻结的静态DOM快照。编辑是对该实时文档的直接DOM操作;并行的获取仅用于可编辑的源模型,绝不能在框架中渲染。
/snapshot - 技能无需Design账户登录。
/visual-edit会为精确的open-visual-edit本地编辑器路由生成一个5分钟有效期的一次性权限。MCP主机会在模型可见文本之外兑换该权限,然后打开具有localhost编辑访问权限的现有编辑器。此权限并非账户会话:/visual-edit/:designId保持未登录状态,且基于账户的保存/分享/生成操作仍被拒绝。/_agent-native/session - 该技能通过本地启动。当该CLI没有账户会话时,操作会使用一个稳定的、工作区范围的本地主体来注册桥接器、创建/复用本地设计并放置屏幕。该主体仅存在于进程内CLI调用中;它不是浏览器登录,无法被HTTP、MCP或隧道调用者选择。
pnpm action open-visual-edit - 公共链接始终是只读的,包括环回链接。环回对等身份不是身份验证边界,因为隧道或反向代理可使远程请求看起来像是本地请求。无权限的或
/visual-edit/:designIdURL永远不会释放连接的/design/:designId。previewToken - 实时编辑器通过本地桥接代理实现同源。这支持CSR应用和根相对资产,但它仍然是localhost编辑代理:应用源Cookie、WebSockets/HMR、SSE和非GET应用API调用可能需要未来的开发服务器/插件集成,才能与应用自身的源完全一致。
- 仅有两种视图。 无限画布是所有编辑操作的场所,响应式交互式视图(Interact)是应用实际运行的地方。不存在第三种“完整视图”/聚焦编辑状态——点击屏幕列表中的屏幕或视图切换按钮会打开响应式视图,关闭后返回画布。
- Interact视图保留左右侧边栏,并在画布上方添加设备栏(设备预设、可编辑宽/高、缩放、关闭)。它渲染应用的常规URL,因此导航、滚动、链接和表单控件的行为与在浏览器中一致,滚轮会滚动应用而非平移画布。画布视图则相反:滚轮会平移和缩放画布,框架内的原生交互会被抑制。
- 当localhost屏幕存在待处理的实时可视化编辑时,在用户将编辑应用到源码或明确中止/放弃预览之前,不要切换回Interact视图。
- 按住Alt键拖动可复制屏幕。对于localhost屏幕,复制操作会复制iframe框架和URL元数据;更改副本的路径/查询可获取新状态。
- 流程可视化包含多个URL状态:、
/checkout?step=shipping、/checkout?step=payment等。/checkout?step=done - 当用户提供命名流程或编号屏幕列表时,保留其顺序并为每个URL/路径创建一个屏幕。类似的简写表示
localhost:1234/onboarding/1。http://localhost:1234/onboarding/1
Useful Canvas Sets
实用画布集合
Translate the user's requested review into the smallest useful set of frames:
- Multi-step flow: one ordered frame per route or query state, such as cart, shipping, payment, and confirmation.
- Multiple pages: one frame per meaningful route, such as home, pricing, docs, and account settings.
- Responsive comparison: repeat the same route at the requested desktop, tablet, and mobile viewports so they align in one row.
- State review: repeat a route for meaningful URL-addressable states such as empty, loading, error, modal-open, or selected-item views.
Do not expand every discovered route or every viewport unless the user asks for
an exhaustive audit. Preserve the user's labels and sequence so the canvas reads
like the workflow they described.
将用户要求的评审转换为最小的实用框架集合:
- 多步骤流程: 每个路由或查询状态对应一个有序框架,例如购物车、配送、支付和确认页面。
- 多个页面: 每个有意义的路由对应一个框架,例如首页、定价、文档和账户设置页面。
- 响应式对比: 在用户要求的桌面、平板和移动视口下重复同一路由,使其在一行中对齐。
- 状态评审: 针对有意义的URL可寻址状态重复同一路由,例如空状态、加载状态、错误状态、模态框打开状态或选中项视图。
除非用户要求全面审核,否则不要展开每个已发现的路由或每个视口。保留用户的标签和顺序,使画布符合用户描述的工作流程。
Select And Reprompt
选择与重新提示
When a chat message begins with , the selected subtree is
a hard write boundary. The only mutation path is with
the exact , target, and captured in
. Never use ,
, , , , or any
other content-writing action for that request. Clarifying questions are allowed,
but a requested change must remain a proposal.
[Reprompt selection]propose-node-rewriterepromptIdbaseVersionHashdesign-reprompt-pending:<designId>:<fileId>apply-visual-editapply-source-editwrite-sourcewrite-local-fileedit-designProduce one variant by default. Produce two or three only when the instruction
asks for options. A retry includes ; keep the same target and
base version, incorporate the feedback, and call again.
The UI previews the returned subtree without persisting it.
priorProposalIdpropose-node-rewriteUse for the accept/reject lifecycle. Accept applies the
chosen variant as one version-checked inline/Yjs content transaction so one
undo restores the prior structure; reject clears the proposal without changing
content. For conversational resolution such as "apply the second one," call
, read the active , and pass its
plus the zero-based to .
resolve-node-rewriteview-screendesign.reprompt.proposalproposalIdvariantIndexresolve-node-rewrite当聊天消息以开头时,所选子树是硬写入边界。唯一的修改路径是使用,并带上中捕获的精确、目标和。绝不要使用、、、、或任何其他内容写入操作来处理该请求。允许提出澄清问题,但请求的修改必须保持为提案形式。
[Reprompt selection]propose-node-rewritedesign-reprompt-pending:<designId>:<fileId>repromptIdbaseVersionHashapply-visual-editapply-source-editwrite-sourcewrite-local-fileedit-design默认生成一个变体。仅当指令要求提供选项时,才生成两个或三个变体。重试时需包含;保持相同的目标和基础版本,纳入反馈后再次调用。UI会预览返回的子树,但不会持久化。
priorProposalIdpropose-node-rewrite使用处理接受/拒绝生命周期。接受操作会将所选变体作为一次版本检查的内联/Yjs内容事务应用,因此一次撤销即可恢复之前的结构;拒绝操作会清除提案而不更改内容。对于诸如“应用第二个变体”的对话式决议,调用,读取活动的,并将其加上从零开始的传递给。
resolve-node-rewriteview-screendesign.reprompt.proposalproposalIdvariantIndexresolve-node-rewriteReview Quality
评审质量
- Treat the running app as the truth. Preserve its component language, tokens, route state, and real content unless the user explicitly asks for a new visual direction.
- Use multiple URL states to reveal meaningful UX moments: empty/loading/error states, focused panels, modals, responsive breakpoints, and completed flow steps when those matter to the review.
- For visual edits, compare before/after at the relevant viewport sizes and check key hover/focus/scroll states when the app exposes them.
- 将运行中的应用视为事实来源。保留其组件语言、令牌、路由状态和真实内容,除非用户明确要求新的视觉方向。
- 使用多个URL状态展示有意义的UX时刻:空/加载/错误状态、聚焦面板、模态框、响应式断点和完成的流程步骤(当这些对评审重要时)。
- 对于可视化编辑,在相关视口大小下对比修改前后,并在应用暴露相关状态时检查关键的悬停/聚焦/滚动状态。
Account And Sharing Model
账户与分享模型
- is the dedicated local-editor surface. The one-time handoff returned by
/visual-edit/:idopens it with edit access without a Design login. A copied or bareopen-visual-editURL is read-only because it does not carry the capability./visual-edit/:id - The capability permits live iframe inspection and session-local edits, undo/redo, Apply design updates through the connected host/local agent, and Copy prompt. Those flows hand bounded source instructions back to the coding agent; they do not silently persist account-owned Design data.
- Public links stay read-only without a signed-in owner/editor session. Never use the local capability to upgrade that ordinary sharing surface.
/design/:id - Prefer links returned by Design actions or deep links. Do not surface URLs with
/_agent-native/opentokens or hand-build capability URLs._session= - Do not attempt account-backed write actions with the browser capability. The
trusted local CLI call may register its bridge, create or reuse its workspace-owned local design, and place screens without an account. Direct source-file action writes, generation, saving into an account, and sharing still require an authenticated action caller. If a signed-out visitor wants those durable account operations, send them through the framework sign-in return flow first.
open-visual-edit
- 是专用的本地编辑器界面。
/visual-edit/:id返回的一次性交接链接无需Design登录即可打开并具有编辑权限。复制或无权限的open-visual-editURL是只读的,因为它不携带权限。/visual-edit/:id - 该权限允许实时iframe检查和会话本地编辑、撤销/重做、通过连接的主机/本地代理应用设计更新,以及复制提示。这些流程将受限的源指令交回编码代理;它们不会静默地持久化账户所有的Design数据。
- 公共链接在没有登录的所有者/编辑器会话时保持只读。绝不要使用本地权限升级该普通分享界面。
/design/:id - 优先使用Design操作或深度链接返回的链接。不要显示带有
/_agent-native/open令牌的URL或手动构建权限URL。_session= - 不要尝试使用浏览器权限执行基于账户的写入操作。受信任的本地CLI调用可在无需账户的情况下注册其桥接器、创建或复用其工作区所有的本地设计并放置屏幕。直接的源文件操作写入、生成、保存到账户以及分享仍需要经过身份验证的操作调用者。如果未登录的访问者需要这些持久化账户操作,请先将其引导至框架登录返回流程。
open-visual-edit
Required Local Bridge
必需的本地桥接器
The live-edit bridge is unlocked by a shared secret (the "bridge token") that
must match on two sides: the local bridge process, and the user's connection row
in Design (which the browser reads to authorize ,
, ). Get them to match by letting the
action mint the token, then starting the
bridge with it. This is the only ordering that works for the remote-MCP flow —
the bridge cannot push its own token to the server without a CLI auth token, so
the server mints instead and the bridge adopts.
/live-edit-bridge/read-file/write-fileopen-visual-editFrom the target app repo, make sure its dev server is running, then:
1. Discover routes without starting a durable bridge (one-shot, exits):
bash
npx @agent-native/core@latest design connect --url http://localhost:5173 --root . --jsonThis prints the manifest (routes + capabilities). Parse it to build
for the next step. (Skip this if the user already gave explicit
paths/URLs to place.)
routeManifestInside the agent-native monorepo itself, use the workspace CLI instead of
— installs the last published , which will not
contain local changes and costs a slow install on every call:
npxnpx@agent-native/corebash
pnpm dev:cli design connect --url http://localhost:5173 --root templates/<app> --json2. Call (see Action Flow below) with NO .
The server mints one, stores it on the user's connection row, copies it into the
placed screens' metadata, and returns it to you as . Capture it.
open-visual-editbridgeTokenbridgeToken3. Start the persistent bridge adopting that token (single line; prefer the
env var so the secret does not appear in ):
psbash
AGENT_NATIVE_BRIDGE_TOKEN="<bridgeToken from step 2>" npx @agent-native/core@latest design connect --url http://localhost:5173 --root . --daemon(Equivalently, pass .) This starts a detached bridge on
, adopts the server-minted token — so bridge and row
agree and live-edit authorizes with no self-registration — and stays alive after
the command exits.
--bridge-token <token>http://127.0.0.1:7331For a manual health/manifest check on the running bridge:
bash
curl http://127.0.0.1:7331/health/health/manifest.jsoncurl{"ok":false,"error":"invalid or missing preview token"}Only use for the step-1 route probe. Never use , ,
or for the durable step-3 bridge: they print the manifest and exit,
so Design falls back to a non-editable live iframe.
--json--json--once--dry-runThe bridge listens on a single fixed port (7331) and refuses to start for a
second, different app. It is detached with no log file, so if reports
a timeout, check for a stale process () before retrying.
--daemonlsof -ti:7331实时编辑桥接器由共享密钥(“桥接令牌”)解锁,该密钥必须在两端匹配:本地桥接器进程和Design中用户的连接行(浏览器读取该行以授权、、)。通过让操作生成令牌,然后使用该令牌启动桥接器,使两者匹配。这是远程MCP流程唯一可行的顺序——桥接器无法在没有CLI auth令牌的情况下将自己的令牌推送到服务器,因此由服务器生成令牌,桥接器采用该令牌。
/live-edit-bridge/read-file/write-fileopen-visual-edit从目标应用仓库中,确保其开发服务器正在运行,然后:
1. 发现路由而不启动持久桥接器(一次性操作,执行后退出):
bash
npx @agent-native/core@latest design connect --url http://localhost:5173 --root . --json此命令会打印清单(路由 + 功能)。解析该清单以构建下一步的。(如果用户已提供明确的路径/URL来放置屏幕,可跳过此步骤。)
routeManifest在agent-native单体仓库内部,使用工作区CLI而非——会安装最后发布的,其中不包含本地更改,且每次调用都会缓慢安装:
npxnpx@agent-native/corebash
pnpm dev:cli design connect --url http://localhost:5173 --root templates/<app> --json2. 调用(见下文的操作流程),且不传入。服务器会生成一个令牌,将其存储在用户的连接行中,复制到已放置屏幕的元数据中,并将其作为返回给您。请捕获该令牌。
open-visual-editbridgeTokenbridgeToken3. 使用该令牌启动持久桥接器(单行命令;优先使用环境变量,以免秘密出现在中):
psbash
AGENT_NATIVE_BRIDGE_TOKEN="<bridgeToken from step 2>" npx @agent-native/core@latest design connect --url http://localhost:5173 --root . --daemon(等效于传入。)此命令会在启动一个独立的桥接器,采用服务器生成的令牌——因此桥接器和连接行匹配,实时编辑无需自注册即可授权——并在命令退出后保持运行。
--bridge-token <token>http://127.0.0.1:7331要对运行中的桥接器进行手动健康/清单检查:
bash
curl http://127.0.0.1:7331/health/health/manifest.jsoncurl{"ok":false,"error":"invalid or missing preview token"}仅在步骤1的路由探测中使用。绝不要在步骤3的持久桥接器中使用、或:这些参数会打印清单并退出,导致Design回退到不可编辑的实时iframe。
--json--json--once--dry-run桥接器监听单个固定端口(7331),并拒绝为第二个不同的应用启动。它是独立运行的,没有日志文件,因此如果报告超时,请在重试前检查是否有 stale 进程()。
--daemonlsof -ti:7331Action Flow
操作流程
Prefer the single action. It registers or
refreshes the localhost bridge connection, mints and stores the bridge token,
creates or reuses a Design project, places URL-backed screens, stores the active
visual-edit context, and navigates to overview mode in one call. This avoids
creating a private design under a synthetic CLI user and then handing the browser
a tokenized URL that may be shadowed by an existing session.
open-visual-editCall it BEFORE starting the durable bridge (step 3 above): it does not contact
the bridge, so the bridge need not be running yet, and you need its returned
to start the bridge with a matching secret. Omit
on the call so the server mints one.
bridgeTokenbridgeTokenbash
pnpm action open-visual-edit '{
"title": "Docs homepage visual edit",
"devServerUrl": "http://localhost:5173",
"bridgeUrl": "http://127.0.0.1:7331",
"rootPath": "/absolute/path/to/app",
"routeManifest": { "...": "from /manifest.json" },
"paths": ["/", "/pricing", "/checkout?step=payment"]
}'The action returns , , , ,
, and a credential-free . Its MCP App metadata separately
carries the one-time editor launcher so the host can redeem it without showing
the capability to the model or retaining it in the action link. Keep
/ in the chat context for follow-ups, and pass
to (step 3) to start the bridge. On follow-up
calls reusing an existing , the same token is returned (it is
minted once and reused), so the running bridge stays valid.
designIdconnectionIdbridgeTokenscreensurlPathopenUrldesignIdconnectionIdbridgeTokendesign connectconnectionId优先选择单个操作。它会注册或刷新localhost桥接器连接,生成并存储桥接令牌,创建或复用Design项目,放置基于URL的屏幕,存储活动的可视化编辑上下文,并在一次调用中导航到概览模式。这避免了在合成CLI用户下创建私有设计,然后向浏览器传递可能被现有会话覆盖的令牌化URL。
open-visual-edit在启动持久桥接器(上述步骤3)之前调用它:它不会联系桥接器,因此桥接器无需已运行,且您需要其返回的来使用匹配的密钥启动桥接器。调用时省略,以便服务器生成一个。
bridgeTokenbridgeTokenbash
pnpm action open-visual-edit '{
"title": "Docs homepage visual edit",
"devServerUrl": "http://localhost:5173",
"bridgeUrl": "http://127.0.0.1:7331",
"rootPath": "/absolute/path/to/app",
"routeManifest": { "...": "from /manifest.json" },
"paths": ["/", "/pricing", "/checkout?step=payment"]
}'该操作会返回、、、、以及无需凭证的。其MCP App元数据单独携带一次性编辑器启动器,因此主机可在不向模型展示权限或在操作链接中保留权限的情况下兑换它。将/保留在聊天上下文中以便后续操作,并将传递给(步骤3)以启动桥接器。在复用现有的后续调用中,会返回相同的令牌(令牌仅生成一次并复用),因此运行中的桥接器保持有效。
designIdconnectionIdbridgeTokenscreensurlPathopenUrldesignIdconnectionIdbridgeTokendesign connectconnectionIdDesktop and mobile side by side
桌面端与移动端并排展示
Pass to place every requested route once per viewport. Frames lay
out as a grid: one row per route, one column per viewport. Presets are
(1280x900), (1440x900), (834x1112), and
(390x844); an explicit also works.
viewportsdesktoplaptoptabletmobile{ "label": "...", "width": N, "height": N }bash
pnpm action open-visual-edit '{
"title": "Tasks responsive visual edit",
"devServerUrl": "http://localhost:5173",
"bridgeUrl": "http://127.0.0.1:7331",
"rootPath": "/absolute/path/to/app",
"paths": ["/tasks", "/inbox"],
"viewports": ["desktop", "mobile"]
}'Prefer this over two separate calls with /: it
keeps each route's viewports aligned in a row and titles them
/ so the canvas reads clearly.
overrides /. With no /, it expands
every route in the localhost manifest, which is usually far more frames than
the user wants — name the paths.
defaultWidthdefaultHeightTasks — DesktopTasks — MobileviewportsdefaultWidthdefaultHeightroutespaths传入可为每个请求的路由按每个视口放置一次屏幕。框架会以网格布局排列:每行对应一个路由,每列对应一个视口。预设包括(1280x900)、(1440x900)、(834x1112)和(390x844);显式的格式也适用。
viewportsdesktoplaptoptabletmobile{ "label": "...", "width": N, "height": N }bash
pnpm action open-visual-edit '{
"title": "Tasks responsive visual edit",
"devServerUrl": "http://localhost:5173",
"bridgeUrl": "http://127.0.0.1:7331",
"rootPath": "/absolute/path/to/app",
"paths": ["/tasks", "/inbox"],
"viewports": ["desktop", "mobile"]
}'优先使用此方式,而非两次单独调用并传入/:它会将每个路由的视口在一行中对齐,并将其命名为 / ,使画布清晰易读。会覆盖/。如果未提供/,它会展开localhost清单中的每个路由,这通常会生成远多于用户所需的框架——请明确指定路径。
defaultWidthdefaultHeightTasks — DesktopTasks — MobileviewportsdefaultWidthdefaultHeightroutespathsAdding more page frames later
后续添加更多页面框架
Call again with the same and and
only the new paths. Existing frames for the same route and viewport are
refreshed in place rather than duplicated, and a frame the user has dragged or
resized keeps its position unless you explicitly pass ///.
open-visual-editdesignIdconnectionIdxywidthheightbash
pnpm action open-visual-edit '{
"designId": "<existing-design-id>",
"connectionId": "<existing-connection-id>",
"devServerUrl": "http://localhost:5173",
"paths": ["/settings", "/team"],
"startY": 2200
}'Do NOT add / just to restate the default size:
supplying either one marks the viewport as explicitly requested, which
overwrites frame sizes the user has already adjusted on the canvas.
defaultWidthdefaultHeightFor a numbered flow the user describes in chat, keep the labels and order:
bash
pnpm action open-visual-edit '{
"designId": "<existing-design-id>",
"connectionId": "<existing-connection-id>",
"devServerUrl": "http://localhost:1234",
"routes": [
{ "url": "localhost:1234/onboarding/1", "title": "Screen 1" },
{ "url": "localhost:1234/onboarding/2", "title": "Screen 2" },
{ "url": "localhost:1234/onboarding/3", "title": "Screen 3" }
]
}'If no or are supplied, uses every route
from the localhost manifest.
routespathsopen-visual-editFallback, only when is unavailable:
open-visual-edit- Register or refresh the bridge with , passing the
connect-localhostresult as/manifest.jsonandrouteManifest.capabilities - Create or reuse a Design project with .
create-design - Place URL-backed screens with .
add-localhost-screens - Navigate to overview mode with .
navigate
再次调用,传入相同的和以及仅新增的路径。同一路由和视口的现有框架会在原地刷新,用户已拖动或调整大小的框架会保持其位置,除非您显式传入///。
open-visual-editdesignIdconnectionIdxywidthheightbash
pnpm action open-visual-edit '{
"designId": "<existing-design-id>",
"connectionId": "<existing-connection-id>",
"devServerUrl": "http://localhost:5173",
"paths": ["/settings", "/team"],
"startY": 2200
}'不要仅为了重申默认大小而添加/:提供其中任何一个都会将视口标记为显式请求,这会覆盖用户已在画布上调整的框架大小。
defaultWidthdefaultHeight对于用户在聊天中描述的编号流程,保留其标签和顺序:
bash
pnpm action open-visual-edit '{
"designId": "<existing-design-id>",
"connectionId": "<existing-connection-id>",
"devServerUrl": "http://localhost:1234",
"routes": [
{ "url": "localhost:1234/onboarding/1", "title": "Screen 1" },
{ "url": "localhost:1234/onboarding/2", "title": "Screen 2" },
{ "url": "localhost:1234/onboarding/3", "title": "Screen 3" }
]
}'如果未提供或,会使用localhost清单中的每个路由。
routespathsopen-visual-edit仅当不可用时使用回退方案:
open-visual-edit- 使用注册或刷新桥接器,传入
connect-localhost的结果作为/manifest.json和routeManifest。capabilities - 使用创建或复用Design项目。
create-design - 使用放置基于URL的屏幕。
add-localhost-screens - 使用导航到概览模式。
navigate
Open The Design Surface
打开Design界面
- Use the ,
link, or MCP App embed returned by Design actions so the user sees the canvas. Follow Put Design Beside The Chat: prefer the MCP App; otherwise surface the credential-free Open design link.deepLink - Return or open the MCP App first. Its host-managed launcher carries the
one-time local-editor capability. The credential-free / action link is the safe read-only fallback; never build a capability URL yourself.
openUrl - Never return or open a hand-built URL.
/design/:id?_session=... - If the user is working in VS Code, the Agent Native extension can open the
same URL via
. Its
vscode://builder.agent-native/open?url=<encoded-design-url>command also starts the local bridge and opens hosted Design in the VS Code side panel.Agent Native: Open Design Canvas - After , confirm the Design editor is in overview mode with the requested URL-backed frames visible, and that they render the app rather than a spinner. Do not stop at "screens added" when the user asked to inspect or edit visually.
open-visual-edit
- 使用Design操作返回的、
link或MCP App嵌入,让用户看到画布。遵循将Design置于聊天窗口旁:优先选择MCP App;否则展示无需凭证的打开设计链接。deepLink - 优先返回或打开MCP App。其主机管理的启动器携带一次性本地编辑器权限。无需凭证的/操作链接是安全的只读回退方案;绝不要自行构建权限URL。
openUrl - 绝不要返回或打开手动构建的URL。
/design/:id?_session=... - 如果用户在VS Code中工作,Agent Native扩展可通过打开相同的URL。其
vscode://builder.agent-native/open?url=<encoded-design-url>命令还会启动本地桥接器并在VS Code侧边面板中打开托管的Design。Agent Native: Open Design Canvas - 在之后,确认Design编辑器处于概览模式,且请求的基于URL的框架可见,并渲染应用而非加载动画。当用户要求可视化检查或编辑时,不要仅停留在“已添加屏幕”的状态。
open-visual-edit
Applying Visual Edits Back To Source
将可视化编辑应用回源码
Canvas edits on a localhost screen do not write source as you make them. They
accumulate as pending edits and the editor shows an Apply design updates
button on the canvas. In an MCP App, clicking it hands the bounded structured
prompt to the current host coding conversation. In an ordinary browser or
standalone Design page, it falls back to the local Design agent. The dropdown's
Copy prompt to your agent action is the universal manual fallback.
- Style, text, and drag/drop structure edits all collect into the same pending batch, so the user can make several changes and apply once.
- After the write lands, the target app's own dev-server HMR refreshes the frames — no manual reload. If frames do not refresh, the write did not land; say so rather than assuming.
- The separate disk-icon "Apply to source" button is the deterministic
whole-file HTML/CSS writer. It is intentionally disabled for compiled
/
.jsxroutes — those must go through the agent path above..tsx
对localhost屏幕的画布编辑不会在您进行编辑时写入源码。它们会累积为待处理的编辑,编辑器会在画布上显示应用设计更新按钮。在MCP App中,点击该按钮会将受限的结构化提示交回当前主机编码对话。在普通浏览器或独立Design页面中,它会回退到本地Design代理。下拉菜单中的将提示复制到您的代理操作是通用的手动回退方案。
- 样式、文本和拖放结构编辑都会收集到同一个待处理批次中,因此用户可进行多项更改后一次性应用。
- 写入完成后,目标应用自身的开发服务器HMR会刷新框架——无需手动重新加载。如果框架未刷新,则表示写入未完成,请告知用户,而非假设已完成。
- 单独的磁盘图标“应用到源码”按钮是确定性的全文件HTML/CSS写入器。对于编译后的/
.jsx路由,它会被故意禁用——这些路由必须通过上述代理路径处理。.tsx
Editing URLs
编辑URL
Keep localhost screens as URL files plus . Do not
replace them with copied HTML unless the user explicitly asks for a
frozen snapshot. To change a state, rerun with the new
path/query or duplicate the screen and update the copy's URL metadata.
screenMetadata[fileId]srcdocopen-visual-edit将localhost屏幕保留为URL文件加上。除非用户明确要求冻结快照,否则不要用复制的HTML替换它们。要更改状态,请使用新的路径/查询重新运行,或复制屏幕并更新副本的URL元数据。
screenMetadata[fileId]srcdocopen-visual-editLocal Files in the Code Tab
代码标签页中的本地文件
Once a connection is registered, the design editor's Code panel (left rail →
Code, or ) shows a
local-files workspace root for that connection next to the design's own files.
Treat that root like VS Code opened at the connected project directory: file
tree, search, open/edit, and save are backed by the real local files. It lists
the connected app's text/code files through the bridge
( / ); build output, ,
, and secret-looking paths (, key files) are always excluded.
navigate --view editor --designId <id> --leftPanel codelist-local-filesread-local-filenode_modules.git.env*- Browsing and reading need only editor access on the design plus the running bridge.
- Saving goes through : the first save opens the write-consent dialog (an 8-hour, folder-scoped grant) and retries automatically once granted. Only text/code files are writable; secret paths are always blocked.
write-local-file - If the agent calls directly (not through a UI save) and it fails with "no write-consent grant", call
write-local-file. It opens the write-consent dialog in the editor, or reportsrequest-localhost-write-consentif one already exists. Granting is human-only —alreadyGrantedis hidden from agents, so you cannot approve it yourself. Tell the user to click "Allow writes", then retrygrant-localhost-write-consentonce. Do not keep retrying blindly: the write stays blocked until the user approves.write-local-file - Saves are conflict-checked against the file's on-disk version — a file that changed since it was read fails with a version conflict instead of being overwritten.
注册连接后,设计编辑器的代码面板(左侧边栏 → 代码,或)会在设计自身文件旁显示该连接的本地文件工作区根目录。将该根目录视为VS Code在连接的项目目录中打开:文件树、搜索、打开/编辑和保存都基于真实的本地文件。它通过桥接器列出连接应用的文本/代码文件( / );构建输出、、和类似秘密的路径(、密钥文件)始终被排除。
navigate --view editor --designId <id> --leftPanel codelist-local-filesread-local-filenode_modules.git.env*- 浏览和读取仅需设计的编辑器权限以及运行中的桥接器。
- 保存通过执行:首次保存会打开写入许可对话框(8小时有效期,文件夹范围的授权),并在获得授权后自动重试。仅文本/代码文件可写入;秘密路径始终被阻止。
write-local-file - 如果代理直接调用(而非通过UI保存)并因“无写入许可授权”失败,请调用
write-local-file。它会在编辑器中打开写入许可对话框,或在已有授权时返回request-localhost-write-consent。授权仅可由人工完成——alreadyGranted对代理隐藏,因此您无法自行批准。告知用户点击“允许写入”,然后重试一次grant-localhost-write-consent。不要盲目重试:在用户批准之前,写入会一直被阻止。write-local-file - 保存会与文件的磁盘版本进行冲突检查——自读取以来已更改的文件会因版本冲突而失败,而非被覆盖。
React Source Writeback
React源码回写
- Use compiler/debug provenance (project-relative file, line, column, component, and runtime multiplicity) to locate React/TSX source. Treat it as evidence, not as permission for a generic AST structural transform.
- Read on every anchor before you trust
positionPrecision/line.columnmeans those are the real JSX coordinates.authoredmeans they are the dev server's own output coordinates — React 19 removedtransformedand exposes only an owner stack, so this is the normal case on a Vite/Next dev server, and the line will not match the file._debugSourcemeans no tier was reported. On anything butunknown, use the file and component to find the element by its JSX shape and re-derive the line from the file you read; never edit at the reported line.authored - A single-instance leaf text edit, literal /
classNameedit, or flat literalclassproperty may usestyle={{ ... }}with aapply-visual-editsource and a completelocal-file. Forward the anchor'starget.sourceAnchorwith it — the action refuses apositionPrecisionanchor withtransformedinstead of seeking to a line that means something else in the authored file. Preview first (omitstatus: "needsAgent"), inspectpersist, then call withproposedDiff.persist: true - Reparenting, grouping/ungrouping, wrappers, dynamic expressions, repeated
instances, shared components, breakpoint-scoped edits, and cross-file changes go through the coding agent with complete subject/target anchors and their runtime relationship.
.map()refuses these withapply-visual-editrather than guessing.status: "needsAgent" - Before each write, read the file and pass its exact to
versionHashwithwrite-local-file; on conflict, re-read and re-plan. Keep the optimistic preview until HMR/runtime confirms the result. Human write consent remains mandatory and agents cannot grant it.requireExpectedVersionHash: true
- 使用编译器/调试来源(项目相对文件、行、列、组件和运行时多样性)定位React/TSX源码。将其视为证据,而非通用AST结构转换的许可。
- 在信任/
line之前,读取每个锚点的column。positionPrecision表示这些是真实的JSX坐标。authored表示这些是开发服务器自身的输出坐标——React 19移除了transformed,仅暴露所有者堆栈,因此这是Vite/Next开发服务器上的正常情况,且行号与文件不匹配。_debugSource表示未报告任何层级。对于除unknown之外的任何情况,使用文件和组件通过其JSX形状查找元素,并从您读取的文件中重新推导行号;绝不要在报告的行号处进行编辑。authored - 单实例叶子文本编辑、字面量/
className编辑或平字面量class属性可使用style={{ ... }},传入apply-visual-edit源和完整的local-file。同时传递锚点的target.sourceAnchor——如果锚点为positionPrecision,操作会拒绝并返回transformed,而非尝试定位到在原始文件中无意义的行号。先预览(省略status: "needsAgent"),检查persist,然后传入proposedDiff调用。persist: true - 重父级、分组/取消分组、包装器、动态表达式、重复的实例、共享组件、断点范围编辑和跨文件更改需通过编码代理处理,传入完整的主体/目标锚点及其运行时关系。
.map()会拒绝这些操作并返回apply-visual-edit,而非猜测。status: "needsAgent" - 每次写入前,读取文件并将其精确的传递给
versionHash,并设置write-local-file;发生冲突时,重新读取并重新规划。在HMR/运行时确认结果之前,保持乐观预览。人工写入许可仍然是必需的,代理无法批准。requireExpectedVersionHash: true
Verification
验证
- returns the expected connection and routes.
list-localhost-connections - The Design editor opens in overview mode.
- Every requested screen renders the intended localhost URL, showing real app content rather than an endless loading spinner.
- The screen iframe carries a , not a
src. A localhost screen with asrcdocis a bug, not a slow load — check it in the browser devtools before reporting the canvas as working.srcdoc - Alt-dragging a screen copies the URL-backed frame, not an inline HTML clone.
- A query/path edit changes only the target screen's URL metadata and iframe.
- The Code tab shows a local-files root for the connection and opens its files.
- 返回预期的连接和路由。
list-localhost-connections - Design编辑器在概览模式下打开。
- 每个请求的屏幕都渲染了预期的localhost URL,显示真实的应用内容而非无限加载动画。
- 屏幕iframe带有,而非
src。带有srcdoc的localhost屏幕是错误,而非加载缓慢——在报告画布正常工作之前,请在浏览器开发者工具中检查它。srcdoc - 按住Alt键拖动屏幕会复制基于URL的框架,而非内联HTML克隆。
- 查询/路径编辑仅更改目标屏幕的URL元数据和iframe。
- 代码标签页显示连接的本地文件根目录并可打开其文件。