PRD:dsh-design(DSH 原型画布)

August 21, 2026 · View on GitHub

字段
产品dsh-design
版本MVP 0.1
状态Approved for implementation
仓库本仓库(开源 MIT bundle)
日期2026-08-20

1. Executive Summary

问题。 在 DeepSeek Harness 里做界面,Agent 只能在聊天里丢 HTML 代码块。用户看不见真实交互,也无法自己点一遍登录、切 tab、弹窗。Tutti 的 Prototype Design(vibe-design)解决了「可点原型」,但它是第二套 Agent 运行时,和 DSH 会话抢控制权。

方案。 做一个官方形态的 DSH bundle:聊天仍只用当前 DSH 会话。插件提供 Agent 可调用的工具,把可点击的 HTML 写进当前 workspace;预览挂在已安装的 dsh-better-sidebar 的「原型」tab。用户在侧边栏点交互,要改就回到同一个输入框。

成功标准。 用户说「做个登录页」→ Agent 调用工具写出 HTML → 侧边栏原型 tab 能打开并能点提交/校验;用户说「按钮再大」→ Agent 覆写同一文件 → 预览更新。全程不出现第二套对话框,不拉起 Claude / Codex。

2. Problem Definition

2.1 用户问题

  • Who:在 DSH 里同时写产品和前端的开发者 / 设计师 / PM;已装 better-sidebar。
  • What:需要「能点的原型」,而不是聊天里的代码块。
  • When:探索界面、对齐交互、给 Agent 视觉反馈的时候。
  • Where:DSH Desktop / web profile 的当前 workspace。
  • Why:DSH 有模型和写文件,没有设计画布;把 vibe-design 整仓搬过来会引入第二套 Agent。
  • Impact:不解决就继续复制粘贴、截图、口头描述按钮位置。

2.2 非目标市场

不是 Tutti 多 Agent 工作台,也不是 Figma。不做多人实时、不做设计系统后台、不做从零实现的独立 IDE。

3. Solution Overview

3.1 一句话

聊天还是 DSH,画布挂在 better-sidebar。

3.2 用户旅程

用户在 DSH 输入框:「做个移动端登录页,要有忘记密码」


当前会话 Agent
  design_status → design_create → design_write(index.html) → design_open


workspace/.dsh-design/projects/<id>/index.html


better-sidebar「原型」tab(+ 菜单可手动打开)
  拉取 snapshot → loopback 静态预览 iframe 渲染 → 用户自己点


用户:「主按钮再大,错误态用红字」


同一会话 Agent 再 design_write → 预览按 revision 刷新

3.3 In Scope(MVP / P0)

ID能力优先级
FR1Host 工具:创建项目、写 HTML、列出文件、打开预览、查看状态P0
FR2产物落在当前 workspace 的 .dsh-design/,可进 gitP0
FR3ctx.systemPrompt.section 指导 Agent:自包含可运行 HTML,不要空谈P0
FR4better-sidebar 注册单实例 tab dsh-design:prototypeP0
FR5tab 内 iframe 预览当前页,用户可点P0
FR6未安装 better-sidebar 时插件不崩,工具仍能写文件P0
FR7官方 bundle 契约:dsh.bundle.patch + dsh.client,不改 DSH 源码P0

3.4 Out of Scope

  • 第二套 Agent / ACP / 再拉起 Claude Code 或 Codex
  • 插件内聊天窗、项目仪表盘、属性检查器、画布就地改 HTML
  • 任何官方 UI 槽:sidebar.footer.actionshell.overlay、官方 sidebar。唯一入口是 better-sidebar 的「原型」tab
  • 16 套设计系统管理后台(MVP 只在 system prompt 里给生成约束)
  • 批注钉点:已做坐标 sidecar;截图 / DOM 锚定仍不在本迭代
  • 多页相对资源:已做;最多两层目录(css/app.css、assets/logo.png)
  • value-import dsh-better-sidebar@deepseek-ai/schemastery

3.5 MVP 完成定义

  1. pnpm test(或 node --test)在无 DSH peer 时跳过 Host 注册、在有 store 时全绿。
  2. 工具能在临时目录创建项目并写出可解析的 HTML。
  3. Client bundle 是 window.__ModuleLoader__.load,软挂 betterSidebar
  4. README 写清:聊天框设计 → 侧边栏点。

4. User Stories

US1 — 用聊天生成可点原型

As a DSH 用户,I want 在输入框里让当前 Agent 设计界面,So that 我不用离开会话去别的设计工具。

Acceptance:

  • Agent 使用 design_* 工具,而不是只在聊天里贴一大段未落盘代码
  • .dsh-design/projects/<id>/ 下有 project.json 和至少一个 .html
  • 不出现插件自己的 composer

US2 — 在侧边栏点交互

As a 已安装 better-sidebar 的用户,I want 在右侧「原型」tab 里点这个页面,So that 我能验证登录、tab、弹窗是否真的能用。

Acceptance:

  • + 菜单有「原型」/ Prototype
  • 当前打开的 HTML 在沙箱 iframe 里运行脚本和表单
  • tab 不可见时不轮询

US3 — 同一会话里改稿

As a 用户,I want 看完再说「改这里」,So that 上下文不丢。

Acceptance:

  • Agent 覆写同一文件后 current.revision 变化
  • 打开的 tab 刷新预览,不必手动重建项目

US4 — 没装 better-sidebar 也不炸

As a 只装了本插件的用户,I want Agent 仍然能把 HTML 写进仓库,So that 我可以用浏览器或别的预览打开文件。

Acceptance:

  • betterSidebar 不在静态 inject
  • 服务缺失时注册跳过
  • Host 工具与 RPC 仍可用

5. Functional Requirements

ID需求优先级
FR-T1design_status:当前 workspace 的项目列表与 current 预览P0
FR-T2design_create:按标题建项目P0
FR-T3design_write:向项目写入文本文件(默认 .html);open 默认 trueP0
FR-T4design_list:列出项目内页面P0
FR-T5design_open:把某 HTML 标为当前预览并 bump revisionP0
FR-P1路径限制在 <cwd>/.dsh-design/**,拒绝 .. 与绝对路径P0
FR-P2文件名 ^[A-Za-z0-9._-]{1,128}$,扩展名 html|css|js|svg|png|jpg|gif|webp|icoP0
FR-P3单文件上限 512KiB;超限失败,不截断装成成功P0
FR-U1Client RPC snapshot / file,payload 带 cwdP0
FR-U2iframe sandbox="allow-scripts allow-forms",无 allow-same-originP0
FR-U3预览用 loopback 静态服务 iframe src(相对资源可解析)P0
FR-S1better-sidebar tab id dsh-design:prototypesingle: true,order 55P0
FR-S2通过 ctx.plugin({ inject: ['betterSidebar'] }) 子 fiber 挂载P0

6. Design & UX

6.1 原则

  • 生成内容是主角:chrome 让路给 iframe。
  • 文案说用户能做什么,不说 RPC / bundle。
  • 空状态给下一步:「在聊天里描述一个界面」而不是「暂无数据」。
  • 失败说清:cwd 没有、文件超限、项目不存在。

6.2 原型 tab 视觉

工作台是「灯箱」:暗色舞台托住一张白纸原型,而不是再做一套聊天皮肤。

TokenHex用途
stage#252A32tab 底
brass#C9A36A唯一强调:当前页标记、空状态短线
ink#E8EDF2主文字
dim#8B95A1次级文字
rule#3A424C分割
paper#F7F5F2iframe 周围纸边

字体:界面用系统 UI 栈;文件名用 ui-monospace。不加载网页字体。

结构:

┌ title · 页名                    刷新 ┐
│ [page] [page]                        │
│ ┌──────────────────────────────────┐ │
│ │           iframe stage           │ │
│ └──────────────────────────────────┘ │

签名元素:舞台四角的铜质定位十字,让它像印前灯箱而不是普通网页预览器。

6.3 空 / 错

  • 无项目:「还没有原型。在左边聊天里说要做什么界面。」
  • 无 better-sidebar:不渲染 tab;工具结果里提示文件路径。
  • RPC 失败:「读不了当前工作区的原型文件。」 + 重试。

7. Technical Specifications

7.1 契约

  • package.jsondsh.bundle.patchdsh.client.platform=webexports["."]exports["./client"]
  • Host:nameinject: ["tools","systemPrompt"]apply省略 Config,不 import schemastery
  • YAML config 仍可作为 plain object 进入 apply
  • Client:window.__ModuleLoader__.load lazy-CJS;inject: ["connection"]
  • dsh-better-sidebar:optional,运行时探测,禁止 value-import
  • 不改 DSH 源码、不改 better-sidebar 源码

7.2 数据

<cwd>/.dsh-design/
  current.json          { projectId, file, title, revision, updatedAt }
  projects/<id>/
    project.json        { id, title, entry, createdAt, updatedAt }
    index.html

revision 为单调整数,每次 design_write(open) / design_open 加一,供 UI 刷新。

7.3 RPC

Channel /designauthority: "loopback",永不抛出;返回 { ok, value | error }

endpointpayloadvalue
snapshot{ cwd }项目列表 + current
file{ cwd, projectId, name }{ content, mime }

7.4 Agent 工具约定

写出的 HTML 必须:

  • 完整文档(<!DOCTYPE html>
  • CSS/JS 内联,可单独在 iframe 里点
  • 真实控件,而不是截图
  • 语言跟随用户

禁止:

  • 再开 Agent
  • 只回复「这是设计思路」而不写文件
  • 把文件写到 .dsh-design 之外(除非用户明确要求落地到产品代码,那时用内置 fs,不走本插件)

8. Risks

风险缓解
link: 安装解析不到 @deepseek-ai/dsh-tools不 import 该包;ctx.tools.register 直接挂普通对象
better-sidebar 未装或版本无 registerTab子 fiber + 特性探测,失败跳过
Desktop webview 拦 loopbackiframe 走 127.0.0.1 + token 路径;失败再考虑降级
iframe 脚本攻击父页allow-same-origin
范围膨胀成 vibe-design本 PRD 的 Out of Scope 作为拒绝清单

9. 后续(非本迭代)

  • 发现流程:第一份 HTML 前必须有 platform / viewport / look(已做)
  • 多页相对资源:loopback 预览 + 最多两层目录(已做)
  • 设计系统样例页 paper/ink(已做);管理后台仍不做
  • 批注选择器(已做);截图仍不做
  • 只读设计系统目录(从 vibe-design 思路借鉴,不复制资产除非许可清晰)
  • 批注、多页资源、设计系统目录仍走 Prototype tab,不新增官方 slot

10. 决策记录

  1. 一套 Agent:只使用当前 DSH 会话。
  2. UI 入口只在 better-sidebar:tab dsh-design:prototype。禁止 sidebar.footer.action / shell.overlay / 官方 sidebar。未装 better-sidebar 时不注册 UI,Host 工具仍写文件。
  3. 不是 vibe-design fork:新 bundle,MIT。
  4. 文件在 workspace.dsh-design/,不用插件私有 SQLite。