dsh-at-file
FSMargoo/dsh-at-fileCodex 风格的 `@file` 文件引用,输入框里直接搜索并引用工作区文件。
运行在 dsh-better-sidebar 中的 Excalidraw 协作原型插件:结构化澄清产品需求、保护用户手工修改的人机画板更新,以及基于原型的前端生成。
中文 | English
面向 DSH、Codex 与其他 MCP Agent 的人机协作原型工具:先通过结构化提问把产品需求想清楚,再让 Agent 和用户在同一张 Excalidraw 画板上共同修改低保真原型,最后基于已经确认的画板生成并验收前端页面。
Draw2Code 使用一个共享 Core 和按需启动的本地 daemon。DSH 与 Codex 不互相依赖,但同时运行时会打开同一份工作区数据。
Vibe Coding 很容易从一句模糊需求直接跳到代码,结果往往是页面范围没想清楚、用户手工删除的内容被 Agent 恢复,或者 Agent 声称已经画完但用户看不到结果。Draw2Code 把协作过程拆成四个边界明确的阶段:
draw2code_create 先提取已经明确的事实,再由 Agent 围绕场景、差异化、核心闭环和关键风险提出产品专属问题。PrototypeBrief 确定性渲染成包含逐页结构、真实 mock 数据、交互关系和验收方式的完整项目简报;最后用一张页面范围确认卡明确列出将绘制的页面,用户确认前不会创建画板。http://127.0.0.1:64775/;画码会从本机已登记工作区恢复,无需先从 Codex 建立连接。用户说“打开画码,我自己画一下”时,由独立的 $draw2code-open 快速入口只调用一次 draw2code_open,不加载 Create、Update、Generate、代表页复核或质量门禁;工具内部的短期定向连接只用于把当前任务的 workspace/board 精确绑定到当前标签页,随后回到可收藏的干净根地址。draw2code_read 读取并复述页面、组件和交互关系,再按用户指令继续修改或生成。draw2code_update action=write 把语义化低保真页面写入 Excalidraw,用户可以直接拖动、删除、改字或添加便签;action=review 使用写入返回的 reviewToken 记录可见复核,不改画板 revision,也不发布新的 reveal。draw2code_read 默认只返回页面、关系、分层容量和当前 review/pending 状态,不把整板元素塞进上下文。需要内容时再按 pageIds、elementIds、区域或近期 revision 增量读取。已有 3 页以上画板的独立小改动不会被旧的首次代表页门禁拦截。drawingPlan,强制先生成代表页,复核通过后才生成其余页面。若 Agent 仍误提前提交其余页面,Update 会返回 pendingUpdateId 暂存该批 ops,复核后以 action=commit_pending 直接提交,避免整批 JSON 被丢弃和重新生成。reduce_batch_size;这与完整画板容量分开治理。画板不再设置正常业务容量:默认 32 MiB 仅进入 large 提示,256 MiB 只作为异常输入保险丝,且可配置提高;元素异常保护同步提高到 50,000。磁盘缩进、内联资源、元素数与 gzip checkpoint / delta 历史分别报告。真正触发保险丝时返回 archive_or_split_board,不会误导 Agent 反复缩小同一批次。draw2code_generate 开始前先用普通对话询问是否有参考风格图片;随后读取最新画板,让用户多选页面范围,并结合参考图或产品语义智能推荐整体视觉方向。dsh-better-sidebar 中的完整 Excalidraw 画布;draw2code_list、draw2code_read、draw2code_create、draw2code_update、draw2code_generate、draw2code_open;dsh web 可以正常启动;dsh-better-sidebar 0.12.3 或更高版本;Codex 可独立安装,不需要 DSH。首版通过本地 personal marketplace 安装,不提交公共 Plugin 目录。开发构建并把仓库的 Plugin 产物同步到 ~/plugins/draw2code 后执行:
codex plugin add draw2code@personal
安装后新建 Codex 任务,使 Skills 与六个 MCP 工具进入新会话。用户不需要进入单独的 Plugin 页面或手输工具名:选择“打开 Draw2Code / 画码”快速入口,或直接说“打开画码”,只走单次 Open;“用 Draw2Code 帮我设计一个习惯追踪 App”“帮我画原型”等产品任务才进入综合工作流。普通“帮我做一个 App”不会自动进入 Draw2Code。
draw2code_open 在 MCP/Codex 中默认使用 presentation=handoff:MCP 连接初始化时会后台预热固定入口网关和按需启动的动态 worker。普通用户直接访问 http://127.0.0.1:64775/ 即可;网关会为 loopback 浏览器自动建立 HttpOnly、SameSite=Strict 的内部会话,从本机登记表恢复最近工作区,并在写请求中校验同源 CSRF token。用户无需理解或手工维护 session。Open 工具仍会返回只含短期 code 的定向连接 URL,以保证多个 Codex 任务可分别定位自己的 workspace/board;浏览器完成定位后立即回到干净根地址,最终地址不保留 workspace 路径、画板名、token 或 code。网关或内部 worker 重启后刷新固定地址即可自动恢复。工具不注册会生成打不开卡片的静态 openai/outputTemplate;只有显式选择 presentation=browser 时才尝试启动外部浏览器。后续更新通过 WebSocket 刷新,断线时继续使用 revision polling,不反复打开窗口。localhost 会永久重定向到规范的 127.0.0.1 地址;端口被其他程序占用时会明确报错,不会静默换端口。
Draw2Code 把画板注册到 dsh-better-sidebar 提供的右侧栏中。DSH 当前只会自动启用用户直接安装的 bundle,不会自动启用另一个插件的传递依赖,因此下面两条安装命令都必须执行。
仓库提交了经过测试的 dist/ 和 lib/ 运行产物,因此普通用户不需要在本地构建:
# 1. 安装右侧栏基础插件
dsh plugin --profile web add dsh-better-sidebar
# 2. 安装 Draw2Code 稳定版
dsh plugin --profile web add github:guchang/draw2code#v0.5.0
# 3. 重启 dsh web;如果已经在运行,请先停止旧进程再启动
dsh web
如果是第一次初始化 DSH web profile,pnpm 可能会先暂停 node-pty 的原生构建,并在 $DSH_HOME/profiles/web/pnpm-workspace.yaml(默认 ~/.dsh/profiles/web/pnpm-workspace.yaml)写入待确认项。按提示把它设为允许后重跑安装命令:
allowBuilds:
node-pty: true
这是 DSH 基础运行时的首次构建授权,不是 Draw2Code 额外执行的安装脚本。
刷新 DSH 页面后,在右侧栏的 + 菜单中选择“画码”。随后可以直接在对话中说:
我想创建一个新的习惯追踪 App。
Agent 会先调用 draw2code_create 澄清需求;确认 brief 后创建独立画板并开始绘制。
git clone https://github.com/guchang/draw2code.git
cd draw2code
npm ci
npm test
dsh plugin --profile web add dsh-better-sidebar
dsh plugin --profile web add link:$(pwd)
修改源码后运行 npm run build,再重启 dsh web 并刷新页面。
Draw2Code 只在当前宿主注册的工作区内创建以下内容:
draw2code/
├── <画板名>.excalidraw.json # 原型画板
├── .active-board.json # 当前画板指针
├── .projects/ # Create 项目 brief 与版本
├── .generations/ # Generate 可恢复会话
└── .generate-settings/ # 项目级视觉方向
draw2code-pages/
└── <画板名>/index.html # 生成并验收的前端 Demo
这些运行数据已加入 .gitignore,不会进入 Draw2Code 源码仓库。
独立画码会记住 Codex、DSH 或其他宿主明确注册过的工作区,并在画板菜单中显示当前工作区及其他已经存在画板的工作区,包括名称、完整路径和画板数量;插件缓存和没有画板的空 root 不进入切换菜单。切换工作区前会先落盘当前待保存内容,再换取目标工作区的新短期凭据;原凭据不能直接读取其他工作区。Draw2Code 不扫描整台电脑,也不会自动复制、合并或迁移不同工作区的画板。
realpath 后不能越过已注册工作区;0600;固定入口为本机浏览器自动建立 HttpOnly、SameSite=Strict 会话,并以同源 CSRF token 保护写请求;Codex 定向连接码一次有效且短时过期,只用于任务/标签页隔离。网关代浏览器持有短期 workspace-scoped token,最终 URL 不暴露 root、board、token 或 code;独立画码切换工作区时仍必须经过已授权会话;/api/draw2code/* 是隐藏 token 的同源 daemon 代理;draw2code_update 使用原子写入、revision 和回读验证,不直接修改未知文件;异常保险丝与传输预算可独立调整:DRAW2CODE_MAX_SCENE_BYTES、DRAW2CODE_SOFT_SCENE_BYTES、DRAW2CODE_MAX_ELEMENTS、DRAW2CODE_MAX_OPS_BYTES、DRAW2CODE_MAX_OPS、DRAW2CODE_MAX_VERSION_STORAGE_BYTES。它们不是套餐或业务配额;日常大画板不会因为磁盘缩进或历史快照增长而突然不可写。
Codex Skill / DSH tools / future MCP clients
│
Host Adapters
│
stable loopback gateway · dynamic worker
│
Draw2CodeRuntime.execute()
│
Create state · Scene/Project store · CAS/merge · Generate gate
│
existing workspace files (no migration)
DSH Host 构建到 dist/index.js;Codex stdio MCP、固定入口网关与动态 worker 分别构建到 dist/draw2code-mcp.js、dist/draw2code-gateway.js、dist/draw2code-daemon.js;共享浏览器画板构建到 lib/canvas.html。Plugin 清单位于 .codex-plugin/plugin.json,跨宿主约束只有一份真值:workflow contract。
npm ci
npm run typecheck
npm test
npm run build
npm pack --dry-run
Draw2Code 代码采用 Apache License 2.0。内置 Excalidraw 素材继续遵循其上游 MIT License,作者与来源见 THIRD_PARTY_NOTICES.md。