# 更新日志 本文件记录本项目的所有重要变更。 ## [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/`),运行时读取——安装即用。