关于 visual-edit
visual-edit 是通过托管的 Design 检查和编辑本地运行应用的技能。它在画布上呈现由 URL 驱动的页面,并将视觉修改建议交给编码 Agent。
主要功能
- 01在画布上展示应用路由页面
- 02通过桥接连接本地应用
- 03支持浏览器 WebMCP 和托管 MCP
- 04生成视觉编辑交接提示词
- 05共享修改保持待审状态
适用场景
- 01可视化检查多个应用路由
- 02根据运行中的页面编辑本地应用
- 03对比不同视口或路由状态
- 04将画布修改建议交给编码 Agent
MCP 相关
可通过托管 MCP 连接器或浏览器 WebMCP 工具连接 Design,包括 `open-visual-edit`。支持打开视觉编辑页面并获取待处理修改以供交接。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ builderio/ skills --skill visual-edit安装后在 Claude Code 中输入/visual-edit确认已加载。
附带文件README.md
详细介绍
视觉编辑
当用户希望以可视化方式检查或编辑真实的本地应用,而不是生成独立的 Alpine HTML 时,使用 /visual-edit。事实来源是正在运行的 localhost 应用及其路由 URL。Design 会在无限画布上将这些路由显示为由 iframe 承载的屏幕。
编辑器托管在 https://design.agent-native.com。切勿启动本地 Design;只有目标应用和桥接服务在本地运行。
请参阅 Visual Edit 指南,了解一个完整的入门流程示例。
本地快速启动
- 不要将此技能安装到目标应用中,也不要启动本地 Design 服务。此技能属于编码宿主;Design 始终是上文所述的托管应用。
- 如果你需要自行启动 Agent-Native 框架应用,请在其常规开发命令前设置
AUTH_DISABLED=1。此设置仅用于本地环境,可让视觉编辑器使用该框架的开发身份,无需用户登录。 - 如果由 Agent 启动的本地服务将所请求的屏幕重定向到
/sign-in,请使用AUTH_DISABLED=1重启该服务,并在打开 Design 前重新探测路由。切勿将登录页面当作用户请求的屏幕展示。 - 在调用
open-visual-edit前,先确认目标 URL 能正常响应。若由 Agent 启动的开发服务已停止,请使用其常规命令启动,并等待所请求的路由正常响应后再打开 Design。切勿在画布上留下失效的 localhost URL。 - 保留并非由你启动的服务;使用其现有的已认证浏览器会话,或说明需要登录的是目标应用,而不是 Design。
- 当用户提供了明确路径时,跳过路由清单,直接放置这些路径。只有用户未提供路径时,才发现路由。
安装
npx @agent-native/core@latest skills add visual-edit 会安装此技能和托管的 Design MCP 连接器。npx skills@latest add BuilderIO/agent-native --skill visual-edit 仅安装说明;支持页面能力的 WebMCP 宿主无需安装连接器。
将 Design 放在聊天旁边
优先使用 open-visual-edit 提供的 MCP App:它会将 Design 放在聊天旁边。使用 复制提示词 将视觉编辑交给编码 Agent;宿主可能会要求确认对话。否则,openUrl 是无需凭据的只读备用方案;切勿声称它可编辑。
- 支持内嵌浏览器的宿主应打开
https://design.agent-native.com/visual-edit并调用其open-visual-editWebMCP 工具。登录或未登录均可使用;一次性能力凭证并非 Design 账户会话。只需使用支持页面的浏览器控制器,因此 Claude-in-Chrome、Claude Code 浏览器工具、ChatGPT Chrome/浏览器扩展、Puppeteer 或 Playwright MCP、CDP,以及其他类似的 JavaScript 控制器,都无需安装托管的 MCP 连接器。 - VS Code 使用其 Design webview/深层链接。若不支持页面 WebMCP,请使用托管的 Design MCP 连接器,并按常规流程进行 OAuth/设备授权。切勿用本地 Design 服务替代这两种方式。
在 Design 中,使用 Cmd K 菜单里的 显示/隐藏 UI,或按 Shift \ 快捷键,切换所有编辑界面元素,只保留画布。
Browser WebMCP(默认不使用连接器)
如果没有连接已连接的 Design MCP,请使用带有主世界 JavaScript 求值器的可见浏览器标签页。优先使用宿主提供的内置浏览器;仅在用户要求或内置浏览器不可用时使用外部 Chrome。打开
https://design.agent-native.com/visual-edit,在工具注册期间保持页面可见,并在开始工作前读取标题。切勿输入、复制或索要密码、Cookie、令牌或验证码。未登录状态下的 loopback visual-edit 可用;其他因未登录而阻止工具使用的页面仍需要已登录的标签页。
如果浏览器支持 CDP 权限,请在调用页面工具前,向
https://design.agent-native.com 授予
local-network-access 权限;否则使用页面上的 Connect 按钮,并等待浏览器完成权限提示。
如果宿主提供原生浏览器会话 WebMCP 桥接,请使用它:通过 list-browser-session-webmcp-tools 列出一次,再通过
run-browser-session-webmcp-tool 运行;也可以使用 list-host-webmcp-tools 和
run-host-webmcp-tool 这一对工具。保持发现的名称、来源和参数完全一致。否则请使用页面世界 API。Agent-Native 页面提供了此辅助函数:
示例假设已登录或已有桥接;全新的未登录 loopback 连接必须添加下文所述的本地持有的 bridgeToken。
const an = window.__agentNativeWebMcp;
const status = await an.ready({ waitMs: 20_000 });
if (status.state !== "ready") throw new Error(status.error ?? status.state);
const tools = await an.tools("visual-edit");
if (!tools.some((tool) => tool.name === "open-visual-edit")) {
throw new Error("open-visual-edit is not registered yet");
}
const result = await an.call("open-visual-edit", {
devServerUrl: "http://localhost:5173",
paths: ["/"],
navigate: true,
}, { waitMs: 2_000 });
if (result.state === "pending") {
// On the next evaluation, read the still-running call without replaying it.
an.result(result.id);
}
如果没有该辅助函数,请直接使用标准 WebMCP。document.modelContext 是规范接口;navigator.modelContext 已弃用:
const ctx = document.modelContext;
const tool = (await ctx.getTools()).find((candidate) => candidate.name === NAME);
if (!tool) throw new Error(`WebMCP tool not found: ${NAME}`);
const codex = typeof ctx.codexExecuteTool === "function" ||
typeof ctx.codexGetTools === "function";
const result = await ctx.executeTool(tool, codex ? ARGS : JSON.stringify(ARGS));
此辅助函数可处理实时发现、不完整的注册表和待处理调用。如果调用返回 state: "pending",请在下一次求值时读取 an.result(id);切勿重放写入操作。对于 Claude Code 或 Cowork,javascript_tool 使用顶层 await 执行此页面世界代码;对于 Codex,使用 cua.createBrowserTab("iab", url, { visible: true }) 打开页面,然后通过 CDP Runtime.evaluate 并设置 awaitPromise: true;Puppeteer 和 Playwright MCP 可使用其页面求值器。Playwright 隔离世界无法访问 document.modelContext。保持求值器输出简短,将有依赖关系的调用批量处理,并且不要在批处理中导航。
工具描述符仅在页面本地有效。不要将其复制到宿主,不要手动构造经过身份验证的 HTTP 请求,也不要用点击、输入、DOM 自动化或截图替代具名工具。对于没有具名工具的画布操作,或用户明确要求时,仍可使用 UI 自动化。如果在一次发现和一次独立的求值器检查后,这两种桥接方式都不可用,请先使用托管 MCP/CLI,再更改状态。
对于全新的未登录 loopback 连接,请在本地生成桥接令牌,用该令牌启动持久桥接,并在页面工具中将同一令牌作为 bridgeToken 传递一次;页面不会返回该令牌。若已有匹配的运行中桥接,请复用它,无需提供令牌。与账户绑定的或私有的 Design 工作需要已登录会话,或经过身份验证的 Design MCP 连接器。完成画布编辑后,调用 an.call("get-visual-edit-prompt", {}, { waitMs: 2_000 }),并应用返回的交接内容。页面工具可能会显示批准对话框;请让用户批准,切勿绕过该同意流程。
核心模型
- 每个屏幕都是由 URL 驱动的 iframe,而非复制的 HTML。
- 每个屏幕都会保留 URL 元数据:
connectionId、routeId、path、url、bridgeUrl、标题和视口大小。 - 所有者通过本地桥接进行编辑。共享的
/visual-edit/:designId?share=1链接会渲染经过净化的惰性快照, 并在路由或 DOM 发生变化时刷新;访客无法访问所有者的 localhost。 访客的编辑会保持待处理状态,直到所有者或编辑者将其应用到源代码。 - 私有设计的授权查看者和评论者可以编辑共享的 Visual Edit 画布并提交待处理更改,而不会写入设计文件。 所有者或编辑者会将这些更改应用到源代码。
/visual-edit技能无需登录 Design 账号。open-visual-edit会为精确的/visual-edit/:designId本地编辑器路由创建一个有效期为五分钟、只能使用一次的能力令牌。MCP 主机会在模型不可见的文本之外兑换该令牌,然后打开现有编辑器并授予 localhost 编辑权限。 公共/visual-edit/:designId路由支持仅通过浏览器编辑公共 localhost 快照的 DOM;交接的更改会保持待处理状态,直到被应用。收件人有待处理更改时,所有者会看到 应用编辑。 此能力令牌不是账号会话:/_agent-native/session仍显示为已登出,基于账号的保存、共享和生成操作仍会被拒绝。- 托管 MCP 突出显示
get-visual-edit-pending;传入 visual-edit 设计 ID,即可在无需切换标签页的情况下交接。它会返回一个版本号;应用更改后,使用该版本号调用acknowledge-visual-edit-pending,然后再次拉取。empty表示没有编辑;session-ended表示编辑已丢失;unknown表示标记无法读取,并不能证明没有更改。 - 浏览器主机可以使用页面本地的
get-visual-edit-prompt。 open-visual-edit操作由 Design 提供。从其他应用调用时,请使用https://design.agent-native.com/mcp上的托管 MCP 服务或页面的 WebMCP 辅助工具,而不要在目标应用中运行pnpm action。页面路径仅在公共模式下对回环应用开放免登录访问,并使用短时有效、受能力令牌范围限制的主体;托管 MCP 使用其常规 OAuth 身份。- 普通公共链接仍为只读。公共
/visual-edit/:designId和经授权的私有共享允许仅编辑 DOM,绝不写入源代码。访客的 Interact 会被阻止;快照会剥离活动内容和所有者本地资源,持久化写入仍受角色限制。回环地址不是信任边界,因为隧道可能会代理远程调用者。 - 通过本地桥接代理,实时编辑器使用同源方式运行。这可以启动 CSR 应用和根相对路径资源,但它仍是 localhost 编辑代理:要与应用自身的源站实现完全一致,可能需要未来的开发服务器/插件集成,以支持应用源站 Cookie、WebSocket/HMR、SSE 和非 GET 应用 API 调用。
- 画布是编辑视图;Interact 会运行带有侧栏和设备栏的常规 URL。Interact 保留导航、滚动、链接和控件;画布则支持平移/缩放,并禁止原生框架交互。
- 当 localhost 屏幕存在待处理的实时视觉编辑时,在用户将编辑应用到源代码或明确中止/丢弃预览之前,不要切回 Interact。
- 按住 Alt 拖动可复制 localhost 框架及其 URL 元数据。要查看其他状态,请更改副本的路径/查询参数;命名或编号流程的顺序应保持不变。
类似
localhost:1234/onboarding/1的简写表示http://localhost:1234/onboarding/1。
有用的画布集
默认使用聚焦的批次,包含 3-7 个画框:每个请求的路由/查询状态对应一个有序画框;在用户要求的桌面、平板和移动视口重复展示路由;并包含可通过 URL 访问的空状态、加载状态、错误状态、模态框打开状态或已选中项目状态。保持 Screens 部分易于阅读,以便编辑时 Layers 仍然实用。除非用户明确要求进行全面审查或完整路由清单,否则不要扩展到 7 个以上的画框。
除非用户要求进行全面审查,否则不要扩展每条发现的路由或每个视口。保留用户的标签和顺序,让画布符合他们描述的工作流。
选择并重新提示
当聊天消息以 [Reprompt selection] 开头时,选定的子树就是不可越过的写入边界。唯一允许的修改路径是 propose-node-rewrite,并且必须使用从 design-reprompt-pending:<designId>:<fileId> 中捕获的准确 repromptId、目标和 baseVersionHash。对于该请求,绝不可使用 apply-visual-edit、apply-source-edit、write-source、write-local-file、edit-design 或任何其他内容写入操作。可以提出澄清问题,但用户要求的修改必须保持为提案。
默认生成一个变体。只有当指令要求提供选项时,才生成两个或三个。重试时包含 priorProposalId;保持相同目标和基础版本,纳入反馈,然后再次调用 propose-node-rewrite。UI 会预览返回的子树,但不会将其持久化。
使用 resolve-node-rewrite 处理接受/拒绝流程。接受会将选定的变体作为一个经过版本校验的 inline/Yjs 内容事务应用,因此一次撤销即可恢复先前结构;拒绝会清除提案,且不更改内容。对于“应用第二个”这类对话式决策,请调用 view-screen,读取当前的 design.reprompt.proposal,并将其 proposalId 和从零开始的 variantIndex 传给 resolve-node-rewrite。
审查质量
以运行中的应用为准,保留其组件风格、设计令牌、路由状态和内容。在用户要求的视口下比较视觉编辑前后的效果,并检查重要的 URL、悬停、焦点、滚动和模态框状态。
账户与共享模型
- 此功能允许检查实时 iframe、进行会话内编辑、撤销/重做,以及使用 Copy prompt。复制的指令会发送给编码 Agent;不会持久化属于账户的 Design 数据。
- 公开的
/design/:id链接在没有已登录的所有者/编辑者会话时保持只读。绝不要使用本地功能来升级普通共享页面。 - 优先使用 Design 操作返回的链接或
/_agent-native/open深层链接;绝不要显示_session=令牌或手动构造功能 URL。 - 不要通过浏览器功能尝试执行账户写入操作。受信任的本地
open-visual-editCLI 调用可以注册其桥接、创建或复用由工作区拥有的本地设计,并在没有账户的情况下放置屏幕。直接写入源文件的操作、生成、保存到账户以及共享仍要求调用操作的用户已通过身份验证。如果已登出的访客需要执行这些持久化账户操作,应先通过框架的登录后返回流程引导他们完成登录。
必需的本地桥接
实时编辑桥接通过共享密钥(“桥接令牌”)解锁,该令牌必须在两端匹配:本地桥接进程,以及用户在 Design 中的连接行(浏览器会读取该行,以授权 /live-edit-bridge、/read-file、/write-file)。通过让 open-visual-edit 操作生成令牌,然后使用该令牌启动桥接,使两端匹配。这是远程 MCP 流程唯一可行的顺序——桥接无法在没有 CLI 身份验证令牌的情况下将自己的令牌推送到服务器,因此由服务器生成令牌,再由桥接接管。
connectionId(通常为 localhost_...)仅用于标识该行;绝不要将其作为 bridgeToken 传递。
对于全新的未登录浏览器流程,在本地生成令牌,将其保存在宿主进程中,并将其作为页面工具的可选 bridgeToken 传递一次;页面绝不会返回该令牌:
BRIDGE_TOKEN="$(node -e 'process.stdout.write(require("node:crypto").randomBytes(32).toString("hex"))')"
AGENT_NATIVE_BRIDGE_TOKEN="$BRIDGE_TOKEN" npx @agent-native/core@latest design connect --url http://localhost:5173 --root . --daemon
如果已有匹配的连接,则无需传递 bridgeToken 即可复用;当页面 WebMCP 不可用时,托管 MCP 可以生成令牌。
在目标应用仓库中,确保其开发服务器正在运行,然后:
1. 发现路由,但不启动持久桥接(运行一次后退出):
npx @agent-native/core@latest design connect --url http://localhost:5173 --root . --json
这会打印清单(路由 + 功能)。解析该清单,为下一步构建 routeManifest。(如果用户已提供要放置内容的明确路径或 URL,则跳过此步骤。)
在 agent-native 单体仓库内部,请使用工作区 CLI,而不要使用 npx——npx 会安装最新发布的 @agent-native/core,其中不包含本地更改,而且每次调用都会耗费时间进行安装:
pnpm dev:cli design connect --url http://localhost:5173 --root templates/<app> --json
2. 对于托管 MCP 流程,调用 open-visual-edit(参见下方的操作流程),
不要传入 bridgeToken。
服务器会生成一个令牌,将其存储在用户的连接行中,将其复制到已放置屏幕的元数据中,并通过 bridgeToken 返回给你。请保存该令牌。
3. 启动持久桥接并接管该令牌(单行命令;优先使用环境变量,以免密钥出现在 ps 中):
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 启动一个分离运行的桥接,并接管服务器生成的令牌——这样桥接和连接行中的令牌就一致,实时编辑无需自行注册即可通过授权——并且命令退出后桥接仍会保持运行。
如需手动检查运行中桥接的健康状态或清单:
curl http://127.0.0.1:7331/health
/health 无需令牌。/manifest.json 中的完整清单受预览令牌保护,因此未经身份验证的 curl 请求会返回 {"ok":false,"error":"invalid or missing preview token"}——此响应意味着桥接已启动,而非出现故障。
路由探测的第 1 步只能使用 --json。持久桥接的第 3 步绝不要使用 --json、--once 或 --dry-run:这些参数会打印清单后退出,导致 Design 回退到不可编辑的实时 iframe。
桥接仅监听一个固定端口(7331),并拒绝为第二个不同的应用启动。它以分离模式运行且不创建日志文件,因此如果 --daemon 报告超时,请在重试前检查是否存在过期进程(lsof -ti:7331)。
如果本地 Design 使用 PGlite,绝不要对该服务器调用进程内 CLI:两者会打开同一目录,第二个所有者会被拒绝。对于未登录的本地测试,请使用 AUTH_DISABLED=1 启动 Design,打开 /visual-edit,并在 window.__agentNativeWebMcp 注册后,通过它调用服务器操作 open-visual-edit。这样可以确保只有一个 PGlite 所有者;get-visual-edit-prompt 仅用于编辑后的交接。启用身份验证时,请先登录托管 Design MCP,或改用共享 Postgres,再使用 CLI 操作。
操作流程
浏览器可用时,复用本地桥接,并调用 Design 页面中的
open-visual-edit WebMCP 工具。对于全新且未登录的连接,传入
本地持有的 bridgeToken;该工具会读取其预览清单和挑战证明,
然后发送两者以供验证。托管版 Design 绝不会获取 127.0.0.1。如果
页面没有 WebMCP,则使用已连接的 Design MCP 服务或其常规托管版
MCP 回退方案。
从另一个应用调用已连接的 Design MCP 工具
mcp__agent-native-design__open-visual-edit,并传入以下 JSON 参数。它会
注册或刷新 localhost 桥接,签发并存储桥接令牌,创建或复用 Design 项目,
放置由 URL 支持的屏幕,存储视觉编辑上下文,并在一次调用中导航到概览模式。
切勿在目标应用的检出目录中运行 pnpm action:其本地注册表不包含 Design 操作。
在启动持久桥接之前调用它:该工具不会联系桥接,因此
服务可以为桥接签发 bridgeToken,供其接管。省略此输入。
{
"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"]
}
该操作会返回 designId、connectionId、bridgeToken、screens、
urlPath 和不含凭据的 openUrl。MCP App 元数据中包含隐藏的一次性启动器。
保留这些 ID 以供后续操作使用,并将令牌传给 design connect;复用该连接时也会复用其令牌。
并排显示桌面端和移动端
传入 viewports,即可为每个请求的视口放置每个路由一次。画布会
以网格布局:每个路由占一行,每个视口占一列。预设包括
desktop(1280x900)、laptop(1440x900)、tablet(834x1112)和 mobile
(390x844);也可以使用显式参数 { "label": "...", "width": N, "height": N }。
{
"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"]
}
优先使用此方式,而不是分别调用两次并传入 defaultWidth/defaultHeight:
这样每个路由的视口会在同一行对齐,标题也会设为
Tasks — Desktop / Tasks — Mobile,使画布内容一目了然。viewports
会覆盖 defaultWidth/defaultHeight。如果没有 routes/paths,它会展开
localhost 清单中的所有路由,通常会生成远超用户所需的屏幕——请指定路径。
手动管理屏幕和断点
选中一个屏幕,然后使用右侧栏中的 Screen 部分,在静态 HTML 和 URL 支持模式之间切换、
编辑其路由/路径、选择 localhost 连接、添加另一个 URL 屏幕,或移除所选屏幕。URL 模式会
保持 iframe 实时运行;切换到静态模式时,会存储当前画面的净化快照,其中包括
当前客户端状态(前提是页面能够提供该状态)。具备页面操作能力的 Agent 也可通过
add-localhost-screens、update-screen-source、add-breakpoint 和
remove-breakpoint 执行相同操作。
稍后添加更多页面画面
再次调用 open-visual-edit,传入相同的 designId 和 connectionId,并且
只包含新的路径。缺少 ID 时会恢复同一连接的已保存项目;newDesign: true 会创建单独的项目。
匹配的画面会原地刷新,并保留用户调整的几何属性,除非传入坐标。
{
"designId": "<existing-design-id>",
"connectionId": "<existing-connection-id>",
"devServerUrl": "http://localhost:5173",
"paths": ["/settings", "/team"],
"startY": 2200
}
不要仅为重申默认尺寸而添加 defaultWidth/defaultHeight:
传入其中任意一个都会将视口标记为显式请求,从而
覆盖用户已在画布上调整的画面尺寸。
对于用户在聊天中描述的编号流程,请保留标签和顺序:
{
"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" }
]
}
如果未提供 routes 或 paths,open-visual-edit 会使用
localhost 清单中的所有路由。
仅当 open-visual-edit 不可用且已获授权使用托管版 Design MCP 时,才使用回退方案:
- 使用
connect-localhost注册或刷新桥接,并将/manifest.json的结果作为routeManifest和capabilities传入。 - 使用
create-design创建或复用 Design 项目。 - 使用
add-localhost-screens放置由 URL 支持的屏幕。 - 使用
navigate导航到概览模式。
回退方案的目标仍是 https://design.agent-native.com;只有应用和
桥接 URL 使用 localhost。切勿在 templates/design 中运行 pnpm action。
打开 Design 画布
- 使用 Design 操作返回的
link、deepLink或 MCP App 嵌入内容,让用户看到画布。优先使用 MCP App;其宿主启动器会携带一次性能力凭证。不含凭证的openUrl是只读备用方案。 - 切勿返回或打开自行拼接的
/design/:id?_session=...URL。 - 如果用户正在使用 VS Code,Agent-Native 扩展可以通过
vscode://builder.agent-native/open?url=<encoded-design-url>打开相同的 URL。其Agent-Native: Open Design Canvas命令还会启动本地桥接服务,并在 VS Code 侧边栏中打开托管的 Design。 open-visual-edit返回预期的screenCount后,交付链接并停止。不要使用浏览器自动化工具自行打开它来截图或轮询页面是否完成渲染——无论是否有人查看,冷启动的开发服务器都可能需要 10-30s,而等待并不会增加响应已确认的信息。只有当用户之后报告画布无法正常工作时,才使用浏览器自动化。
将视觉编辑应用回源代码
关闭 Design 后,调用托管的 Design MCP 高亮显示的
get-visual-edit-pending,并传入设计 ID;它会返回交接内容和修订版本。验证已应用的源代码,确认该修订版本,然后再次拉取。
如果 MCP 不可用,请读取本地桥接服务:
npx @agent-native/core@latest design pending --root . --design-id <design-id-from-visual-edit-url>
在 Design URL 中 visual-edit 后传入 ID;CLI 会打印该设计的提示词(为空时为 null)。
localhost 屏幕上的画布编辑不会直接写入源代码。它们会保持待处理状态,直到编码 Agent 使用 get-visual-edit-pending 或复制的提示词拉取,然后写入源代码。画布上没有单独的“应用”按钮。MCP App 会通过宿主或本地 Design Agent 发送提示词;否则请使用 复制提示词给你的 Agent。
ChatGPT 和 Claude Code 应先拉取、应用、确认,然后再次拉取。
浏览器 WebMCP 宿主可以调用 get-visual-edit-prompt。应用源代码更改之前,切勿确认。
- 样式、文本和拖放编辑会汇总为一个待处理批次,以便一次性应用。
- 写入生效后,目标应用自身的开发服务器 HMR 会刷新画面——无需手动重新加载。如果画面没有刷新,说明写入未生效;请如实说明,不要想当然。
- 单独的磁盘图标“应用到源代码”按钮是用于写入整个 HTML/CSS 文件的确定性写入器。它会有意对已编译的
.jsx/.tsx路由禁用——这些路由必须通过上述 Agent 流程处理。
编辑 URL
将 localhost 屏幕保留为 URL 文件加 screenMetadata[fileId]。除非用户明确要求冻结快照,否则不要用复制的 srcdoc HTML 替换它们。若要更改状态,请使用新的路径/查询参数重新运行 open-visual-edit,使用 Screen settings 部分,调用 update-screen-source,或复制屏幕并更新副本的 URL 元数据。
代码选项卡中的本地文件
注册连接后,设计编辑器的「代码」面板(左侧栏 →
「代码」,或 navigate --view editor --designId <id> --leftPanel code)会在设计自身文件旁显示该连接的本地文件工作区根目录。请将其视为在已连接项目目录中打开的 VS Code:文件树、搜索、打开/编辑和保存操作都由真实的本地文件支持。它通过桥接程序列出已连接应用的文本/代码文件(list-local-files / read-local-file);构建输出、node_modules、.git 和看起来包含机密的路径(.env*、密钥文件)始终会被排除。
- 浏览和读取只需要对该设计的编辑器访问权限,以及正在运行的桥接程序。
- 保存通过
write-local-file完成:首次保存会打开写入许可对话框(有效期为 8 小时,并限定于指定文件夹),获批后会自动重试一次。只有文本/代码文件可写入;机密路径始终会被阻止。 - 如果 Agent 直接调用
write-local-file(而非通过 UI 保存)并因「no write-consent grant」而失败,请调用request-localhost-write-consent。该调用会在编辑器中打开写入许可对话框;如果许可已存在,则会报告alreadyGranted。只有人类可以授予许可——Agent 看不到grant-localhost-write-consent,因此无法自行批准。请告知用户点击「允许写入」,然后重试一次write-local-file。不要盲目反复重试:用户批准前,写入会一直被阻止。 - 保存时会根据文件在磁盘上的版本进行冲突检查:文件自读取后若发生更改,保存会因版本冲突而失败,不会覆盖该文件。
React 源码回写
- 使用编译器/调试来源信息(相对于项目的文件路径、行、列、组件和运行时实例数量)定位 React/TSX 源码。请将其视为依据,而非对通用 AST 结构转换的许可。
- 信任
line/column前,先读取每个锚点上的positionPrecision。authored表示这些坐标是真实的 JSX 坐标。transformed表示这些坐标是开发服务器自身输出中的坐标——React 19 移除了_debugSource,只公开所有者堆栈,因此这是 Vite/Next 开发服务器上的常见情况,行号不会与文件匹配。unknown表示未报告精度级别。若不是authored,请根据文件和组件找到 JSX 形态匹配的元素,并根据读取的文件重新推导行号;切勿在报告的行号处编辑。 - 单实例叶节点文本编辑、字面量
className/class编辑,或扁平字面量style={{ ... }}属性编辑,可以使用带有local-file来源和完整target.sourceAnchor的apply-visual-edit。同时传入锚点的positionPrecision——如果锚点为transformed,该操作会以status: "needsAgent"拒绝,而不会跳转到源码文件中含义不同的行。先预览(省略persist),检查proposedDiff,然后再以persist: true调用。 - 重新挂接、分组/取消分组、包装器、动态表达式、重复的
.map()实例、共享组件、限定断点的编辑和跨文件更改,都应交由编码 Agent 处理,并提供完整的主体/目标锚点及其运行时关系。对于这些操作,apply-visual-edit会以status: "needsAgent"拒绝,而不会进行猜测。 - 每次写入前,都要读取文件,并将其精确的
versionHash与requireExpectedVersionHash: true一同传给write-local-file;若发生冲突,请重新读取并重新制定计划。保留乐观预览,直到 HMR/运行时确认结果。人类授予写入许可仍是强制要求,Agent 无法授予许可。
验证
对于单纯的“打开此应用”请求,open-visual-edit 自身的响应就是验证结果——参见打开设计画布。仅在诊断实际报告的问题或确认已应用的编辑生效时,才使用以下检查:
list-localhost-connections返回预期的连接和路由。- 设计编辑器以概览模式打开。
- 每个请求的屏幕都呈现预期的 localhost URL,显示真实的应用内容,而不是无限加载的旋转图标。
- 屏幕 iframe 使用
src,而非srcdoc。localhost 屏幕使用srcdoc是错误,不是加载缓慢——在报告画布正常工作之前,先在浏览器开发者工具中检查。 - 按住 Alt 并拖动屏幕时,复制的是由 URL 驱动的框架,而不是内嵌 HTML 克隆。
- 查询参数/路径编辑只会更改目标屏幕的 URL 元数据和 iframe。
get-visual-edit-pending是无需切换标签页的交接方式;应用后确认其修订版本。get-visual-edit-prompt是浏览器中的对应方式。- “代码”标签页显示该连接的本地文件根目录,并能打开其中的文件。