Repository navigation
Releases
dsh-session-eater v0.14.1
跳到 v0.14.1(仓库里的代码从 0.6.0 一次性更新到 0.14.1,中间 0.7.0 → 0.14.0 的历次改动见 CHANGELOG.md)。
0.14.1
修复:点药丸还是进不了「设置 → 会话喂鱼」。这一版不再猜 DOM,直接调设置面板自己的 store。
-
根因。 设置面板的开合状态(
open/activeId)不是公开 API,是dsh-client-ui-settings-general
自己那个 store 里的状态,而它是挂在槽位注册上的:const shellHandle = createSettingsShellStore(); const shellInstance = shellHandle.create(); const shellStore = { ...shellHandle, create: () => shellInstance }; // 特意 memo 成常量 ctx.slots.register({ name: "sidebar.settings", store: shellStore, children: {…} }, SettingsRoot);
0.14.0 只知道去点 DOM(点侧栏底部的触发器 → 等面板挂载 → 点导航项),
环节多、还要赌懒挂载的时序,用户看到的就是「点了没反应 / 只把设置打开、停在别的分区」。 -
修法(正路)。
SlotCore.entries(key)返回的是原始 entry(不是投影视图),
store就摆在 entry 顶层,所以从插件侧能直接把面板的 store 拿回来:ctx.slots.entries("sidebar.settings")[0].store.create().actions.openSection(NS)
一句
openSection同时展开面板 + 把分区切到我们这一页,不碰 DOM、不等懒挂载。
openPluginSettings()现在先走这条路,命中就返回(openSettingsTrace.step === "store-opened")。 -
DOM 那条路保留为兜底(账本里没有 store 时,或者只有
open()没有openSection()时):visible()改成以el.getClientRects().length > 0为主 —— 渲染器的槽位出口是
display:contents,那种祖先下offsetParent是null,旧写法会把真正的触发器判成不可见。settingsTrigger()在槽位标记缺失时(Windows 侧栏收起时整块footArea都不渲染)
退到[class*='settingsArea']、再退到全文档button[aria-haspopup='dialog']。- 导航项匹配加了关键词兜底(
喂鱼/大白饭/吃会话),只在正式标签会话喂鱼找不到时才用。
-
自检。 控制台
__dshSessionEater.openSettings()现在还会报via(store/dom)、
entries(账本里几条注册)、storeNote(账本那条路为什么没用上:no-ctx/no-api/
no-entry/error)。
0.14.0
这一版按作者的五条复核逐条修:掉图标、点图标不进设置、卡片颜色不协调、拖拽永远是白饭、碗不够大不够高。
- 修复(关键):拖谁都是大白饭。 0.13.0 虽然把三只碗都内联了,但
useRiceModelSrc(id)
是useState(model.url)+useEffect里取图 —— 慢一帧。刷新页面后第一次拖拽时
riceSrcRef.current还是初始值(内联大白饭),于是setDragImage拿到的是白饭;
等 effect 跑完才变成你选的那只。现在内联图同步返回:
if (inline) return model.url;—— 选蛋炒饭,第一次拖就是蛋炒饭。 - 修复:点药丸进不了「会话喂鱼」。 上一版的打开逻辑只轮询
10 × 80ms(0.8 秒),
而设置面板是懒挂载的,面板还没渲染出来就已经放弃。现在:- 触发器从
document.querySelector("[data-slot='sidebar.settings']")(renderer 给每个
槽位出口渲染的稳定锚点)里优先找button[aria-haspopup='dialog'](设置触发器带这个
契约级属性与aria-expanded),再退到button/[class*='trigger']/[role='button']; - 用
requestAnimationFrame逐帧重试,超时 3.6 秒,每过 1 秒补点一次触发器
(只在aria-expanded不是"true"、面板 DOM 也不在场上时才补点 —— 面板开着还点
等于把它关掉); - 「会话喂鱼」导航项只在设置面板这个 dialog(
[data-shortcut-modal='settings'])里找,
面板已经开着时直接点,不走触发器; - 全过程记在
openSettingsTrace里(step/clicks/ms/hasTrigger/hasNav/
expanded/panelOpen,失败终态gave-up),诊断桥多出openSettings()与
tryOpenSettings()两个口子 —— 卡在哪一步,控制台一眼能看到。
- 触发器从
- 修复:卡片颜色和软件不协调。 0.13.0 的卡片写死用
--dsw-alias-bg-module-platform
加一层阴影,浅色主题下是一块偏灰的、和侧栏拼不上的填充。现在运行时采样那一行
自己的底色(sampleSurface(row, slot):从行往上最多 8 层,找第一个不透明的背景,
优先取alpha >= 0.95的实色),写成--dse-surface/--dse-tone,
卡片的底色、描边、hover 全部由它推导(color-mix(in srgb, …)),阴影去掉。
采样不到就退回透明(也就是"跟侧栏长得一样"),不会比原来更难看。 - 修复:容易掉图标。 这条有两个根因,都修了。
- 默认形象指向一条不存在的路由。 「跟随挂件」那一档原来直接用
/dsh-whale/image.png(余额挂件的角色图),但这条路由在本机是 404
(实测GET /dsh-whale/image.png → 404,全盘也没有任何插件注册过它)——
于是每次刷新、每次侧栏重挂,药丸都先加载一次失败、再靠onError换成内置立绘,
中间那一下就是用户看到的"掉图标"。现在先把内置立绘当默认(内联、不可能失败),
同时在后台试加载一次挂件图(useWidgetWhale),确认能用才切过去;
运行时才发现挂掉就撤回结论,不再反复试。探测结论全局只探一次。 - 兜底立绘自己也走宿主路由。 宿主没重启时
API + "/whale.png"也是 404 ——
"想要的源失败 + 兜底也失败 = 头像被摘"。现在whale-fallback.png内联
(WHALE_FALLBACK_DATA,同一个构建脚本生成)。
另外onError从"一次失败就降一级"改成连败计数:连续失败 3 次才收起头像,
中间任何一次成功都清零;图片源一变(换碗、切自定义)计数与"收起"状态一起重置。
- 默认形象指向一条不存在的路由。 「跟随挂件」那一档原来直接用
- 新增:碗更大、更靠上。 默认
rice.size96 → 128,上限 200 → 320。
拖拽时幽灵图的位置从"指针原地"改成"碗浮在指针上方、碗底压着指针":
setDragGhost(true, { x: clientX - size/2, y: clientY - h + 8 })+
setDragImage(ghost, size/2, h * 0.9)—— 拖到会话行上时,碗是对着那一行的。 - 构建流程(内部):
build-rice-models.mjs改成靠显式区域标记定位生成块
(// #region RICE_EXTRA_DATA/// #endregion)。之前靠"找长得像声明的行 + 找收尾的
\t\t};"来切,结果两次把lib/client.js打坏 —— 文件里的 JSDoc 引用了同样的声明
文本、base64 数据行又可能以};开头,切点落进注释里,数据被从中间截断。改标记之后
脚本幂等(--check报"已是最新"),lib/client.js现在约 2.5 MB(三张图 + 兜底立绘全在里面)。
dsh-session-eater v0.6.0
这一版把「吃不了」这件事说清楚了:拖到不能吃的会话时,当场在鱼头上给出红色 + 原因
(以前只有屏幕底部一条容易被漏看的回执,像"点了没反应");删除前那句询问也精简成只问一句,
并把这条会话烧掉多少 token 写进去了。
-
修复:拖"正在聊的这个会话"上来时不再像"点了没反应"。以前只拦在松手那一刻,
而且提示只出现在屏幕底部那条约 6 秒的 toast 上 —— 眼睛盯着左上角的鱼,很容易漏掉。
现在拒绝是就地给出的:- 拖到鱼头上还没松手,投放区就变红、那行字直接写原因(「别喂正在聊的这个会话」),
鱼闭着嘴(不摆出要吃的张嘴样子,"没反应"和"在犹豫"不再分不清); - 松手时整块晃两下、停在红色状态约 1.8 秒,底部再补一条 toast(双通道);
- 判定逻辑收拢成
refusalOf()一处,dragover与drop共用,不再有重复的拦截分支。 - 空白会话走同一套拒绝 UI(同样是红色 + 写明「空白会话不用清理…」+ 闭嘴)。
- 宿主回 409「会话还在跑」也走同一套就地拒绝。以前它落进普通失败分支,弹的是
「没吃下去:该会话正在运行…」,看着像插件出错;其实这条和前两条一样只是"此刻不能吃"。
现在客户端保留宿主给的code(session-running)并路由到同一个refuse():
红色投放区 + 「会话还在跑,先停下来再喂」+ 鱼闭嘴摇头,1.8 秒后自动归位。
可改文案 17 段(新增「会话还在跑」这条)。
- 拖到鱼头上还没松手,投放区就变红、那行字直接写原因(「别喂正在聊的这个会话」),
-
新增:删除前确认会写出这个会话消耗了多少 token,而且只问一句:
「消耗了1.2Mtoken,真的给我吃吗?」—— 不列会话名、不写轮数与缓存命中率
(弹窗正文只有"询问语 + 按钮行"两个元素,最小化打断)。- 确认期间大肥鱼张着嘴不动、脑袋慢慢点、腮红亮着(
data-eager),一副"快给我吃"的
渴望表情;跟悬停时那种咀嚼dse-chew明确区分 —— 这里是静止张开(animation:none)。 - token 数来自内核自己的会话投影缓存(
storages/session_projcache/sessions/<id>.json的
tokenUsage.totals),与界面同源。特意不去解session.v3.jsonl.zstd—— 那是多帧 zstd
(5MB 的会话要解出 19MB 文本、花 300ms),而且里面data.usage是「每轮一条、上下文递增」的,
求和会算出 5 亿这种荒谬值(正确读法是取最后一条,还得自己拼 4 个 bucket)。 - 总量 = 未缓存输入 + 输出 + 缓存读 + 缓存写;读不到时(空白会话 / 投影还没生成)退回
不带数字的「真的给我吃吗?」,不写"未知"。 - 宿主新增
POST /usage(读的是小 JSON,几十毫秒);客户端在 drop 时 await 一次并缓存。 - 可改文案 15 段 → 17 段:新增「确认弹窗标题(带用量)」(里面的
{tokens}会被替换成实际用量)
与「拒绝:会话还在跑」。
- 确认期间大肥鱼张着嘴不动、脑袋慢慢点、腮红亮着(
dsh-session-eater v0.5.0
这一版把"用起来"打磨了一遍:删会话多了一道确认(可在设置里关)、设置页能直达也能折叠、
外观重做了一轮;另外修掉两个"看起来像坏了、其实刷新就好"的真问题。
交互
- 新增:删除前确认。拖上去松手不再直接删,而是在左侧会话列表里弹出
「确定要删除这个会话吗?」并列出会话名 + 删除/取消两个按钮;按Esc或点取消则一个请求都不发。
默认焦点在取消上(回车不会误删)。设置里有 删除前确认 开关(默认开,关掉=回到"松手即删"),
确认框那三段文案(询问语 / 删除 / 取消)也可自定义 —— 可改文案从 12 段增到 15 段。 - 新增:点侧栏药丸(会话框里的图标)直接进「设置 → 会话喂鱼」(键盘 Tab + 回车/空格同样可用),
不用再"点设置 → 找分区"两步;鼠标悬停提示「点击打开会话喂鱼」。 - 移除:侧边栏药丸行右侧那个「撤销最近吃掉的一条」按钮。它读的是 localStorage 台账,
而台账本来就要跨刷新保留 —— 于是刷新/重启后按钮一直挂在那儿,看着像个删不掉的按钮。
撤销只保留两条路:回执上的撤销(内存态,刷新自然消失)+ 设置里的 12 条台账(可持久)。
设置页
- 新增:可折叠区块。「文案」(15 段)和「最近吃掉」(最多 12 条)太长,现在默认收起、
点标题展开,标题右侧给15 段/2 条这样的摘要;收起时正文不渲染(不是藏起来)。
展开状态记在config.ui.open里,刷新后保持。 - 精简:「删除前确认」区块只留功能名 + 开关,去掉说明文字。
- 美化:整体收拾了一遍 ——
- 卡片:圆角 14px、内边距 14/16、柔和描边 + 1px 投影
- 每个区块标题前加 3px 渐变竖条,扫读时一眼分辨分组
- 开关改成胶囊拨杆(原生 checkbox 用
appearance:none重画,a11y 与点击行为不变) - 折叠标题:箭头固定
▸、展开时 CSS 转 90°,摘要做成小胶囊,展开带 180ms 淡入 - 滑块数值改成等宽胶囊;输入框统一 28px 高、聚焦绿色描边;分段控件选中态用品牌绿
- 台账每行加悬停高亮与行间细分隔线;空态改成居中的「🐟 还没有吃掉任何会话」
- 底部「恢复全部默认」用分隔线断开;预览台加极淡棋盘格(能看出自定义图的透明区域)
- 配色全走主题变量(tint 用
label-primary调),浅色主题不会发黑
修复
- 修复:样式自愈。注入的
<style>原本只在apply()时挂一次,而它挂在ctx.effect
的清理函数上 —— 客户端半边热重载时会被摘掉,若那次重载没跑完,页面就一直没样式
(药丸/投放区退回默认块级布局)。现在用MutationObserver盯<head>,样式不在就补一次
(ensureCss幂等,不会死循环)。这个坑是从别人的插件上实测出来的:表情包选择面板因此从
4 列网格 退化成 774×1800 的一列竖排,刷新才好。 - 修复:
/status的version之前写死成0.3.0(包早就到 0.4.x 了),排障时差点把
"宿主其实是新版"误判成"宿主没重载";现在直接读package.json。客户端诊断桥的version
同样写死过,现在改成启动时问一次宿主/status并用 getter 暴露 —— 两半边都不会再漂移。 - 修复:
inject里补上sessions。之前apply()跑得比该服务注册更早,导致"隐藏已吃掉会话"
的过滤器被静默跳过 —— 现象是删掉后切到「单列表」视图,被吃的会话又整排冒回来。
工具与文档
- 新增:
scripts/submit-market.mjs—— 一条命令投 DSH 插件市场(加 topic / 补无版本号 tarball /
fork + 建分支 + 写 yml + 开 PR),带--dry-run与--prepare(先做不受 1 天门槛限制的部分)。 - 新增:
tests/verify-market-entry.mjs—— 投稿前自检,对照市场 CI 规则核 entry/category/引号/tarball。 - 新增:
tests/loop.mjs—— 把咀嚼动画导成循环动图(透明 GIF / 动画 WebP + 透明 PNG 序列),
做视频片头/封面用。 - 新增:
screenshots.json—— 插件市场详情页展示你仓库里的截图。 - 文档:新增「排障:删不掉 / 拖了没反应 / 界面样式裸奔」——先 F5、再打
/status、再查
日志里的duplicate loader entry id;并修掉「本机当前的实际装法」那节的自相矛盾
(既让人抄- insert:到用户 patch 层、又警告别加进 bundles,两边都写会让 loader 直接起不来)。
dsh-session-eater v0.4.1
- 修复:
scripts/*.mjs --dry-run之前会先校验凭据,没有令牌就直接报错 —— 跟"先看看会推哪些文件"这个用途自相矛盾。现在 dry-run 完全离线,不需要任何凭据。 - 文档:新增「不需要令牌的发版路径」(
git tag+ 网页 Draft a new release),并记录 github.com:443 时通时断的实测结论。
Full Changelog: v0.4.1...v0.4.1
dsh-session-eater v0.4.0
- 新增:侧边栏药丸行最右侧的撤销按钮(与图标同一行对齐),一键撤回最近吃掉的一条;
台账为空时不显示,鼠标悬停会说明要撤的是哪条。 - 新增:设置页「最近吃掉」台账(最多 12 条,存浏览器本地),每条可单独撤销 ——
不必再去抓那条几秒就消失的回执。 - 新增:界面文案全部可自定义(12 段),留空即不显示;默认值改为「想吃大白饭 / 啊啊啊」等。
- 修复:「删了之后刷新会话又回来了」。真正的根因是宿主进程里会话对象仍然存活,
新页面拉 baseline 时它被重新塞回客户端列表;「按工作区」视图靠账目过滤看不出来,
但切到**「单列表」视图**就会整排冒回来。现在插件会把台账里的会话从客户端列表里持续摘掉。 - 修复:带撤销的回执不再 4 秒自动消失(改为常驻 + ✕ 关闭)。
- 修复:回执加了宽度上限与不可压缩的按钮,长标题不会再把撤销按钮挤出屏幕。
- 修复:自定义图标不是正方形时,嘴按
object-fit: contain后的实际显示矩形定位,
不再飘到留白上。 - 修复:
inject里补上sessions—— 之前apply()跑得比该服务注册更早,
导致隐藏已吃掉会话的过滤器被静默跳过。