dsh-drawai 0.1.1 → 0.2.1

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/README.md CHANGED
@@ -6,23 +6,24 @@
6
6
 
7
7
  [![GitHub stars](https://img.shields.io/github/stars/fourzkw/dsh-drawai?style=social)](https://github.com/fourzkw/dsh-drawai) [![MIT License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
8
8
 
9
- **DSH 右侧栏里的可编辑画布 —— 加上让模型直接改图的两个工具。**
9
+ ## 功能一览
10
10
 
11
- > *An editable diagram canvas in the DSH right sidebar, plus two agent tools (`diagram_read` / `diagram_apply`) that read and edit the workspace's native `.drawio` files in place.*
11
+ `dsh-drawai` 把可编辑画布放进 DeepSeek Harness 右侧栏,并给模型两个改图工具;人和 AI 读写的是同一份原生 `.drawio`。
12
12
 
13
- `dsh-drawai` 把一块**可编辑的画布**放进 DeepSeek Harness 的右侧栏,再给模型**两个工具**;两者读写的是同一份文件。
13
+ 1. **右侧栏可编辑画布** —— 打开 / 新建工作区 `.drawio`:画节点、连边、就地改字、分层、排序、对齐、导出;双击即可改标签。
14
+ 2. **自然语言改图** —— 对话里说需求,模型用 `diagram_read` / `diagram_apply` 读现状、结构化改图、自动布局并原子写回。
15
+ 3. **选区感知与回退** —— 你在画布上选中什么,模型就知道什么;模型改动最多可退 8 步。
16
+ 4. **SVG 图形节点** —— 图标 / logo 可直接当节点内容,拼流程图与示意图。
17
+ 5. **位图矢量化(`traceImage`)** —— 照着工作区图片逐像素描成 SVG 节点,不是凭印象手写近似图。
18
+ 6. **原生 `.drawio` 载体** —— 无需导入导出;画布读不懂的单元逐字节保留,文件可直接用 drawio / diagrams.net 继续编辑。
14
19
 
15
- - **画布(右侧栏面板)** —— 打开工作区里的 `.drawio`:画节点、连边、就地改字、分层、排序、对齐、导出,双击节点就能改标签。
16
- - **`diagram_apply`** —— 模型改图的入口:15 个结构化 ops,改完自动布局并**原子写回**。
17
- - **`diagram_read`** —— 模型的眼睛:结构、样式键、图层、父级、页面尺寸、**你此刻的选区**、文件指纹 `revision`。
18
- - **选中与回退** —— 你在画布上选中什么,模型就知道什么;模型的改动最多可以退 8 步。
19
- - **载体是原生 `.drawio` 文件** —— 不需要导入导出,存出来的文件可以直接用 drawio / diagrams.net 打开继续编辑。
20
+ ![整体界面:右侧栏画布与多标签](docs/picture/整体界面图.png)
20
21
 
21
- ```
22
- 人(侧边栏画布) ┐
23
- AI(diagram_apply) ├──→ 工作区的 .drawio(mxfile) ──→ 用 drawio / diagrams.net 直接打开继续编辑
24
- drawio 本体 ┘ ↑ 无损写回:画布读不懂的单元逐字节保留
25
- ```
22
+ ![从对话到改图的逻辑流程](docs/picture/drawai逻辑图.png)
23
+
24
+ ![用 SVG 节点拼的流程图与图标](docs/picture/图标绘制.png)
25
+
26
+ ![位图矢量化复刻对比](docs/picture/大肥鱼复刻图.png)
26
27
 
27
28
  ## 安装 / Install
28
29
 
@@ -55,7 +56,7 @@ dsh plugin --profile web add github:fourzkw/dsh-drawai
55
56
 
56
57
  | 入口 | 你能得到什么 |
57
58
  |---|---|
58
- | **右侧栏画布** | 打开或新建画布、画节点与连线、就地改字、图层、顺序、多选对齐、复制粘贴、导出 SVG / PNG |
59
+ | **右侧栏画布** | 打开或新建画布、画节点与连线、就地改字、图层、分区、顺序、多选对齐、查找、微移、多页切换、复制粘贴、导出 SVG / PNG(含导出选中) |
59
60
  | **`diagram_apply`** | 让模型按 ops 改图:增删改、重接边、复制、排序、分层、导出;支持 `ids` 批量、`as` 别名、`expectRevision` |
60
61
  | **`diagram_read`** | 让模型看见图的结构与样式、图层与父级、页面尺寸、你此刻的选区、文件指纹 `revision` |
61
62
  | **选中与回退** | 你选中什么模型就知道什么;模型的每一轮改动都能在界面上退回去 |
@@ -66,12 +67,15 @@ dsh plugin --profile web add github:fourzkw/dsh-drawai
66
67
 
67
68
  | 功能 | 它解决什么问题 |
68
69
  |---|---|
69
- | **画布外观** | 9 种形状(矩形 / 圆角 / 椭圆 / 菱形 / 圆柱 / 文档…)、8 色调色板、白纸 + 网格、正交折线 + 障碍避让、明暗切换 |
70
+ | **画布外观** | 矩形 / 圆角 / 椭圆 / 菱形 / 圆柱 / 文档 / **SVG 图形** / **位图** 等形状族(右侧元素条按族放置)、8 色调色板、白纸 + 网格、正交折线 + 障碍避让、明暗切换 |
71
+ | **SVG 图形节点** | 节点内容直接是一段 **SVG 标记**(图标 / logo / 示意图这种形状词汇表里没有的东西):右键「SVG 内容…」贴进去即可,或让模型用 `addNode {shape:"svg", svg:"<svg viewBox…>…</svg>"}`。落盘是 drawio **原生**的图片形状(`shape=image` + `image=data:image/svg+xml,<百分号编码>`),所以 drawio 桌面版打开同样画得出来;标记只喂给 `<image>`(独立文档,脚本不执行、也不碰页面 DOM) |
72
+ | **内嵌位图** | 从剪贴板粘贴或拖入 PNG / JPEG / GIF / WebP,画布会**真的画出来**(同为 `shape=image` + data URI)。`diagram_read` 把 base64 省略成 `«image N 字符»`,不撑爆上下文 |
73
+ | **位图矢量化 traceImage** | 让模型照着工作区里一张图**逐像素**描成 SVG 内容节点(读像素 → 泛洪去背景 → k-means 调色板 → 3× 超采样归类 → 按颜色取像素级闭合轮廓 → 每色一条 nonzero path)。形状词汇表表达不了的照片 / 插画走这条,而不是让模型手写一段近似 SVG 冒充复刻 |
70
74
  | **文本** | 双击节点就地改字;「T 文字」放一段无边框、无底色的独立文字;字号有 10 / 12 / 14 / 18 / 24 五档,也可以手调 8–72;字色板 |
71
75
  | **连线** | 四选一画法(直线 / 直角折线 / 圆角折线 / 曲线)× 线型(含虚线间距)× 箭头(单向 / 双向 / 无 / 反向)× 颜色 × 引出段长度;自环;悬空端(从节点脱开后成为自由端点,还能再拖回去) |
72
76
  | **连线上的文字** | 双击改、按住拖(半格 + 贴线吸附)、右键「标签居中」;**线在文字的位置真的断开**(不盖白底) |
73
77
  | **选中与移动** | 框选 / Shift 加选 / `Ctrl+A`;整体拖动(折点与自由端点跟着同一个位移走);对齐辅助线;多选对齐与分布 |
74
- | **图层** | 列出 / 新建 / 显示隐藏 / 设为当前层;隐藏状态会写入文件(用 drawio 打开同样是隐藏的),层里的单元一个字节都不动 |
78
+ | **图层** | 列出 / 新建 / 显示隐藏 / 锁定 / 重命名 / 删除(合并到邻层)/ 选中移层 / 设为当前层;隐藏与锁定写入文件 |
75
79
  | **顺序** | 置顶 / 上移 / 下移 / 置底 —— 写回时**真的改动文件里单元的先后**(否则重新打开就变回去了) |
76
80
  | **自定义数据** | 右键「编辑数据」,按 `key=value` 一行一项改单元属性;按 user object 存回文件,drawio 打开不会丢 |
77
81
  | **导出** | SVG / PNG(2×);「看一眼画布效果」走 DSH 附件服务,**不在工作区落文件** |
@@ -90,15 +94,40 @@ dsh plugin --profile web add github:fourzkw/dsh-drawai
90
94
  | 结构 | `addLayer` `setLayer` `setLayerProps` `order` |
91
95
  | 交互 | `highlight`(让画布替你选中,不改文档、不重排) |
92
96
  | 输出 | `export`(`svg` 落在 `.drawio` 旁边;`png` 走浏览器下载) |
97
+ | 图像 | `traceImage`(把工作区里一张位图**逐像素**矢量化成 svg 内容节点) |
93
98
 
94
99
  - **批量修改**:`setStyle` / `setLabel` / `move` / `remove` 都接受 `ids:[…]`,不必发 N 个 op。
95
100
  - **`expectRevision`**:把上次 `diagram_read` 返回的 `revision` 传进来 —— 对不上(说明你在 drawio 里同时改过)就**报错,且一个字节都不写**,重读再改。
96
101
  - **写盘之前就报错**:边引用了不存在的节点会直接失败,并列出已知 id。
97
102
  - **不动手工摆好的版面**:ops 里自带几何时(`addNode` 给了 `x/y`,或者有 `move`)不会重排 —— 否则"挪 40px"会被布局立刻冲掉。
103
+ - **画图形用 `svg`**:`addNode {shape:"svg", svg:"<svg viewBox…>…</svg>", w, h}` 让节点内容就是那段标记(`setStyle {id, svg:"…"}` 换图、`svg:null` 清掉回到矩形)。标记**必须带 `viewBox`**,否则放大缩小时图形不会跟着变;缺 `xmlns` 宿主会补。
104
+ - **照着一张位图描矢量图用 `traceImage`**:
105
+
106
+ ```
107
+ diagram_apply({ op:"traceImage", image:"refs/角色.png", x:40, y:40 })
108
+ ```
109
+
110
+ 它**真的去读那张图的像素**,在宿主里跑一条完整管线:
111
+
112
+ | 步骤 | 做什么 |
113
+ |---|---|
114
+ | ① 解码 | PNG 走**自带解码器**(零依赖,只用 `node:zlib`);JPEG/GIF/WebP 需要宿主装了 sharp |
115
+ | ② 去背景 | 从四边泛洪,把近白/近灰/透明像素排除(不画截图底色;与边界不连通的白围裙不会误删) |
116
+ | ③ 调色板 | k-means(K 默认 12,k-means++ 初始化,多次重启取最优);背景单独占一色 |
117
+ | ④ 归类 | 3× 双线性超采样 → 3×3 众数滤波 → 降回原分辨率 → 小于 `minArea` 的碎块并进**颜色最接近**的邻色 |
118
+ | ⑤ 轮廓 | 按颜色分 4 连通域,沿**像素格边**建"区域恒在左侧"的有向图,左转优先走闭合环(外环顺时针 / 洞逆时针) |
119
+ | ⑥ 输出 | RDP 简化 + 相对增量编码 → 每色一条 `fill-rule="nonzero"` 的 `<path>`,按面积降序铺 |
120
+
121
+ - 默认 **`w/h` = 原图像素尺寸**、`viewBox` = 原图像素坐标系,所以画布坐标就是图片坐标(1:1 铺满)。
122
+ - 要更简洁:`colors` 调小、`scale:2|3`(先降采样)、`grid` 调小;要更保真:`epsilon` 调小(默认 2px)、`minArea` 调小(默认 10px²)。
123
+ - 返回的 summary 会报**色数 / 路径数 / 轮廓环数 / 字符数 / 像素覆盖是否精确**(精确 = 各色轮廓面积之和等于图像总像素,没有像素丢失或重复)。
124
+ - 单次上限:SVG 标记 60000 字符;宿主会先自己收紧 `epsilon` 与碎块阈值,仍超才报错让你调参。
125
+ - 落盘仍是 drawio **原生**的图片形状(`shape=image` + `image=data:image/svg+xml,<百分号编码>`),drawio 桌面版打开同样画得出来。
126
+ - **它不是"让模型凭印象画"**:形状取决于像素,同一张图同样的参数跑两次结果一致(已纳入自测)。
98
127
 
99
128
  ### `diagram_read` —— 模型怎么看见图
100
129
 
101
- 读回:节点 / 边 / 标签、每个单元的**样式键**(就是文件里那串 `style`,另外给出派生的形状、线型、箭头、颜色名便于阅读)、图层表与单元所属层、容器父级 `parent`、页面尺寸、边标签的 `labelX/labelY`、**`revision`**(文件内容指纹)、当前选区。
130
+ 读回:节点 / 边 / 标签、每个单元的**样式键**(就是文件里那串 `style`,另外给出派生的形状、线型、箭头、颜色名便于阅读)、图层表与单元所属层、容器父级 `parent`、页面尺寸、边标签的 `labelX/labelY`、**`revision`**(文件内容指纹)、当前选区。SVG 图形节点的内容单独放在 `svg` 字段里(style 串里的 `image=` 则省略成 `«svg N 字符»`,避免一次读取被 data URI 撑爆)。
102
131
 
103
132
  - 可以只读一层(`layer`)或只看几个单元(`ids`)—— 大图上能省下不少上下文;过滤时会同时报 `totalNodes` / `totalEdges`,免得漏看。
104
133
  - `render:true` 会让画布把当前画面渲成 PNG 交给模型"看一眼";图片走 DSH 的附件服务,**不在工作区落任何文件**。
@@ -144,7 +173,7 @@ dsh plugin --profile web add github:fourzkw/dsh-drawai
144
173
 
145
174
  由此得到一条可以断言的性质:**打开后原样保存,文件逐字节不变**(`tools/check-mxfile.mjs` 里有断言盯着)。
146
175
 
147
- **读不懂的地方一律如实报。** 多页只显示第 1 页、分组按绝对位置显示、图片按矩形显示 —— 这些会作为 `notes`
176
+ **读不懂的地方一律如实报。** 多页可切换编辑当前页(其它页原样保留)、分组按绝对位置显示、**外链 / 相对路径**图片按矩形占位(内嵌 SVG 与内嵌位图会真的画出来)—— 这些会作为 `notes`
148
177
  出现在工作栏和 `diagram_read` 的返回里。用户会拿这份文件继续在 drawio 里编辑,不说明就等于骗人。
149
178
 
150
179
  `revision` 不是时间戳,而是**文件内容的指纹** —— 所以无论 drawio 还是别的编辑器改过文件,乐观锁照样准。
@@ -166,13 +195,12 @@ id / layer / parent、选区能上报给模型、写回是逐单元的、画布
166
195
  | 主题跟随 DSH 的明暗 | —— |
167
196
  | 显示层、当前层 | 「图层」菜单(会写进文件) |
168
197
 
169
- 右键空白处就是**元素库**:形状平铺成一片缩略图,点哪个就直接放哪个形状的节点(没有"先在下拉里选中、
170
- 再点新增"这一步)。节点上右键则是同一片缩略图,点一下就换成那个形状。就地改标签用 `Enter` 提交、
171
- `Shift+Enter` 换行、`Esc` 取消。
198
+ **右侧常驻元素条**:按类型(图形 / 文字 / 分区 / SVG / 图片)放置,点画布落下**一次**即卸工具;
199
+ 「图形」的矩形、圆角、菱形等是同族变体,只在侧面板展开,不全部铺在主条上。悬停或选中图形后可换同族形状。就地改标签用 `Enter` 提交、`Shift+Enter` 换行、`Esc` 取消。
172
200
 
173
201
  ## 须知 / Good to know
174
202
 
175
- - **兼容性**:DSH(DeepSeek Harness)Web;官方包以 `peerDependencies` 声明(`@deepseek-ai/dsh-tools`),Node `>= 20`。
203
+ - **兼容性**:DSH(DeepSeek Harness)Web `0.1.x` 与 `0.2.x`(含 `0.2.0-rc.*`);官方包以 `peerDependencies` 声明(`@deepseek-ai/dsh-tools`),Node `>= 20`。
176
204
  - **生效方式**:宿主侧只在 `dsh web` 启动时加载,换 `lib/index.js` 必须**重启**;客户端是独立 bundle,刷新页面即可。
177
205
  - **界面语言**:目前只有简体中文,还没有 i18n。
178
206
  - **大图性能**:几百个单元时的重渲染与路由开销还没测过。
@@ -180,12 +208,11 @@ id / layer / parent、选区能上报给模型、写回是逐单元的、画布
180
208
 
181
209
  ## 已知限制 / Limitations
182
210
 
183
- - **图层只到 v1**:画布菜单里还不能锁定、重命名、删除图层,也不能把选中单元移到别的层(AI 侧可以用 `setLayer` 做到)。
184
- - **分组与多页**:文件里的层级与其余页逐字节保留,但画布按绝对位置拍平显示,只显示和编辑第 1 页。
185
- - **所有边都画在所有节点下面**(文件里是按单元顺序混合层叠的);绕法是把那条边放进更上面的一层。
211
+ - **多页**:可切换编辑当前页(视图菜单);其它页保存时原样保留。AI 可用 `diagram_read` / `diagram_apply` 的 `page` 参数指定页。多页的**新建页**尚未实现。
186
212
  - 独立 `edgeLabel` 单元只读;`entityRelation` 等其它 edgeStyle、箭头字形、旋转 / 翻转 / 透明、stencil 形状只保留、不渲染;`.drawio.svg` / `.png` / `.html` 内嵌载体不支持。
187
- - 导出只有 SVG 与 PNG(2×):没有 PDF,也不能"只导出选中部分"。
188
- - 交互细节:没有方向键微移、没有查找;对齐辅助线只跟节点比(不与折点、端点对齐);单条选中的连线不能复制。
213
+ - **图片**:内嵌 SVG(`data:image/svg+xml,…`)与内嵌位图(PNG/JPEG/GIF/WebP data URI)都会画出来;**外链 / 相对路径**图片仍按矩形占位,单元原样保留(工作区磁盘上的图片文件画布直接读不到——要复刻请用 `traceImage`)。
214
+ - 导出只有 SVG 与 PNG(2×):没有 PDF。
215
+ - 交互细节:对齐辅助线只跟节点比(不与折点、端点对齐);单条选中的连线不能复制。
189
216
 
190
217
  完整的取舍与实现细节在 [docs/design.md](docs/design.md)。
191
218
 
@@ -195,7 +222,7 @@ id / layer / parent、选区能上报给模型、写回是逐单元的、画布
195
222
  npm run watch # 常驻:监听 src/,变化即重建 lib/
196
223
  npm run build # 一次性构建
197
224
  npm run check # 安装前烟测(含 lib 与 src 是否同步)
198
- npm test # 五份自测(mxfile 编解码 / 路由预览 / 宿主行为 / 渲染 / 组件),1526 项断言
225
+ npm test # 六份自测(mxfile 编解码 / 路由预览 / 宿主行为 / 渲染 / 组件 / 矢量化),1716 项断言
199
226
  ```
200
227
 
201
228
  > ⚠️ **绝不改 `lib/` 下的文件** —— 它们是构建产物,会被覆盖。改 `src/`。