Repository navigation
Releases: yangsong608/dsh-session-handoff
Release list
v0.2.5 路由 disposer 修复
v0.2.5:路由 disposer 绑定 fiber
用 DSH Host Inspector 读取真实进程状态时发现,dsh-session-handoff 的宿主 fiber 处于 FAILED:
webserver: duplicate exact route "/session-handoff/health"
根因
webServer.register() 返回 disposer,但宿主半直接丢弃了它。插件热重载(bundle replay / HMR)时
旧 fiber 的注册没有被撤销,第二次 apply 注册同一 exact 路径即失败,整个宿主半进入 FAILED——
按钮还在,但 /session-handoff/prepare 并不存在。
修复
- 路由注册改为
ctx.effect(() => webServer.register(...)),disposer 随 fiber 释放; - 新增回归测试:apply → 执行 disposer → 再次 apply 不再冲突;
- 宿主冒烟 56/56,浏览器 34/34,parity 5/5,verify 32/32。
恢复
旧路径只存在于当前进程内;重启 DSH 加载 v0.2.5 即恢复,不需要清理文件。
v0.2.4 按钮共存核查与 id 加固
v0.2.4:按钮共存核查与座位 id 加固
问题:会话输入框右侧的「接力」按钮会不会覆盖其他插件注册到 conversation.input.right 的按钮?
结论:不会。
依据(DSH 0.2.1-rc.2 源码)
conversation.input.right声明为list座位(ui-conversation/src/client/contract/slots.ts:278);SlotCore.register对 list「按 id 分格」,只有相同 id + 相同 priority 才抛重复错误;
不同 id 一律追加(ui-slots/src/index.ts:1227-1240);- 渲染取每格 winner 后按
order排序,格子之间不会互相替换(entriesOfSlot,同文件 1353-1375); - 实机核查:当前 profile 里唯一同座位的第三方注册是
dsh-connect-qoder的余额胶囊
(order: 4),与本按钮(order: 40)并存。
本次加固
- 按钮/预览卡的 cell id 改为包名限定:
dsh-session-handoff/dsh-session-handoff-preview; - 注册调用加 try/catch:即使真的撞格,也只让本按钮缺席,不影响同座位其他插件;
- 不传
priority(不会遮蔽任何内置/第三方条目);CSS 只命中.dsh-handoff-btn; - 唯一的「遮挡」是用户主动打开预览卡时的全屏遮罩,关闭即恢复,且不注销任何注册项。
验证
verify 32/32 · 宿主 smoke 53/53 · 浏览器 smoke:client 34/34 · parity 5/5 · CI 全绿。
升级
dsh plugin --profile desktop add link:/abs/path/to/dsh-session-handoff
客户端 bundle 改动通常可热加载;若界面未更新,重启一次 DSH。
v0.2.3 真实交接产物复查修正
v0.2.3:按真实交接产物复查修正
对用户真实执行的一次交接(同一会话点了两次)逐份核对后修正。结论:
- 第一份(LLM 生成)内容基本正确:标题、摘要、commit(5726f44 / 62f4ead)、版本 1.9.3、
设计文档目录均与仓库事实一致;记忆候选 6 条合理。 - 第二份(降级生成)不合格:标题取成了会话首条消息,完成项出现「```dsh-ui」,
当前状态是被截断的 UI JSON,下一步泛化;新会话实际使用的是这一份。
修复
- 标题:采集最新
session/title事件(SessionHeader.title通常为空)。 - max-tokens:先保留已产出文本尝试解析;失败才翻倍重试一次(上限 16384)。
默认输出预算 4096 → 8192(DeepSeek reasoning 计入输出预算,4096 会被吃满导致整单降级)。 - 兜底质量:
proseOf()剥离代码围栏 / dsh-ui JSON / 标题 / 表格行;
完成项与现状只取可读段落;标题回退到最近诉求;历史工具失败标注「历史失败」,不再冒充当前阻塞。 - 参考文件:
filterReferences()丢弃不存在的绝对路径,工作区内优先;/tmp与畸形路径不进提示词。 - 记忆台账:时间戳改为本地时间(原来用 UTC,20:28 与本地 04:28 不一致)。
用真实日志验证
把源会话(4820 事件)解压后喂给新构建做确定性生成:标题为「项目工程分析」、
完成项是可读散文、没有 dsh-ui/JSON 段落、参考文件只保留真实存在的路径。
验证基线
tsc 0 错误 · verify 31/31 · 宿主 smoke 53/53 · 浏览器 smoke:client 34/34 · parity 5/5 · CI 全绿。
升级
dsh plugin --profile desktop add link:/abs/path/to/dsh-session-handoff重启 DSH 后新生成才会使用修复后的宿主逻辑。已生成的两份文档保持原样(历史产物),
可重新点一次「接力」生成修正版。
v0.2.2 修复 Handoff inject 报错
v0.2.2:修复 Handoff failed: cannot get property "llm" without inject
现象
真实安装后点「接力」按钮,toast 报 Handoff failed: cannot get property "llm" without inject,交接无法生成。
根因
宿主半在 prepare 里把原始 cordis ctx 直接传给 summarize(),后者读 ctx.llm。
llm 是可选能力,没有(也不应该)写进 inject;cordis 4 的插件作用域是严格代理,
读取未注入的服务会抛错而不是返回 undefined。冒烟测试此前用普通对象 ctx,因此没有暴露。
修复
prepare先用service(ctx, 'llm')(内部ctx.get(name, false))解析成普通对象,再传{ llm };- 统一可选服务读取:host 的
sessionQuery/llm/sessions,client 的
shortcuts/locale/uiWorkspace/sessions全部走软取,禁止把ctx原样传给子模块; - 冒烟改用严格 Proxy 模拟 cordis:直读未注入服务即抛错。并做了回滚验证——
把修复临时撤掉后,回归测试会准确复现cannot get property "llm" without inject。
验证
tsc0 错误- 产物契约 31/31
- 宿主冒烟 44/44(含严格代理用例)
- 浏览器半冒烟 34/34(严格 ctx)
- 提示词一致性 5/5
- CI 全绿
升级
dsh plugin --profile desktop add link:/abs/path/to/dsh-session-handoff必须重启一次 DSH:宿主半 bundle 在启动时装载,运行中的实例不会热更新。
v0.2.1 复查修正
v0.2.1:复查修正
对 v0.2.0 做「实现 ↔ 设计 ↔ 计划」逐项复查后修正,其中一项会让快捷键在所有平台静默失效。
修复
- 快捷键默认键位无效:DSH 的键位校验把
primary+KeyH列为保留组合(桌面 Linux 与全部 Web Linux),
原来六档都用KeyH会让ctx.shortcuts.register整体抛错(被 catch 后快捷键静默消失)。
现在:macOS/Windows(Desktop/Web)保持Cmd/Ctrl+Shift+H;Linux(Desktop/Web)用Cmd/Ctrl+Shift+.。 - 记忆台账写失败导致整单失败:
prepare在记忆写盘异常时返回 500,而文档其实已生成。
现在记memory-write-failed降级并继续返回文档。 - 超时定时器泄漏:
sendToSession成功路径未清理 10s 定时器,已在 finally 清理。 - 预览体验:成功 toast 带上标题;textarea 自动聚焦并补
aria-label;「重新生成失败」使用独立文案。 - 文档:修订快捷键与预览卡描述、更新架构/时序图、清理编号;新增复查修正记录。
验证
tsc0 错误- 产物契约 31/31
- 宿主冒烟 41/41(新增记忆写失败降级 3 项)
- 浏览器半冒烟 33/33(新增六档键位断言 2 项)
- 提示词一致性 5/5
- CI 全绿
升级
dsh plugin --profile desktop add link:/abs/path/to/dsh-session-handofflink 安装会直接读取新产物;重启一次 DSH 让宿主 bundle 生效。
v0.2.0 可编辑预览 + 快捷键
v0.2.0:可编辑预览 + 参考文件勾选 + 快捷键
在 v0.1(一键总结 → 交接文档 → 新会话)之上,把「生成后直接开新会话」改成可审阅、可编辑的确认流程。
新增
- 可编辑预览卡(
shell.overlay):标题 / 一句话状态 / 下一步 / 记忆候选 / 交接文档路径 /
可编辑提示词 / 参考文件勾选;动作打开新会话、复制提示词、重新生成、复制文档路径、关闭(Esc/遮罩)。 - 参考文件勾选:取消或补充参考文件后,用结构化
PromptParts立即重建提示词;手动编辑提示词后勾选锁定,
需「重新生成」才能再调整(避免覆盖编辑)。 - 快捷键
Cmd/Ctrl+Shift+H(macOS / Windows / Linux,Desktop 与 Web 一致)。 - 降级:
shell.overlay缺失 → 退回 v0.1 直接打开;ctx.shortcuts缺失 → 只是没有快捷键;两者都不阻断主流程。 - 配置
preview: true|false:默认预览;关闭后恢复 v0.1 一键直达(autoSend仍可配)。
一致性保证
- 提示词由服务端
PromptParts生成,浏览器半composePrompt复制同一份格式化逻辑;
新增 parity 测试逐字比较两端输出,避免预览重建与服务端默认提示词漂移。
验证
tsc0 错误- 产物契约自检 31/31
- 宿主半冒烟 38/38(真实构建产物 + 假 ctx + 临时目录)
- 浏览器半冒烟 31/31(真实 bundle + 真 React SSR:预览渲染/动作/参考文件/快捷键 resolve)
- 提示词一致性 5/5
- GitHub Actions 全绿
升级
dsh plugin --profile desktop add link:/abs/path/to/dsh-session-handoff
# 或(发布后)dsh plugin --profile desktop add dsh-session-handoff@0.2.0CLI 升级后重启一次 DSH(宿主 bundle 启动时装载)。若使用市场/插件页安装,通常可热加载。
延期(v0.3 评估)
@引用 chip:DSH 未公开「编程式插入引用」的稳定 API,当前用提示词中的路径清单替代。- 记忆插件写入适配器:mnemon 等无公开写入协议,当前保留独立
交接记忆.md台账。 /handoff命令:命令结果不能导航/创建会话,价值有限,待 commandview 方案。
v0.1.0 会话接力 MVP
会话接力 MVP
在 DSH 输入框右侧(conversation.input.right,提交按钮前)增加「接力」按钮:一次点击完成
总结当前会话 → 提炼工作内容 → 固化记忆候选 → 生成交接文档 → 打开新会话并预填提示词。
交付内容
- 插件:宿主半(
lib/index.js)+ 浏览器半(lib/client.js),零运行时依赖 - 产物:
WorkSummary.md(五段式 + 工具附录)、handoff.json(schema: dsh-session-handoff/v1)、交接记忆.md(去重台账) - 降级:无
sessionQuery/ 无 LLM / 无路由 / 超时 / 输出非法 → 确定性摘要,文档照常产出 - 文档:DSH 插件机制分析、同类插件调研、技术设计、可行性分析、产品设计
验证
tsc0 错误- 产物契约自检 29/29
- 宿主半冒烟 35/35(真实构建产物 + 假 ctx + 临时目录)
- 浏览器半冒烟 22/22(真实 bundle + 真 React SSR 渲染)
- GitHub Actions 全绿
安装
dsh plugin --profile desktop add link:/abs/path/to/dsh-session-handoff
# 或发布后:dsh plugin --profile desktop add dsh-session-handoffCLI 安装后如按钮未出现,刷新页面;仍没有则重启一次 DSH(宿主 bundle 在启动时装载)。
已知限制
conversation.input.right位于发送键所在右侧工具行、模型选择器左侧,不是像素级紧贴发送键。autoSend依赖半公开的sessions.retain/prompt,失败会自动回退草稿。- npm 包名已有无版本占位,正式发布将改用 scope。