happyskills 0.35.1 → 0.35.2
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/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/commands/search.js +24 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.35.2] - 2026-04-11
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Add match quality labels to smart search output — each result shows its confidence level (Strong match, Good match, Partial match, Weak match) based on cosine similarity
|
|
14
|
+
- Add weak-match notice when no results have strong or good match quality, warning that results may not match the user's intent
|
|
15
|
+
- Add `match_quality` and `match_notice` fields to JSON search output
|
|
16
|
+
|
|
10
17
|
## [0.35.1] - 2026-04-10
|
|
11
18
|
|
|
12
19
|
### Fixed
|
package/package.json
CHANGED
package/src/commands/search.js
CHANGED
|
@@ -46,6 +46,13 @@ const QUALITY_TIERS = [
|
|
|
46
46
|
{ min: 20, label: 'Low quality', color: yellow },
|
|
47
47
|
]
|
|
48
48
|
|
|
49
|
+
const MATCH_QUALITY_LABELS = {
|
|
50
|
+
strong: { label: 'Strong match', color: cyan },
|
|
51
|
+
good: { label: 'Good match', color: cyan },
|
|
52
|
+
partial: { label: 'Partial match', color: yellow },
|
|
53
|
+
weak: { label: 'Weak match', color: yellow },
|
|
54
|
+
}
|
|
55
|
+
|
|
49
56
|
const get_quality_label = (score) => {
|
|
50
57
|
if (score == null) return null
|
|
51
58
|
for (const tier of QUALITY_TIERS) {
|
|
@@ -67,10 +74,12 @@ const format_smart_result = (item, index) => {
|
|
|
67
74
|
const name = `${item.workspace_slug}/${item.name}`
|
|
68
75
|
const stars = item.star_count || 0
|
|
69
76
|
const tier = get_quality_label(item.quality_score)
|
|
77
|
+
const match = item.match_quality ? MATCH_QUALITY_LABELS[item.match_quality] : null
|
|
70
78
|
|
|
71
79
|
const star_str = `★ ${stars}`
|
|
72
80
|
const quality_str = tier ? tier.color(tier.label) : ''
|
|
73
|
-
const
|
|
81
|
+
const match_str = match ? match.color(match.label) : ''
|
|
82
|
+
const meta_parts = [match_str, star_str, quality_str].filter(Boolean).join(' · ')
|
|
74
83
|
|
|
75
84
|
const num = ` ${String(index + 1).padStart(2)}. `
|
|
76
85
|
const name_and_meta = `${bold(name)}${meta_parts ? ` ${dim(meta_parts)}` : ''}`
|
|
@@ -114,6 +123,13 @@ const run_smart_search = (args, query, options) => catch_errors('Smart search fa
|
|
|
114
123
|
return
|
|
115
124
|
}
|
|
116
125
|
|
|
126
|
+
const has_strong_or_good = items.some(item =>
|
|
127
|
+
item.match_quality === 'strong' || item.match_quality === 'good'
|
|
128
|
+
)
|
|
129
|
+
const match_notice = !has_strong_or_good && items.length > 0
|
|
130
|
+
? 'No strong matches found. The results below are the closest available but may not match your intent.'
|
|
131
|
+
: null
|
|
132
|
+
|
|
117
133
|
if (args.flags.json) {
|
|
118
134
|
const mapped = items.map(item => ({
|
|
119
135
|
skill: `${item.workspace_slug}/${item.name}`,
|
|
@@ -126,17 +142,23 @@ const run_smart_search = (args, query, options) => catch_errors('Smart search fa
|
|
|
126
142
|
quality_score: item.quality_score != null ? item.quality_score : null,
|
|
127
143
|
quality_tier: get_quality_tier_name(item.quality_score),
|
|
128
144
|
relevance_score: item.relevance_score != null ? item.relevance_score : null,
|
|
145
|
+
match_quality: item.match_quality || null,
|
|
129
146
|
tags: item.tags || [],
|
|
130
147
|
download_count: item.download_count || 0,
|
|
131
148
|
created_at: item.created_at,
|
|
132
149
|
updated_at: item.updated_at,
|
|
133
150
|
}))
|
|
134
|
-
|
|
151
|
+
const data = { query, mode: 'smart', results: mapped, count: mapped.length }
|
|
152
|
+
if (match_notice) data.match_notice = match_notice
|
|
153
|
+
print_json({ data })
|
|
135
154
|
return
|
|
136
155
|
}
|
|
137
156
|
|
|
138
157
|
// Human-readable smart output
|
|
139
158
|
console.log(`\n${bold(`Skills for: "${query}"`)}\n`)
|
|
159
|
+
if (match_notice) {
|
|
160
|
+
console.log(` ${yellow(match_notice)}\n`)
|
|
161
|
+
}
|
|
140
162
|
items.forEach((item, i) => {
|
|
141
163
|
console.log(format_smart_result(item, i))
|
|
142
164
|
if (i < items.length - 1) console.log('')
|