Skip to content

Releases: DSH-PackForge/dsh-pack-plugin

v0.3.5

Choose a tag to compare

@hxh230802 hxh230802 released this 30 Sep 10:09

v0.3.5 合并发布:v0.3.2 / v0.3.3 / v0.3.4 未单独发 Release,此处一并列出(对应 tag 均已在仓库中)。

0.3.5 · 修复:vendored 内嵌把范围声明当版本,上游全被误判「消失」(2026-09-28)

导出 fluent-deepseek-harness-1.0.0.dspack 时,8 个依赖全部被内嵌为 -local.1 且 reason: upstream-missing,但上游全都活着。追查下来是两个正交问题:

1. version 解析 bug(src/core/vendored.js)

listProfileDependencies 把 package.json 里的依赖声明原文直接当版本(version: spec,即 ^2.0.2)。registry 的 tarball / 元数据 URL 不接受 ^:

  • GET /dsh-opencode-palette/^2.0.2 → 404(精确版本 2.0.2 才是 200)
  • …/dsh-opencode-palette-^2.0.2.tgz → 404

于是取件失败 → 回落本地重打包 → 乱加 -local.1。修复:读 node_modules/<pkg>/package.json 的真实安装版本折算(spec 保留原文),取件与「三处一致」都用精确版本。

顺带修了 fetchRegistryTarball 的 URL:DEFAULT_REGISTRY 带尾斜杠再拼 / 产生双斜杠(npm 容忍但部分 registry 会 404),现归一为单斜杠。

2. 删掉「死上游探测」(probeNpmAlive)

auto 档默认会对每个 npm 依赖联网探测上游存活、404 就擅自补选内嵌。这次就是它:探测用带 ^ 的版本必 404 → 8 个包全部误判「上游消失」→ 自动内嵌 + -local.1。与其「替用户检测」翻车,不如不检测:

  • auto 档改为手动勾选 + 已内嵌 round-trip,打包全程不联网;
  • probeNpmAlive 及其 UI 文案(vendor.mode.auto)一并清理;
  • full 档行为不变(全部直接依赖 + 传递闭包)。

新增/调整用例:npm 范围 spec 折算为精确版本(^ 不进 tarball URL)、expandVendorSelection 的 auto 档不再探测。全量 161 通过。


0.3.4 · 修复:悬浮球打开设置后停在别人分区的成因(2026-09-28)

0.3.3 实测(desktop profile 装的就是 0.3.3 的包):点球后设置弹窗打开了,仍停在「费用估算」。

先把根因钉死:SettingsPanel 的当前分区是

const active = rows.find((r) => r.id === activeId)?.id ?? rows[0]?.id;

—— 一旦我们这一节此刻不在 rows 里,shell 会把选择回退到第一行(别的插件 order 更小,占着「费用估算」)。所以「点了我们那一行」并不等于「切过去了」,光看一眼点击事件是不够的。

  • 切分区改成闭环:点 → 下一拍读 shell 的 aria-current(它标的就是当前选中行)→ 不是我们就再点(maxClicks 上限 3 次)→ 2s 内始终不是我们才如实报失败。弹窗已开着的情形也走同一条循环(旧实现那条路径只点一次、不验收)。
  • 旗标握手:球在点官方入口之前先立 window.__dspackWantSection;客户端插件在同一个 MutationObserver 里看到旗标,会在弹窗挂上的第一时间把导航切过去 —— 比球自己轮询更早,而且它认识自己的 label。
  • 标签通道 window.__dspackSectionLabel:球拿不到钩子时也能按文案认行(归一化空白 + 容忍包含关系);导航图标标记仍作最后兜底。
  • 失败要能自证:提示里带上「我看到的导航」,例如
    设置已打开,请在左侧选「整合包」;我看到的导航:通用 / 费用估算 / 整合包,
    同时 console.info 一份诊断;window.__dspackBall.diag() 可拿到完整快照(钩子在不在、标记在不在、我方 label、当前选中行、各行文案)。

顺带确认了一件事:profiles/desktop 是 better-deepseek-harness 的 Junction,里面装的正是 17:49 落地的 0.3.3。若点球时页面没做过硬刷新,跑的还是旧球脚本(旧脚本既没有 2s 重试,也没有失败提示)。

新增 4 个用例(aria-current 验收、点了没落上要再点、下一拍才表态不许重复点、标签通道),全量 160 通过。


0.3.3 · 修复:悬浮球打开设置后停在别人的分区(2026-09-28)

0.3.2 实测现象:点球之后官方设置弹窗正常打开了,但停在「费用估算」那一节。

根因不在「找入口」,而在「切分区」:别的插件注册的 settings.section order 比我们小(我们 order 20),占了导航第一行,而 SettingsRoot 的 activeId 初值就是 rows[0] —— 于是弹窗一开就落在别人的分区上。0.3.2 的切分区实现有两个短板:只认导航图标标记 [data-dspack-nav-icon](由 MutationObserver + label 文本匹配打上,可能晚一两帧、也可能压根没打上),而且只轮询 300ms(6 × 50ms)就放弃。

  • 改为调用客户端插件提供的钩子 window.__dspackFocusSection(settings-nav-icon.js 的 installSectionFocusHook):按当前 locale 的分区标签找到本插件那一行并点击,locale 切换后立刻反映,不再依赖标记时机;导航图标标记仍作兜底。
  • 轮询窗口 300ms → 2s(40 × 50ms),期间持续尝试切到本插件分区。
  • 切不过去也要指路:新增 onFocusFail 回调,球提示「设置已打开:请在左侧选『整合包』」,不把用户晾在别人的分区上。
  • 顺带的防御性加固(不是本次现象的根因):找官方设置入口不再「取第一个 aria-haspopup="dialog" 匹配」——那个属性同类插件的费用气泡(.dsh-cost-pill 等)也有,且 createPortal 到 body,一旦设置触发按钮当时不在 DOM 里就可能点错。改为正向打分:设置区祖先 _settingsArea +5、aria-label 命中设置/偏好/Settings +4、自身类名 _trigger +2、带 aria-haspopup="dialog" +1;命中 cost/usage/billing/pet/whale/meter/stats 特征或身处已开弹窗 → 出局。低于阈值(4)一律不点,返回 no-trigger 并如实提示。另外点完会轮询校验设置弹窗真的出现,没出现就把误点的开关收回去(设置区里的官方入口绝不收回 —— 它 expanded=true 说明弹窗正在开,可能只是慢)。

新增 11 个用例(切分区钩子优先、慢弹窗、切不过去的指路回调、打分边界、费用气泡与设置入口并列时的回归等),全量 154 通过。


0.3.2 · 悬浮球:绕开侧边栏 / 设置页的独立入口(2026-09-28)

整合包会装进各种 client 插件,有的会把侧边栏或设置页搞坏 —— 那时用户进不去「整合包」设置界面,连换包、卸载都做不到。新增一个悬浮球,由宿主注入 index.html(不经过任何前端插件,别人把 UI 拆了它还在),点击直接打开原来的设置页并切到本插件分区。

  • 不另造页面:官方设置界面本身就是完整弹窗,诉求是「进不去」而不是「没有这个页面」。SettingsRoot(dsh-client-ui-settings-general)的开合是组件内部 state、官方无对外 API(ctx.remote.settings.openSettingsDocument() 是「在本地打开设置文档」,不是打开这个弹窗),唯一的路是点它注册到 settings.trigger 的按钮 —— 好在属性是语义化的 button[aria-haspopup="dialog"][aria-expanded](无构建哈希类名),而合成 click() 不要求元素可见:侧边栏被主题藏起来、被挤扁、变轨道态,只要弹窗组件还挂着就点得动。点开后再把导航切到本插件分区(认 data-dspack-nav-icon 标记,不依赖中英文文案)。
  • 注入两条通道:webserver/index-inject 结构化行(桌面壳 index.html 从静态 dist 直出、函数变换过不去,这是桌面端唯一生效通道)+ webServer.tapIndex(web 形态兜底),靠路径标记互相去重。行内容用内联 script 而非 script-src 行:官方页面解释器对两类行处理不对称 —— 内联那条是 createElement + textContent + append、没有 await,不可能「加载失败」;script-src 那条会 await loadScript(src),失败即 reject 成致命错误把整个页面带下水。内联 loader 自己建 <script src> 并吞掉 onerror:路由在就有球,不在也只是没球。
  • 球体行为:position:fixed 自建 DOM、纯尺寸驱动(不量 DOM → 无测量竞态);document 级 pointer 拖拽(down 挂、up/cancel 摘)+ 3px 点击阈值;松手按四分之一区域吸附、横纵轴独立(可组合出四角);位置只存「吸附边 + 离边偏移」,resize 后仍贴边、脏数据夹回可视区(对应「启动闪一下 → 滑出屏幕 → 消失」那类坑);贴左整体镜像、图标反向镜像保持可读;关键样式 !important 顶回宿主皮肤按几何特征(position:fixed + 高 z-index)的拦截;touch-action:none 让移动端可拖。
  • 资源路由:GET /dsh-pack/ball.js(cache-control: no-store)复用既有 /dsh-pack prefix 路由,不新增路由以免撞重复路径检查;缺 lib/ball.js 时回 404 而非抛错。
  • 第二道保险:客户端插件也调一次 mountBall()(window.__dspackBall 幂等守卫,不会挂出两个球)。window.__dspackBall 暴露 openSettings() / setAction(fn) / showTip() / settle() / destroy(),要接别的动作直接换。
  • 已知边界(不粉饰):若坏插件让侧边栏那棵 slot 子树整个崩掉(React 抛错),设置弹窗与触发按钮一起不存在,此时谁也开不了官方设置页 —— 球会如实提示「没找到官方设置入口」,不假装成功。那种场景需要的是急救(禁用坏插件)或自建面板。

新增测试 21 个(几何 / 锚点往返 / 脏数据钳制 / 注入行去重 / 资源下发分支 / 幂等挂载 / 官方设置入口识别与打开时序),全量 149 通过。


v0.3.1

Choose a tag to compare

@hxh230802 hxh230802 released this 27 Sep 14:29

v0.3.1 是 v0.3.x 首个对外发布版(v0.3.0 未单独发布,此处合并 0.3.0 + 0.3.1 改动)。

适配 DSH 最新协议:manifest v5 r2 / pack-structure v3 r2

本版本核心是接入 DSH 打包协议第 2 版(r2),导入 / 导出 / 市场三侧全量落地。

导入侧

  • vendored 阶段 0 预检:装前对账 + 逐 tarball 校验 sha256 / size,不合规直接拒装
  • 统一安装算法:vendor-blobs 落盘 + package.json file: 改写 + --prefer-offline(闭包完整自动 --offline)
  • DSHL vendor 隐式条目消费
  • dshVersions 交集决策(dshVersion 优先 → 集合内最新)
  • launchers 判定表(v3 §8.4 六行,警告放行不硬拒并留痕)

导出侧

  • 依赖清单端点 + 面板手动勾选内嵌(round-trip / registry 原件 / 本地重打包三处一致)
  • vendor 档位 auto / off / full;full 沿 lockfile 收齐传递闭包
  • dshVersions / launchers 兼容性编辑(.dshpkcfg 持久化 + 打包前强校验)
  • 体积阈值(>500MB 警告 / >2GiB 拒绝)

市场与注册表

  • pack / market-detail 懒加载 + r2 徽标
  • launchers/registry 机器可读注册表(1h 缓存 + 内置回落)
  • 安装前 launchers 警告确认弹窗

技能提供器 + sendToChat

新增技能提供器(skill provider),把本项目技能(如「上传到 GitHub」)注册进 DSH;配套 sendToChat——新建会话 → 切换视图 → 经 session scope 直接发 prompt 进聊天栏。

宿主自包含 bundle + 健壮性修复

  • 宿主入口切 lib/host.js:esbuild 内联 fflate / proxy-agent 等,迁装不再依赖顶层 node_modules
  • 修复切换 profile 后 failed to import(依赖清单漏更)与自动重启失效(migrate-helper / progress 资源随打包产出)
  • 修复热重载后「整合包」设置入口消失(locale 重复注册安全忽略 + section-gate 幂等闸门)
  • 新增设置页导航图标(folder-zip logo)
  • skills 读 SKILL.md 容错、安装源路径去引号、sessions.create 返回形状修正

完整说明见仓库 release_log/v0.3.0.md 与 release_log/v0.3.1.md。

v0.2.0

Choose a tag to compare

@hxh230802 hxh230802 released this 27 Sep 07:55

安装依赖复用 DSH 自带运行时(2026-09-27)

安装 .dspack 不再要求用户装 node/pnpm,复用 DSH 自带运行时;失败回退 PATH,代理配置两条路径一致生效。

下载支持代理(2026-09-27)

市场包下载支持代理,解析顺序:显式配置 → 环境变量(HTTP_PROXY/HTTPS_PROXY/ALL_PROXY/NO_PROXY)→ Windows 系统代理(WinINET 注册表,含 ProxyOverride 绕过)→ 直连。设置页「网络」三按钮切换:自动 / 直连 / 手动(填代理地址),配置持久化到 dsh-packforge.json。

安装日志标注代理来源(2026-09-27)

安装 .dspack 的日志首行写明本次走哪个代理:手动配置 / 环境变量 / 系统代理 / 直连(未检测到代理或用户已禁用),便于定位网络问题。

已安装整合包忽略 node_modules(2026-09-27)

「已安装的整合包」列表不再把 node_modules(以及 __temp__、点目录)当成整合包,与 profile 发现逻辑复用同一套跳过规则。

切换默认拉取最新管理器(次之复制)(2026-09-27)

切换 profile 迁装管理器默认从 NPM 拉取最新版,失败(未发布 / 网络不通)时次之回退从当前 profile 复制;确认弹窗安装方式顺序同步为「拉取最新 → 复制」。