dsh-skill-picker 0.5.19 → 0.5.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -141,7 +141,9 @@ source.onPick = (args) => { track(args?.candidate?.name); return onPick.call(sou
141
141
 
142
142
  ## 更新日志
143
143
 
144
- - **v0.5.18**:**修掉 v0.5.17 里"预热走错了路"的 bug** —— 上一版已经把胜负手找对了(技能组要 **0 个 `await`** 才抢得到高亮),但它预热时调的是**官方 `source.warm()`**:`warm()` 只预热**官方模块自己的**缓存,**插件自己的 `itemCache` 依然是空的** → 菜单打开那次**仍然未命中**、仍然 `await` 官方、仍然比命令组多一跳、**仍然输**。这一条是从你机器上读到的运行诊断里确认的:`{"mode":"runtime","installed":true,"took":"candidates+order+onPick"}` 与 `{"servedFromCache":false,"sessionId":"session-de1f2494-…","primed":true,"count":71}` —— 即"接管装上了、缓存也被填过,但菜单那次仍是 `servedFromCache:false`"。**修法**:预热改为**走插件自己的包装路径**(一次空查询 `candidates`),**一次调用同时填满两层**(包装层写快照 + 官方层自然预热)。另:缓存**热重载后不再被清空**,所以重载后的第一次打开也是命中。**回归测试**:新增一条直击要害的用例 —— 官方取数故意慢 60ms,预热后菜单调用**必须在 30ms 内返回**;另把"预热走官方 `warm()`"这条反例锁死(断言**不会**只调 `warm()`)。全量 `npm test`:**65 tests / 64 pass / 0 fail**
144
+ - **v0.5.20**:**`/` 菜单的空查询也走排序,「置顶」技能排到最前面(与 ⚡ 面板一致)**——国豪指出:按 ⚡ 按钮时列表是「📌 置顶(3)」在前、再「📁 全部(57)」,但直接打 `/` 出来的却**是纯字母序、置顶不在前面**,两边排序不一样。**根因**:包装层对**空查询**做了短路 —— `if (query === '') return cached` / `if (query === '' || ...) return everything`,即"空查询把官方列表原封不动返回"。而 ⚡ 面板走的是 `rankPickerItems(items, '')`,它会先 `groupByPinned(...)` 把置顶提到最前。**于是同一个数据源、两套排序。** **修法**:去掉空查询短路,**空查询也交给 `rank()`** —— `rankPickerItems(items, '')` 本就设计为"空查询 = 全部条目、按面板顺序(置顶优先)",所以两边从此同源同序。**顺带发现一条假通过的测试**:旧的 `an empty query returns the official result untouched` 里 `rank` 是**故意抛错**的,而 `rank` 一抛错就被包装层的 try/catch 兜住、仍然返回官方列表 —— 也就是说那条测试**测的是兜底路径,不是它声称的语义**,所以它在新行为下照样"通过"。已改写为正面断言:空查询**必须**调用 `rank`,且置顶技能排第一。全量 `npm test`:**65 tests / 64 pass / 0 fail**
145
+ - **v0.5.19**:**修掉 v0.5.17 里"预热走错了路"的 bug**(0.5.18 因 npm 发布延迟被误判为"卡住",实际已发布;两者代码逐字节相同)—— 上一版已经把胜负手找对了(技能组要 **0 个 `await`** 才抢得到高亮),但它预热时调的是**官方 `source.warm()`**:`warm()` 只预热**官方模块自己的**缓存,**插件自己的 `itemCache` 依然是空的** → 菜单打开那次**仍然未命中**、仍然 `await` 官方、仍然比命令组多一跳、**仍然输**。这一条是从运行诊断里确认的:`{"mode":"runtime","installed":true,"took":"candidates+order+onPick"}` 与 `{"servedFromCache":false,"sessionId":"session-de1f2494-…","primed":true,"count":71}` —— 即"接管装上了、缓存也被填过,但菜单那次仍是 `servedFromCache:false`"。**修法**:预热改为**走插件自己的包装路径**(一次空查询 `candidates`),**一次调用同时填满两层**(包装层写快照 + 官方层自然预热)。另:缓存**热重载后不再被清空**,所以重载后的第一次打开也是命中。**桌面端已实测确认修好**。**回归测试**:新增一条直击要害的用例 —— 官方取数故意慢 60ms,预热后菜单调用**必须在 30ms 内返回**;另把"预热走官方 `warm()`"这条反例锁死(断言**不会**只调 `warm()`)。全量 `npm test`:**65 tests / 64 pass / 0 fail**
146
+ - **v0.5.18**(**从未发布到 npm**):修复内容与 0.5.19 完全相同,但版本号因 npm 暂存槽位冲突(`E409 Cannot publish over previously staged version`)无法发布,改用 0.5.19。**教训:npm 上"已 staging"的版本号会被占住且 `npm stage list` 看不到,直接换号最快。**
145
147
  - **v0.5.17**:**修复「打 `/` 时菜单开到下面去、高亮不在第一条技能」**——症状是输入一个 `/`,菜单**滚到底部**、高亮停在命令组(`添加 / 文件` 或 `指令 / compact`)上,而不是停在最上面第一条技能。**根因**:官方斜杠菜单的高亮是一条「**谁先就绪谁拿高亮、拿到就粘住**」的规则 —— `highlight = validHighlight(旧高亮, groups) ?? firstHighlight(groups)`,`firstHighlight` 取的是**第一个「已就绪」分组**的第一条;随后 `scrollIntoView({ block: "nearest" })` 把高亮滚进视野。本插件为了让技能组排在最上面把它的 `order` 从 2 改成 `-1`,于是**命令组一旦先就绪,高亮就落在它身上、而它现在被压在技能组下面** → 菜单往下滚去够高亮。**关键:这是 microtask 跳数的比赛,不是网络快慢** —— 「已就绪的 promise」`await` 一次就是一个 microtask;实测三种写法的胜负(技能组在 roster 里排第一,命令源至少一层 `await`):| 写法 | 先就绪 |
146
148
  |---|---|
147
149
  | 包装层 `await` 官方 candidates(2 跳) | 命令组 ❌ |
package/lib/client.js CHANGED
@@ -25890,7 +25890,6 @@ function wrapSkillSource(source, hooks = {}) {
25890
25890
  if (cached !== void 0) {
25891
25891
  noteDiag({ mode: "runtime", servedFromCache: true, sessionId: cacheKey, query });
25892
25892
  refreshCache(cacheKey, original.candidates, this, projection, options);
25893
- if (query === "") return cached;
25894
25893
  try {
25895
25894
  return rank(cached, query);
25896
25895
  } catch {
@@ -25902,7 +25901,7 @@ function wrapSkillSource(source, hooks = {}) {
25902
25901
  itemCache.set(cacheKey, everything.slice());
25903
25902
  noteDiag({ mode: "runtime", servedFromCache: false, sessionId: cacheKey, primed: true, count: everything.length });
25904
25903
  }
25905
- if (query === "" || !Array.isArray(everything)) return everything;
25904
+ if (!Array.isArray(everything)) return everything;
25906
25905
  try {
25907
25906
  return rank(everything, query);
25908
25907
  } catch {