dsh-cindy-host 0.1.25 → 0.1.27
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/CHANGELOG.md +19 -511
- package/README.md +15 -164
- package/lib/client.js +81 -1
- package/package.json +5 -6
- package/src/cindy-channels.js +63 -5
- package/src/dsh-input-delivery.js +86 -0
- package/src/dsh-plugin.js +21 -1
- package/src/host-attachments.js +2 -1
- package/src/host-device-name.js +55 -0
- package/src/host-frame-budget.js +12 -1
- package/src/host-history-locate.js +39 -0
- package/src/host-input-delivery-store.js +57 -0
- package/src/host-input-delivery.js +158 -0
- package/src/host-input-queue.js +33 -8
- package/src/host-settings.js +17 -1
- package/src/host-version.js +5 -3
- package/src/host.js +89 -9
- package/doc/architecture.md +0 -34
- package/doc/cindy-android-verify.md +0 -362
- package/doc/cindy-mobile-freeze-handoff.md +0 -124
- package/doc/cindy-phone-link.md +0 -2902
- package/doc/desktop-runtime-fix-20260930.md +0 -69
- package/doc/development-plan.md +0 -19
- package/doc/file-peer-apply-recovery-20260921.md +0 -35
- package/doc/file-peer-installed-hotfix-20260921.md +0 -53
- package/doc/file-peer-minimal-apply-20260921.md +0 -78
- package/doc/file-peer-original-contract-alignment-20260921.md +0 -119
- package/doc/file-peer-phone-export-observation-20260921.md +0 -75
- package/doc/file-peer-product-contract-audit-20260921.md +0 -106
- package/doc/file-peer-root-cause-20260921.md +0 -53
- package/doc/file-transfer.md +0 -50
- package/doc/host-performance-20260930.md +0 -91
- package/doc/neonabyss-apk-file-peer-diagnosis-20260921.md +0 -87
- package/doc/new-session-sync-fix-20260930.md +0 -59
- package/doc/patches/cindy-peer-silence-probe.patch +0 -1112
- package/doc/projection-read-probe.md +0 -77
- package/doc/publishing.md +0 -259
- package/doc/releasing.md +0 -149
- package/doc/research.md +0 -24
- package/doc/session-discovery-2026-09-20.md +0 -67
package/CHANGELOG.md
CHANGED
|
@@ -1,520 +1,28 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
[Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),版本号遵循语义化版本。
|
|
3
|
+
## 0.1.27 — 2026-10-28
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
- Implements current input-delivery v1 in Host: transactional complete-payload ownership before ACK, receipts, cancellation seals, authoritative clear boundaries, immutable logical identity and recoverable edits.
|
|
6
|
+
- Adds real persistent around/around-client-id history with content bounds and confirmation-anchor-preserving frame degradation.
|
|
7
|
+
- Uses public DSH flush and storage read checkpoints; a live claim/admission gap never authorizes replay. Verified dead-process/cold-owned-queue recovery is distinct from same-process reload.
|
|
8
|
+
- Captures attachment bytes before handoff; no temporary file receipt or staging URL is treated as durable ownership.
|
|
9
|
+
- Requires the verified DSH 0.2.1-rc.3 carrier and Node >=22.16; exact DSH peers prevent mixed-prerelease dependency graphs. Unsupported optional operations remain explicit refusals.
|
|
10
|
+
- Retains editable names, desktop string queue content, production model/active-session features and optional keytar.
|
|
11
|
+
- Upstream mobile outbox execution tests cover FIFO, lost ACK, cancellation and history-cache completion. Live handset acceptance remains a separate gate.
|
|
7
12
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- 设备删除遇到令牌过期时使用 Host 共享凭据刷新通道,最多重试一次;保留登录态,并在重试前重新检查设备在线状态。
|
|
11
|
-
- 按上游实际 HTTP 状态区分登录过期、权限、设备不存在、冲突和服务故障,不再统一误报“设备可能已上线”。
|
|
12
|
-
- 删除请求补齐官方客户端使用的 JSON Content-Type;Cindy 兼容版本仍为 0.1.82。
|
|
13
|
-
|
|
14
|
-
## [0.1.24] - 2026-10-20
|
|
15
|
-
|
|
16
|
-
### Fixed
|
|
17
|
-
|
|
18
|
-
- 设置页支持二次确认删除账号中的离线设备;拒绝删除在线设备和当前 Host,删除失败不清除登录态。
|
|
19
|
-
- 设备身份读取失败时停止注册而非生成新身份,并合并并发身份初始化,避免插件制造重复设备。
|
|
20
|
-
- Cindy 兼容版本统一为真实桌面稳定版 0.1.82(2026-09-14),与插件发行版本独立。
|
|
21
|
-
- 基于正式 0.1.23 集成,保留会话删除确认、交互与设置兼容能力。
|
|
22
|
-
|
|
23
|
-
## [0.1.23] - 2026-10-14
|
|
24
|
-
|
|
25
|
-
### Fixed
|
|
26
|
-
|
|
27
|
-
- 手机删除已不存在的 DSH 会话时,在删除标记持久化成功后返回最小删除确认,重复删除也成功,避免手机因 NOT_FOUND 回滚而留下幽灵任务。
|
|
28
|
-
- 仅放宽纯删除元数据请求(可同时取消置顶);归档、重命名和混合编辑仍保留 NOT_FOUND。保存或读取失败不冒充删除成功,不伪造完整会话。
|
|
29
|
-
|
|
30
|
-
### 验证
|
|
31
|
-
|
|
32
|
-
- 完整测试:770 通过 / 3 跳过 / 0 失败;另设置 CINDY_SOURCE_ROOT 补跑其中 2 项真实双端契约测试,均通过。剩余跳过项为需显式启用的 11 分钟慢上传测试。
|
|
33
|
-
- 通道审计:54 served / 142 declined / 0 unclassified。干净 DSH 0.2.0-rc.2 隔离 profile 加载 tarball 成功,HTTP 连续两次删除不存在会话均返回成功;未构建原生凭据依赖,未登录账号。
|
|
34
|
-
- 旧版整体验收 67/77:存在账号/历史数据前置条件缺失及旧协议断言,不计为全绿。用户明确接受本次专项验证范围后发布;手机端实测及真实宿主重启生效仍需单独确认。
|
|
35
|
-
|
|
36
|
-
## [0.1.22] - 2026-10-03
|
|
37
|
-
|
|
38
|
-
### Fixed
|
|
39
|
-
|
|
40
|
-
- 补齐桌面模型选择入口要求的真实上下文容量:Host 在请求级按精确 provider/model 从 DSH llm.resolveModelInfo 获取 context.contextWindow,不再仅转发省略容量的 catalog。三 alias 共用同一结果,查询去重、最多4路并发、总期限3秒,不修改模型路由或默认选择。
|
|
41
|
-
- 保留手机依赖的 routing 存在标记与未知容量0;单模型元数据失败不删除模型、不清空其它模型,不用 defaultMaxTokens 或硬编码数值冒充容量。真正未知容量在旧桌面的 >0 校验下仍会被过滤,需要客户端明确支持未知合同;本补丁不声称修复旧客户端这一固有限制。
|
|
42
|
-
- 双端回归现在经过真实桌面 parseDeviceProvidersPayload 和手机 deviceProvidersCache,再进入共享选择器。保留0.1.21响应“手机可见、桌面全被过滤”的红例;之前仅测共享筛选不构成完整桌面入口验收。
|
|
43
|
-
|
|
44
|
-
### 验证
|
|
45
|
-
|
|
46
|
-
- 完整测试:768 通过 / 1 跳过 / 0 失败;通道审计 54 served / 142 declined / 0 unclassified。
|
|
47
|
-
- 重启后的真实 HTTP 响应经过桌面解析器与手机缓存入口:新建及已有会话均 Host 7 / Desktop 7 / Mobile 7,2 个供应商、未知容量 0 项。此为本次安装环境观测,不是固定模型数量。
|
|
48
|
-
- 用户已确认当前双端界面测试通过。安装目录补丁与源码一致;本修复由 0.1.22 发布,0.1.21 不包含真实容量补齐。
|
|
49
|
-
|
|
50
|
-
## [0.1.21] - 2026-10-02
|
|
51
|
-
|
|
52
|
-
### Fixed
|
|
53
|
-
|
|
54
|
-
- 修复桌面供应商目录上线后手机模型选择器为空:`maker:provider:list` 为每个已广告的 DSH agent 别名补齐 `routing[agent]: {}` 可用性标记。仍只由 DSH catalog 决定 connected 和模型清单,不发送 endpoint、认证信息或 headers,不臆造 wireProtocol。
|
|
55
|
-
- 补充投影/通道回归与可选的真实 Cindy registry、分段列表、统一选择器跨仓契约测试;设置 `CINDY_SOURCE_ROOT` 后运行 `node --test test/host-models-cindy-contract.test.js`(需支持 registerHooks/TypeScript stripping 的 Node)。覆盖旧响应复现空列表、新建/已有会话、多来源、不可连接/禁用 runtime 和目录读取失败。
|
|
56
|
-
- 运行期补证:当前 DSH `buildModelCatalog` 不输出 `contextWindow`,旧投影把所有缺失窗口的模型丢弃,导致能力列表有模型而 provider 列表为空。缺失/无效窗口现在以 `0` 表示未知展示容量,不作为模型准入条件;跨仓测试改为真实的无窗口目录结构。
|
|
57
|
-
|
|
58
|
-
### 验证
|
|
59
|
-
|
|
60
|
-
- 完整单元与契约测试:**759 通过 / 1 跳过 / 0 失败**,包含真实 Cindy 消费端及无 contextWindow 的 DSH 目录结构。
|
|
61
|
-
- 运行中的 desktop Host 返回 **2 个供应商 / 7 个模型**;真实 HTTP 响应经过 Cindy 新建/已有会话筛选均得到 7 个可选项。用户已确认手机端模型列表恢复。
|
|
62
|
-
- 保留桌面供应商目录和真实 DSH 模型路由;不增加客户端专用模型表。
|
|
63
|
-
|
|
64
|
-
## [0.1.20] - 2026-10-01
|
|
65
|
-
|
|
66
|
-
### Changed
|
|
67
|
-
|
|
68
|
-
- npm/DSH bundle 包名由 `dsh-cindy-host-demo` 正式迁移为 `dsh-cindy-host`;项目已不是 demo。
|
|
69
|
-
- `package.json`/lock、`cordis.patch.yml` bundle name、Web `ModuleLoader` id、安装与发布说明同步使用新名。
|
|
70
|
-
- 业务身份保持不变:Cordis row id、server plugin name、settings namespace 和 HTTP API prefix 继续是 `dsh-cindy-host`,现有设置与 Cindy 登录状态无需迁移。
|
|
71
|
-
- 旧 npm 包不删除,迁移验证成功后对全版本标记 deprecated 并指向新包,仍可精确安装旧版本回滚。
|
|
72
|
-
|
|
73
|
-
### Migration
|
|
74
|
-
|
|
75
|
-
- desktop Profile 必须把 dependency、`dsh.profile.bundles`、lockfile、node_modules、Cordis patch/composed config 一次替换为新名;不得让新旧包同时加载。
|
|
76
|
-
- 旧 `plugin-releases/dsh-cindy-host-demo/*` 历史产物只读保留;新产物存放于 `plugin-releases/dsh-cindy-host/0.1.20`。
|
|
77
|
-
|
|
78
|
-
## [0.1.19] - 2026-10-01
|
|
79
|
-
|
|
80
|
-
### Fixed
|
|
81
|
-
|
|
82
|
-
- Cindy 会话发现列表不再同步没有真实非空标题的会话,因此不会再出现由 Host 合成的 “Untitled DSH task”。过滤依据是 title 事实,不是显示文案字符串。
|
|
83
|
-
- 首次 title 读取失败、缺项或空白时,未知行保持隐藏;一旦已有有效 title,后续临时失败继续使用 last-known-good,不会让正常任务从列表闪退。
|
|
84
|
-
- `local-db:sessions:get` 的精确读取保持不变:新建 draft 在第一条 prompt 生成标题前仍可由 create/get/enqueue 流程访问,只是不进入发现列表。
|
|
85
|
-
- 有界 title warm-up 的发现语义改为“当前已确认标题的批次先显示,后台补齐后续批次”,继续避免大型 profile 的列表超时。
|
|
86
|
-
|
|
87
|
-
### 验证
|
|
88
|
-
|
|
89
|
-
- 完整单元与契约测试:**755 通过 / 1 跳过 / 0 失败**。
|
|
90
|
-
- 通道审计:**54 served / 142 declined / 0 unclassified**。
|
|
91
|
-
|
|
92
|
-
## [0.1.18] - 2026-10-01
|
|
93
|
-
|
|
94
|
-
验证环境:DSH **0.2.0-rc.2**(桌面端)与 **0.1.5-rc.2**(Web profile),Node **24.12.0**;要求 Node >=22,werift 固定 **0.24.4**。
|
|
95
|
-
|
|
96
|
-
### Fixed
|
|
97
|
-
|
|
98
|
-
- **桌面项目分类恢复。** Host 从 DSH transcript 的同一 fold 派生精确 `messageCount` 与首条 durable user 消息时间 `userSendAt`,通过 4 会话有界批次预热并缓存;live event 会失效对应证据。Cindy 的远程项目分组因此能区分已有内容的项目任务和真草稿,不再把所有 DSH 会话放进“未分类”。未知/不可读证据保持 `null`,绝不伪造固定计数或发送时间。
|
|
99
|
-
- **DSH 与 Cindy 可同时处理 approval / ask_user_question。** 单一 Host registry 向两端 fan-out,同一 pending 由任一端首答原子结算;本地先答会 dismiss Cindy,Cindy 先答会 abort DSH 下游卡片,late answer 返回未接受。本地 UI 失败时 Cindy 路径继续有效;不使用无取消合同的裸 `Promise.race`。
|
|
100
|
-
- **远程新建草稿默认值补齐。** `maker:get-new-maker-defaults` 从 DSH `modelCatalog.default` 投影 model/provider/default effort 与真实 `fastMode:false`,不冒充 Cindy 本地 draft preference;catalog 暂不可读时按 Cindy 原生语义返回 `{}`。
|
|
13
|
+
## 0.1.26 — 2026-10-28
|
|
101
14
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
- 固化 P0 发现/身份、P1 对话闭环、P2 会话控制的 owner / read / write / push / capability / shape / error 矩阵。
|
|
105
|
-
- 继续 fail-closed 的独立产品家族:Orca、Bots/Workers、Schedule/Automation、Remote Desktop、Voice、Telegram、Learn、Usage、Memory、Worktree/Git Review、PI Subagent tree,以及 Cindy 自己拥有的 sidebar/project-order 与草稿偏好写穿。
|
|
106
|
-
- `tools/channel-audit.mjs`:所有 allowlist channel 继续是 served 或有理由 declined,`unclassified: 0`;provider/defaults 的陈旧拒绝规则已删除。
|
|
107
|
-
|
|
108
|
-
### 验证
|
|
109
|
-
|
|
110
|
-
- 完整单元与契约测试:**754 通过 / 1 跳过 / 0 失败**。
|
|
111
|
-
- 新增 project grouping activity evidence、local-first/Cindy-first/DSH-local-failure/late-answer、draft defaults 与 fail-closed 契约测试。
|
|
112
|
-
- 仍需目标 Profile 安装并重启后,在真实 Cindy 桌面完成项目分类与双端询问卡的最终人工体验确认。
|
|
113
|
-
|
|
114
|
-
## [0.1.17] - 2026-10-01
|
|
115
|
-
|
|
116
|
-
验证环境:DSH **0.2.0-rc.2**(桌面端)与 **0.1.5-rc.2**(Web profile),Node **24.12.0**;要求 Node >=22,werift 固定 **0.24.4**。
|
|
117
|
-
|
|
118
|
-
### Fixed
|
|
119
|
-
|
|
120
|
-
- Cindy 桌面端现在能读取 DSH Host 的供应商分组与模型目录;新增 `maker:provider:list` 展示投影,只发送 provider/model 的非敏感显示字段,不发送路由凭据或 endpoint。
|
|
121
|
-
- 控制权限在协议边界双向映射:DSH `read-only / workspace-write / danger-full-access` 对应 Cindy `ask / acceptEdits / bypassPermissions`;会话行、能力列表、创建与修改路径不再暴露 DSH 内部预设名。
|
|
122
|
-
- 任务同步遵守 Cindy 原生 `local-db:sessions:list(limit, status, { includePinned })` 契约,active/archived 不再混在同一响应里,避免“正在自动重试;先显示已加载的内容”常驻。
|
|
123
|
-
- `maker:event` 运行状态补齐非空 `data.status`,避免 Cindy 状态栏对 `undefined.trim()` 崩溃;等待交互显示为 `waiting on input`。
|
|
124
|
-
- 普通 assistant/user/reasoning 消息按 Cindy 桌面原生格式发送字符串;仅附件和工具数据保留对象,桌面端不再把 `{"text":"…"}` 当正文显示,手机端继续兼容。
|
|
125
|
-
|
|
126
|
-
### 验证
|
|
127
|
-
|
|
128
|
-
- 完整单元与契约测试:**745 通过 / 1 跳过 / 0 失败**。
|
|
129
|
-
- 通道与安全边界继续 fail-closed;provider 投影和权限映射新增双向契约测试。
|
|
130
|
-
- 用户已确认本轮任务同步、状态栏与消息显示现象无其它问题;发布后仍需安装并重启目标 Host 才会加载新版本。
|
|
131
|
-
|
|
132
|
-
## [0.1.16] - 2026-09-30
|
|
133
|
-
|
|
134
|
-
验证环境:DSH **0.2.0-rc.2**(桌面端)与 **0.1.5-rc.2**(Web profile)—— 同一份产物。
|
|
15
|
+
Host-only patch based on 0.1.25; retains its DSH 0.2 adapter, model catalog, active-session listing, optional keytar and bundle identity.
|
|
135
16
|
|
|
136
17
|
### Fixed
|
|
137
|
-
|
|
138
|
-
-
|
|
139
|
-
`inject` 原本是 `["slots", "settingsScope"]`。`settingsScope` 是 **0.1.x** 的客户端设置服务;
|
|
140
|
-
**0.2 把它换成了 `configForms` + `settingsSchema`**(同一个包 `dsh-client-ui-settings`)。
|
|
141
|
-
模块级 `inject` 是**阻塞**依赖:服务永不出现 → 客户端半边永不激活 → 0.2 把它报成唯一未激活
|
|
142
|
-
条目并**拒绝继续启动**。
|
|
143
|
-
(对照:better-tasks 用非阻塞的 `ctx.inject(['settingsScope'], cb)`,服务缺席只是那个回调不执行,
|
|
144
|
-
插件照常激活。同一个名字,写法不同,后果就不同。)
|
|
145
|
-
- **设置访问改为两代兼容且非阻塞。** 模块级 `inject` 现在只有 `slots`;设置控制器由两条
|
|
146
|
-
**非阻塞**分支解析,先到者胜:
|
|
147
|
-
- 0.2 → `ctx.inject(["configForms"], …)` + `configForms.get(entryId)`
|
|
148
|
-
- 0.1.x → `ctx.inject(["settingsScope"], …)` + `settingsScope.bind({ namespace })`
|
|
149
|
-
|
|
150
|
-
两个控制器暴露同一套面(`getSnapshot()` / `subscribe()` / `set(field, value)`),快照形状也都是
|
|
151
|
-
`{status, value, base, user, revision, writable, mode}`,所以页面与 `writeSwitch` 无需分支。
|
|
152
|
-
两代服务互斥(0.1.x 只有前者、0.2 只有后者),即使将来某代同时提供也不会重复注册。
|
|
153
|
-
|
|
154
|
-
### 客户端服务提供方审计(实测,非推断)
|
|
155
|
-
|
|
156
|
-
扫 `@deepseek-ai/*/lib/client.js` 全量客户端 bundle(0.2:71 个;0.1.5:55 个),
|
|
157
|
-
按 `super(ctx, "…")` / `provide("…")` 提取提供方:
|
|
158
|
-
|
|
159
|
-
| 服务 | 0.2.0-rc.2 | 0.1.5-rc.2 |
|
|
160
|
-
|---|---|---|
|
|
161
|
-
| `slots` | 提供方 `dsh-client-ui-renderer` | 提供方 `dsh-client-ui-renderer` |
|
|
162
|
-
| `settingsScope` | **无提供方** | 提供方 `dsh-client-ui-settings` |
|
|
163
|
-
| `configForms` | 提供方 `dsh-client-ui-settings` | **无提供方** |
|
|
164
|
-
|
|
165
|
-
因此产物里的模块级 `inject = ["slots"]` 在两条线上都有提供方 → 客户端半边在两条线上都会激活。
|
|
166
|
-
`ctx.inject([...], cb)` 也是 0.2 客户端面的标准写法(`ui-agent-preset` / `ui-approval` / `ui-chat` /
|
|
167
|
-
`ui-commands` / `ui-conversation` / `ui-input-trigger` 等至少 6 个内盒插件在用)。
|
|
168
|
-
|
|
169
|
-
### 发布验证
|
|
170
|
-
|
|
171
|
-
- 单元测试 **684 通过 / 1 跳过 / 0 失败**。`test/client-card.test.js` 16/16,含两个新增用例:
|
|
172
|
-
0.2 经 `configForms.get(entryId)` 注册出同一个页面(同一 section id / order,开关跟随控制器快照),
|
|
173
|
-
以及"两代设置服务都不存在时仍能激活、只是不注册页面"。
|
|
174
|
-
- 真机启动(独立 `DSH_HOME`):0.2 与 0.1.5 两侧均 `add exit=0`、`dsh.profile.bundles` 已登记、
|
|
175
|
-
`rows disabled 0 / bundles skipped 0 / pending 0`、`GET /api/dsh-cindy-host/status` → 200。
|
|
176
|
-
- **诚实标注证据边界**:客户端半边的"激活"发生在浏览器里,沙盒 boot 自检覆盖不到。本轮给的
|
|
177
|
-
间接证据是 ①产物模块级 `inject` 只含 `slots`(单测直接断言),②`slots` 在两侧都有真实提供方
|
|
178
|
-
(上面的全量扫描),③设置服务的用法与 0.2 内盒插件一致(`ui-theme`: `ctx.configForms.get(NS)`),
|
|
179
|
-
④`ctx.inject([...], cb)` 是 0.2 客户端面的标准用法。真实浏览器里的最终确认仍需在桌面端页面里看一眼。
|
|
180
|
-
|
|
181
|
-
## [0.1.15] - 2026-09-30
|
|
182
|
-
|
|
183
|
-
验证环境:DSH **0.2.0-rc.2**(桌面版 `@deepseek-ai/dsh-desktop-runtime`,Electron 44 / Node 24.18.1)
|
|
184
|
-
**与** DSH **0.1.5-rc.2**(Web profile)—— 同一份产物同时服务两条线。要求 Node >=22,werift 固定 **0.24.4**。
|
|
18
|
+
- Queue UI echoes use string content, preventing desktop text parsers from receiving SDK block arrays.
|
|
19
|
+
- Early durable consumption cannot be undone by a later enqueue/steer ACK or stale queue/inbox snapshot. Evidence is session-scoped, capped at 2,048 recent entries and cleared on teardown.
|
|
185
20
|
|
|
186
21
|
### Added
|
|
22
|
+
- Persistent editable Host display name with separate local-save/cloud-sync feedback.
|
|
23
|
+
- Host status pluginVersion for loaded-release verification.
|
|
187
24
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
### Fixed
|
|
193
|
-
|
|
194
|
-
- **设置 seam 在 0.2 上不再抛错**。0.2 删掉了 `settings.register`,插件原本会在 mount 时
|
|
195
|
-
抛 `settings.register is not a function`;DSH 把加载失败的 entry 当致命错误,于是**整个
|
|
196
|
-
profile 起不来**。现在按宿主能力选路径:有 `register` 走 0.1.x 的命名空间注册(行为不变),
|
|
197
|
-
没有则用**插件条目自己的 `Config`** —— 0.2 的 `SettingsForms` 按 **profile entry id** 投影它,
|
|
198
|
-
并把解析结果作为 `apply(ctx, config)` 的第二个参数。`SETTINGS_NAMESPACE` 正好就是本 bundle
|
|
199
|
-
的行 id(`dsh-cindy-host`),所以两条路径操作的是同一个面,下游代码无需分支。
|
|
200
|
-
- **`@deepseek-ai/dsh-host-apiproxy` 从 `peerDependencies` 移除**。0.2 已删除该包,而
|
|
201
|
-
`evaluatePluginCompatibility` 遍历 peers 的**每一个键、且不查 `peerDependenciesMeta`**,
|
|
202
|
-
所以只要它还在 peers 里,安装与启动两道门禁都会拒绝整个插件(bundle 被跳过后
|
|
203
|
-
`dsh-cindy-host` 行根本不会出现)。该适配器仍是惰性 `require` + 失败降级,运行时行为不变。
|
|
204
|
-
- **`.volatile()` 改为特性检测**。只有 0.2 的 schemastery `3.18.4` 有这个方法;`0.1.5-rc.2`
|
|
205
|
-
解析到的 `3.18.2` 没有(仍在声明的 `^3.18.1` 区间内)。无条件调用会在**模块加载**时抛错,
|
|
206
|
-
把 profile 一起拖垮;没有它时纯 schema 仍服务于 0.1.x 的 `register` 路径。
|
|
207
|
-
- **`keytar` 移入 `optionalDependencies`**。它是原生模块,没有 C++ 工具链的机器上必然构建失败,
|
|
208
|
-
而普通 dependency 的构建失败会让 pnpm 退出 1(见下面"部署注意"的后果)。
|
|
209
|
-
|
|
210
|
-
### 部署注意(**必须看**)
|
|
211
|
-
|
|
212
|
-
pnpm 11 把 `strictDepBuilds` 默认设为 **true**,于是"构建脚本被忽略"从警告变成**硬错误**:
|
|
213
|
-
`add` 退出码 1。而 DSH 只在 pnpm 成功时才把 bundle 写进 `dsh.profile.bundles` —— 结果是
|
|
214
|
-
**包装上了、行却永远不出现**(这正是历史上要手写 insert 行的原因)。
|
|
215
|
-
|
|
216
|
-
在没有 C++ 工具链的机器上,安装前请在 profile 的 `pnpm-workspace.yaml` 里**显式承认**这一条:
|
|
217
|
-
|
|
218
|
-
```yaml
|
|
219
|
-
allowBuilds:
|
|
220
|
-
keytar: false
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
这样 `add` 退出 0、bundle 正常登记,插件在没有 keytar 二进制时照常 mount,只是凭据能力不可用。
|
|
224
|
-
`strictDepBuilds: false` 也能让安装通过(实测),但它会**全局**关掉这道保护,不建议。
|
|
225
|
-
|
|
226
|
-
### 发布验证
|
|
227
|
-
|
|
228
|
-
- 单元测试:**682 通过 / 1 跳过 / 0 失败**(`node --test`)。
|
|
229
|
-
- peer 门禁:用宿主自带 semver 复现 `evaluatePluginCompatibility` → **compatible**,无需版本豁免。
|
|
230
|
-
- 干净 profile 真机启动(独立 `DSH_HOME`,宿主 `0.2.0-rc.2`,profile 里只装本 tarball):
|
|
231
|
-
`add exit=0`、`profile-local @deepseek-ai = 0`、`rows disabled 0 / bundles skipped 0 / pending 0`、
|
|
232
|
-
`GET /` → 200 且含 `__DSH_BOOT__`、**`GET /api/dsh-cindy-host/status` → 200
|
|
233
|
-
`{"ok":true,"installed":true,…,"diagnostics":{"dataSource":"session-controller",…}}`**、
|
|
234
|
-
未知 Cindy 路由 → 404(证明路由表确已挂载,而不是被鉴权层统一挡掉)。
|
|
235
|
-
- **keytar 未构建时仍能 mount**:本机无 VS Build Tools,`keytar@7.9.0` 未编译,插件照常挂载并
|
|
236
|
-
服务上述路由(`login.authenticated:false` 属预期:沙盒无 Cindy 会话)。§5.2 的说法这次是
|
|
237
|
-
在 0.2 上**实测**的,不是沿用旧结论。
|
|
238
|
-
- **0.1.5-rc.2 侧同产物复验**(独立 `DSH_HOME`、0.1.5 CLI 起独立实例):`add exit=0`
|
|
239
|
-
(该运行时的 pnpm 是 10.33.2)、`profile-local @deepseek-ai = 0`、`GET /` 200 且含 boot manifest、
|
|
240
|
-
**`GET /api/dsh-cindy-host/status` → 200 `ok:true installed:true`**、stderr 干净。
|
|
241
|
-
即这次的双代 seam 不是"只在 0.2 上验过",两条线各跑了一次真机。
|
|
242
|
-
|
|
243
|
-
## [0.1.13] - 2026-09-23
|
|
244
|
-
|
|
245
|
-
验证环境:DSH **0.1.5-rc.2**、Node **24.12.0**;要求 Node >=22,werift 固定 **0.24.4**。
|
|
246
|
-
|
|
247
|
-
### Changed
|
|
248
|
-
|
|
249
|
-
- Cindy 任务图标的未知来源/模型默认值由 Pi 改为 Claude;Pi 现在只用于明确识别为 DeepSeek 的来源(即使该来源的模型名未知)。旧会话在重新拉取列表时也按当前来源重新映射。
|
|
250
|
-
|
|
251
|
-
### 部署注意
|
|
252
|
-
|
|
253
|
-
- 当前 Web profile 如仍安装旧版(实查曾为 `0.1.10`),单独重启不会自动升级;先安装本版再按预警重启。重启后的短暂凭证恢复/中继重连不能当作 running 通道失败。
|
|
254
|
-
|
|
255
|
-
## [0.1.12] - 2026-09-23
|
|
256
|
-
|
|
257
|
-
验证环境:DSH **0.1.5-rc.2**、Node **24.12.0**;要求 Node >=22,keytar 需要原生构建,werift 固定 **0.24.4**。
|
|
258
|
-
|
|
259
|
-
### Changed
|
|
260
|
-
|
|
261
|
-
- Cindy 手机任务的三种 agent 图标在 DSH Host 上按会话实际来源和模型展示:DeepSeek 来源(任意模型)→ Pi、GPT 模型 → Codex、其他已知来源模型 → Claude。来源无法确认时回退 Pi;创建时手机所选 agent 平台不决定 DSH 的执行 harness。
|
|
262
|
-
- 三种 Cindy agentKind 均为同一 DSH harness 的协议别名,能力列表和模型/权限入口一致。手机的 agent 标签、搜索分类与最近会话草稿也会随图标的 kind 变化,属于本方案已接受的表现。
|
|
263
|
-
|
|
264
|
-
### 发布验证与限制
|
|
265
|
-
|
|
266
|
-
- 完整 Host 单测 680 通过、1 跳过;通道审计 `unclassified: 0`;独立沙盒普通验收 79/79、带真实 prompt 的沙盒验收 103/103。手机实际图标表现及文件直传仍需发布后真机复核,不能将沙盒验收视作真机验证。
|
|
267
|
-
- 本版本包含当前工作区其他已验证的文件传输、队列与登录修订;传输的真实手机 P2P 连接尚未确认建立,不宣称已修复。仅发布 npm 包不会让运行中的 DSH Host 加载新代码,需另行通知并重启。
|
|
268
|
-
|
|
269
|
-
## [0.1.11] - 2026-09-21
|
|
270
|
-
|
|
271
|
-
验证环境:DSH **0.1.5-rc.2**、Node **24.12.0**;要求 Node >=22,原生凭据依赖 keytar,werift 保持 **0.24.4**。
|
|
272
|
-
|
|
273
|
-
### Fixed
|
|
274
|
-
|
|
275
|
-
- 手机原 Export 的 OSS 兜底从 512 MiB 提升为 **2 GiB(含边界)**,遵守调用方更小的 maxBytes;采用64 KiB分块读取、SHA-256与网络背压,不再整文件读入内存。
|
|
276
|
-
- 持续有进展的上传不再被原10分钟总时限截断;保留阶段与无进展超时、两个活动槽和取消/清理配额。签名401仅受控刷新一次,文件PUT不自动重传。
|
|
277
|
-
- Export任务绑定已认证账号和请求设备;撤销、关闭及账号切换阻止迟到结果发布,短暂Relay断线不取消在途OSS上传。显式成功登录/选择账号可替换旧连接,上传与刷新不主动重连。
|
|
278
|
-
- 保留25秒peer offer等待预算;在既有status诊断中增加有界、脱敏的传输阶段信息。
|
|
279
|
-
|
|
280
|
-
### 验证与已知限制
|
|
281
|
-
|
|
282
|
-
- 已实测本地HTTP完整2 GiB、约11分钟持续流式上传及取消;真实约1.3 GB文件经OSS上传完成,用户确认手机下载完成。
|
|
283
|
-
- **本次成功走的是OSS,不是P2P。实际手机P2P未建立的原因仍待后续定位**;不宣称直连、TURN或系统分享问题已修复。
|
|
284
|
-
- 手机原30分钟总轮询预算未改;不新增断点续传、手机上传或超过2 GiB支持。OS文件/凭据库阻塞不保证按网络超时收口。
|
|
285
|
-
|
|
286
|
-
## [0.1.10] - 2026-09-20
|
|
287
|
-
|
|
288
|
-
验证环境:DSH **0.1.5-rc.2**、Node **24.12.0**、werift **0.24.4**;要求 Node >=22。
|
|
289
|
-
|
|
290
|
-
### Added
|
|
291
|
-
|
|
292
|
-
- **手机文件直传**:对接 Cindy `device-link:file-peer` / `files-v1`,电脑到手机按块下载,上限 2 GiB;需要支持该协议的客户端。固定 werift 0.24.4,处理空文件 EOF、连接复用、授权撤销和资源清理;保留 512 MiB OSS 导出兜底。
|
|
293
|
-
- 真实 Chromium + Cindy 接收器验证空文件、1B、16KiB、256KiB、跨批次及连续两次 32MiB+37B 文件,落盘 SHA-256 一致。
|
|
294
|
-
|
|
295
|
-
### Fixed
|
|
296
|
-
|
|
297
|
-
- **手机显示已插入而 DSH 仍排队**:不再把未消费输入混进正式历史;普通排队和等待插话均保留完整待发送内容,真正回流后才变为正式消息,重新进入会话仍可看到等待中的正文。
|
|
298
|
-
- **任务标题退化为 Untitled DSH task**:缓存到期仅触发刷新,不清空已知标题;暂时读取失败、批次缺项或空白标题保留最后有效值。过滤从未输入过内容的空白会话。
|
|
299
|
-
- 通道审计明确分类当前不支持的远端模型收藏与下一条输入预测,不再把它们当成未决通道;未新增这两项能力。
|
|
300
|
-
|
|
301
|
-
### 限制
|
|
302
|
-
|
|
303
|
-
- 手机真机、前后台行为、跨 NAT 和公网 TURN UDP/TCP/TLS、完整 2 GiB 文件尚未实测。
|
|
304
|
-
- 不新增手机上传、持久断点续传或嵌套 SSH 文件导出;直传失败时大于 512 MiB 的文件不能由旧 OSS 导出接管。详见 [文件直传说明](doc/file-transfer.md)。
|
|
305
|
-
- 发布/更新安装包不等于运行进程生效;安装后仍需手动重启原 DSH Web。
|
|
306
|
-
|
|
307
|
-
## [0.1.8] - 2026-09-18
|
|
308
|
-
|
|
309
|
-
### Fixed
|
|
310
|
-
|
|
311
|
-
- **Host 忙的时候手机把 Host 判成「设备离线」** —— 线上实测(19:08–19:15):七分钟里 18 次
|
|
312
|
-
`local-db:sessions:list` 以 `TimeoutError` 被中止,而手机把一次失败的列表读渲染成"设备离线"
|
|
313
|
-
(当时本机正在打包,CPU 被占满)。中止发生在 **invoke 层**(列表读 + 标题折叠 + 拼行一起超预算),
|
|
314
|
-
所以数据源里那道陈旧兜底看不到它。`local-db:sessions:list` 同时是手机的**响应性探针**,现在它
|
|
315
|
-
不再等读:有过一次成功读取后按缓存应答(5 秒内零读取),超过 5 秒则"先给旧页、后台刷新"
|
|
316
|
-
(stale-while-revalidate);写路径(归档/删除/置顶/重命名、新建会话)会作废缓存 ——
|
|
317
|
-
`patch-meta` 的回包就是控制器要落库的那一行,回旧行等于叫它撤销用户的编辑。
|
|
318
|
-
|
|
319
|
-
## [0.1.7] - 2026-09-18
|
|
320
|
-
|
|
321
|
-
### Added
|
|
322
|
-
|
|
323
|
-
- **手机自报的诊断单列一条时间线**(`diagnostics.phoneDiagnostics`)。控制器没有落盘日志:它靠
|
|
324
|
-
invoke 一个未知通道、把读数编进**通道名**来自报(`psdiag.*` 来自 device-link 的对端静默判据,
|
|
325
|
-
`tdiag.*` 来自移动端的计时器存活守卫)。这些自报原本落在会被普通轮询数秒冲掉的拒绝环里,
|
|
326
|
-
两分钟前发生的停摆在有人去看时已经读不到。现在它们有独立容量(40),每条带**到达时刻**与来源设备。
|
|
327
|
-
|
|
328
|
-
## [0.1.6] - 2026-09-18
|
|
329
|
-
|
|
330
|
-
### Fixed
|
|
331
|
-
|
|
332
|
-
- **手机端「导出/下载」安装包时秒失败**(实测不到 5 秒),而 Host 侧显示导出成功 —— 失败卡在最后一跳。
|
|
333
|
-
账号暂存区在阿里云 OSS 的**公网裸域名**,阿里云禁止该端点分发安装包:**key 后缀为 `.apk`/`.ipa`**,
|
|
334
|
-
或**对象 Content-Type 恰为 `application/vnd.android.package-archive`**,GET 一律
|
|
335
|
-
`400 ApkDownloadForbidden`(上传 PUT 与 `presign-get` 都成功,所以两边各自看着都对)。
|
|
336
|
-
现在 staging 会把这类对象按**不透明字节**发出(`ext → bin`、`Content-Type →
|
|
337
|
-
application/octet-stream`)—— 两个触发条件都要中性化,只改后缀仍会被拒(实测)。文件字节不动,
|
|
338
|
-
用户看到的文件名也不变:手机按浏览到的文件名自己命名、分享用的 mime 也取自文件名。
|
|
339
|
-
实测 77.2MB 安装包往返 sha256 一致。判因线索也补齐了:`download-failed` 现在带上对象存储的
|
|
340
|
-
错误码(如 `download-failed: ApkDownloadForbidden`)。证据与矩阵见
|
|
341
|
-
[`doc/cindy-android-verify.md`](doc/cindy-android-verify.md) 第九节。
|
|
342
|
-
|
|
343
|
-
## [0.1.5] - 2026-09-18
|
|
344
|
-
|
|
345
|
-
### Fixed
|
|
346
|
-
|
|
347
|
-
- **手机端「导出/下载本机文件」对大文件直接失败** —— 手机点文件时先要 `exportFileStart`,Host 把文件
|
|
348
|
-
交给账号的暂存区(OSS),手机再自己 presign 下载;但 `resolveInsideWorkdir` 复用了
|
|
349
|
-
`device-link:media:fetch` 的 **25MB** 上限,一个 77MB 的安装包被判 `OVERSIZE`,App 只好退回预览
|
|
350
|
-
(1MB 上限),用户看到「超出大小」(线上实测 `file-browser:remote-op / OVERSIZE` ×4)。
|
|
351
|
-
导出现在有独立额度与时限:**512MB / 10 分钟**(媒体取件仍保持 25MB / 30 秒)。导出会把文件整体读进
|
|
352
|
-
内存,注释里写明了这一点;新增测试覆盖「26MB 的文件必须能开始并完成导出」。
|
|
353
|
-
|
|
354
|
-
## [0.1.3] - 2026-09-17
|
|
355
|
-
|
|
356
|
-
### Fixed
|
|
357
|
-
|
|
358
|
-
- **手机又看不到自己发的照片了** —— 这是修过的回归,但**修复本身没有失效**:它只挂在一条读取路径上。
|
|
359
|
-
图片水合(把行里的 `imageRef` 读成内联 `images[]`)当年只接在 `local-db:messages:list`(旧转录读取);
|
|
360
|
-
后来控制器改用 `local-db:messages:view`(历史视图,广告了 `history-view-v1`),而那条路从没接过水合
|
|
361
|
-
—— 照片于是又变成"没有可展示的远程路径"的文件条目。线上实测:那一行确实带着 `imageRef` 被服务出去,
|
|
362
|
-
而 `diagnostics.attachmentReads` 是 `{attempted:0, served:0, failed:0}`,即水合一次都没跑。
|
|
363
|
-
- **刚发完的那一刻同样看不到**:实时推送 `local-db:messages:created` 也从不水合,所以承载照片的那一帧
|
|
364
|
-
到达时渲染不出图片,要等某次"刚好走水合路径"的重读才会出现。
|
|
365
|
-
|
|
366
|
-
现在**三条路(`messages:list` 页面、`messages:view` 页面、实时推送)共用同一个水合器**,因此
|
|
367
|
-
"live append 与 transcript read 产生同样的行"这句注释重新成立;水合失败只损失那一张图片,绝不损失消息。
|
|
368
|
-
|
|
369
|
-
### Tests
|
|
370
|
-
|
|
371
|
-
- 历史视图页面:带 `imageRef` 的行返回时必须带 `images[]`、`imageRef` 被剔除,**且不在页内的旧行一次读都不产生**;
|
|
372
|
-
没有水合器时页面照常应答(退回文件 chip,不崩)。
|
|
373
|
-
- 实时推送:承载图片的那一帧里就有 base64;水合器抛错时消息照发(未水合)。
|
|
374
|
-
|
|
375
|
-
## [0.1.4] - 2026-09-18
|
|
376
|
-
|
|
377
|
-
验证于 **DSH `0.1.5-rc.2`**(Web profile,Windows)。
|
|
378
|
-
|
|
379
|
-
### Fixed
|
|
380
|
-
|
|
381
|
-
- **新建对话时选的模型被丢掉,首个 prompt 跑在默认模型上**:`maker:create-session` 只读 `id` /
|
|
382
|
-
`workingDir`,把控制端**一起提交**的 `model` / `providerId` / `effort` 全丢了。新建页没有会话可以调
|
|
383
|
-
`maker:set-model`(手机管线是 create → getSession → enqueue,`setModel` 在仓库里连一个生产调用点都没有),
|
|
384
|
-
所以这套 runtime 只有这一条路能到达 Host。丢掉它 = 新会话没有任何会话级选择,DSH 的 `selectionFor`
|
|
385
|
-
于是回落到 profile 的 `agent-default-model`(deepseek-flash),首个 prompt 就跑在它上面;而手机随后从
|
|
386
|
-
权威会话行读到 `modelSelection.next ?? lastUsed` 也是 deepseek——用户看到的就是「新对话选了 gpt,
|
|
387
|
-
一运行又变成 deepseek」。现在 create 会把这三个字段转给 seam,并在**创建成功后立刻落成会话级选择**
|
|
388
|
-
(DSH 只允许这个顺序:选择必须属于某个会话);`providerId` 缺省时按 `maker:set-model` 已有的口径从本
|
|
389
|
-
Host 目录解析 provider,若整个目录里都没有能路由该模型的 provider,则回拒绝码 `NOT_AVAILABLE` 而不是
|
|
390
|
-
回一个假的成功(会话此时已存在,控制端的 create 幂等且重试前会 probe `getSession`,所以老实的拒绝只花
|
|
391
|
-
一次重试,而静默的错模型会毁掉一整段对话)。
|
|
392
|
-
- 同一条路径上 `maker:set-effort` 与 create 现在共用同一个 `applyModelSelection`,避免第二份 provider 解析;
|
|
393
|
-
并把 DSH 自己的 `session/model-unavailable`(来源在挑选与创建之间掉线等)翻成 `NOT_AVAILABLE`——原样抛出去,
|
|
394
|
-
控制器读到的 `THREW` 是「Host 崩了」,而不是「这个模型在这里不可用」。
|
|
395
|
-
- **同一个 create 还丢掉了权限档,这一处更危险**:手机的权限选项**就是**本 Host 广告的
|
|
396
|
-
`capabilities.permissionModes`(DSH 预设表里的 `read-only` / `workspace-write` / `danger-full-access`),
|
|
397
|
-
草稿里不在表内的值还会被手机的协调器改写成表内第一项。于是用户选 `read-only` 新建对话,会话照样跑 profile
|
|
398
|
-
默认的 `danger-full-access`——**他以为被限制住了,实际是最高权限**。现在 create 会在建会话后用与
|
|
399
|
-
`maker:set-permission-mode` 同一个写入(`installPermissionMode`)安装它,但**只安装本 Host 广告过的
|
|
400
|
-
名字**:控制端自己的词表(`ask`/`auto`/`acceptEdits`/`bypassPermissions`…,只在能力读取失败时才发)
|
|
401
|
-
既不翻译(等于替用户决定权限级别),也不拒绝(那会让那台手机建不出任何会话),而是保留 profile 档位、
|
|
402
|
-
记一条 `ctx.logger` 告警,并由权威会话行如实回报。
|
|
403
|
-
- **会话行补上模型的来源**:`providerId` 与 `model`/`effort` 同在 `modelSelection` 投影里,本 Host 的行
|
|
404
|
-
却从不带它,于是手机「跟随最近会话」推导出的是「有模型没来源」的下一个对话草稿。现在两个折叠点读同一个
|
|
405
|
-
投影(`next ?? lastUsed`),没有选择过的会话则**不带这个字段**(缺失 = 走被控端默认路由,正是它实际跑的)。
|
|
406
|
-
|
|
407
|
-
### 文档与注释(无行为变化)
|
|
408
|
-
|
|
409
|
-
- 一次独立复核(更强模型对抗式核对)发现若干**与实现相反**的说法,已修正:presence 报离线
|
|
410
|
-
**不会**删除设备订阅(它只决定一次推送算不算「已送达」);运行工作组的「钉底」只作用于升序的
|
|
411
|
-
`messages:view` 页,新到旧的 `local-db:messages:list` 不重排;`pulseRepair` 补的是输入投影与
|
|
412
|
-
视图失效,turn 状态由 `markDeviceReachable` 补发。`src/host.js` 里 5 处描述旧行为的注释一并更正。
|
|
413
|
-
- 陈旧的数字断言更正:单测 446(README 原写 407)、通道 52 served / 140 declined
|
|
414
|
-
(`doc/cindy-phone-link.md` 原写 48 / 144);README 的「尚未配置远端」改为已推送到公开远端并发了
|
|
415
|
-
`v0.1.1` Release;CHANGELOG 补上 `[0.1.1]` 链接、去掉并不存在的 `v0.1.0` 死链。
|
|
416
|
-
|
|
417
|
-
## [0.1.2] - 2026-09-17
|
|
418
|
-
|
|
419
|
-
**这是 0.1.1 那个附件的修复版。0.1.1 装进别人的 profile 会让那个 profile 起不来**,所以请不要再用
|
|
420
|
-
0.1.1 的 tarball 安装。本版**发布到 npm registry**(MIT):`dsh plugin --profile <p> add
|
|
421
|
-
dsh-cindy-host-demo@0.1.2`。
|
|
422
|
-
|
|
423
|
-
### Fixed
|
|
424
|
-
|
|
425
|
-
- **不再把 DSH 自己的一代装进 profile**:`@deepseek-ai/dsh-session` / `@deepseek-ai/dsh-settings` 由
|
|
426
|
-
`dependencies` 移到 `peerDependencies`,`@deepseek-ai/dsh-host-apiproxy` 改为 optional 的 peer
|
|
427
|
-
(`optionalDependencies` **不是**"可以不装"——pnpm 默认会装它)。此前它会牵出
|
|
428
|
-
`dsh-host-apiproxy@0.1.1-rc.2` 的 **28 个 `@deepseek-ai/*@^0.1.1-rc.2`**,整代装进 profile;
|
|
429
|
-
宿主 `0.1.5-rc.2` 再去组合这个混合体就失败:`ctx.commands.registerFileReceiptResolver is not a
|
|
430
|
-
function`(`dsh-client-file-upload`)、`@deepseek-ai/dsh-llm does not provide an export named
|
|
431
|
-
'CallId'`(`dsh-session`)。
|
|
432
|
-
- **不再 import 只在旧代存在的导出**:`settingsNamespace` 只存在于
|
|
433
|
-
`@deepseek-ai/dsh-settings@0.1.1-rc.2`;`0.1.5-rc.2` 的导出面是 `SettingsProvider` /
|
|
434
|
-
`SettingsConflictError` / `redactSecrets` / `default`。它是"校验后原样返回字符串"的 brand,现已内联
|
|
435
|
-
到 `src/dsh-plugin.js`。这就是此前必须把旧代声明成依赖的原因。
|
|
436
|
-
|
|
437
|
-
### 验收(干净安装,全新 `DSH_HOME` + `--from-default-profile web`)
|
|
438
|
-
|
|
439
|
-
```
|
|
440
|
-
dsh plugin add <0.1.2 tarball> → exit 0
|
|
441
|
-
profile-local @deepseek-ai → 0 (不再拖任何一代 DSH 进来)
|
|
442
|
-
dsh --profile <p> --dump-config → exit 0,含 dsh-cindy-host 行
|
|
443
|
-
dsh web → 启动,监听端口
|
|
444
|
-
GET /api/dsh-cindy-host/status → 200 installed=true
|
|
445
|
-
npm test → 446/446
|
|
446
|
-
```
|
|
447
|
-
|
|
448
|
-
### 文档
|
|
449
|
-
|
|
450
|
-
- `doc/publishing.md` §5.4 的结论**更正**:原先写"全新 profile 起不来是 DSH 侧的问题、与本包无关",
|
|
451
|
-
这是错的,根因正是本包把旧一代 DSH 装进了 profile。§5.6 新增依赖规则与写死的检查步骤。
|
|
452
|
-
|
|
453
|
-
## [0.1.1] - 2026-09-17
|
|
454
|
-
|
|
455
|
-
> **这个版本的附件有缺陷,不要用它安装**(见 0.1.2)。缺陷是"装进别人的 profile 会让它起不来",
|
|
456
|
-
> 不是插件功能本身。
|
|
457
|
-
|
|
458
|
-
打包与安装修复:两者都只在**干净安装**(干净 DSH_HOME + tarball)下才会出现,本地 link 装法不会暴露。
|
|
459
|
-
|
|
460
|
-
### Fixed
|
|
461
|
-
|
|
462
|
-
- **插件不再因为可选依赖而装不上**:`@deepseek-ai/dsh-host-apiproxy`(只有老 DSH 的 `apiProxy`
|
|
463
|
-
路径需要)由顶层静态 import 改为惰性加载,并移入 `optionalDependencies`。它在干净环境里会拖入不兼容的
|
|
464
|
-
`@deepseek-ai/dsh-agent-presets`,原先会让插件加载失败、整个 profile 起不来;现在缺失或不兼容时降级为
|
|
465
|
-
"该 seam 不提供服务"。
|
|
466
|
-
- **`keytar` 缺失不再致命**:pnpm 10 默认不执行依赖的构建脚本,干净安装下没有 `keytar.node`,原先顶层
|
|
467
|
-
`import keytar` 会让插件加载失败。现在惰性加载:读凭据回"无会话",写凭据抛
|
|
468
|
-
`CREDENTIAL_STORE_UNAVAILABLE`,插件照常挂载。(装法见 `doc/publishing.md` §5.2。)
|
|
469
|
-
|
|
470
|
-
## [0.1.0] - 2026-09-17
|
|
471
|
-
|
|
472
|
-
首个发布版本。验证于 **DSH `0.1.5-rc.2`**(Web profile,Windows)。
|
|
473
|
-
|
|
474
|
-
> 这一版**没有打 tag、也没有分发**:它的干净安装缺陷(见上)由 `0.1.1` 修掉,实际发布并从
|
|
475
|
-
> `v0.1.1` 起算。所以这里没有 `[0.1.0]` 的链接可指——它没有对应的 release。
|
|
476
|
-
|
|
477
|
-
### Added
|
|
478
|
-
|
|
479
|
-
- **手机通道(52 个被服务,140 个显式拒绝)**:会话列表/详情、消息窗口与工作分组视图
|
|
480
|
-
(`local-db:messages:view` / `work-details` / `view-intent`,广告 `history-view-v1` 能力)、
|
|
481
|
-
输入队列(排队/插话/编辑/移动/删除/清空/停止)、审批与提问的往返、todo 计划卡、goal 读写、
|
|
482
|
-
文件浏览与导出、图片取件(`thumbnail` 降采样 + 内联,逐级降级到 `ossKey`)。
|
|
483
|
-
- **设置卡片**:手机连接开关、控制器授权、设备状态与诊断面板(`/api/dsh-cindy-host/status`)。
|
|
484
|
-
- **诊断面(可观测而不是尽力而为)**:`invokeTotals` / `refusalTotals` / 带设备归属的
|
|
485
|
-
`recentInvokes` / 带 watcher 数的 `recentPushes` / `handlerErrors`(`where` 带通道名)/
|
|
486
|
-
`boundaries` 判决(`recovered` | `starting` | `silent`)/ `suppressedNotices`。
|
|
487
|
-
|
|
488
|
-
### 手机端实时性(本轮修复的现象)
|
|
489
|
-
|
|
490
|
-
- **不再长时间转圈**:中继报设备离线时不再删除订阅集(presence 只决定"是否计入已送达");
|
|
491
|
-
设备再次开口时撤销该判定并重播回合终态。
|
|
492
|
-
- **进度可见**:会话回合状态的权威来源改为 DSH 自己的边界(`liveTurnState`),并显式接入视图控制器
|
|
493
|
-
—— 此前正在跑的回合被标成"未在跑",于是既没有实时卡片,也没有可锁定的工作项。
|
|
494
|
-
- **排序可预期**:待发送消息按**接受时间**归并进页面(按你打字的位置出现);**正在运行的工作组锁定
|
|
495
|
-
在页面最后**,你刚发的话永远在它上面。
|
|
496
|
-
- **插入(steer)不再丢话**:没有正在跑的回合时按普通消息发送;回合已走过可插入点时,被拒的 steer
|
|
497
|
-
会**重试为普通消息**(原先会以 `current turn no longer accepts steering` 报错并吞掉内容)。
|
|
498
|
-
- **重订阅/开口即补帧**:`device-link:subscribe` 与任何点名了会话的入站帧,会补一次权威输入投影 +
|
|
499
|
-
一次视图失效(每会话 30 秒最多一次),用于修复中继抖动造成的丢帧。
|
|
500
|
-
|
|
501
|
-
### 健壮性
|
|
502
|
-
|
|
503
|
-
- **不因一个未处理的 rejection 拖垮整个 `dsh web`**:队列提交改为真异步(原先未 await 的拒绝会让
|
|
504
|
-
进程 `exit(1)`);宿主面监听器统一走 `guarded()` 单入口,并有源码级不变量测试。
|
|
505
|
-
- **长会话不再永久失去视图**:移除 >20000 行即回 `UNSUPPORTED_CAPABILITY` 的拒绝(该码会让客户端
|
|
506
|
-
永久降级,且当时的拒绝并未省下任何读取)。
|
|
507
|
-
- **列表读抗压**:并发读单飞;错过预算时用最近一次成功的列表兜底;冷启动无兜底时重试一次。
|
|
508
|
-
- **通知不再冒充用户消息**:harness 的后台任务通知(`source.kind === 'plugin'`)不再投影到手机,
|
|
509
|
-
隐去条数在 `diagnostics.suppressedNotices` 可查。
|
|
510
|
-
|
|
511
|
-
### 已知限制
|
|
512
|
-
|
|
513
|
-
- **App 切后台回前台后入站失效**(鸿蒙 + 安卓兼容层):官方客户端同样复现,判定为客户端/OS 侧,
|
|
514
|
-
本 Host 不再为此投入;现场绕过是"等约 1 分钟,或退出会话再进"。详见
|
|
515
|
-
`.claw/truth/dsh-cindy-host-mobile-resume-limitation.md`。
|
|
516
|
-
- 真机 219 会话冷启动时,`local-db:sessions:list` 仍可能出现超时(已有上述三层保护)。
|
|
517
|
-
- 当前 DSH 不再挂 `apiProxy`;本插件在没有它时安全挂载,并在相关通道回 `NOT_AVAILABLE`。
|
|
518
|
-
|
|
519
|
-
[Unreleased]: https://github.com/chanyuenpang/dsh-cindy-host/compare/v0.1.1...HEAD
|
|
520
|
-
[0.1.1]: https://github.com/chanyuenpang/dsh-cindy-host/releases/tag/v0.1.1
|
|
25
|
+
### Boundaries
|
|
26
|
+
- No Cindy desktop or mobile modifications. DSH 0.2.1-rc.3 desktop runtime; Node >=22.
|
|
27
|
+
- Automated regressions cover protocol shape and queue ordering; live incident-specific phone/desktop verification is still required.
|
|
28
|
+
- Optional advanced client features remain unavailable; this is not a full new-client feature release.
|