dsh-skill-picker 0.5.6 → 0.5.7
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 +2 -1
- package/lib/client.js +15 -5
- package/lib/client.js.map +2 -2
- package/package.json +68 -68
- package/src/client/index.jsx +37 -12
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ DSH Web GUI 的技能选择器:在输入框(composer)工具行右侧加一
|
|
|
26
26
|
|
|
27
27
|
English: A skill picker for the DSH Web GUI — a button in the composer's right tool row opens a searchable list of installed skills; picking one inserts the official `/skill-name` gesture into the draft, so DSH's native user-invocation path loads the skill with your message.
|
|
28
28
|
|
|
29
|
-
当前版本:**v0.5.
|
|
29
|
+
当前版本:**v0.5.7**(⚡ 面板**置顶分组** + `/` 补全**自动增强补丁** + 拼音搜索 + **搜索结果按匹配相关度排序**)
|
|
30
30
|
|
|
31
31
|
## 为什么用它(vs 官方 `/` 补全)
|
|
32
32
|
|
|
@@ -124,6 +124,7 @@ DSH 的 [dsh-tool-skill](https://github.com/deepseek-ai/deepseek-harness) 在 `a
|
|
|
124
124
|
|
|
125
125
|
## 更新日志
|
|
126
126
|
|
|
127
|
+
- **v0.5.7**:**搜索结果按匹配相关度排序**——⚡ 面板与 `/` 补全统一:名字开头匹配 > 名字包含 > 描述 > 拼音,置顶/最近使用只做同级次序;同时过滤掉纯粹"字母分散"的子序列噪音(如搜 `svg` 不再混入 deepseek/openviking 等恰好含 s-v-g 分散字母的技能)。`svg` → svg-diagram 稳居第一
|
|
127
128
|
- **v0.5.6**:**AI 安装指引升级为「GitHub 直装优先」**——快速安装部分改为给 AI/安装助手的优先级决策树:①要最新版/不确定 → `git+ssh` GitHub 直装(git 依赖拉最新 commit,**天然绕过 npm 24h 门禁,百分百新版**);②要 npm 正式版 → 先 `npm view` 查版本再指定 `@版本` 安装;③**禁止裸名安装**(24h 内会落回旧版)
|
|
128
129
|
- **v0.5.5**:**安装指引升级(AI 友好)**——README 快速安装改为「先 `npm view dsh-skill-picker version` 查版本号 → 再 `add dsh-skill-picker@版本号` 指定安装」,并给 AI/安装助手显式提示:新版本发布后 **24 小时内裸名安装会被 minimumReleaseAge 门禁拦截并自动落回旧版**,必须指定版本号才能装到最新
|
|
129
130
|
- **v0.5.4**:**斜杠选技能后 ⚡ 面板同步变「最近使用」**——修复双列表状态不同步:斜杠路径的 usage 记录此前只写 localStorage、面板组件不会刷新(React state 挂载后不再重读),现在 trackPick 写入后会广播 `usage-updated` 事件,⚡ 面板实时重读;面板每次打开时也强制刷新 usage。两条路径的选择现在**双向同步**
|
package/lib/client.js
CHANGED
|
@@ -25852,6 +25852,16 @@ function skillPinyinText(name, description = "") {
|
|
|
25852
25852
|
pinyinCache.set(key, text);
|
|
25853
25853
|
return text;
|
|
25854
25854
|
}
|
|
25855
|
+
function matchRank(skill, q) {
|
|
25856
|
+
const name = skill.name.toLowerCase();
|
|
25857
|
+
const desc = String(skill.description ?? "").toLowerCase();
|
|
25858
|
+
const py = skillPinyinText(skill.name, skill.description ?? "").toLowerCase();
|
|
25859
|
+
if (name.startsWith(q)) return 0;
|
|
25860
|
+
if (name.includes(q)) return 1;
|
|
25861
|
+
if (desc.includes(q)) return 2;
|
|
25862
|
+
if (py.includes(q)) return 3;
|
|
25863
|
+
return 4;
|
|
25864
|
+
}
|
|
25855
25865
|
var buttonStyle = {
|
|
25856
25866
|
display: "inline-flex",
|
|
25857
25867
|
alignItems: "center",
|
|
@@ -26059,11 +26069,11 @@ function SkillPickerButton(props) {
|
|
|
26059
26069
|
}, [open]);
|
|
26060
26070
|
const groups = groupByPinned(skills ?? [], usage, pinned);
|
|
26061
26071
|
const flat = groups.flatMap((group) => group.items);
|
|
26062
|
-
const filtered =
|
|
26072
|
+
const filtered = (() => {
|
|
26063
26073
|
const q = query.trim().toLowerCase();
|
|
26064
|
-
if (q === "") return
|
|
26065
|
-
return
|
|
26066
|
-
})
|
|
26074
|
+
if (q === "") return flat.slice(0, 60);
|
|
26075
|
+
return flat.map((skill, index) => ({ skill, index, score: matchRank(skill, q) })).filter((x) => x.score < 4).sort((a, b) => a.score - b.score || a.index - b.index).slice(0, 60).map((x) => x.skill);
|
|
26076
|
+
})();
|
|
26067
26077
|
const showTitles = query.trim() === "" && groups.length > 1;
|
|
26068
26078
|
const filteredNames = new Set(filtered.map((skill) => skill.name));
|
|
26069
26079
|
(0, import_react.useEffect)(() => {
|
|
@@ -26268,7 +26278,7 @@ function apply(ctx) {
|
|
|
26268
26278
|
limit: 30,
|
|
26269
26279
|
threshold: -1e4
|
|
26270
26280
|
});
|
|
26271
|
-
return results.filter((r) => r.score > 0).map((r) => r.obj.s).sort((a, b) => (rankByName.get(a.name) ?? 0) - (rankByName.get(b.name) ?? 0));
|
|
26281
|
+
return results.filter((r) => r.score > 0).map((r) => r.obj.s).filter((s) => matchRank(s, q) < 4).sort((a, b) => matchRank(a, q) - matchRank(b, q) || (rankByName.get(a.name) ?? 0) - (rankByName.get(b.name) ?? 0));
|
|
26272
26282
|
};
|
|
26273
26283
|
window.__dshSkillPickerFuzzy = fuzzyMatch;
|
|
26274
26284
|
const trackPick = (name) => {
|