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/package.json CHANGED
@@ -1,68 +1,68 @@
1
- {
2
- "name": "dsh-skill-picker",
3
- "description": "DSH Web GUI skill picker: a button beside the composer opens a searchable list of installed skills; picking one inserts the official `/skill-name` gesture into the input box, so the skill loads with your message (WorkBuddy-style skill invocation for DeepSeek Harness).",
4
- "version": "0.5.6",
5
- "type": "module",
6
- "main": "lib/index.js",
7
- "exports": {
8
- ".": "./lib/index.js",
9
- "./client": "./lib/client.js",
10
- "./package.json": "./package.json"
11
- },
12
- "scripts": {
13
- "build": "node build.mjs"
14
- },
15
- "devDependencies": {
16
- "esbuild": "^0.25.0",
17
- "fuzzysort": "^4.0.2"
18
- },
19
- "dsh": {
20
- "bundle": {
21
- "patch": "./cordis.patch.yml"
22
- },
23
- "client": {
24
- "inject": [
25
- "@deepseek-ai/dsh-client-runtime",
26
- "@deepseek-ai/dsh-client-locale"
27
- ],
28
- "platform": "web"
29
- },
30
- "compatibility": {
31
- "dshReleases": {
32
- "0.1.1-rc.1": "unknown",
33
- "0.1.1-rc.2": "compatible",
34
- "0.1.2-alpha.2": "compatible",
35
- "0.1.2-alpha.3": "compatible",
36
- "0.1.2-alpha.4": "compatible",
37
- "0.1.2-alpha.5": "compatible"
38
- }
39
- }
40
- },
41
- "engines": {
42
- "node": "\u003e=22"
43
- },
44
- "peerDependencies": {
45
- "@deepseek-ai/cordis": "^4.0.1",
46
- "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6",
47
- "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
48
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
49
- "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
50
- "@deepseek-ai/dsh-skill": "^0.1.0-rc.6",
51
- "@deepseek-ai/dsh-system-prompt": "^0.1.0-rc.6",
52
- "react": "^18.2.0"
53
- },
54
- "files": [
55
- "lib",
56
- "src",
57
- "cordis.patch.yml",
58
- "README.md"
59
- ],
60
- "license": "MIT",
61
- "repository": {
62
- "type": "git",
63
- "url": "https://github.com/a735624258/dsh-skill-picker.git"
64
- },
65
- "dependencies": {
66
- "pinyin-pro": "^3.29.3"
67
- }
68
- }
1
+ {
2
+ "name": "dsh-skill-picker",
3
+ "description": "DSH Web GUI skill picker: a button beside the composer opens a searchable list of installed skills; picking one inserts the official `/skill-name` gesture into the input box, so the skill loads with your message (WorkBuddy-style skill invocation for DeepSeek Harness).",
4
+ "version": "0.5.7",
5
+ "type": "module",
6
+ "main": "lib/index.js",
7
+ "exports": {
8
+ ".": "./lib/index.js",
9
+ "./client": "./lib/client.js",
10
+ "./package.json": "./package.json"
11
+ },
12
+ "scripts": {
13
+ "build": "node build.mjs"
14
+ },
15
+ "devDependencies": {
16
+ "esbuild": "^0.25.0",
17
+ "fuzzysort": "^4.0.2"
18
+ },
19
+ "dsh": {
20
+ "bundle": {
21
+ "patch": "./cordis.patch.yml"
22
+ },
23
+ "client": {
24
+ "inject": [
25
+ "@deepseek-ai/dsh-client-runtime",
26
+ "@deepseek-ai/dsh-client-locale"
27
+ ],
28
+ "platform": "web"
29
+ },
30
+ "compatibility": {
31
+ "dshReleases": {
32
+ "0.1.1-rc.1": "unknown",
33
+ "0.1.1-rc.2": "compatible",
34
+ "0.1.2-alpha.2": "compatible",
35
+ "0.1.2-alpha.3": "compatible",
36
+ "0.1.2-alpha.4": "compatible",
37
+ "0.1.2-alpha.5": "compatible"
38
+ }
39
+ }
40
+ },
41
+ "engines": {
42
+ "node": ">=22"
43
+ },
44
+ "peerDependencies": {
45
+ "@deepseek-ai/cordis": "^4.0.1",
46
+ "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6",
47
+ "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
48
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
49
+ "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
50
+ "@deepseek-ai/dsh-skill": "^0.1.0-rc.6",
51
+ "@deepseek-ai/dsh-system-prompt": "^0.1.0-rc.6",
52
+ "react": "^18.2.0"
53
+ },
54
+ "files": [
55
+ "lib",
56
+ "src",
57
+ "cordis.patch.yml",
58
+ "README.md"
59
+ ],
60
+ "license": "MIT",
61
+ "repository": {
62
+ "type": "git",
63
+ "url": "https://github.com/a735624258/dsh-skill-picker.git"
64
+ },
65
+ "dependencies": {
66
+ "pinyin-pro": "^3.29.3"
67
+ }
68
+ }
@@ -145,6 +145,25 @@ function skillPinyinText(name, description = '') {
145
145
  return text
146
146
  }
147
147
 
148
+ /**
149
+ * Search relevance rank for the ⚡ panel (and any exact-match filtering):
150
+ * 0 = name starts with the query, 1 = name contains it, 2 = description
151
+ * contains it, 3 = pinyin text contains it, 4 = no match (filtered out).
152
+ * Lower is more relevant; the panel keeps the pinned/usage order as the
153
+ * tiebreak within the same rank, so a name-exact skill like svg-diagram
154
+ * surfaces above merely-used-but-vaguely-matching ones.
155
+ */
156
+ function matchRank(skill, q) {
157
+ const name = skill.name.toLowerCase()
158
+ const desc = String(skill.description ?? '').toLowerCase()
159
+ const py = skillPinyinText(skill.name, skill.description ?? '').toLowerCase()
160
+ if (name.startsWith(q)) return 0
161
+ if (name.includes(q)) return 1
162
+ if (desc.includes(q)) return 2
163
+ if (py.includes(q)) return 3
164
+ return 4
165
+ }
166
+
148
167
  /** Row height matches the resident chrome (access mode, plan, attach, model). */
149
168
  const buttonStyle = {
150
169
  display: 'inline-flex',
@@ -403,17 +422,16 @@ function SkillPickerButton(props) {
403
422
  const groups = groupByPinned(skills ?? [], usage, pinned)
404
423
  const flat = groups.flatMap((group) => group.items)
405
424
 
406
- const filtered = flat
407
- .filter((skill) => {
408
- const q = query.trim().toLowerCase()
409
- if (q === '') return true
410
- return (
411
- skill.name.toLowerCase().includes(q) ||
412
- String(skill.description ?? '').toLowerCase().includes(q) ||
413
- skillPinyinText(skill.name, skill.description ?? '').toLowerCase().includes(q)
414
- )
415
- })
416
- .slice(0, 60)
425
+ const filtered = (() => {
426
+ const q = query.trim().toLowerCase()
427
+ if (q === '') return flat.slice(0, 60)
428
+ return flat
429
+ .map((skill, index) => ({ skill, index, score: matchRank(skill, q) }))
430
+ .filter((x) => x.score < 4)
431
+ .sort((a, b) => a.score - b.score || a.index - b.index)
432
+ .slice(0, 60)
433
+ .map((x) => x.skill)
434
+ })()
417
435
 
418
436
  // Group titles show only while browsing (no query); searching collapses the
419
437
  // list into one flat, pinned-first result set.
@@ -662,10 +680,17 @@ export function apply(ctx) {
662
680
  limit: 30,
663
681
  threshold: -10000,
664
682
  })
683
+ // Relevance first (name-startsWith > name-contains > description >
684
+ // pinyin), then the ⚡ panel's pinned/usage order as the tiebreak —
685
+ // the shared rule with the bolt panel, so a name-exact skill like
686
+ // svg-diagram for "svg" surfaces above merely-recently-used ones.
665
687
  return results
666
688
  .filter((r) => r.score > 0)
667
689
  .map((r) => r.obj.s)
668
- .sort((a, b) => (rankByName.get(a.name) ?? 0) - (rankByName.get(b.name) ?? 0))
690
+ // Drop pure subsequence noise (dispersed letters that never form an
691
+ // actual substring): keep only name/description/pinyin hits.
692
+ .filter((s) => matchRank(s, q) < 4)
693
+ .sort((a, b) => matchRank(a, q) - matchRank(b, q) || (rankByName.get(a.name) ?? 0) - (rankByName.get(b.name) ?? 0))
669
694
  }
670
695
  window.__dshSkillPickerFuzzy = fuzzyMatch
671
696
  // Usage tracking for picks made from the official `/` menu: the patched