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 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 { TARGET_CHOICES, resolveTargets, TARGETS } from '../lib/targets.js'
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,mermaid-diagram --target claude
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' ? Object.keys(TARGETS) : [targetArg]
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
- ...TARGET_CHOICES,
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 const TARGET_CHOICES = Object.entries(TARGETS).map(([name, dir]) => ({
12
- name: `${name.padEnd(8)} (${dir})`,
13
- value: name,
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
- if (selected.includes('all')) return Object.entries(TARGETS).map(([name, dir]) => ({ name, dir }))
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
- const dir = TARGETS[name]
21
- if (!dir) throw new Error(`Unknown target: "${name}"`)
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "harveyz-skill",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Skill manager for Claude Code, Cursor, and Codex",
5
5
  "type": "module",
6
6
  "bin": {