harveyz-skill 0.17.0 → 0.17.1
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 +5 -0
- package/bin/cli.js +17 -10
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.17.1] - 2026-06-15
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- `hskill` TUI:未安装的 skill 现在按 `installScope` 显示推荐图标(`»` essential / `▸` global/project),不再统一显示 `—`
|
|
14
|
+
|
|
10
15
|
## [0.17.0] - 2026-06-15
|
|
11
16
|
|
|
12
17
|
## [0.16.0] - 2026-06-15
|
package/bin/cli.js
CHANGED
|
@@ -729,34 +729,41 @@ function fzfSelect() {
|
|
|
729
729
|
const hookItems = getAllHookItems()
|
|
730
730
|
const previewPath = path.join(__dirname, 'preview.mjs')
|
|
731
731
|
|
|
732
|
-
// 构建 fzf 输入:每行 "NAME\tVERSION\tBUNDLE\tKIND\tSRCPATH"
|
|
732
|
+
// 构建 fzf 输入:每行 "NAME\tVERSION\tBUNDLE\tKIND\tSRCPATH\tINSTALLSCOPE"
|
|
733
733
|
const lines = [
|
|
734
734
|
...skillItems.map(s => {
|
|
735
735
|
const bundle = s.srcPath.split('/').slice(-2, -1)[0]
|
|
736
|
-
return `${s.skillName}\t${s.version ?? '—'}\t${bundle}\tskill\t${s.srcPath}`
|
|
736
|
+
return `${s.skillName}\t${s.version ?? '—'}\t${bundle}\tskill\t${s.srcPath}\t${s.installScope ?? ''}`
|
|
737
737
|
}),
|
|
738
|
-
...toolItems.map(t => `${t.toolName}\t${t.version ?? '—'}\tshell-tool\ttool\t${t.srcPath}`),
|
|
739
|
-
...hookItems.map(h => `${h.name}\t${h.version ?? '—'}\thook\thook\t${h.srcPath}`),
|
|
738
|
+
...toolItems.map(t => `${t.toolName}\t${t.version ?? '—'}\tshell-tool\ttool\t${t.srcPath}\t${t.installScope ?? ''}`),
|
|
739
|
+
...hookItems.map(h => `${h.name}\t${h.version ?? '—'}\thook\thook\t${h.srcPath}\t${h.installScope ?? ''}`),
|
|
740
740
|
]
|
|
741
741
|
|
|
742
742
|
const nameWidth = Math.max(...lines.map(l => l.split('\t')[0].length))
|
|
743
743
|
const versionWidth = Math.max(...lines.map(l => l.split('\t')[1].length))
|
|
744
744
|
|
|
745
|
-
const G = '\x1b[32m', Y = '\x1b[33m', D = '\x1b[2m', R = '\x1b[0m'
|
|
745
|
+
const G = '\x1b[32m', Y = '\x1b[33m', C = '\x1b[36m', D = '\x1b[2m', R = '\x1b[0m'
|
|
746
746
|
function colorIcon(status) {
|
|
747
747
|
if (status === 'up-to-date') return G + '✓' + R
|
|
748
748
|
if (status === 'update') return Y + '↑' + R
|
|
749
749
|
return D + '—' + R
|
|
750
750
|
}
|
|
751
|
+
function scopeHint(installScope) {
|
|
752
|
+
if (installScope === 'essential') return Y + '»' + R
|
|
753
|
+
if (installScope === 'global' || installScope === 'project') return C + '▸' + R
|
|
754
|
+
return D + '—' + R
|
|
755
|
+
}
|
|
751
756
|
|
|
752
757
|
// fzf 展示格式:NAME VERSION U:? P:? BUNDLE
|
|
753
758
|
const displayLines = lines.map(l => {
|
|
754
|
-
const [name, ver, bundle, kind, srcPath] = l.split('\t')
|
|
755
|
-
let uIcon =
|
|
759
|
+
const [name, ver, bundle, kind, srcPath, installScope] = l.split('\t')
|
|
760
|
+
let uIcon = scopeHint(installScope), pIcon = D + '—' + R
|
|
756
761
|
if (kind === 'skill') {
|
|
757
762
|
const installed = checkInstalled(name, ver)
|
|
758
|
-
|
|
759
|
-
|
|
763
|
+
const uStatus = scopeSummary(installed.user)
|
|
764
|
+
const pStatus = scopeSummary(installed.project)
|
|
765
|
+
uIcon = uStatus !== 'none' ? colorIcon(uStatus) : scopeHint(installScope)
|
|
766
|
+
pIcon = pStatus !== 'none' ? colorIcon(pStatus) : (installScope === 'project' ? C + '▸' + R : D + '—' + R)
|
|
760
767
|
} else if (kind === 'tool') {
|
|
761
768
|
uIcon = colorIcon(checkToolInstalled(name, srcPath).status)
|
|
762
769
|
} else if (kind === 'hook') {
|
|
@@ -772,7 +779,7 @@ function fzfSelect() {
|
|
|
772
779
|
// 把原始数据附在末尾(隐藏列,用于解析和 preview)
|
|
773
780
|
const fzfInput = displayLines.map((d, i) => `${d}\t${lines[i]}`).join('\n')
|
|
774
781
|
|
|
775
|
-
const header = ` hskill · U=user P=project ${G}✓${R}=ok ${Y}↑${R}=update ${D}—${R}=none · tab 多选 · enter 确认`
|
|
782
|
+
const header = ` hskill · U=user P=project ${G}✓${R}=ok ${Y}↑${R}=update ${Y}»${R}=essential ${C}▸${R}=recommended ${D}—${R}=none · tab 多选 · enter 确认`
|
|
776
783
|
|
|
777
784
|
const result = spawnSync('fzf', [
|
|
778
785
|
'--multi',
|