dsh-draw 0.2.15 → 0.2.17

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-zh.md CHANGED
@@ -11,11 +11,13 @@
11
11
  [![Gitee](https://img.shields.io/badge/Gitee-mirror-c71d23?logo=gitee)](https://gitee.com/perrylink/dsh-draw)
12
12
  [![DSH plugin](https://img.shields.io/badge/dsh--plugin-✅-green)](https://github.com/topics/dsh-plugin)
13
13
  [![dsh-doctor](https://raw.githubusercontent.com/PerryLink/dsh-plugin-doctor/main/badges/PerryLink__dsh-draw.svg)](https://github.com/PerryLink/dsh-plugin-doctor#verified-徽章)
14
+ [![DSH Market](https://raw.githubusercontent.com/2BingLing/dsh-market/master/assets/readme/badge-listed-zh.svg)](https://dsh.market/)
14
15
  [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
15
16
  [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-draw/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-draw/actions)
16
17
  [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-draw?label=version)](https://github.com/PerryLink/dsh-draw/releases)
17
18
  [![npm version](https://img.shields.io/npm/v/dsh-draw)](https://www.npmjs.com/package/dsh-draw)
18
19
  [![npm downloads](https://img.shields.io/npm/dm/dsh-draw)](https://www.npmjs.com/package/dsh-draw)
20
+ [![dshfind](https://dshfind.com/api/badge/PerryLink/dsh-draw?metric=downloads&lang=zh)](https://dshfind.com/zh/plugins/PerryLink/dsh-draw?ref=badge)
19
21
 
20
22
  [English](README.md) · [简体中文](README-zh.md) · [Español](README-es.md) · [Português](README-pt.md) · [हिन्दी](README-hi.md)
21
23
 
@@ -27,14 +29,15 @@
27
29
 
28
30
  | 方面 | 状态 |
29
31
  |---|---|
30
- | Harness | DeepSeek Harness `dsh-v0.1.5-rc.2`(声明兼容 `0.1.5-rc.2`) |
32
+ | Harness | DeepSeek Harness `dsh-v0.1.7-rc.1`(声明兼容 `0.1.5-rc.2`) |
31
33
  | Node | `^22.19.0 \|\| >=24.0.0` |
32
34
  | 引擎 | 任意 OpenAI 兼容图像端点;内置 OpenAI Images(`gpt-image-1`)与智谱 CogView(`cogview-3-flash`)预设 |
33
35
  | 界面 | Host `image_generate` 工具 + Web 结果卡片 + Plugins 设置页签 |
34
36
 
35
37
  浏览器半边基于 cordis `Context` 与已发布的客户端包(`dsh-client-ui-slots`、`dsh-client-ui-settings`、`dsh-client-ui-tool`、`dsh-client-locale`、`dsh-client-connection`);它不再依赖已移除的 `dsh-client-runtime` 包(工具调用块经本地结构契约读取),因此客户端接口面同样对齐 `0.1.2-rc.1` 宿主。
36
- 0.1.2-rc.1(2026-09-02 已适配):会话信封保留 ignorable 字段但仅用于存量日志读取兼容——Session.append 仍无法盖章,门控行为不变。已于 2026-09-06 对照 dsh-v0.1.3-alpha.1 master 检出核验(完整门禁链 + profile 安装冒烟)。
38
+ 0.1.2-rc.1(2026-09-02 已适配):会话信封保留 ignorable 字段但仅用于存量日志读取兼容——Session.append 仍无法盖章,门控行为不变。已于 2026-09-06 对照 dsh-v0.1.7-alpha.1 master 检出核验(完整门禁链 + profile 安装冒烟)。
37
39
  0.1.6-alpha.2(2026-09-18 已适配):`Session.append` 的第三参仅对表面事件类型存在且为 `SurfaceIntent`,绝非 `ignorable` 信封,因此非表面的 `draw/generated` 在该线上仍不落盘——配额按会话内存计数、会话重启归零(与下方「配额持久性」一致)。已于 2026-09-18 核验(双 typecheck 尺子 + 全量测试 + self-contained/artifacts/readme 门)。
40
+ 0.1.7-rc.1(2026-09-23 已适配):客户端 `tool.call.toolview` 契约把 owner 拆成三个阶段(`preparing` / `start` / `result`),且参数仍在流式到达时就会派发带 key 的卡片。因此结果卡片现在也为这些更早的阶段渲染「进行中」行——已占用的 keyed 槽位永远不会落到宿主自带的通用行,所以对准备阶段不作回应会让整行在整个流式窗口内空白。其余行为不变:结算后的卡片、账目行与重新生成与之前完全一致。已于 2026-09-23 核验(双 typecheck 尺子 + 全量测试 + 新增 host-contract 门)。
38
41
 
39
42
  ## 你能得到什么
40
43
 
@@ -117,7 +120,7 @@ profile patch 中的覆盖示例:
117
120
  | 界面 | 说明 |
118
121
  |---|---|
119
122
  | `image_generate` | 标准参数;返回规范 JSON(引擎/模型/尺寸、图片引用、配额、回退标志、尝试记录)加图片内容块 |
120
- | 结果卡片(`tool.call.toolview`,key `image_generate`) | 图片、引擎/配额行、一键重新生成(完整 drawer 路径:配额 + 路由 + 审计) |
123
+ | 结果卡片(`tool.call.toolview`,key `image_generate`) | 覆盖调用的每个阶段:参数流式到达时先显示进行中行,结算后显示图片、引擎/配额行与一键重新生成(完整 drawer 路径:配额 + 路由 + 审计) |
121
124
  | 设置页签(Plugins → 图像生成) | 引擎链、凭据状态、设置/移除 API 密钥(凭据引用)、连通性探测、配额上限 |
122
125
 
123
126
  ## 权限与数据
@@ -145,10 +148,11 @@ profile patch 中的覆盖示例:
145
148
  ```sh
146
149
  pnpm install # node ^22.19 || >=24
147
150
  pnpm run typecheck # tsc:src + tests,对照本地 harness checkout
148
- pnpm run typecheck:ci # tsc:对照已发布的 0.1.5-rc.2 类型(无 paths)
149
- pnpm test # vitest:17 个 spec 文件(scripted 传输、真实 Context/Session/ToolRuntime)
151
+ pnpm run typecheck:ci # tsc:对照已发布的 0.1.7-rc.1 类型(无 paths)
152
+ pnpm test # vitest:19 个 spec 文件(scripted 传输、真实 Context/Session/ToolRuntime)
150
153
  pnpm run build # tsc 声明 + tsdown 打包(lib/)
151
154
  pnpm run verify:self-contained # 依赖声明全部来自 registry
155
+ pnpm run verify:host-contract # 宿主 tool-view 契约仍与本插件声明一致
152
156
  pnpm run verify:artifacts # host ESM 面 + typert manifest + 浏览器包 + 配置文件
153
157
  pnpm pack # 发布用 tarball
154
158
  ```
@@ -164,56 +168,56 @@ pnpm pack # 发布用 tarball
164
168
 
165
169
  ## PerryLink DSH Plugin Family
166
170
 
167
- 这是 [PerryLink](https://github.com/PerryLink) 维护的 [40 个 DeepSeek Harness 插件](https://github.com/PerryLink) 之一。如果它能帮到你,其他的也会:
171
+ This project is one of the **45 DeepSeek Harness plugins** maintained by [PerryLink](https://github.com/PerryLink). If this one helps you, the others likely will too:
168
172
 
169
173
  | Plugin | One-liner |
170
174
  |---|---|
171
- | **[dsh-auto-review](https://github.com/PerryLink/dsh-auto-review)** | 审批链上的第二模型自动审查,默认失败关闭 | |
172
- | **[dsh-background-agents](https://github.com/PerryLink/dsh-background-agents)** | 带 Web UI 侧栏、消息与中断的持久后台子代理 | |
173
- | **[dsh-budget](https://github.com/PerryLink/dsh-budget)** | DeepSeek Harness 的成本治理:预算、碳排与延迟一屏呈现。 | |
174
- | **[dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind)** | Claude Code /rewind 等价:快照、会话 fork、一次性恢复 | |
175
- | **[dsh-claude-move](https://github.com/PerryLink/dsh-claude-move)** | 把 Claude Code 会话、记忆、技能与 CLAUDE.md 迁入 DSH | |
176
- | **[dsh-click](https://github.com/PerryLink/dsh-click)** | 跨平台原生桌面控制(DeepSeek Harness),Windows 优先。 | |
177
- | **[dsh-composer-history](https://github.com/PerryLink/dsh-composer-history)** | Web 输入框的终端式历史:方向键、Ctrl+R 搜索 | |
178
- | **[dsh-data-quality](https://github.com/PerryLink/dsh-data-quality)** | 数据集质量检查与引文核查(本插件可选消费的数字核查桥) | |
179
- | **[dsh-defend](https://github.com/PerryLink/dsh-defend)** | DeepSeek Harness 的提示注入、越狱与密钥泄露防护。 | |
180
- | **[dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck)** | 工程纪律守卫:需求质询、测试门禁、对手评审 | |
181
- | **[dsh-fast](https://github.com/PerryLink/dsh-fast)** | DeepSeek Harness 只读性能诊断。 | |
182
- | **[dsh-fund-research](https://github.com/PerryLink/dsh-fund-research)** | 面向中国公募基金的确定性研究报告 | |
183
- | **[dsh-github](https://github.com/PerryLink/dsh-github)** | 面向 DSH 的 GitHub PR/issues 集成,每次写入经审批门控 | |
184
- | **[dsh-industry-research](https://github.com/PerryLink/dsh-industry-research)** | 行业研究编排,经本插件的 `ctx.researchReport.assemble` 封存交付物 | |
185
- | **[dsh-library](https://github.com/PerryLink/dsh-library)** | DeepSeek Harness 的本地文档知识库。 | |
186
- | **[dsh-local-ai](https://github.com/PerryLink/dsh-local-ai)** | DeepSeek Harness 的本地模型(Ollama)接入。 | |
187
- | **[dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions)** | 通过语言服务器的 LSP 诊断、格式化、补全、代码操作与重命名 | |
188
- | **[dsh-mask](https://github.com/PerryLink/dsh-mask)** | PII 脱敏中间件:模型边界匿名化、展示层还原 | |
189
- | **[dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel)** | 只读 MCP 运行时面板:/mcp 命令 + 带状态、工具与错误的 Settings 标签页 | |
190
- | **[dsh-memento](https://github.com/PerryLink/dsh-memento)** | 审批门控的跨会话记忆:ctx.memory 接缝 + SQLite + 记忆工具 | |
191
- | **[dsh-observe](https://github.com/PerryLink/dsh-observe)** | DeepSeek Harness 的 OpenTelemetry 与 Langfuse 可观测导出器。 | |
192
- | **[dsh-output-styles](https://github.com/PerryLink/dsh-output-styles)** | Claude Code outputStyles 等价的运行时风格切换 | |
193
- | **[dsh-reach](https://github.com/PerryLink/dsh-reach)** | 多渠道审批/提问桥接:微信/Telegram/飞书,会话控制台 |
194
- | **[dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules)** | Claude Code 风格声明式 allow/deny/ask 权限规则,带审计 | |
195
- | **[dsh-personal-directive](https://github.com/PerryLink/dsh-personal-directive)** | 个人指令注入器:顶栏开关(框架版) |
196
- | **[dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide)** | 作为按需代理技能的插件开发知识库 | |
197
- | **[dsh-plugin-doctor](https://github.com/PerryLink/dsh-plugin-doctor)** | Zero-dependency static + sandbox smoke detector for DSH plugins | |
198
- | **[dsh-research-report](https://github.com/PerryLink/dsh-research-report)** | 可验证研究报告引擎:内容寻址证据账本与封存版本 | |
199
- | **[dsh-score](https://github.com/PerryLink/dsh-score)** | DeepSeek Harness 插件的多维质量评分。 | |
200
- | **[dsh-session-pin](https://github.com/PerryLink/dsh-session-pin)** | 在 Web 侧栏置顶会话,带持久排序 | |
201
- | **[dsh-session-sync](https://github.com/PerryLink/dsh-session-sync)** | DeepSeek Harness 的跨设备会话同步——会话存储的专用 git 镜像。 | |
202
- | **[dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security)** | 安全审计技能包:密钥扫描、依赖与供应链审查 | |
203
- | **[dsh-talk](https://github.com/PerryLink/dsh-talk)** | DeepSeek Harness 的语音优先会话闭环:对它说,听它答。 | |
204
- | **[dsh-test-drive](https://github.com/PerryLink/dsh-test-drive)** | DeepSeek Harness 插件的隔离试装冒烟。 | |
205
- | **[dsh-ticktick](https://github.com/PerryLink/dsh-ticktick)** | TickTick/滴答清单任务桥接:会话头面板 + 11 个工具 |
206
- | **[dsh-translate](https://github.com/PerryLink/dsh-translate)** | DeepSeek Harness 的厂商参数翻译与确定性 JSON 修复。 | |
207
- | **[dsh-wechat](https://github.com/pan17/dsh-wechat)** | 微信 ↔ DSH 桥接(Tencent iLink 机器人):文本/图片/文件/语音,聊天内审批卡片 |
175
+ | **[dsh-auto-review](https://github.com/PerryLink/dsh-auto-review)** | Second-model auto-review on the approval chain, fail-closed by default | |
208
176
  | **[dsh-autotier](https://github.com/PerryLink/dsh-autotier)** | Automatic strong/cheap model-tier routing with deterministic risk guards and a `/tier` command | |
177
+ | **[dsh-background-agents](https://github.com/PerryLink/dsh-background-agents)** | Durable background child agents with a Web UI sidebar, messaging and interrupt | |
178
+ | **[dsh-budget](https://github.com/PerryLink/dsh-budget)** | Cost governance for DeepSeek Harness: budgets, carbon, and latency in one panel. | |
209
179
  | **[dsh-catalog](https://github.com/PerryLink/dsh-catalog)** | DSH Desktop Market standard catalog source for the PerryLink family | |
210
180
  | **[dsh-cert-mcp](https://github.com/PerryLink/dsh-cert-mcp)** | Read-only MCP server exposing the certification registry: grades, snapshots and five-dimension evidence | |
211
- | **[dsh-kit](https://github.com/PerryLink/dsh-kit)** | One-command starter pack that installs the core family | |
181
+ | **[dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind)** | Claude Code /rewind-equivalent: snapshots, session forks, one-shot restore | |
182
+ | **[dsh-claude-move](https://github.com/PerryLink/dsh-claude-move)** | Migrate Claude Code sessions, memory, skills and CLAUDE.md into DSH | |
183
+ | **[dsh-click](https://github.com/PerryLink/dsh-click)** | Cross-platform native desktop control for DeepSeek Harness — Windows first. | |
184
+ | **[dsh-composer-history](https://github.com/PerryLink/dsh-composer-history)** | Terminal-style input history for the web composer: arrows, Ctrl+R search | |
185
+ | **[dsh-data-quality](https://github.com/PerryLink/dsh-data-quality)** | Dataset quality checks and citation cross-checks (the optional numeric bridge consumed here) | |
186
+ | **[dsh-defend](https://github.com/PerryLink/dsh-defend)** | Prompt-injection, jailbreak, and secret-leak defense for DeepSeek Harness. | |
187
+ | **[dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck)** | Engineering-discipline guard: requirements grill, test gates, adversary review | |
188
+ | **[dsh-draw](https://github.com/PerryLink/dsh-draw)** | Unified static-image generation routing for DeepSeek Harness. | |
189
+ | **[dsh-fast](https://github.com/PerryLink/dsh-fast)** | Read-only performance diagnostics for DeepSeek Harness. | |
190
+ | **[dsh-fund-research](https://github.com/PerryLink/dsh-fund-research)** | Deterministic research reports for Chinese public mutual funds | |
191
+ | **[dsh-github](https://github.com/PerryLink/dsh-github)** | GitHub PR/issues integration for DSH, every write gated by approval | |
192
+ | **[dsh-industry-research](https://github.com/PerryLink/dsh-industry-research)** | Industry research orchestration that seals its deliverables through this plugin's `ctx.researchReport.assemble` | |
193
+ | **[dsh-laya](https://github.com/PerryLink/dsh-laya)** | Laya typed decisions (`noul`/`choice`/`score`) as a first-class Cordis service and model-visible tools | |
194
+ | **[dsh-library](https://github.com/PerryLink/dsh-library)** | Local document knowledge base for DeepSeek Harness. | |
195
+ | **[dsh-local-ai](https://github.com/PerryLink/dsh-local-ai)** | Local-model (Ollama) integration for DeepSeek Harness. | |
196
+ | **[dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions)** | LSP diagnostics, formatting, completion, code actions and rename over language servers | |
197
+ | **[dsh-mask](https://github.com/PerryLink/dsh-mask)** | PII masking middleware: anonymize at the model boundary, restore at the display layer | |
198
+ | **[dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel)** | Read-only MCP runtime panel: /mcp command + Settings tab with status, tools and errors | |
199
+ | **[dsh-memento](https://github.com/PerryLink/dsh-memento)** | Approval-gated cross-session memory: ctx.memory seam + SQLite + memory tool | |
200
+ | **[dsh-observe](https://github.com/PerryLink/dsh-observe)** | OpenTelemetry and Langfuse observability exporter for DeepSeek Harness. | |
201
+ | **[dsh-output-styles](https://github.com/PerryLink/dsh-output-styles)** | Claude Code outputStyles-equivalent runtime style switching | |
202
+ | **[dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules)** | Claude Code-style declarative allow/deny/ask permission rules with audit | |
212
203
  | **[dsh-plugin-certification](https://github.com/PerryLink/dsh-plugin-certification)** | Community certification registry with repro-checkable grades and badges | |
204
+ | **[dsh-plugin-doctor](https://github.com/PerryLink/dsh-plugin-doctor)** | Zero-dependency static + sandbox smoke detector for DSH plugins | |
205
+ | **[dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide)** | Plugin-development knowledge base as an on-demand agent skill | |
213
206
  | **[dsh-plugin-kit](https://github.com/PerryLink/dsh-plugin-kit)** | Shared zero-runtime-dependency toolkit for the PerryLink DSH plugins | |
214
- | **[dsh-plugin-portal](https://github.com/PerryLink/dsh-plugin-portal)** | Zero-dependency static portal rendering the whole plugin family as one page | |
207
+ | **[dsh-plugin-upgrade](https://github.com/PerryLink/dsh-plugin-upgrade)** | One-package, one-corridor-index plugin upgrade skill: routes a repository to the matching closed corridor card | |
215
208
  | **[dsh-plugin-upgrade-015](https://github.com/PerryLink/dsh-plugin-upgrade-015)** | Merged `0.1.3-alpha.1` → `0.1.5-rc.1` upgrade corridor card plus a zero-dependency seam scanner | |
209
+ | **[dsh-reach](https://github.com/PerryLink/dsh-reach)** | Multi-channel approval/question bridge: WeChat/Telegram/Feishu, session console | |
210
+ | **[dsh-research-report](https://github.com/PerryLink/dsh-research-report)** | Verifiable research-report engine: content-addressed evidence ledger and sealed versions | |
211
+ | **[dsh-score](https://github.com/PerryLink/dsh-score)** | Multi-dimensional quality scoring for DeepSeek Harness plugins. | |
212
+ | **[dsh-session-pin](https://github.com/PerryLink/dsh-session-pin)** | Pin sessions in the Web sidebar with durable ordering | |
213
+ | **[dsh-session-sync](https://github.com/PerryLink/dsh-session-sync)** | Cross-device session sync for DeepSeek Harness — a dedicated git mirror of your session store. | |
214
+ | **[dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security)** | Security-audit skill pack: secret scan, dependency and supply-chain review | |
215
+ | **[dsh-talk](https://github.com/PerryLink/dsh-talk)** | Voice-first session loop for DeepSeek Harness: talk to it, hear it answer. | |
216
216
  | **[dsh-team-rooms](https://github.com/PerryLink/dsh-team-rooms)** | Cross-session team rooms: shared message bus, task board and timeline | |
217
+ | **[dsh-test-drive](https://github.com/PerryLink/dsh-test-drive)** | Isolated install-and-smoke test drives for DeepSeek Harness plugins. | |
218
+ | **[dsh-ticktick](https://github.com/PerryLink/dsh-ticktick)** | TickTick/Dida365 task bridge: session-header panel + 11 tools | |
219
+ | **[dsh-translate](https://github.com/PerryLink/dsh-translate)** | Vendor parameter translation and deterministic JSON repair for DeepSeek Harness. | |
220
+
217
221
 
218
222
  ## License
219
223
 
package/README.md CHANGED
@@ -3,6 +3,8 @@
3
3
  # 🎨 dsh-draw
4
4
  - **1024 store channel**: `npm i -g dsh1024` once, then `dsh1024 plugin --profile web add dsh-draw` (counts toward the [deepseek1024.com](https://deepseek1024.com) install ranking).
5
5
  [![Gitee](https://img.shields.io/badge/Gitee-mirror-c71d23?logo=gitee)](https://gitee.com/perrylink/dsh-draw)
6
+ [![dshfind](https://dshfind.com/api/badge/PerryLink/dsh-draw?metric=downloads)](https://dshfind.com/plugins/PerryLink/dsh-draw?ref=badge)
7
+ [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/PerryLink/dsh-draw/badge)](https://api.securityscorecards.dev/projects/github.com/PerryLink/dsh-draw)
6
8
 
7
9
  **Unified static-image generation routing for DeepSeek Harness.**
8
10
 
@@ -11,6 +13,7 @@
11
13
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
12
14
  [![DSH plugin](https://img.shields.io/badge/dsh--plugin-✅-green)](https://github.com/topics/dsh-plugin)
13
15
  [![dsh-doctor](https://raw.githubusercontent.com/PerryLink/dsh-plugin-doctor/main/badges/PerryLink__dsh-draw.svg)](https://github.com/PerryLink/dsh-plugin-doctor#verified-徽章)
16
+ [![DSH Market](https://raw.githubusercontent.com/2BingLing/dsh-market/master/assets/readme/badge-listed-en.svg)](https://dsh.market/)
14
17
  [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
15
18
  [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-draw/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-draw/actions)
16
19
  [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-draw?label=version)](https://github.com/PerryLink/dsh-draw/releases)
@@ -27,14 +30,15 @@
27
30
 
28
31
  | Surface | Status |
29
32
  |---|---|
30
- | Harness | DeepSeek Harness `dsh-v0.1.5-rc.2` (compat declared for `0.1.5-rc.2`) |
33
+ | Harness | DeepSeek Harness `dsh-v0.1.7-rc.1` (compat declared for `0.1.5-rc.2`) |
31
34
  | Node | `^22.19.0 \|\| >=24.0.0` |
32
35
  | Engines | Any OpenAI-compatible images endpoint; presets for OpenAI Images (`gpt-image-1`) and Zhipu CogView (`cogview-3-flash`) |
33
36
  | Surfaces | Host `image_generate` tool + web result card + Plugins settings tab |
34
37
 
35
38
  The browser half rides the cordis `Context` and the published client packages (`dsh-client-ui-slots`, `dsh-client-ui-settings`, `dsh-client-ui-tool`, `dsh-client-locale`, `dsh-client-connection`); it no longer depends on the removed `dsh-client-runtime` package (the tool-call block is read through a local structural contract), so the client surface also lines up with `0.1.2-rc.1` hosts.
36
- 0.1.2-rc.1 (adapted 2026-09-02): the session envelope keeps its ignorable field for stored-log read compatibility only - Session.append still cannot stamp it, so audit-gate behavior is unchanged. Verified 2026-09-06 against the dsh-v0.1.5-rc.2 master checkout (full gate chain + profile install smoke).
39
+ 0.1.2-rc.1 (adapted 2026-09-02): the session envelope keeps its ignorable field for stored-log read compatibility only - Session.append still cannot stamp it, so audit-gate behavior is unchanged. Verified 2026-09-06 against the dsh-v0.1.7-alpha.1 master checkout (full gate chain + profile install smoke).
37
40
  0.1.6-alpha.2 (adapted 2026-09-18): `Session.append`'s third parameter exists only for surface-eligible event types and is a `SurfaceIntent`, never an `ignorable` envelope, so `draw/generated` (a non-surface type) is still not written on this line — quota is counted in memory per session and resets when the session restarts, exactly as the "Quota durability" note below describes. Verified 2026-09-18 (dual typecheck rulers + the full suite + self-contained/artifacts/readme gates).
41
+ 0.1.7-rc.1 (adapted 2026-09-23): the client `tool.call.toolview` contract split its owner into three stages (`preparing` / `start` / `result`), and a keyed card is now dispatched while the arguments are still streaming. The result card therefore also renders the in-flight row for those earlier stages — an occupied keyed slot never reaches the host's own generic row, so answering a prepared stage with nothing blanked the line for the whole streaming window. Nothing else changed: the settled card, the accounting line, and regenerate behave exactly as before. Verified 2026-09-23 (dual typecheck rulers + the full suite + the new host-contract gate).
38
42
 
39
43
  ## What you get
40
44
 
@@ -117,7 +121,7 @@ Example override in your profile patch:
117
121
  | Surface | Notes |
118
122
  |---|---|
119
123
  | `image_generate` | Standard parameters; returns canonical JSON (engine/model/size, image references, quota, fallback flag, attempts) plus image content blocks |
120
- | Result card (`tool.call.toolview`, key `image_generate`) | Images, engine/quota line, one-click regenerate (full drawer path: quota + routing + audit) |
124
+ | Result card (`tool.call.toolview`, key `image_generate`) | In every stage of the call: an in-flight row while the arguments stream, then images, engine/quota line, and one-click regenerate once it settles (full drawer path: quota + routing + audit) |
121
125
  | Settings tab (Plugins → Image generation) | Engine chain, credential status, set/remove API keys (credential references), connectivity probes, quota limits |
122
126
 
123
127
  ## Permissions & data
@@ -145,10 +149,11 @@ Example override in your profile patch:
145
149
  ```sh
146
150
  pnpm install # node ^22.19 || >=24
147
151
  pnpm run typecheck # tsc: src + tests against the local harness checkout
148
- pnpm run typecheck:ci # tsc against the published 0.1.5-rc.2 faces (no paths)
149
- pnpm test # vitest: 17 spec files (scripted transport, real Context/Session/ToolRuntime)
152
+ pnpm run typecheck:ci # tsc against the published 0.1.7-rc.1 faces (no paths)
153
+ pnpm test # vitest: 19 spec files (scripted transport, real Context/Session/ToolRuntime)
150
154
  pnpm run build # tsc declarations + tsdown bundles (lib/)
151
155
  pnpm run verify:self-contained # dependency specs resolve from the registry
156
+ pnpm run verify:host-contract # the host tool-view contract still matches what this plugin declares
152
157
  pnpm run verify:artifacts # host ESM face + typert manifest + browser bundle + config files
153
158
  pnpm pack # the published tarball
154
159
  ```
@@ -164,13 +169,16 @@ pnpm pack # the published tarball
164
169
 
165
170
  ## PerryLink DSH Plugin Family
166
171
 
167
- This project is one of the [40 DeepSeek Harness plugins](https://github.com/PerryLink) maintained by [PerryLink](https://github.com/PerryLink). If this one helps you, the others likely will too:
172
+ This project is one of the **45 DeepSeek Harness plugins** maintained by [PerryLink](https://github.com/PerryLink). If this one helps you, the others likely will too:
168
173
 
169
174
  | Plugin | One-liner |
170
175
  |---|---|
171
176
  | **[dsh-auto-review](https://github.com/PerryLink/dsh-auto-review)** | Second-model auto-review on the approval chain, fail-closed by default | |
177
+ | **[dsh-autotier](https://github.com/PerryLink/dsh-autotier)** | Automatic strong/cheap model-tier routing with deterministic risk guards and a `/tier` command | |
172
178
  | **[dsh-background-agents](https://github.com/PerryLink/dsh-background-agents)** | Durable background child agents with a Web UI sidebar, messaging and interrupt | |
173
179
  | **[dsh-budget](https://github.com/PerryLink/dsh-budget)** | Cost governance for DeepSeek Harness: budgets, carbon, and latency in one panel. | |
180
+ | **[dsh-catalog](https://github.com/PerryLink/dsh-catalog)** | DSH Desktop Market standard catalog source for the PerryLink family | |
181
+ | **[dsh-cert-mcp](https://github.com/PerryLink/dsh-cert-mcp)** | Read-only MCP server exposing the certification registry: grades, snapshots and five-dimension evidence | |
174
182
  | **[dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind)** | Claude Code /rewind-equivalent: snapshots, session forks, one-shot restore | |
175
183
  | **[dsh-claude-move](https://github.com/PerryLink/dsh-claude-move)** | Migrate Claude Code sessions, memory, skills and CLAUDE.md into DSH | |
176
184
  | **[dsh-click](https://github.com/PerryLink/dsh-click)** | Cross-platform native desktop control for DeepSeek Harness — Windows first. | |
@@ -178,10 +186,12 @@ This project is one of the [40 DeepSeek Harness plugins](https://github.com/Perr
178
186
  | **[dsh-data-quality](https://github.com/PerryLink/dsh-data-quality)** | Dataset quality checks and citation cross-checks (the optional numeric bridge consumed here) | |
179
187
  | **[dsh-defend](https://github.com/PerryLink/dsh-defend)** | Prompt-injection, jailbreak, and secret-leak defense for DeepSeek Harness. | |
180
188
  | **[dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck)** | Engineering-discipline guard: requirements grill, test gates, adversary review | |
189
+ | **[dsh-draw](https://github.com/PerryLink/dsh-draw)** | Unified static-image generation routing for DeepSeek Harness. | |
181
190
  | **[dsh-fast](https://github.com/PerryLink/dsh-fast)** | Read-only performance diagnostics for DeepSeek Harness. | |
182
191
  | **[dsh-fund-research](https://github.com/PerryLink/dsh-fund-research)** | Deterministic research reports for Chinese public mutual funds | |
183
192
  | **[dsh-github](https://github.com/PerryLink/dsh-github)** | GitHub PR/issues integration for DSH, every write gated by approval | |
184
193
  | **[dsh-industry-research](https://github.com/PerryLink/dsh-industry-research)** | Industry research orchestration that seals its deliverables through this plugin's `ctx.researchReport.assemble` | |
194
+ | **[dsh-laya](https://github.com/PerryLink/dsh-laya)** | Laya typed decisions (`noul`/`choice`/`score`) as a first-class Cordis service and model-visible tools | |
185
195
  | **[dsh-library](https://github.com/PerryLink/dsh-library)** | Local document knowledge base for DeepSeek Harness. | |
186
196
  | **[dsh-local-ai](https://github.com/PerryLink/dsh-local-ai)** | Local-model (Ollama) integration for DeepSeek Harness. | |
187
197
  | **[dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions)** | LSP diagnostics, formatting, completion, code actions and rename over language servers | |
@@ -190,30 +200,25 @@ This project is one of the [40 DeepSeek Harness plugins](https://github.com/Perr
190
200
  | **[dsh-memento](https://github.com/PerryLink/dsh-memento)** | Approval-gated cross-session memory: ctx.memory seam + SQLite + memory tool | |
191
201
  | **[dsh-observe](https://github.com/PerryLink/dsh-observe)** | OpenTelemetry and Langfuse observability exporter for DeepSeek Harness. | |
192
202
  | **[dsh-output-styles](https://github.com/PerryLink/dsh-output-styles)** | Claude Code outputStyles-equivalent runtime style switching | |
193
- | **[dsh-reach](https://github.com/PerryLink/dsh-reach)** | Multi-channel approval/question bridge: WeChat/Telegram/Feishu, session console |
194
203
  | **[dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules)** | Claude Code-style declarative allow/deny/ask permission rules with audit | |
195
- | **[dsh-personal-directive](https://github.com/PerryLink/dsh-personal-directive)** | Personal directive injector with top-bar toggle (framework edition) |
196
- | **[dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide)** | Plugin-development knowledge base as an on-demand agent skill | |
204
+ | **[dsh-plugin-certification](https://github.com/PerryLink/dsh-plugin-certification)** | Community certification registry with repro-checkable grades and badges | |
197
205
  | **[dsh-plugin-doctor](https://github.com/PerryLink/dsh-plugin-doctor)** | Zero-dependency static + sandbox smoke detector for DSH plugins | |
206
+ | **[dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide)** | Plugin-development knowledge base as an on-demand agent skill | |
207
+ | **[dsh-plugin-kit](https://github.com/PerryLink/dsh-plugin-kit)** | Shared zero-runtime-dependency toolkit for the PerryLink DSH plugins | |
208
+ | **[dsh-plugin-upgrade](https://github.com/PerryLink/dsh-plugin-upgrade)** | One-package, one-corridor-index plugin upgrade skill: routes a repository to the matching closed corridor card | |
209
+ | **[dsh-plugin-upgrade-015](https://github.com/PerryLink/dsh-plugin-upgrade-015)** | Merged `0.1.3-alpha.1` → `0.1.5-rc.1` upgrade corridor card plus a zero-dependency seam scanner | |
210
+ | **[dsh-reach](https://github.com/PerryLink/dsh-reach)** | Multi-channel approval/question bridge: WeChat/Telegram/Feishu, session console | |
198
211
  | **[dsh-research-report](https://github.com/PerryLink/dsh-research-report)** | Verifiable research-report engine: content-addressed evidence ledger and sealed versions | |
199
212
  | **[dsh-score](https://github.com/PerryLink/dsh-score)** | Multi-dimensional quality scoring for DeepSeek Harness plugins. | |
200
213
  | **[dsh-session-pin](https://github.com/PerryLink/dsh-session-pin)** | Pin sessions in the Web sidebar with durable ordering | |
201
214
  | **[dsh-session-sync](https://github.com/PerryLink/dsh-session-sync)** | Cross-device session sync for DeepSeek Harness — a dedicated git mirror of your session store. | |
202
215
  | **[dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security)** | Security-audit skill pack: secret scan, dependency and supply-chain review | |
203
216
  | **[dsh-talk](https://github.com/PerryLink/dsh-talk)** | Voice-first session loop for DeepSeek Harness: talk to it, hear it answer. | |
217
+ | **[dsh-team-rooms](https://github.com/PerryLink/dsh-team-rooms)** | Cross-session team rooms: shared message bus, task board and timeline | |
204
218
  | **[dsh-test-drive](https://github.com/PerryLink/dsh-test-drive)** | Isolated install-and-smoke test drives for DeepSeek Harness plugins. | |
205
- | **[dsh-ticktick](https://github.com/PerryLink/dsh-ticktick)** | TickTick/Dida365 task bridge: session-header panel + 11 tools |
219
+ | **[dsh-ticktick](https://github.com/PerryLink/dsh-ticktick)** | TickTick/Dida365 task bridge: session-header panel + 11 tools | |
206
220
  | **[dsh-translate](https://github.com/PerryLink/dsh-translate)** | Vendor parameter translation and deterministic JSON repair for DeepSeek Harness. | |
207
- | **[dsh-wechat](https://github.com/pan17/dsh-wechat)** | WeChat ↔ DSH bridge (Tencent iLink bot): text/image/file/voice, approvals in chat |
208
- | **[dsh-autotier](https://github.com/PerryLink/dsh-autotier)** | Automatic strong/cheap model-tier routing with deterministic risk guards and a `/tier` command | |
209
- | **[dsh-catalog](https://github.com/PerryLink/dsh-catalog)** | DSH Desktop Market standard catalog source for the PerryLink family | |
210
- | **[dsh-cert-mcp](https://github.com/PerryLink/dsh-cert-mcp)** | Read-only MCP server exposing the certification registry: grades, snapshots and five-dimension evidence | |
211
- | **[dsh-kit](https://github.com/PerryLink/dsh-kit)** | One-command starter pack that installs the core family | |
212
- | **[dsh-plugin-certification](https://github.com/PerryLink/dsh-plugin-certification)** | Community certification registry with repro-checkable grades and badges | |
213
- | **[dsh-plugin-kit](https://github.com/PerryLink/dsh-plugin-kit)** | Shared zero-runtime-dependency toolkit for the PerryLink DSH plugins | |
214
- | **[dsh-plugin-portal](https://github.com/PerryLink/dsh-plugin-portal)** | Zero-dependency static portal rendering the whole plugin family as one page | |
215
- | **[dsh-plugin-upgrade-015](https://github.com/PerryLink/dsh-plugin-upgrade-015)** | Merged `0.1.3-alpha.1` → `0.1.5-rc.1` upgrade corridor card plus a zero-dependency seam scanner | |
216
- | **[dsh-team-rooms](https://github.com/PerryLink/dsh-team-rooms)** | Cross-session team rooms: shared message bus, task board and timeline | |
221
+
217
222
 
218
223
  ### Install from the DSH Desktop Market
219
224
 
@@ -13,9 +13,9 @@ everything else is install-time:
13
13
  | [zod](https://github.com/colinhacks/zod) | `^4.4.3` | MIT | Wire codecs shared by the host and client Typert faces (bundled into `lib/`) |
14
14
  | [tsdown](https://github.com/rolldown/tsdown) | `^0.22.14` | MIT | Build-time bundling of `lib/` (a regular dependency so the git-install channel's `prepare` script can build) |
15
15
  | [typescript](https://github.com/microsoft/TypeScript) | `^7.0.2` | Apache-2.0 | Build-time declaration emission (`lib/types/`) |
16
- | [@deepseek-ai/cordis](https://www.npmjs.com/package/@deepseek-ai/cordis) | `^4.0.1` (peer) | See package | The plugin runtime |
17
- | [@deepseek-ai/schemastery](https://www.npmjs.com/package/@deepseek-ai/schemastery) | `^3.18.0` (peer) | See package | Configuration schema |
18
- | `@deepseek-ai/dsh-*` peers | `0.1.0-rc.6` (peer) | See packages | Official harness seams (`dsh-tools`, `dsh-session`, `dsh-attachment`, `dsh-credentials`, `dsh-llm`, `dsh-brand`, `dsh-typert-protocol`) |
16
+ | [@deepseek-ai/cordis](https://www.npmjs.com/package/@deepseek-ai/cordis) | `^4.0.4` (peer) | See package | The plugin runtime |
17
+ | [@deepseek-ai/schemastery](https://www.npmjs.com/package/@deepseek-ai/schemastery) | `^3.18.2` (peer) | See package | Configuration schema |
18
+ | `@deepseek-ai/dsh-*` peers | `>=0.1.2-rc.1 <0.2.0 \|\| >=0.1.5-alpha.1 <0.2.0 \|\| >=0.1.6-0 <0.2.0 \|\| >=0.1.7-0 <0.2.0` (peer) | See packages | Official harness seams (`dsh-tools`, `dsh-session`, `dsh-attachment`, `dsh-credentials`, `dsh-llm`, `dsh-brand`, `dsh-typert-protocol`) |
19
19
 
20
20
  At runtime the plugin only talks to the image-generation endpoints the user
21
21
  configures and to the harness services listed as peerDependencies.
package/lib/client.js CHANGED
@@ -7,13 +7,35 @@ window.__ModuleLoader__.load({
7
7
  let react = require("react");
8
8
  //#region src/client/present.ts
9
9
  /**
10
+ * Classify a frozen tool block into its Host stage, mirroring the Host's own
11
+ * `toolCallPhase`: a settled node wins on `kind`, and the running family splits
12
+ * on `phase`. `ToolCallBlock` is structurally narrower than the Host union
13
+ * (`RunningToolCallBlock` declares no `phase` field), so the running arm is
14
+ * read through a structural probe rather than a declared member.
15
+ *
16
+ * @param block - the frozen tool block the owner delivered.
17
+ * @returns the stage this block belongs to.
18
+ */
19
+ function toolCallPhase(block) {
20
+ if ("kind" in block) return "result";
21
+ return block.phase === "preparing" ? "preparing" : "start";
22
+ }
23
+ /**
10
24
  * Project one settled `image_generate` tool block onto the card model.
11
25
  *
26
+ * The stage guard is explicit, not incidental: only the Host's `result` stage
27
+ * carries `kind`, and the preparing stage's block is an ordinary object, so
28
+ * an `undefined` return is the presenter's answer for every non-result stage
29
+ * as well as for a foreign tool, an error result, or a window-truncated call
30
+ * head. The card pairs that answer with {@link toolCallPhase} to render its
31
+ * in-flight row instead of an empty node.
32
+ *
12
33
  * @param block - the frozen tool-call block (running or settled).
13
34
  * @returns the presented model, or `undefined` when the block is not a settled
14
35
  * image_generate result.
15
36
  */
16
37
  function presentDrawResult(block) {
38
+ if (toolCallPhase(block) !== "result") return void 0;
17
39
  if (!("kind" in block) || block.kind !== "tool-result" || block.isError) return void 0;
18
40
  if (block.call?.name !== "image_generate") return void 0;
19
41
  const value = block.meta ?? {};
@@ -86,10 +108,16 @@ window.__ModuleLoader__.load({
86
108
  //#endregion
87
109
  //#region src/client/DrawResultCard.tsx
88
110
  /**
89
- * The keyed `image_generate` tool result card: engine/quota facts and the
90
- * regenerate action. The images themselves are the attachment content blocks
91
- * the shell already renders from the tool result, so the card only adds the
92
- * accounting line and the action — it never duplicates image transport.
111
+ * The keyed `image_generate` tool view: engine/quota facts and the regenerate
112
+ * action once the call settles, and an in-flight row of its own while the
113
+ * arguments are still arriving. The images themselves are the attachment
114
+ * content blocks the shell already renders from the tool result, so the card
115
+ * only adds the accounting line and the action — it never duplicates image
116
+ * transport.
117
+ *
118
+ * The Host dispatches this keyed entry in EVERY stage of the call, and a keyed
119
+ * cell that is occupied never reaches the owner fallback — so the earlier
120
+ * stages cannot be answered with nothing without blanking the row.
93
121
  *
94
122
  * The `tool.call.toolview` SlotMap member is declared locally (mirroring the
95
123
  * harness's own ui-tool contract declaration, which its package index does not
@@ -98,11 +126,40 @@ window.__ModuleLoader__.load({
98
126
  * @module dsh-draw/client/DrawResultCard
99
127
  */
100
128
  /**
101
- * The keyed tool result card.
102
- * @param props - owner currency, locale, and injected bindings.
103
- * @returns the card element.
129
+ * The keyed tool view. Dispatched by the wire tool name in EVERY stage of the
130
+ * call, so the card owes a presentation to the in-flight stages too: returning
131
+ * an empty node would leave the row blank, because an occupied keyed cell
132
+ * never reaches the Host's own generic row.
133
+ *
134
+ * @param props - owner currency (common + stage shares), locale, and injected bindings.
135
+ * @returns the in-flight row, or the settled result card.
104
136
  */
105
137
  function DrawResultCard(props) {
138
+ const phase = toolCallPhase(props.block);
139
+ if (phase !== "result") {
140
+ const stage = props.phase === "result" ? phase : props.phase;
141
+ return (0, react.createElement)("div", {
142
+ className: "dshdraw-inflight",
143
+ "aria-busy": "true",
144
+ "data-phase": stage
145
+ }, (0, react.createElement)("span", { className: "dshdraw-inflight-title" }, props.t("row.title")), (0, react.createElement)("span", {
146
+ className: "dshdraw-sep",
147
+ "aria-hidden": "true"
148
+ }, "·"), (0, react.createElement)("span", { className: "dshdraw-inflight-summary" }, props.toolName), (0, react.createElement)("span", { className: "dshdraw-inflight-state" }, props.t(inFlightKey(stage))));
149
+ }
150
+ return (0, react.createElement)(DrawResultCardBody, props);
151
+ }
152
+ /** Locale key naming the stage of a call that has not settled yet. */
153
+ function inFlightKey(phase) {
154
+ return phase === "preparing" ? "row.preparing" : "row.running";
155
+ }
156
+ /**
157
+ * The settled result card: engine/quota facts and the regenerate action.
158
+ *
159
+ * @param props - the owner at its `result` stage, locale, and injected bindings.
160
+ * @returns the card element.
161
+ */
162
+ function DrawResultCardBody(props) {
106
163
  const { block, regenerate, t } = props;
107
164
  const presented = presentDrawResult(block);
108
165
  const [busy, setBusy] = (0, react.useState)(false);
@@ -275,6 +332,9 @@ window.__ModuleLoader__.load({
275
332
  "result.regenerate": "Regenerate",
276
333
  "result.regenerating": "Regenerating…",
277
334
  "result.failed": "Regenerate failed",
335
+ "row.title": "Tool call",
336
+ "row.preparing": "Preparing tool call",
337
+ "row.running": "Running",
278
338
  "tab": "Image generation",
279
339
  "tab.engines": "Engines",
280
340
  "tab.preferred": "preferred",
@@ -300,6 +360,9 @@ window.__ModuleLoader__.load({
300
360
  "result.regenerate": "重新生成",
301
361
  "result.regenerating": "正在重新生成…",
302
362
  "result.failed": "重新生成失败",
363
+ "row.title": "工具调用",
364
+ "row.preparing": "正在准备调用",
365
+ "row.running": "运行中",
303
366
  "tab": "图像生成",
304
367
  "tab.engines": "引擎",
305
368
  "tab.preferred": "首选",
@@ -5622,6 +5685,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5622
5685
  .dshdraw-figure img { max-width: 100%; border-radius: 6px; border: 1px solid var(--dsh-border, #d0d7de); }
5623
5686
  .dshdraw-figure figcaption { font-size: 11px; opacity: 0.75; overflow-wrap: anywhere; }
5624
5687
  .dshdraw-meta { font-size: 12px; opacity: 0.85; display: flex; flex-wrap: wrap; gap: 12px; }
5688
+ .dshdraw-inflight { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; font-size: 13px; min-height: 20px; }
5689
+ .dshdraw-inflight .dshdraw-sep { opacity: 0.45; }
5690
+ .dshdraw-inflight-title { font-weight: 500; }
5691
+ .dshdraw-inflight-summary { opacity: 0.85; overflow-wrap: anywhere; }
5692
+ .dshdraw-inflight-state { font-size: 12px; opacity: 0.7; }
5625
5693
  .dshdraw-actions { display: flex; gap: 8px; }
5626
5694
  .dshdraw-button {
5627
5695
  border: 1px solid var(--dsh-border, #d0d7de); border-radius: 6px; background: transparent;