# 更新日志 本文件记录本项目的所有重要变更。 ## [2.4.0] - 2026-10-07 ### Fixed - **子代理(sub-agent)会话用量并入看板口径(Issue #9)**:看板此前只统计 `agents.roots()` 返回的顶层会话——DSH 契约下 roots 仅含无 owner 的主会话,子代理 会话(`SessionHeader.origin='subagent'`)的用量被整条丢弃,而 UI 多处声明「含子代理」。 重度扇出场景下总量实测偏低约 59%~2.6 倍,日限额/里程碑警报随之欠触发。修复: 新增 `host/corpus.js` 全语料采集器,经 `sessionQuery`(live-preferred 官方口径) 把非根会话喂进引擎折叠缓存——活会话走内存快照(零盘读、指纹增量重折),冷会话走 `readSession` 一次性重放(冷日志不可变,进程内缓存;每轮冷读预算 25 条分轮收敛, 32 日窗口外不读);活→冷转换强制补一次终读。`aggregateFold` 新增 `extraFolds` 参数并入用量侧(五桶/grand/命中率/模型/工具/趋势/区间),scan 侧(宠物卡片、 审批提醒、黑板统计)仍只认 roots,宠物 UX 不变。附带修复:根会话收尾后其折叠 不再从快照口径消失(此前活→收尾瞬间 hero 会变小);`sessionQuery` 缺席的老宿主 静默降级为旧口径。 - **fork/续跑谱系不双计继承前缀(评审修复)**:DSH 完整会话日志含 fork 继承的前 `inheritedEventCount` 条父会话事件——用量折叠(roots 活路径与 corpus 冷/活路径) 一律只吃自身事件,防止「父会话 + fork 子会话」把同一段历史计两遍;scan(卡片/ 标题/回合)维持全量日志语义不变。 - **趋势图节流门感知 corpus 到达(评审修复)**:trend 整点锚定节流原先只看整点翻转 与 roots 重扫计数,子代理/冷会话折叠落地后最长一小时不刷新——hero 已并入而趋势图 停在旧口径。现以 corpus 变更计数为第三失效条件,折叠集合一动趋势即随之下轮刷新。 - **真机验收观测点**:`/state` 快照新增 `diag.corpusAvailable`(sessionQuery 接线与否) 与 `diag.corpus`(`{folds, rev}`——corpus 折叠条数与变更计数,启动收敛期 folds 应 分批增长后稳定);宿主日志每轮折叠摘要 `[foxbell-pet] corpus round: +N live +M cold`, 失败逐条 warn。采集器对宿主调用(listSessions/readSession)加 30s 超时与退避重试, 挂起类失败不再冻结采集循环。人工验收手册见 `docs/QA-CHECKLIST.md` §10。 - 已知行为:插件启动后首轮采集完成时,历史上已有的用量会一次性并入,日阈值/里程碑 警报可能相对前一分钟「跳档」补发(数字真实,且按日去重只发一次);冷会话采集以 32 日窗口为界(trend 14 日 + 区间 31 日的外沿),窗口外的已收尾历史不计入。 ## [2.3.3] - 2026-10-04 ### Fixed - **语言跟随 DSH 应用语言设置(热切换)**:宠物语言此前冻结在模块加载时的 `navigator.language`(浏览器引擎 locale),与 App 内语言设置完全解耦——设置里切中/英文 对宠物无效。现接入 DSH 客户端 locale 服务:`adoptLocaleService` 采纳 `active`(zh→zh, 其余→en)并热订阅切换;`langStore` + `useLang`(OverlayEntry / DashboardPanel / SettingsCard 三个槽入口锚点)驱动重渲染,切换即时生效无需重启。locale 服务缺席 (老宿主/TUI)仍回退 `navigator.language` 兜底。 - **拖拽钳制窗口边界**:pointer capture 下指针移出窗口后 pointermove 事件流持续, `onPointerMove` 原样写入指针坐标(全客户端唯一绕过 clampPos 的位置来源)——惯性甩拽 可把宠物送出视口外滞留(物理关闭时松手还会持久化越界坐标,只能停用/重载插件恢复)。 新增 `dragPos`(指针位移 → clampPos)钳制拖拽路径:宠物停在窗口边缘、松手存储值必在 界内;采样/方向判定/物理坠落的甩掷语义不变。 ## [2.3.2] - 2026-10-03 ### Fixed - **桌面版(dsh desktop 0.2.0-rc.2)点击「📈 用量看板」面板不显示**:settings scope ready 时 `cfgStore.getSnapshot` 每次调用都返回新合并对象,违反 useSyncExternalStore 的引用稳定契约。DashboardPanel 是客户端唯一以 uSES 消费 cfgStore 的组件,挂载即 「Maximum update depth exceeded」(Minified React error #185)被槽系统以 "slot entry crashed in 'main'" 卸载,表现为点击菜单后看板无反应。修复:合并结果按 输入身份缓存(local 引用 / scope 快照引用 / pending 键集),两次调用间引用稳定。 已在桌面 0.2.0-rc.2 运行时隔离复现验证(面板稳定挂载、console 零错误)。 ## [2.3.1] - 2026-10-03 ### Fixed — 客户端加固(v2.3.0 tag 后合入) - **设置 RPC 超时**:客户端 `settingsRpc` 各请求加 8s `AbortSignal.timeout`,宿主挂起时 不再卡死 pending 状态。 - **0.2 设置适配器自愈**:describe 视图中本插件行缺失(entry 改名/重装等)且 ns 已缓存时 清缓存并在下轮重新发现,避免按旧 ns 永久错配。 - **依赖下限**:`@deepseek-ai/schemastery` 提至 `^3.18.4`(`.volatile()` API 的真实下限)。 ### 内部 - 简化 0.2 适配代码(行为不变):client 抽出 `rowOf`/`writeSetting` 助手消除四处重复; host 设置接线改提前退出结构并抽 `readEntryValue` 纯函数。inject 回调内服务缺席属不可达 防御路径(cordis inject 语义下回调触发时服务必在场),旧代码对 undefined 误报警告、对 null 抛 TypeError,现统一为静默保持 entry 回退。 - 测试:settings 接线形状分支全覆盖——0.1 `installSection` 注册参数与 scope 值生效、 既无 installSection 也无 describe 时告警一次、回调内服务缺席静默降级;`mount0x2` 抽出 通用 `mountWithSettings` 助手。另含 v2.3.0 tag 后合入的 host 0.2 接线 4 个专项用例。 - 文档:更正 volatile 机制描述(`.volatile()` 解析返回 ref 单元、默认值不丢)并补配置跨 0.1→0.2 迁移说明(见 [2.3.0] 节内更新,随本版首次对外发布)。 - 发版脚本:快进校验前物化 `origin/release` 引用(新 clone 无远端跟踪 ref 时不再误报 NOT a valid object)。 ## [2.3.0] - 2026-10-03 ### 兼容性(适配 dsh 0.2.0-rc.2 运行时;向下兼容 0.1.2-rc.1) - **C1(设置 host 半,entry-config 模型)**:dsh-settings 0.2 删除了 `installSection`/`register`, 设置表单改为由插件自身导出的 `Config`(volatile 根)派生,`describe()` 按 Loader entry id (本包 `cordis.patch.yml` 的 insert id `dsh-foxbell-pet`)寻址。宿主侧改为双模型兼容层 (参考 @hytime/dsh-thinking-effort@0.3.7 已验证结构):检测到 `installSection` 走 0.1 命名空间注册;检测到 `describe` 走 0.2 entry-config——配置值从 `settings.describe()` 投影, 以 `settings/document-updated` 事件失效缓存(写路径不变:客户端 RPC 直达宿主 settings 服务)。 schema 拆为双导出:`Config = ConfigSchema.volatile()` 是 0.2 表单描述符(describe 只列出含 volatile 字段的 entry,update 拒绝非 volatile 路径写入);`ConfigSchema` 保留可调用的 默认值解析/校验(apply 入口与 0.1 installSection 注册用)。实测机制(已复核):schemastery 的 `.volatile()` 解析(调用/`~standard.validate`)返回的是 **ref 单元** `{get, [Symbol(cosmokit.volatile.write)]}`——`.get()` 即含默认值的完整解析结果,`JSON.stringify(ref)` 打印 `{}` 只是函数不序列化,并非丢值;loader 与 settings 服务沿线穿引 ref(`fiber._config`/ `_commitVolatile` → describe 的 plainConfig 解析),因此 describe 投影的 value 默认值完备。 插件侧 apply 收到的 config 是 ref 形状,经 `ConfigSchema` 归一后 entry 只剩默认值(行配置值 经 describe 浮现、不进 entry thunk)——`readConfig()` 以 `{...entry, ...describeValue}` 合并 属双保险,`CONFIG_DEFAULTS` 作无 settings 部署的兜底(@hytime 同款运作方式)。 - **C2(依赖结构,根因修复)**:`@deepseek-ai/dsh-settings` 从 `dependencies` 移至 `devDependencies`(钉 `0.2.0-rc.2`,仅供类型/测试对齐新 API)。此前插件带入的 dsh-settings@0.1.2-rc.1 会被 profile(`nodeLinker: hoisted`)平铺进 profile node_modules, 遮蔽运行时内置的 settings 插件行,cordis 加载器按其 peerDependencies (`^0.1.2-rc.1`)判定与 dsh 0.2.0-rc.2 不兼容并禁用该行 → settings 服务缺失 → 桌面端欢迎流程 `settings/describe` RPC 失败、主进程连续崩溃。settings 服务一律由 宿主运行时提供,插件不再自带副本(与官方样例插件同构)。 - 新增 `peerDependencies`(`@deepseek-ai/cordis ^4.0.1`、`@deepseek-ai/dsh >=0.1.2-rc.1`, 后者 optional)与 `engines.dsh` 声明;devDependencies 补钉 dsh-settings 0.2.0-rc.2 的 全套 peer(dsh-brand/dsh-session/dsh-invariants/cordis 精确版)以让 npm 严格解析可安装。 ### Changed — 客户端半(0.2 桌面端 UI 契约) - **设置后端**:0.1 的客户端 `settingsScope` 服务在 0.2 已删除。配置读写改为 `createHttpSettingsScope()` 适配器——`settings/describe` + `settings/update` HTTP RPC (两端线缆形状一致,仅 ns 语义不同:0.1 = 注册命名空间 `foxbell-pet`;0.2 = entry id `dsh-foxbell-pet`),ns 由 describe 动态发现(候选 id 优先、标记字段兜底),配置 store 的乐观更新/写后回读/冲突重试逻辑零改动;订阅侧以 8s 轮询 describe 模拟推送。 - **设置 UI 槽位**:0.1 的 `settings.plugin.item` 卡片槽在 0.2 已删除,改为 `settings.section` 整节注册(设置页导航出现「Foxbell 桌宠」一节);旧槽位注册保留 (槽位未声明时 inject 工厂不运行),双运行时都能出 UI。 - **会话服务**:客户端 `sessions.list` 快照形状双兼容——0.1 `{current}` / 0.2 `{ids, byId}`(当前会话 = `retainedBy.mainView > 0`,与官方 ui-layout 同口径)。 > **配置跨 0.1 → 0.2 迁移**:宿主侧 0.1 命名空间(`foxbell-pet`)的存量值不做服务端迁移; > 延续靠客户端「首次 ready 将 localStorage 缺失字段 seed 进新配置面」(0.1 客户端本就双写 > localStorage),同一浏览器内自动带入;换浏览器/清存储则回到默认值。0.1 运行时上设置推送 > 由原 scope 订阅降为 8s 轮询(双窗口同步略延迟,写入路径不受影响)。 ### Fixed - dsh 0.2.0-rc.2 桌面端安装本插件后无法启动(C2 根因);0.2 下设置卡不出现、 配置写不进 settings(C1/客户端适配)。 - 测试套件在 Windows(无 symlink 特权)环境下的 5 个环境性失败改为能力探测跳过 (防御逻辑断言不变);bundle-smoke 补 `react-dom` external 桩(DialogHost 的 createPortal 属合法平台种子依赖)。 ## [2.2.2] - 2026-09-15 ### Fixed - **小黑板「工具 Top3」行水平溢出被裁切**:v2.2.1 重排把工具明细并入「标签-数值」行后,数值段 `flex: none` 不收缩,三工具长串(`bash×54(共 1.5 分钟) · …`)超出 310px 板宽直接溢出,条目尾部被裁掉。修复:明细行数值段改为可收缩换行(`flex: 1 1 auto + min-width: 0`,全体 kv 行通用安全网,短值右对齐观感不变);工具行按条目拆分渲染——条目为整体换行单元(`inline-block`),只在条目间隙断行、不在「(共 X 分钟)」内部断行,单条目超宽时内部软换行兜底。`value` 拼接串契约不变(双侧测试钉住),新增 `entries` 逐条目字段的用例。 ## [2.2.1] - 2026-09-13 ### Fixed - **导出图页脚水印消失、宠物脚贴画布边**:估高干跑与实际绘制逐段不一致(趋势段干跑 210 vs 实际 250 等,净低估 36px),画布以偏小高度创建、创建后再改 `H` 也改不了画布——页脚两行水印被画到画布外不可见,宠物脚越过卡底线贴住画布底边。修复:干跑步进与实际绘制逐段对齐、画布创建后 `H` 冻结;宠物脚下 24px 呼吸再收卡底线,页脚(「纯 token · 含子代理 · 本地聚合」/「DSH · Foxbell 用量看板」)落在卡底线之下并完整可见。 - **导出图宠物变小/越界**:立绘高度此前随上方内容长度被压缩(模型/工具行越多宠物越小)。改为**固定 360px 高、顶部锚定紧跟工具区(间距 24px)**;画布尺寸两遍绘制定稿(先干跑计算内容高度再创建画布),卡身止于内容底、页脚紧随、无多余空白;宠物与气泡之间、气泡文字四向内边距统一为 20px;主界面「宠物大小」设置只影响桌面精灵,与导出图无关。 - **悬浮窗「活跃」时内容消失**:用户配置里遗留的 `usageEnabled: false`(旧版开关时代残留)会隐藏悬浮窗全部用量行,只剩表盘与状态计数。该开关已移除并**恒为开启**,遗留值彻底失效(今日/缓存/产出/本会话行恢复)。 - **模型展示数量**:大看板「模型」区从 Top6 扩到 **Top10**(有 10 个模型就依次展示 10 行)。 - **黑板模型行对齐**:与大看板统一——模型名(含供应商)左对齐、token 数右对齐固定宽。 - **设置卡 i 徽标两处问题**:点击 i 不再误触该行配置(此前因位于 label 内会切换复选框);悬浮说明改自绘气泡,悬停立即显示(原生 title 有延迟且部分环境不弹),气泡从徽标右侧弹出(不再向左溢出窗口)。 - **大看板模型进度条等长**:名称/数值列宽按最长一行实测对齐(CSS 变量),全部行进度条起点与长度统一,不再随文字长短参差。 - **黑板明细行**:标签左对齐、数值右对齐(同一竖线基准)。 - **多标签页语音重叠**:多个 DSH 页面同时打开时,状态切换语音/警报音各页都会播放并相互重叠。新增「唯一发声方」仲裁(Web Locks 选主)——自动播报仅由持锁页发出,持锁页关闭后其余页面自动接手;可见优先(发声方页面转后台即让位,可见页面立即接手);不支持 Web Locks 的环境退化为原行为(每页可发声)。用户手势(双击说话)不仲裁。 - **悬浮条「详情 »」点不到**:悬停事件绑定在精灵方块上,鼠标离开精灵(悬浮条与精灵间的空隙)即卸载悬浮条。改为 200ms 宽限卸载——进入悬浮条或回到精灵即取消,真人移动可稳定点到「详情 »」(此前 Playwright 瞬移式自动化点击掩盖了该问题)。 - **导出图模型名截断**:导出卡中模型名不再缩略(DeepSeek-V… → 完整名称)。 - **导出图评语气泡遮挡宠物**:竖版重排后评语气泡位于宠物左侧、间距 ≥24px,立绘完整全身可见。 ### Changed - **导出图片改版**:对齐 Codex++ 竖版排版(720×1600 浅色卡)——头部日期范围/累计 Token hero(完整千分位)/五口径指标行/趋势卡(峰值+渐变折线+数据点+x 轴标签)/按 Model 分布进度条(≤6 行全名)/工具调用 2×2/聊天式评语气泡 + 宠物立绘/口径页脚。 - **自定义评语内联**:从设置卡迁移至看板头部「按自定义评语导出」(内联输入 + localStorage 草稿,占位符 `{range}` `{tokens}` `{hitPct}` `{models}` 不变);宿主/客户端配置键 `exportQuote` 移除(遗留值自动忽略)。 ## [2.2.0] - 2026-09-12 ### Added — 用量看板三级披露(R0-R10) - **三级披露**(一个数据核、三级呈现):L1 迷你条(内容冻结)→ L2 小黑板加料 → L3 主列大看板;黑板出现即顶替迷你条,关闭即恢复 - **L2 黑板加料**:既有容器追加三行——7 日 sparkline(静态 SVG 微缩趋势)、模型 Top3 行(超 3 折「等N」)、「查看完整看板 →」入口行 - **L3 大看板**(复刻 Codex++ 排版,挂 `main` keyed 面板 `foxbell-dashboard`):视图选项卡【近 5 小时 | 近 7 天 | 近 30 天 | 自定义 ≤31 天】+「复制文本」「导出图片」;hero 区间累计大数字 + 本周/上周命中率对比(±pt);五口径网格(用户输入(估,含子代理)/产出/请求输入(全文累计)/缓存命中/命中率 + 请求次数 + 数据截止时间);蓝→紫渐变趋势图(三横网格线/面积/数据点/峰值/hover tooltip/轴标签);模型分布通栏进度条(≤6 行,title 显精确值);2×2 工具格 + Top5 工具;底部口径说明。面板内自滚动,不注册任何默认常驻 UI - **模型/供应商分布**(F05 清偿):`foldUsage` 在 (turn,step) 替换槽结算时按 `message.source.{provider,model}` 路由记账(`byRoute` 会话账 + `byDayRoute` 日×路由交叉账,替换冲回同步归因,长会话跨日不污染);快照当日 Top6、L2 Top3、L3 随视图联动全量;路由缺失归「未知」桶 - **趋势窗口**:快照常驻近 14 日日粒度 + 当日 24 小时桶(整点锚定:5h 视图取最近 5 个完整整点桶);更早历史走按需路由 `/dashboard/range?from&to`(日粒度,宿主 ≤31 天校验 + 前端钳制提示),返回逐日数组 + 区间聚合(五口径合计/模型/工具 Top5) - **导出分享**:canvas 绘制 1200×675 PNG(标题/hero/趋势折线/口径网格/模型行/底部当前激活宠物立绘 + 评语气泡);立绘姿态默认**随机动作**、设置卡可选(ANIM 行清单 +「随机」);**智能评语**按命中率档 → 总量档 → 趋势方向 → 多模型 → 摸鱼优先级规则匹配(zh/en 各 10 条);设置卡「导出评语」支持自定义模板占位符 `{range}` `{tokens}` `{hitPct}` `{models}` - **看板音效(MAM 机制 + 默认音效)**:警报链改四组配齐播宠物 `general` 组语音、否则播内置看板默认音效(脚本合成两音上行 chime ×3 轮换,`assets/sounds/alert-{1,2,3}.wav`,生成脚本留仓、许可洁净),`/sounds/` 静态路由服务(文件名白名单防穿越);客户端 `'usage'` 幽灵语音组退役(与调用点改造同 commit);TTS 不参与看板警报 - **入口与钻取链**:迷你条尾部「详情 »」(迷你条唯一可点元素)→ 黑板「查看完整看板 →」→ L3;右键菜单新子项「📈 用量看板」直达 L3;设置卡「侧栏看板入口」开关(默认关,开启注册 sidebar.panellist 图标;注:rc.2 真机上该侧栏图标可能不投影——上游子槽生命周期待排查,右键菜单与黑板链为实测可用入口) - **设置卡 3 项**:「侧栏看板入口」(默认关)、「导出评语」(留空走评语池)、「导出姿态」(random + 动画行清单) ### Changed - **迷你条铁律修订**(用户裁决):「纯只读」→「单一钻取入口」——容器整体仍 pointer-events:none,仅「详情 »」按钮局部开启,区域外点击照旧穿透;拖拽无命令/单击每目标单行为/本体无操作按钮不变 - **黑板锚定跟随**:从 fixed 右下角改为锚定宠物左侧(越界自动翻右侧)、顶部对齐宠物,三档缩放跟随;黑板出现即**顶替**迷你条(v2.1 的「互让」改为「互斥顶替」) - **警报文案结构化**:宿主 alerts 增 `reached` 数值字段,客户端按 `kind + reached` 以 i18n 拼装 zh/en 文案(旧宿主无 `reached` 时回退 zh 原文) - **MiniBar 状态计数口径**:改用宿主引擎全量计数(`usage.counts`),缺省回退本地卡片计数 ### Performance - **P1 引擎增量缓存**:按「末事件 seq 指纹」每会话缓存事件折叠量(五口径账/用户输入估算/工具按日/状态机结论),指纹未变零重扫;时间派生量(节奏档位/审批等待/年龄/黑板行)每轮从缓存重算;`scanInfo` 双扫描透传复用(issue #4) - **P2 宠物 IO 缓存**:宠物目录与清单 mtime 指纹缓存(含逐宠物 manifest mtime 复验,清单编辑即时失效),/state 每 1.5s 的 readdir + 逐宠物读文件清零 - **P3 /state 短路**:客户端带 `?since=`,内容修订号未变返回 134B 微型响应(对比全量 ~14.5KB,−99%);全量响应仅新增顶层 `rev` 字段,旧客户端零感知 - **P4 不可见降频**:页面不可见时轮询 1.5s → 5s,`visibilitychange` 可见即恢复 ### 兼容性 - `engines.dsh >= 0.1.2-rc.1` 不变;`package.json` 与 `dsh.plugin.json` 同步 2.2.0 - **纯 token 口径**延续:全部新界面/导出不出现任何价格金额字段 - `test/dashboard.test.mjs` 29 个 v2.1 summarize 字节契约用例原样通过;警报触发语义(阈值跨越/日键去重)、L1 用量行内容排版、黑板 TTL 与四路关闭、宠物导入管理体系均未变 - 正确性对账:会话事件重放聚合 vs harness 官方 tokenUsage totals 四口径逐字节一致(含子代理会话) ## [2.1.0] - 2026-09-11 ### Added — 效率看板移植(v1.4.0 → v2 双树架构) - v1.4.0 效率看板一期(五组件 + 两小增强)整体移植到 v2 架构:宿主半聚合新模块 `src/host/dashboard.js`(时长档位/五口径 token/警报阈值/总结摘取),全部经 `/state` 快照随既有 1.5s 轮询下发,**零新增轮询通道与常驻 UI**(迷你条仅悬停期间存在) - **时长档位**(节奏姿态引擎):宠物姿态随事件时间轴自动变档——高强度 / 活跃 / **长任务**(turn 开着静默 ≥3 分钟,防挂机干等)/ 空闲 / **摸鱼四阶**(turn 关着静默 ≥15 分钟起小憩→躺平→咸鱼→咸鱼干渐进,抑制环视);换动画变体不变速,档位跃迁只播一次短动画,新事件立即复位 - **Token 五口径计量**:**请求输入 / 缓存命中 / 命中率 / 产出 / 你的输入(估)**(另标「含子代理」口径);一个计数器、三个表现面——悬停 ≈0.5s 浮现**迷你条**(节奏表盘 +「今日 / 本会话」用量 +「N 等审批 / N 运行 / N 完成」状态行,纯只读,移开即消失,右键「🏷 今日用量」手动唤出)、**日阈值举牌**(`dayLimitTokens` 达 80%/100% 各举牌一次)、**里程碑播报**(累计 token 过 `milestoneUnit` 整数关口,气泡一句话)。用量一律**纯 token 口径,不折算金额**(设置卡内有说明文案) - **审批召集链**:审批等待 ≥N 分钟(`approvalFlickerMin` 可配)**且页面不可见**时标签页标题轮换「🦊 审批等待中…」,批准或回到页面即恢复;右键「🗂 会话一览」列出全部会话(状态色点 + 点击直达);点状态卡 = 智能跳转(有待审批直达审批锚点,否则跳会话 + 已读) - **小黑板**:任务完成后宠物旁限时出现「📖 总结」入口(默认 15s,可配 10/15/20s)→ 点开浮现总结浮窗(会话/turn/五口径 token 三分账/工具调用 Top3 及耗时/最长单 turn/报错数),`boardTtlSec` 自动消失,✕ / 点外部 / ESC 均可关;隐藏桌宠时 farewell「今日收工」黑板分发一次;右键「📊 查看最近总结」随时唤回;黑板与迷你条互让(黑板优先,迷你条延后) - **表达容器**:内容按形态分流——短数字 → **警报举牌**、一句话 → 气泡、明细 → 黑板浮窗;警报语音三优先级 **语音组音频 > TTS 朗读 > 静默**(`ttsEnabled` 可开;v2 语音清单固定四组、无 usage 组,故阈值/里程碑警报实际走 TTS/静默) - **年龄标注**:状态卡动态行尾追加灰色「×s/×m」(与事件时间戳同源),分清「刚发生」还是「已挂 5 分钟」 - **设置卡草稿 + 统一保存**:上述 **12 项新配置**(`paceEnabled` / `usageEnabled` / `summaryEnabled` / `ttsEnabled` / `dayLimitTokens` / `milestoneUnit` / `paceIntenseEvents` / `paceLongrunMin` / `paceLoafStartMin` / `approvalFlickerMin` / `summaryEntrySec` / `boardTtlSec`)进设置卡;编辑先入草稿,保存/放弃统一生效,保存自动收起卡片;**修复数字配置经 Number 转换静默丢配**(非法值阻断保存并提示,不再静默写默认值) - **双语 UI**:效率看板全部新文案(档位/五口径/黑板行/菜单项/设置卡标签)入插件内部 zh/en 双字典,浏览器语言自动选择,不依赖 harness locale ### 兼容性 - 宿主基线不变:**dsh ≥ 0.1.2-rc.1**;协议面(事件订阅/路由族/settings 服务)已在 **dsh 0.1.5-rc.2** 上逐项自检兼容,无破坏面 - 旧 API 零残留守卫延续:`dashboard.js` 为 v1.4.0 原样移植的双兼容事件读取器(`session.snapshotEvents()` 优先),validate 对该精确表达式定向豁免,其余 `session.events` 用法依旧零容忍 ## [2.0.0] - 2026-09-07 ### 兼容性(dsh ≥ 0.1.2-rc.1,破坏性升级) - **B1**:状态聚合改用 rc.1 的 `session.snapshotEvents()` 方法(旧 `session.events` 数组属性已删除;判定逻辑不变) - **B2**:设置卡注册改用 `ctx.settings.installSection(owner, ns, schema, entry, hooks)` 服务方法(旧 `installSettingsSection` 辅助函数已删除;hooks 形状 `{setSource, onChange, validate?}` 兼容);`@deepseek-ai/dsh-settings` 依赖提升至 `^0.1.2-rc.1` - **B3**:`dsh.client.inject` 按 rc.1 包级依赖边语义清理,移除已删除的 `@deepseek-ai/dsh-client-runtime`;客户端只依赖平台种子模块(react / react/jsx-runtime),inject 声明为空并与产物 require 面强校验一致 - 最低 harness 版本:**dsh ≥ 0.1.2-rc.1**(旧 rc.7/rc.8 不再支持) ### ⚠️ 用户可见变化:状态卡片色彩语义切换为 MAM 口径 - **红 = 待审批**、**黄 = 运行中**、**绿 = 完成且未读**(旧版:绿运行 / 黄待批准 / 红报错 / 蓝完成) - 本插件特有的**错误/断联态以深红 + ⚠ 错误标识**呈现,与「待审批」红明确区分 - 卡片点击跳会话 + 已读行为不变;审批语音 10 秒限流、绿卡点击即确认(本地立即消卡) ### Added — 外部宠物体系(MAM v0.3.0 移植) - 磁盘商店 `~/.dsh/foxbell-pet/pets//`(spritesheet.webp + manifest.json + voice//);导入暂存区 `.import-staging/`(插件启动清扫残留,崩溃自愈);manifest 原子写 + 一层 `.bak` 备份 - 清单 v2 格式(schemaVersion/id/displayName/description/source/spriteVersionNumber/spritesheetSizeBytes/hasVoice/hasSubtitle/voices[]);内置 foxbell 包内清单同步升级 v2(`foxbell` 为保留 id);spriteVersionNumber 1=9 行 / 2=11 行图集运行时自适应 - 四来源导入:本地文件夹 / zip 包(宿主安全解压:总量 ≤100MB、文件数 ≤200、条目路径防穿越)/ Codex 宠物目录 `~/.codex/pets/` / Petdex 在线仓库(列表与下载均宿主代理:域名 allowlist、响应大小上限、8s 超时) - 统一导入配置向导:宠物 id 实时校验(字符集/长度/保留字/Windows 保留设备名/查重,前后端双重校验)、显示名与描述、字幕开关、语音分组编辑(并行时长探测;1s < 时长 < 20s 且单文件 ≤10MB;四组齐全判定「有语音」) - 管理对话框:改名(id 同步 manifest 与目录)、编辑显示名/描述、按组增删语音、字幕开关、安全删除(二次确认后移入 `~/.dsh/foxbell-pet/.trash/`,不物理删除)、查看目录路径;编辑激活中宠物沿用闪切保护(暂切 foxbell,保存后切回) - 切换对话框与热切换:卡片式列表(内置 foxbell + 全部外部宠物)→ 激活即时生效(精灵/语音/清单热替换,无需刷新页面) - 激活守卫:激活与每次切换校验完整性(图集缺失/被改动、语音缺失/变动/多余、清单缺失),问题随 /state 快照下发,客户端弹修复对话(更新清单 / 换回 foxbell / 忽略 / 隐藏宠物);宠物本体运行中不弹 - 无语音宠物:音效开关禁用(带提示)、任务完成只播动画不出声;无字幕宠物:不显示字幕气泡 - 右键菜单新增「🔁 切换宠物」子菜单(当前项打勾,点击即热切换)与「📏 大小」三档缩放子菜单 - 设置卡扩展为单卡双分区:「配置」区(既有配置项 + 三档缩放 0.75/1/1.25,作用于精灵/卡片/菜单整体)与「宠物管理」区(当前宠物、切换/导入/管理按钮、Petdex 入口) - 错误码体系对齐 MAM PetError 码表(宿主 49 码 + 客户端本地 8 码),路由错误统一 `{code, params, detail}` JSON,客户端按插件内部 zh/en 字典映射文案、内联呈现于对话框 - 私有路由族扩展:宠物列表/单宠物资产/四来源导入/暂存音频增删/完成取消导入/清单更新/改名/删除/激活切换/Petdex 搜索代理;`/state` 快照新增 `activePet`、`pets[]`、`guard`,`voices` 改为当前激活宠物语音清单(轮询频率维持 1.5s) - vitest 测试套件:状态映射、id/清单校验、清单 diff 与修复计划、导入暂存管线(真实临时目录)、zip 防护、Petdex mock、安全拒绝用例 ### Changed — 构建体系 - 源码重组为 `src/host/`(纯 JS)+ `src/client/`(TSX)双树;引入 esbuild - `npm run build` 产物:`lib/index.js`(ESM 宿主 bundle)+ `lib/client.js`(单文件 iife 包装,react 与 `@deepseek-ai/*` external,React 18 目标,样式 CSS 内联注入) - `npm run validate` 扩展:产物纯度(无残留 import/export)、`dsh.client` 声明与客户端实际依赖一致、路由前缀/设置命名空间/版本号一致性、错误码表两侧一致、内置清单与磁盘素材一致——既有检查全部保留 - 宠物本体以 MAM 为基准重写:动画优先级模型(拖拽 > 瞬时动作 > 任务态 > 环视 > 待机)、拖拽方向动画(150ms 采样窗)、投掷惯性、重力坠落(1400 px/s²)与落地压扁回弹(scaleY 0.55 / 60ms+240ms+补跳 1500ms)、单击挥手/双击语音+可配置动作、环视待机(6s 空闲触发);Tauri 窗口几何改为 WebUI 内 DOM 定位(视口为工作区,位置记忆与边界钳制保留) - Config 新增 `scale`(默认 1)与 `activePetId`(默认 `foxbell`),既有字段与语义不变,旧保存配置自动得默认值 ### Fixed - rc.1 下状态卡片永远无数据(B1 静默失效)、设置卡不出现(B2)、客户端半无法挂载(B3) ## [1.3.0] - 2026-08-18 ### Added - 右键菜单:声音/语音字幕/落地物理开关、双击/黄灯/红灯/蓝灯四场景动作绑定、隐藏、关于 - 四场景动作绑定:双击(dblAction)、待批准黄灯(approvalAction)、报错红灯(errorAction)、完成蓝灯(doneAction),6 种动作可选(跳/挥手/委屈/等待/审查/工作) - 拖拽物理手感:松手重力坠落、水平抛掷惯性、落地压扁回弹(菜单/设置卡片可关「落地物理」) - 设置卡片(dsh rc.7+,settings.plugin.item):与右键菜单读写同一份配置 - 配置持久化:localStorage + settings scope 双后端(~/.dsh/settings.yaml) ### Changed - 移除「完成时喊」与「戳我动作」独立配置(声音开关已覆盖;单击固定挥手,双击走 dblAction) - 静音(muted)只拦截发声,不再拦截动作动画(静音 ≠ 静止) - 「🔊 声音」开关语义修正:开 = 有声(此前 muted 语义反了,显示"开"实际是静音) - 「💬 气泡」改名「💬 语音字幕」,明确为语音字幕显示开关 - 动作子菜单实时预览:进入子页桌宠循环播当前选中动作,点选其它动作即时预览切换,「← 返回」回主菜单后停止 ### Fixed - 拖拽坠落停止后不再瞬移回右下角:落点 x 记忆到 localStorage(`dyn-pet-foxbell-x`),刷新后停在上次落点 ## [1.2.0] - 2026-08-18 ### Added - 语音库按状态分四组放入 `assets/voice/` 子目录:`general`(双击闲聊)、`approval`(待批准,10s 限频)、`error`(任务报错)、`done`(任务完成);文件名即字幕文字。运行中(绿)不发声;空组静默跳过。 - 由用户录制视频产出 31 条儿童语音并随包发布(error 7 / approval 6 / done 7 / general 11),取代原先 4 条通用语音。 ### Changed - `scripts/validate.mjs` 改为校验每个语音组目录存在且非空(原先只校验单个写死文件)。 ## [1.1.2] - 2026-08-16 ### Changed - 所有动画改为 JS 逐帧步进,复刻 Codex V2 契约的逐帧时长(每轮末帧更长停顿),取代统一 CSS `steps()`。动作更舒缓自然。各行动画帧时长:idle 280/110/110/140/140/320、running 120×n+220、waving/jumping 140×n+280、failed 140×7+240、waiting/review 150×5+260/280 ms;look 行保持 16 帧顺时针扫视(250 ms/帧)。 ## [1.1.1] - 2026-08-16 ### Fixed - 修复双击/完成语音的加载延迟:语音列表同步时把每个文件预载进独立 `Audio` 元素,播放即时出声,不再每次现场拉取。字幕时长逻辑不变(仍与预载元素真实时长对齐)。 ## [1.1.0] - 2026-08-16 ### Added - 使用全部 11 行 Codex V2 图集的状态驱动动画: - 拖动方向:左拖向左跑、右拖向右跑、上拖跳起。 - 任务状态:项目报错 → 委屈(failed 行)、完成 → 高兴跳跃、待批准 → 等待姿态、完成未读 → 审查姿态、当前会话运行 → 工作姿态。 - 空闲环顾:look 行 9 → 10 连续 16 帧顺时针扫视一圈。 - 动画状态机(拖拽 > 瞬时事件 > 任务态 > 环顾 > idle),带代数计数器防止过期定时器覆盖新状态。 ## [1.0.0] - 2026-08-16 ### Added - 首个公开版本,作为持久化 DSH web profile 插件。 - DSH Web 右下角可拖拽的 Foxbell 桌宠。 - 多项目状态监控:每个活跃项目一张状态卡片,带状态灯(绿运行 / 黄待批准 / 红报错或断联 / 蓝完成未读)。 - 点项目卡片切换到对应会话并标记已读;完成/报错卡片打开后消失,新事件再次亮起。 - 完成语音提醒:随机 `voice/*.m4a` + 挥手 + 与音频长度对齐的字幕。 - 语音交互:单击只挥手、双击说话+挥手、点卡片只切换(不出声)。 - 侧栏设置图标旁的 🦊 显隐开关,持久化于 localStorage。 - 等宽多行项目卡片(加粗标题 + 状态灯 + 最新运行状态)。 - 素材随包(`assets/`),运行时读取——安装即用。