harveyz-skill 0.4.0 → 0.5.0
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/bin/cli.js +22 -6
- package/lib/targets.js +20 -9
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { checkbox } from '@inquirer/prompts'
|
|
2
|
+
import { checkbox, select } from '@inquirer/prompts'
|
|
3
3
|
import chalk from 'chalk'
|
|
4
4
|
import { execSync } from 'child_process'
|
|
5
5
|
import { createRequire } from 'module'
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
resolveSkills, resolveSkillsByName, resolveTools, resolveToolsByName,
|
|
9
9
|
TOOL_BUNDLE_CHOICES,
|
|
10
10
|
} from '../lib/bundles.js'
|
|
11
|
-
import {
|
|
11
|
+
import { buildTargetChoices, resolveTargets, TARGETS } from '../lib/targets.js'
|
|
12
12
|
import { installSkills, installTools } from '../lib/installer.js'
|
|
13
13
|
|
|
14
14
|
const require = createRequire(import.meta.url)
|
|
@@ -29,6 +29,7 @@ function printHelp() {
|
|
|
29
29
|
hskill install --skill <s> install specific skill(s)
|
|
30
30
|
hskill install --tool <t> install shell tool(s)
|
|
31
31
|
hskill install --target <t> set target (claude/cursor/codex/all)
|
|
32
|
+
hskill install --scope <s> set scope: user (default) or project
|
|
32
33
|
hskill install --force overwrite existing installs
|
|
33
34
|
hskill list list available skills and bundles
|
|
34
35
|
hskill update update hskill to the latest version
|
|
@@ -37,7 +38,7 @@ function printHelp() {
|
|
|
37
38
|
|
|
38
39
|
${chalk.cyan('Examples:')}
|
|
39
40
|
hskill install --bundle dev --target claude
|
|
40
|
-
hskill install --skill git-workflow-init
|
|
41
|
+
hskill install --skill git-workflow-init --target claude --scope project
|
|
41
42
|
hskill install --tool p-launch
|
|
42
43
|
hskill update
|
|
43
44
|
`)
|
|
@@ -95,10 +96,12 @@ const bundleIdx = installArgs.indexOf('--bundle')
|
|
|
95
96
|
const targetIdx = installArgs.indexOf('--target')
|
|
96
97
|
const toolIdx = installArgs.indexOf('--tool')
|
|
97
98
|
const skillIdx = installArgs.indexOf('--skill')
|
|
99
|
+
const scopeIdx = installArgs.indexOf('--scope')
|
|
98
100
|
const bundleArg = bundleIdx !== -1 ? installArgs[bundleIdx + 1] : undefined
|
|
99
101
|
const targetArg = targetIdx !== -1 ? installArgs[targetIdx + 1] : undefined
|
|
100
102
|
const toolArg = toolIdx !== -1 ? installArgs[toolIdx + 1] : undefined
|
|
101
103
|
const skillArg = skillIdx !== -1 ? installArgs[skillIdx + 1] : undefined
|
|
104
|
+
const scopeArg = scopeIdx !== -1 ? installArgs[scopeIdx + 1] : undefined
|
|
102
105
|
|
|
103
106
|
const TOOL_BUNDLE_VALUES = new Set(TOOL_BUNDLE_CHOICES.map(c => c.value))
|
|
104
107
|
|
|
@@ -164,21 +167,34 @@ try {
|
|
|
164
167
|
|
|
165
168
|
// ── Install skills ──────────────────────────────────────────────────────────
|
|
166
169
|
if (skillItems.length > 0) {
|
|
170
|
+
// Resolve scope
|
|
171
|
+
let scope = scopeArg ?? 'user'
|
|
172
|
+
if (!scopeArg && !targetArg) {
|
|
173
|
+
scope = await select({
|
|
174
|
+
message: 'Scope:',
|
|
175
|
+
choices: [
|
|
176
|
+
{ name: `user — ~/.claude/skills/ (shared across all projects)`, value: 'user' },
|
|
177
|
+
{ name: `project — .claude/skills/ (current project only)`, value: 'project' },
|
|
178
|
+
],
|
|
179
|
+
})
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Resolve target
|
|
167
183
|
let selectedTargets
|
|
168
184
|
if (targetArg) {
|
|
169
|
-
selectedTargets = targetArg === 'all' ?
|
|
185
|
+
selectedTargets = targetArg === 'all' ? ['claude', 'cursor', 'codex'] : [targetArg]
|
|
170
186
|
} else {
|
|
171
187
|
selectedTargets = await checkbox({
|
|
172
188
|
message: 'Install to which tools (space to select, enter to confirm):',
|
|
173
189
|
choices: [
|
|
174
|
-
...
|
|
190
|
+
...buildTargetChoices(scope),
|
|
175
191
|
{ name: 'all — all tools', value: 'all' },
|
|
176
192
|
],
|
|
177
193
|
})
|
|
178
194
|
}
|
|
179
195
|
|
|
180
196
|
if (selectedTargets.length > 0) {
|
|
181
|
-
const targets = resolveTargets(selectedTargets)
|
|
197
|
+
const targets = resolveTargets(selectedTargets, scope)
|
|
182
198
|
console.log('')
|
|
183
199
|
const summary = await installSkills(skillItems, targets, forceFlag)
|
|
184
200
|
console.log('')
|
package/lib/targets.js
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import os from 'os'
|
|
2
2
|
import path from 'path'
|
|
3
3
|
|
|
4
|
+
const SKILL_TARGETS = ['claude', 'cursor', 'codex']
|
|
5
|
+
|
|
6
|
+
function skillDir(name, scope) {
|
|
7
|
+
if (scope === 'project') return path.join(process.cwd(), `.${name}`, 'skills')
|
|
8
|
+
return path.join(os.homedir(), `.${name}`, 'skills')
|
|
9
|
+
}
|
|
10
|
+
|
|
4
11
|
export const TARGETS = {
|
|
5
12
|
claude: path.join(os.homedir(), '.claude', 'skills'),
|
|
6
13
|
cursor: path.join(os.homedir(), '.cursor', 'skills'),
|
|
@@ -8,17 +15,21 @@ export const TARGETS = {
|
|
|
8
15
|
shell: path.join(os.homedir(), '.local', 'bin'),
|
|
9
16
|
}
|
|
10
17
|
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
})
|
|
18
|
+
export function buildTargetChoices(scope = 'user') {
|
|
19
|
+
return SKILL_TARGETS.map(name => {
|
|
20
|
+
const dir = skillDir(name, scope)
|
|
21
|
+
return { name: `${name.padEnd(8)} (${dir})`, value: name }
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const TARGET_CHOICES = buildTargetChoices('user')
|
|
15
26
|
|
|
16
27
|
// 返回选中 targets 的 { name, dir } 列表,all 展开为全部
|
|
17
|
-
export function resolveTargets(selected) {
|
|
18
|
-
|
|
28
|
+
export function resolveTargets(selected, scope = 'user') {
|
|
29
|
+
const allTargets = SKILL_TARGETS.map(name => ({ name, dir: skillDir(name, scope) }))
|
|
30
|
+
if (selected.includes('all')) return allTargets
|
|
19
31
|
return selected.map(name => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return { name, dir }
|
|
32
|
+
if (!SKILL_TARGETS.includes(name)) throw new Error(`Unknown target: "${name}"`)
|
|
33
|
+
return { name, dir: skillDir(name, scope) }
|
|
23
34
|
})
|
|
24
35
|
}
|