Skip to content

Releases

dsh-session-eater v0.14.1

Choose a tag to compare

@mikugui mikugui released this 07 Oct 14:06

跳到 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, …)),阴影去掉。
    采样不到就退回透明(也就是"跟侧栏长得一样"),不会比原来更难看。
  • 修复:容易掉图标。 这条有两个根因,都修了。
    1. 默认形象指向一条不存在的路由。 「跟随挂件」那一档原来直接用
      /dsh-whale/image.png(余额挂件的角色图),但这条路由在本机是 404
      (实测 GET /dsh-whale/image.png → 404,全盘也没有任何插件注册过它)——
      于是每次刷新、每次侧栏重挂,药丸都先加载一次失败、再靠 onError 换成内置立绘,
      中间那一下就是用户看到的"掉图标"。现在先把内置立绘当默认(内联、不可能失败),
      同时在后台试加载一次挂件图(useWidgetWhale),确认能用才切过去;
      运行时才发现挂掉就撤回结论,不再反复试。探测结论全局只探一次。
    2. 兜底立绘自己也走宿主路由。 宿主没重启时 API + "/whale.png" 也是 404 ——
      "想要的源失败 + 兜底也失败 = 头像被摘"。现在 whale-fallback.png 内联
      (WHALE_FALLBACK_DATA,同一个构建脚本生成)。
      另外 onError 从"一次失败就降一级"改成连败计数:连续失败 3 次才收起头像,
      中间任何一次成功都清零;图片源一变(换碗、切自定义)计数与"收起"状态一起重置。
  • 新增:碗更大、更靠上。 默认 rice.size 96 → 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

Choose a tag to compare

@mikugui mikugui released this 22 Sep 16:40

这一版把「吃不了」这件事说清楚了:拖到不能吃的会话时,当场在鱼头上给出红色 + 原因
(以前只有屏幕底部一条容易被漏看的回执,像"点了没反应");删除前那句询问也精简成只问一句,
并把这条会话烧掉多少 token 写进去了。

  • 修复:拖"正在聊的这个会话"上来时不再像"点了没反应"。以前只拦在松手那一刻,
    而且提示只出现在屏幕底部那条约 6 秒的 toast 上 —— 眼睛盯着左上角的鱼,很容易漏掉。
    现在拒绝是就地给出的:

    • 拖到鱼头上还没松手,投放区就变红、那行字直接写原因(「别喂正在聊的这个会话」),
      鱼闭着嘴(不摆出要吃的张嘴样子,"没反应"和"在犹豫"不再分不清);
    • 松手时整块晃两下、停在红色状态约 1.8 秒,底部再补一条 toast(双通道);
    • 判定逻辑收拢成 refusalOf() 一处,dragover 与 drop 共用,不再有重复的拦截分支。
    • 空白会话走同一套拒绝 UI(同样是红色 + 写明「空白会话不用清理…」+ 闭嘴)。
    • 宿主回 409「会话还在跑」也走同一套就地拒绝。以前它落进普通失败分支,弹的是
      「没吃下去:该会话正在运行…」,看着像插件出错;其实这条和前两条一样只是"此刻不能吃"。
      现在客户端保留宿主给的 code(session-running)并路由到同一个 refuse():
      红色投放区 + 「会话还在跑,先停下来再喂」+ 鱼闭嘴摇头,1.8 秒后自动归位。
      可改文案 17 段(新增「会话还在跑」这条)。
  • 新增:删除前确认会写出这个会话消耗了多少 token,而且只问一句:
    「消耗了 1.2M token,真的给我吃吗?」—— 不列会话名、不写轮数与缓存命中率
    (弹窗正文只有"询问语 + 按钮行"两个元素,最小化打断)。

    • 确认期间大肥鱼张着嘴不动、脑袋慢慢点、腮红亮着(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

Choose a tag to compare

@mikugui mikugui released this 21 Sep 16:43

这一版把"用起来"打磨了一遍:删会话多了一道确认(可在设置里关)、设置页能直达也能折叠、
外观重做了一轮;另外修掉两个"看起来像坏了、其实刷新就好"的真问题。

交互

  • 新增:删除前确认。拖上去松手不再直接删,而是在左侧会话列表里弹出
    「确定要删除这个会话吗?」并列出会话名 + 删除/取消两个按钮;按 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

Choose a tag to compare

@mikugui mikugui released this 20 Sep 10:03
  • 修复: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

Choose a tag to compare

@mikugui mikugui released this 20 Sep 09:34
  • 新增:侧边栏药丸行最右侧的撤销按钮(与图标同一行对齐),一键撤回最近吃掉的一条;
    台账为空时不显示,鼠标悬停会说明要撤的是哪条。
  • 新增:设置页「最近吃掉」台账(最多 12 条,存浏览器本地),每条可单独撤销 ——
    不必再去抓那条几秒就消失的回执。
  • 新增:界面文案全部可自定义(12 段),留空即不显示;默认值改为「想吃大白饭 / 啊啊啊」等。
  • 修复:「删了之后刷新会话又回来了」。真正的根因是宿主进程里会话对象仍然存活,
    新页面拉 baseline 时它被重新塞回客户端列表;「按工作区」视图靠账目过滤看不出来,
    但切到**「单列表」视图**就会整排冒回来。现在插件会把台账里的会话从客户端列表里持续摘掉。
  • 修复:带撤销的回执不再 4 秒自动消失(改为常驻 + ✕ 关闭)。
  • 修复:回执加了宽度上限与不可压缩的按钮,长标题不会再把撤销按钮挤出屏幕。
  • 修复:自定义图标不是正方形时,嘴按 object-fit: contain 后的实际显示矩形定位,
    不再飘到留白上。
  • 修复:inject 里补上 sessions —— 之前 apply() 跑得比该服务注册更早,
    导致隐藏已吃掉会话的过滤器被静默跳过。