@mingmaple/dsh-handover 0.9.6 → 0.9.13

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.
Files changed (50) hide show
  1. package/README.md +53 -17
  2. package/docs/migrate.md +1 -1
  3. package/docs/releases/0.9.12.md +28 -0
  4. package/docs/releases/0.9.13.md +30 -0
  5. package/docs/troubleshoot.md +43 -6
  6. package/package.json +70 -57
  7. package/scripts/blank-dsh.mjs +6 -5
  8. package/scripts/blank-smoke.mjs +268 -58
  9. package/scripts/build.mjs +3 -0
  10. package/scripts/check-docs.mjs +23 -2
  11. package/scripts/office.mjs +81 -0
  12. package/src/client.js +92 -23
  13. package/src/index.mjs +264 -145
  14. package/src/lib/api.mjs +67 -9
  15. package/src/lib/config.mjs +4 -3
  16. package/src/lib/consent.mjs +59 -20
  17. package/src/lib/facts.mjs +5 -4
  18. package/src/lib/guide.mjs +14 -7
  19. package/src/lib/handover-io.mjs +20 -0
  20. package/src/lib/manual.mjs +23 -12
  21. package/src/lib/names.mjs +2 -2
  22. package/src/lib/office.mjs +272 -0
  23. package/src/lib/pack-ops.mjs +3 -0
  24. package/src/lib/phase.mjs +6 -4
  25. package/src/lib/prompt.mjs +18 -0
  26. package/src/lib/role.mjs +52 -18
  27. package/src/lib/schedule.mjs +10 -14
  28. package/src/lib/session-create.mjs +42 -0
  29. package/src/lib/session-ops.mjs +183 -79
  30. package/src/lib/sessions.mjs +9 -8
  31. package/src/lib/status.mjs +8 -2
  32. package/src/lib/succession.mjs +244 -0
  33. package/src/lib/text.mjs +27 -0
  34. package/src/lib/webroute.mjs +1 -1
  35. package/src/lib/workspace.mjs +1 -1
  36. package/src/selftest.mjs +15 -0
  37. package/src/templates/Charter.skeleton.md +1 -1
  38. package/src/templates/Prompt_Templates.md +9 -17
  39. package/src/templates/Runtime_Manual.md +17 -14
  40. package/src/templates/rules/Handover_Rules.md +3 -2
  41. package/src/templates/rules/Misc_Task_Standard.md +3 -3
  42. package/src/tools/ho_checkpoint.mjs +11 -4
  43. package/src/tools/ho_diag.mjs +5 -3
  44. package/src/tools/ho_handover.mjs +7 -6
  45. package/src/tools/ho_office.mjs +59 -0
  46. package/src/tools/ho_profile.mjs +10 -2
  47. package/src/tools/ho_sessions.mjs +3 -2
  48. package/src/tools/ho_snapshot.mjs +2 -1
  49. package/src/tools/ho_succeed.mjs +24 -0
  50. package/src/tools/ho_workspace.mjs +7 -3
package/README.md CHANGED
@@ -12,11 +12,14 @@ DeepSeek Harness 插件,用于管理长会话的上下文水位、交接文档
12
12
 
13
13
  - 起始简报:水位、闸门、活跃与沉默、阶段建议,一条命令返回。
14
14
  - 交接体检:检查交接文档的结构、字段与占位符,逐条列出问题。
15
- - 压缩与续跑:由水位判定时机,由用户授权,回合结束后执行,完成后自动续跑;状态切换与失败原因写入结果。
15
+ - 压缩与续跑:由水位与剩余压缩次数共同判定时机,由用户授权,回合结束后执行;压缩后的去向由助手在登记时选择,继续工作时续跑,任务已收尾时静默等待;状态切换与失败原因写入结果。
16
+ - 在任登记与查询:每一类会话(全局、各个项目、各个杂项任务)都登记当前在任的会话与历代编号,记录保存在工作区内的 `Office.json`;按名字或旧编号查询现任,不启动会话也可用命令行查询。
17
+ - 换任由会话自行办理:在任会话在用户授权后自行检查交接、建立接任会话并登记在任,不再由全局会话转交。
16
18
  - 会话清点与角色:查看会话水位与状态,设定角色,建立下一代会话,归档与解归档。
19
+ - 会话间通信:会话之间可直接对话,不必经全局转述;默认沉默,任务完成不向全局报告。
17
20
  - 工作区迁移:预检、复制并逐文件校验、切换、改写登记、重建链接、清理旧副本。
18
21
  - 快照与迁移包:库快照、打包、校验与恢复,包内绝对路径单独体检。
19
- - 设置页:压缩授权、移动全局根目录、会话角色、全局前置提示词、会话水位、通用约束条闸门、交接文档体检、插件状态与唤醒权守卫。
22
+ - 设置页:常规卡片为压缩授权、移动全局根目录、会话角色、全局前置提示词、会话水位、通用约束条闸门、交接文档体检、插件与会话间通信守卫,末尾另有默认折叠的「使用说明」;尚未接入工作区时置顶显示「首次安装」,可一键部署文件体系、工作区与会话;已接入但还没有全局会话时显示「全局会话」卡片。
20
23
 
21
24
  ## 安装
22
25
 
@@ -30,12 +33,31 @@ Web 或 CLI:
30
33
  dsh plugin --profile web add github:MingMaple/dsh-handover
31
34
  ```
32
35
 
36
+ ### 从 npm 安装
37
+
38
+ 包名为 `@mingmaple/dsh-handover`,版本与仓库同步:
39
+
40
+ ```bash
41
+ dsh plugin --profile web add @mingmaple/dsh-handover
42
+ ```
43
+
33
44
  ### 从本地源码安装
34
45
 
35
46
  1. 构建:`node scripts/build.mjs`,产物在 `dist/`。
36
47
  2. 用 DSH 的插件管理器安装本地目录 `dist/`,target 传绝对路径。
37
48
  3. 在插件列表里启用,重启 DSH。
38
- 4. 首次使用按设置页「首次安装」卡片的引导建立全局文件体系,或执行 `ho_init(parent="<已存在目录>", register=true)`。
49
+ 4. 首次使用按下一节「首次使用」的引导部署。
50
+
51
+ ### 首次使用
52
+
53
+ 首次安装后,工作区、文件体系与会话一次部署完成:
54
+
55
+ 1. 打开设置页中的 dsh-handover,在「首次安装」卡片粘贴一个长期存在目录的绝对路径。
56
+ 2. 点「一键部署」。插件在该目录内建立 `_Workspace` 与整套文件结构,注册为「全局」工作区,并新建一个「全局」会话。
57
+ 3. 在左侧「全局」工作区打开该会话即可开始。只需先铺文件时点「仅建立文件体系」,之后再点「注册为工作区」。
58
+ 4. 工作区已接入但还没有全局会话时,设置页会单独出现「全局会话」卡片,可随时补建。
59
+
60
+ 命令行等价操作:`ho_init(parent="<已存在目录>", register=true)`,再新建一个标题含「全局」的会话。
39
61
 
40
62
  ## 使用
41
63
 
@@ -46,7 +68,8 @@ dsh plugin --profile web add github:MingMaple/dsh-handover
46
68
  | 看整体状态 | 先出一份起始简报 |
47
69
  | 查规则 | 把 Charter 第 7.2.3 节取出来 |
48
70
  | 交接并压缩 | 先把交接文档写好,再压缩并继续 |
49
- | 换任 | 建立下一代全局会话 |
71
+ | 换任 | 写好交接,请用户授权,由本会话自己换任 |
72
+ | 查在任 | 现在全局是谁在任 |
50
73
  | 设置角色 | 把 Demo1 设成项目角色,并让它整理自己的文件 |
51
74
  | 自检 | 检查插件当前状态 |
52
75
 
@@ -54,11 +77,13 @@ dsh plugin --profile web add github:MingMaple/dsh-handover
54
77
 
55
78
  | 角色 | 提示段 | 工具数 | 说明 |
56
79
  |---|---|---|---|
57
- | 全局 | 有 | 22 | 协调会话、维护规则与交接 |
58
- | 项目 | 有 | 9 | 管理单个项目库,自己写骨架档案 |
59
- | 杂项 | 有 | 9 | 管理单个杂项任务 |
80
+ | 全局 | 有 | 24 | 协调会话、维护规则与交接 |
81
+ | 项目 | 有 | 11 | 管理单个项目库,自己写骨架档案 |
82
+ | 杂项 | 有 | 11 | 管理单个杂项任务 |
60
83
  | 普通 | 无 | 0 | 不注入提示、不加载工具 |
61
84
 
85
+ 代理子会话不装配 `ho_` 与 `peer_` 工具。宿主逐步解析工具表,子会话在解析阶段即被排除,首轮即不可用。
86
+
62
87
  ### 交接与压缩
63
88
 
64
89
  | 水位 | 动作 |
@@ -66,10 +91,16 @@ dsh plugin --profile web add github:MingMaple/dsh-handover
66
91
  | 低于 32% | 继续 |
67
92
  | 32% 至 35% | 可写交接;处于关键步骤时可暂缓 |
68
93
  | 35% 至 85%,已压少于 3 次 | 写交接、原地压缩、读交接续跑 |
69
- | 35% 至 85%,已压满 3 次 | 写交接、建立新会话 |
70
- | 85% 及以上 | 强制压缩兜底 |
94
+ | 85% 及以上,已压少于 3 次 | 强制压缩 |
95
+ | 任意水位,已压满 3 次 | 写交接、建立新会话 |
96
+
97
+ 压缩次数用尽(默认 3 次)的判定先于水位:额度用尽后,无论水位高低均建议换任;`force` 不能越过额度,`ho_sessions` 的压缩指令(`action="order", order="compact"`)同样会被拒绝。
71
98
 
72
- 压缩须由用户在设置页点「压缩授权」,单次授权 5 分钟内有效;`confirm=true` 只表示意图。压缩在回合结束后执行,完成后自动续跑。交接文档写在 `_Control_Center/records/Global_Handover.md`,每次写入前备份。
99
+ 压缩须由用户在设置页点「压缩授权」,单次授权 5 分钟内有效;`confirm=true` 只表示意图。压缩在回合结束后执行;登记时以 `resume` 选择去向,继续工作时续跑,任务已收尾时不唤醒。全局交接写在 `_Control_Center/records/Global_Handover.md`,项目与杂项交接写在各自目录,每次写入前备份。
100
+
101
+ 归档文件名为 `<原文件名>_<YYYYMMDD_HHMMSS>.md`,同一秒重复时追加 `-2`。全局与项目的归档位于 `_Archives/<范围>/Handover/`,杂项归档位于 `_Misc/tasks/<任务>/_archive/`。
102
+
103
+ 换任由在任会话自行办理:写完交接后,由用户在聊天框发送 `/allow-succeed`,或在设置页「压缩授权」卡片内的「换任授权」区域点「允许换任」。授权一次有效,5 分钟内可用,按会话生效。随后会话调用 `ho_succeed`,插件依次校验授权与交接结构,按记录分配下一代编号,建立接任会话并写入角色,登记在任,投递启动提示词,并在旧交接末尾追加换任登记。任何一项校验不通过时,整体不做任何改动,并逐条列出缺项。全局的建会话与换任能力保留,作为自动流程失败时的备选方案。
73
104
 
74
105
  ### 设置页
75
106
 
@@ -83,36 +114,41 @@ dsh plugin --profile web add github:MingMaple/dsh-handover
83
114
 
84
115
  ## 故障处理
85
116
 
86
- 工具数量不符、工作区未接入、设置页刷新失败、压缩未生效、迁移后原路径失效,各有对应处置。
117
+ 工具数量不符、工作区未接入、设置页刷新失败、压缩未生效、换任未执行、项目名或任务名不合法、新建会话找不到工作区、设置角色后工具未更新、迁移后原路径失效,各有对应处置。
87
118
 
88
119
  详见 [常见故障处理](docs/troubleshoot.md)。
89
120
 
90
121
  ## 上下文开销
91
122
 
92
- 固定开销为工具 schema 与提示段。按角色载入后,全局提示段约 271 加权 token,项目约 247 至 256,杂项约 248 至 254,随项目名与路径长度小幅波动;单条工具描述不超过 70 token。
123
+ 固定开销为工具 schema 与提示段。按 0.9.13 实测,按角色载入后,全局提示段约 385 加权 token(长路径加迁移提示行约 435),项目与杂项约 370(最坏约 419),随项目名与路径长度波动;单条工具描述最宽约 56。以上为实测参考值,不设硬性上限:某条判定需要写清楚时,优先保证表达完整。
93
124
 
94
125
  ## 边界与限制
95
126
 
96
127
  - 依赖 DSH 的 `ctx.compaction` 服务;未挂载时压缩相关工具明确报错。
97
128
  - `ptc` 呈现模式下,插件工具只能经程序调用。
98
- - 会话压力读取依赖宿主的投影缓存布局;字段变化时用 `ho_diag` 排查。
129
+ - 会话压力读取依赖宿主保存的会话状态文件布局;字段变化时用 `ho_diag` 排查。
99
130
  - 迁移只搬文件与清单,不改写文件内容;写死的绝对路径以体检形式报出。
131
+ - 工具可见性按每一步计算:换角色在下一轮请求即生效,不必重启 DSH。插件重载后,已存在的会话沿用旧提示段文本,需要新文本时重启一次。
132
+ - 项目名与任务名按目录名校验:项目名不超过 24 字符,任务名不超过 40 字符;不含 `< > : " / \ | ? *` 与控制字符;不以点或空格结尾;不使用设备保留名。名字来自自由文本时同样校验,不合法则报错且不写入磁盘。
100
133
  - 卸载后残留只限 `~/.dsh/storages/dsh-handover.*` 与 `~/.dsh/storages/dsh-handover/logs/`,删除即可清零。
101
134
 
102
135
  ## 开发与测试
103
136
 
104
137
  ```bash
105
138
  npm test # 开发自测:逐个工具跑只读用例
106
- npm run test:blank # 空白 DSH 验收:临时 HOME 与空目录跑 22 工具及迁移四件
139
+ npm run test:blank # 空白 DSH 验收:临时 HOME 与空目录跑 24 工具及迁移四件
107
140
  npm run test:smoke # 空白环境冒烟:工具装配、状态路由、浏览器半渲染、语体扫描
108
- npm run test:docs # 文档校验:工具名、旧数、链接、版本
141
+ npm run test:migrate # 迁移与恢复端到端
142
+ npm run test:docs # 文档校验:工具名、旧数、链接、版本、语体与长度上限
109
143
  ```
110
144
 
111
- 源码在 `src/`,`dist/` 为构建产物,不入版本库。客户端 bundle 不热更新,改设置页必须重建并重启 DSH。
145
+ 源码在 `src/`,`dist/` 为构建产物,不入版本库。服务端代码替换 `dist/` 后在插件列表停用再启用即生效,不必重启 DSH;已存在的会话继续使用旧的提示段文本,需要新文本时重启 DSH 或让会话重建。客户端 bundle 不热更新,改设置页必须重建并重启 DSH。
112
146
 
113
147
  ## 版本
114
148
 
115
- 当前版本 0.9.6,首次公开版本。内部版本史不随仓库发布。
149
+ 当前版本 0.9.13,首次公开版本为 0.9.6。内部版本史不随仓库发布。
150
+
151
+ 支持的内核为 0.2.1-rc.2 至 0.3.0(不含 0.3.0 及其候选版),见 `package.json` 的 `engines.dsh`;0.2.2-rc.1 上的工具装配、角色裁剪与压缩调度已实测通过。
116
152
 
117
153
  ## 许可
118
154
 
package/docs/migrate.md CHANGED
@@ -32,7 +32,7 @@ ho_workspace(action="move")
32
32
  ho_workspace(action="move-switch")
33
33
  ```
34
34
 
35
- 生成并派出后台助手,等你完全退出 DSH 后自动完成:旧目录改名为 `<旧>.old-<时间戳>`,再在原位置建 junction 指向新位置,并校验指向。日志写在 `~/.dsh/storages/dsh-handover/logs/`。
35
+ 生成并派出后台助手,等你完全退出 DSH 后自动完成:旧目录改名为 `<旧>.old-<时间戳>`,再在原位置建 junction 指向新位置,并校验指向。日志写在 `~/.dsh/storages/dsh-handover.move.log`。
36
36
 
37
37
  也可以双击生成的 `dsh-handover.move.cmd`。切换后原路径成为链接,工作区登记、profile 与会话工作目录都无需修改。
38
38
 
@@ -0,0 +1,28 @@
1
+ # 0.9.12
2
+
3
+ 本次更新:首次安装改为一键部署;修「设置角色后必须重启 DSH」,并把角色装配收敛成一条主线;新建会话必须指明工作区。
4
+
5
+ ## 新增与调整
6
+
7
+ - 一键部署:在设置页「首次安装」卡片粘贴绝对路径后点「一键部署」,一次完成三件事:建立 `_Workspace` 与整套文件结构,把该目录注册为「全局」工作区,新建一个「全局」会话并登记全局角色。「全局」会话的产生不再依赖手工新建标题含「全局」的会话。
8
+ - 补建入口:工作区已接入但还没有全局会话时,设置页单独出现「全局会话」卡片,可随时补建;只建会话,不建体系,不动既有文件。
9
+ - 新建会话必须指明工作区:`ho_sessions(action="new")` 未给 `workspace` 或 `cwd`、或项目没有对应工作区时直接报错,并列出已注册的工作区,不再静默落到调用者所在的工作区。传 `project` 且存在同名工作区时自动匹配;`cwd` 必须是已注册工作区的根。
10
+ - `ho_workspace(action="create")` 新增 `ensure`:目录不存在时自动创建再注册。仍是显式开关,默认不建目录。
11
+
12
+ ## 修正
13
+
14
+ - 设置角色后必须重启 DSH 才生效:此前角色装配散在三套机制上——每步条件只排子会话、角色裁剪另用 `restrict`、角色表晚到再靠 1.5 秒与 4.5 秒的延迟复核。会话休眠期间改了角色,唤醒时宿主不保证重发创建事件,`restrict` 没有机会撤销,工具仍是旧的。现在收敛为一条主线:工具可见性由每步启用条件算,角色判定用 2 秒短缓存、写角色表即失效;提示段由创建、开轮前核对与重载补装三处对齐;只有不支持按步解析的旧内核才退回 `restrict`。
15
+ - 角色查找增加一层兜底:按会话 id 无法取到活体时,再按会话头的 id 在活体列表中查找,避免把仍在内存中的会话误判为已休眠。
16
+ - 删除不再使用的旧逻辑:延迟复核、一次性引导状态、重复的会话投递与建会话代码、未使用的辅助函数。会话投递与建会话各收敛成一个共用入口。
17
+
18
+ ## 升级
19
+
20
+ - 从 npm 或 GitHub 安装后启用插件;已安装旧版时先停用再换版本,安装完成后启用并重启 DSH 一次。
21
+ - 以本地 `dist/` 挂载的安装方式:替换 `dist/` 后在插件列表停用再启用即换用新代码,不必重启 DSH。
22
+ - 升级后已有的角色与交接无需迁移。已存在的会话若仍显示旧提示段文本,重启 DSH 一次即可换成新文本,工具裁剪不受影响。
23
+
24
+ ## 兼容
25
+
26
+ - 支持 DSH 内核 0.2.1-rc.2 至 0.3.0,不含 0.3.0 及其候选版,见 `package.json` 的 `engines.dsh`。
27
+ - 已在 DSH NEXT 2.0.22 与内核 0.2.2-rc.1 上实测:设置角色后按轮换装、新建会话的工作区校验与报错清单。
28
+ - 一键部署的建体系、注册工作区与建会话三步,在空白环境验证通过;首次实机安装建议先在空环境验证一次。
@@ -0,0 +1,30 @@
1
+ # 0.9.13
2
+
3
+ 本次更新新增两项能力:查询当前在任的会话,以及由会话在用户同意后自行完成换任。换任不再需要由全局会话代为办理;建立新会话时会同时写入在任记录。
4
+
5
+ ## 新增
6
+
7
+ - 在任登记:每一类会话(全局、各个项目、各个杂项任务)都在 `_Control_Center/records/Office.json` 中记录当前在任的会话与历代编号;新的编号按该类已用的最大编号加一分配。`_Project_Meta/Registry.md` 中的「在役会话」一列由插件填写,只改这一格,其余文字不动。
8
+ - `ho_office`:查询某一类会话当前由哪个会话在任,返回名字与会话 id。可以输入不确定的名字(例如「全局3」会返回现任全局),多个名字用空格分隔,留空则列出全部;`json=true` 返回可供程序处理的结果。
9
+ - 命令行 `node scripts/office.mjs 全局 全局3`:与 `ho_office` 使用同一份实现与同一份记录,不启动会话即可查询;支持 `--root` 指定工作区根、`--all` 列出全部、`--json` 输出 JSON。
10
+ - `ho_succeed`:在任会话在用户授权后自行完成换任。依次校验授权、交接内容与在任身份,按记录分配新编号,建立接任会话并写入角色,登记在任,投递启动提示词,在旧交接末尾追加换任登记,最后注销本次授权。
11
+ - 换任授权:聊天框命令 `/allow-succeed`,或设置页「压缩授权」卡片内的「换任授权」区域。一次有效,5 分钟内可用,按会话生效;与压缩授权分别记录,互不影响。
12
+
13
+ ## 改动
14
+
15
+ - 换任改由会话自行办理:由在任会话自己执行,不再由全局会话转交;全局的建会话与换任能力保留,作为自动流程失败时的备选方案。
16
+ - `ho_sessions(action="new")` 建立会话后自动写入在任记录,原在任者转为历史记录;全局手动建立会话不再漏记。
17
+ - 工具数量按角色调整:全局 24 个,项目 11 个,杂项 11 个,普通 0 个。
18
+ - 工作区规则同步:`Workspace_Charter.md` §7.2.8 为换任流程,§7.2.3 中的扫描与通知流程停止使用。
19
+
20
+ ## 修复
21
+
22
+ - 修复换任需经全局会话转交、全局繁忙或休眠时换任停滞的问题。
23
+ - 修复全局手动建立会话后,在任记录与实际状态不一致的问题。
24
+
25
+ ## 说明
26
+
27
+ - 换任有三项限制:只按会话自身已登记的角色确定它属于哪一类会话,不采用调用时传入的参数;只有该类会话当前在任者本人可以换任;已交接的旧会话不得再次换任。
28
+ - 交接内容检查只看结构:包含「下一步」一节且至少有一个条目,内容非空,且不含模板占位符。任何一项不通过时,整体不做任何改动,并逐条列出缺项。
29
+ - 换任授权与压缩授权分别记录,一种授权不能替代另一种;授权使用后即失效。
30
+ - 升级不需要迁移数据,已有交接无需改写。首次登记后,插件在工作区生成 `Office.json`。
@@ -3,20 +3,39 @@
3
3
  ## 工具缺失或数量不对
4
4
 
5
5
  1. 在全局会话执行 `ho_diag`,看「角色判定与工具集」一节。
6
- 2. 全局应为 22 个,项目与杂项 9 个,普通 0 个。
7
- 3. 新建会话出生时角色表里还没有它,插件会判为普通,并在 1.5 秒与 4.5 秒后复核。角色写入后应自动装配。
6
+ 2. 全局应为 24 个,项目与杂项 11 个,普通 0 个。
7
+ 3. 新建会话时角色表中尚无该会话,插件会判为普通;角色写入后,该会话下一轮请求即按新角色装配。
8
8
  4. 仍未装配时,在设置页「会话角色」卡片里重新设一次角色;仍无效则执行 `ho_diag` 查 `roleGating` 字段。
9
- 5. 改过源码但没生效:执行 `node scripts/build.mjs` 并重启 DSH。`dist/` 是安装面。
9
+ 5. 改过源码但未生效:执行 `node scripts/build.mjs`,然后在插件列表停用并启用一次,不必重启 DSH。提示段文本不随重载替换,仍显示旧文本时重启 DSH。
10
+ 6. 子会话不装配 `ho_` 与 `peer_` 工具,属正常:子会话在工具表解析阶段即被排除,与角色设置无关。
10
11
 
11
12
  ## 工作区未接入
12
13
 
13
- `ho_diag` 或设置页显示未接入时,走设置页「首次安装」卡片,或执行:
14
+ `ho_diag` 或设置页显示未接入时,走设置页「首次安装」卡片:粘贴绝对路径后点「一键部署」,文件体系、工作区与会话一次建好;也可以只点「仅建立文件体系」,再点「注册为工作区」。命令行等价操作:
14
15
 
15
16
  ```text
16
17
  ho_init(parent="<已存在目录的绝对路径>", register=true)
17
18
  ```
18
19
 
19
- 装配里没有写死 `workspaceRoot`,插件按以下顺序定位:配置项、标题含「全局」且带 `_Control_Center` 的工作区、任一带 `_Control_Center` 的工作区、会话工作目录向上查找。
20
+ 装配里没有写死 `workspaceRoot`。工具侧按配置项、会话工作目录向上查找的顺序定位,向上找不到时再查工作区登记;设置页没有会话上下文,按配置项、标题含「全局」且带 `_Control_Center` 的工作区、任一带 `_Control_Center` 的工作区定位。
21
+
22
+ ## 新建会话报「必须指明工作区」
23
+
24
+ `ho_sessions(action="new")` 必须落到明确的工作区:传 `workspace`(id、标题或路径),或传某个已注册工作区根的 `cwd`。两者都没有,或项目没有对应工作区时,工具会报错并列出已注册的工作区,不会静默落到调用者所在的工作区。
25
+
26
+ 处置:
27
+
28
+ 1. 先看清单:`ho_workspace(action="list")`,或直接读报错文本里的清单。
29
+ 2. 还没有工作区时先建:`ho_workspace(action="create", path="<目录>", title="<标题>", ensure=true)`。`ensure=true` 会在目录不存在时自动创建。
30
+ 3. 再建会话:`ho_sessions(action="new", confirm=true, workspace="<id 或标题>", title="<标题>")`。项目会话可同时传 `project`,插件会按同名工作区匹配。
31
+
32
+ ## 设置角色后工具没有变化
33
+
34
+ 会话休眠时设定角色,插件会在它下次开轮时装配工具与提示段。0.9.12 起这一装配由全局会话事件驱动,不必重启 DSH。若仍看不到应有的工具:
35
+
36
+ 1. 在设置页「会话角色」重新设定一次,注意「存活会话当场生效」一栏的提示。
37
+ 2. 执行 `ho_diag`,看「角色收窄」一栏的已装配会话数与最近时间。
38
+ 3. 插件刚从旧版本换上来时,已存在的会话沿用旧提示段文本;重启 DSH 一次即换成新文本,工具裁剪不受影响。
20
39
 
21
40
  ## 设置页刷新失败
22
41
 
@@ -31,7 +50,25 @@ ho_init(parent="<已存在目录的绝对路径>", register=true)
31
50
  1. 压缩须由用户在设置页点「压缩授权」,单次授权 5 分钟内有效,或在聊天框发送 `/allow-compact`。
32
51
  2. `ho_checkpoint` 只登记,由调度器在回合结束后执行;目标必须空闲。
33
52
  3. 交接体检不通过时拒绝排压缩,先用 `ho_handover(action=read)` 检查结构。
34
- 4. 已压满 3 次后不再压缩,应换任:`ho_sessions(action="new")`,须用户同意后传 `confirm=true`。
53
+ 4. 已压满 3 次后不再压缩,应换任:由本会话写好交接后调用 `ho_succeed` 自行换任,须用户先发送 `/allow-succeed` 授权。额度用尽的判定先于水位;低水位与 `force` 均不能越过,`ho_sessions` 的压缩指令(`action="order", order="compact"`)同样会被拒绝。
54
+
55
+ ## 换任未执行
56
+
57
+ `ho_succeed` 报「换任未执行,未做任何写入」时,按报出的原因逐项处理:
58
+
59
+ 1. 没有授权:由用户在聊天框发送 `/allow-succeed`(可留空,也可带 8 位短号授权别的会话),或在设置页「压缩授权」卡片的「换任授权」区域点「允许换任」。授权一次性、5 分钟有效、按会话生效;压缩授权不能顶替换任授权。
60
+ 2. 不是在任者:只有登记表中该类会话的现任本人可以换任;已记过一次换任的旧会话也不得再次换任。先用 `ho_office` 确认现任的名字与会话 id,再由现任会话执行。
61
+ 3. 交接体检不合格:报错逐条列出缺项——「下一步」一节缺失或没有条目、内容为空、仍有「待填」「TODO」一类占位符。补齐后用 `ho_handover(action=read)` 复核,再重新调用。
62
+
63
+ ## 项目名或任务名不合法
64
+
65
+ 工具报出「项目名不合法」「任务名不合法」一类错误时,说明名字不能作为目录名使用;此时不写入磁盘,也不改动登记。按下列规则改名后重试:
66
+
67
+ - 项目名不超过 24 字符,任务名不超过 40 字符。
68
+ - 不含 `< > : " / \ | ? *` 与控制字符,不以点或空格结尾,不使用 `CON`、`NUL`、`COM1` 这类设备保留名。
69
+ - 名字通常从会话工作目录、首条提示或标题推断。若报错指出名字含 `*` 等字符,检查首条提示中是否将 `Projects/**` 这类通配写法写在与项目名相邻的位置。
70
+
71
+ 名字合法但被判为普通角色的会话,用设置页「会话角色」卡片或 `ho_sessions(action="role")` 明确设定。
35
72
 
36
73
  ## 迁移后原路径失效
37
74
 
package/package.json CHANGED
@@ -1,58 +1,71 @@
1
- {
2
- "name": "@mingmaple/dsh-handover",
3
- "version": "0.9.6",
4
- "type": "module",
5
- "description": "DeepSeek Harness 插件:把「全局」的交接、闸门、会话清点与上下文压缩续跑流程做成工具(dsh-handover)",
6
- "license": "MIT",
7
- "publishConfig": {
8
- "access": "public"
9
- },
10
- "repository": {
11
- "type": "git",
12
- "url": "git+https://github.com/MingMaple/dsh-handover.git"
13
- },
14
- "homepage": "https://github.com/MingMaple/dsh-handover#readme",
15
- "bugs": {
16
- "url": "https://github.com/MingMaple/dsh-handover/issues"
17
- },
18
- "keywords": [
19
- "dsh",
20
- "deepseek-harness",
21
- "plugin",
22
- "handover",
23
- "context-compaction"
24
- ],
25
- "engines": {
26
- "node": ">=20"
27
- },
28
- "exports": {
29
- ".": "./src/index.mjs",
30
- "./client": "./src/client.js"
31
- },
32
- "files": [
33
- "src",
34
- "scripts",
35
- "docs",
36
- "README.md",
37
- "LICENSE"
38
- ],
39
- "dsh": {
40
- "bundle": {
41
- "patch": "./src/cordis.patch.yml"
42
- },
43
- "client": {
44
- "platform": "web",
45
- "inject": [
46
- "@deepseek-ai/dsh-client-ui-settings"
47
- ]
48
- }
49
- },
50
- "scripts": {
51
- "build": "node scripts/build.mjs",
52
- "test": "node src/selftest.mjs --tool all",
53
- "test:blank": "node scripts/blank-dsh.mjs",
54
- "test:smoke": "node scripts/blank-smoke.mjs",
55
- "test:migrate": "node scripts/e2e-migration.mjs",
56
- "test:docs": "node scripts/check-docs.mjs"
57
- }
1
+ {
2
+ "name": "@mingmaple/dsh-handover",
3
+ "version": "0.9.13",
4
+ "type": "module",
5
+ "description": "DeepSeek Harness 插件:把「全局」的交接、闸门、会话清点与上下文压缩续跑流程做成工具(dsh-handover)",
6
+ "license": "MIT",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/MingMaple/dsh-handover.git"
13
+ },
14
+ "homepage": "https://github.com/MingMaple/dsh-handover#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/MingMaple/dsh-handover/issues"
17
+ },
18
+ "keywords": [
19
+ "dsh",
20
+ "deepseek-harness",
21
+ "plugin",
22
+ "handover",
23
+ "context-compaction"
24
+ ],
25
+ "engines": {
26
+ "node": ">=20",
27
+ "dsh": ">=0.2.1-rc.2 <0.3.0-0"
28
+ },
29
+ "exports": {
30
+ ".": "./src/index.mjs",
31
+ "./client": "./src/client.js"
32
+ },
33
+ "files": [
34
+ "src",
35
+ "scripts",
36
+ "docs",
37
+ "README.md",
38
+ "LICENSE"
39
+ ],
40
+ "scripts": {
41
+ "build": "node scripts/build.mjs",
42
+ "test": "node src/selftest.mjs --tool all",
43
+ "test:blank": "node scripts/blank-dsh.mjs",
44
+ "test:smoke": "node scripts/blank-smoke.mjs",
45
+ "test:migrate": "node scripts/e2e-migration.mjs",
46
+ "test:docs": "node scripts/check-docs.mjs"
47
+ },
48
+ "dsh": {
49
+ "bundle": {
50
+ "patch": "./src/cordis.patch.yml"
51
+ },
52
+ "client": {
53
+ "platform": "web",
54
+ "inject": [
55
+ "@deepseek-ai/dsh-client-ui-settings",
56
+ "@deepseek-ai/dsh-client-connection"
57
+ ]
58
+ },
59
+ "compatibility": {
60
+ "dsh": "0.2.2-rc.1",
61
+ "profiles": [
62
+ "desktop",
63
+ "web"
64
+ ],
65
+ "dshReleases": {
66
+ "0.2.1-rc.2": "compatible",
67
+ "0.2.2-rc.1": "compatible"
68
+ }
69
+ }
70
+ }
58
71
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * 空白 DSH 验收:证明「移到一个没有任何旧全局文件的空 DSH 上,插件所有功能 100% 可用」。
3
- * 做法:临时 HOME(无 ~/.dsh 状态)→ 只靠 dist/ 自带的东西跑完 22 个工具 + 迁移四件。
3
+ * 做法:临时 HOME(无 ~/.dsh 状态)→ 只靠 dist/ 自带的东西跑完 24 个工具 + 迁移四件。
4
4
  * 额外覆盖:7-Zip 不存在(强制 format=tar)、工作区规则文件被删光(必须退回内置模板)。
5
5
  * 用法:node scripts/blank-dsh.mjs
6
6
  */
@@ -58,7 +58,7 @@ const ctx = {
58
58
  apply(ctx, { packFormat: 'tar' }); // 强制内置归档器:模拟一台没有 7-Zip 的机器
59
59
 
60
60
  section('装配');
61
- ok(reg.tools.length === 22, '注册 22 个工具', String(reg.tools.length));
61
+ ok(reg.tools.length === 24, '注册 24 个工具', String(reg.tools.length));
62
62
  ok(reg.tools.every((t) => t && t.name && t.description && typeof t.execute === 'function'), '每个工具都有 name/description/execute');
63
63
  const names = reg.tools.map((t) => t.name).sort();
64
64
  ok(names.indexOf('ho_pack') !== -1 && names.indexOf('peer_send') !== -1, '关键工具都在');
@@ -96,7 +96,7 @@ for (const rel of [
96
96
  ok(fs.existsSync(path.join(WS, rel)), '铺好 ' + rel);
97
97
  }
98
98
 
99
- section('22 个工具在空白工作区逐个跑');
99
+ section('24 个工具在空白工作区逐个跑');
100
100
  const calls = [
101
101
  ['ho_diag', {}],
102
102
  ['ho_brief', {}],
@@ -118,6 +118,7 @@ const calls = [
118
118
  ['peer_status', { session_id: 'session-blank-test' }],
119
119
  ['peer_peek', { session_id: 'session-blank-test', limit: 2 }],
120
120
  ['peer_rename', { session_id: 'session-blank-test', title: '空白验收' }],
121
+ ['ho_succeed', {}],
121
122
  ];
122
123
  for (const [tool, args] of calls) {
123
124
  const r = await run(tool, args, WS, 'session-blank-test', '空白验收');
@@ -199,5 +200,5 @@ if (fails.length) {
199
200
  for (const f of fails) console.log(' - ' + f);
200
201
  process.exit(1);
201
202
  }
202
- console.log('BLANK-DSH OK(空白 DSH 上 22 工具 + 迁移四件全部可用)');
203
-
203
+ console.log('BLANK-DSH OK(空白 DSH 上 24 工具 + 迁移四件全部可用)');
204
+