@rch4com/agent-setup 1.28.0 → 2.0.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.
Files changed (63) hide show
  1. package/README.md +31 -20
  2. package/install.mjs +25 -8
  3. package/lib/activation.mjs +31 -0
  4. package/lib/args.mjs +5 -2
  5. package/lib/bootstrap/manifest.mjs +17 -47
  6. package/lib/bootstrap/templates.mjs +7 -60
  7. package/lib/catalog.mjs +14 -240
  8. package/lib/clis.mjs +7 -118
  9. package/lib/commands.mjs +47 -0
  10. package/lib/engine.mjs +16 -11
  11. package/lib/i18n/catalog/en.mjs +50 -48
  12. package/lib/i18n/catalog/ko.mjs +50 -48
  13. package/lib/items/mcp.codebase-memory.mjs +6 -4
  14. package/lib/items/mcp.graft.mjs +6 -4
  15. package/lib/items/mcp.graphify.mjs +6 -4
  16. package/lib/items/mcp.headroom.mjs +6 -4
  17. package/lib/items/mcp.notion.mjs +7 -4
  18. package/lib/items/mcp.supabase.mjs +7 -4
  19. package/lib/items/mcp.vercel.mjs +7 -4
  20. package/lib/items/plugin.ai-memory.mjs +29 -0
  21. package/lib/items/plugin.cli-anything.mjs +16 -15
  22. package/lib/items/plugin.ecc.mjs +16 -20
  23. package/lib/items/plugin.hyperframes.mjs +15 -13
  24. package/lib/items/plugin.impeccable.mjs +17 -22
  25. package/lib/items/plugin.mattpocock-skills.mjs +19 -17
  26. package/lib/items/plugin.ponytail.mjs +21 -106
  27. package/lib/items/plugin.superpowers.mjs +17 -24
  28. package/lib/items/plugin.understand-anything.mjs +16 -18
  29. package/lib/items/skill.agent-browser.mjs +6 -6
  30. package/lib/items/skill.archify.mjs +5 -5
  31. package/lib/items/skill.caveman.mjs +5 -5
  32. package/lib/items/skill.diagram-design.mjs +5 -5
  33. package/lib/items/skill.eli5.mjs +6 -6
  34. package/lib/items/skill.find-skills.mjs +5 -5
  35. package/lib/items/skill.gsd.mjs +24 -89
  36. package/lib/items/skill.gstack.mjs +54 -65
  37. package/lib/items/skill.hallmark.mjs +5 -5
  38. package/lib/items/skill.i-have-adhd.mjs +6 -6
  39. package/lib/items/skill.im-not-ai.mjs +5 -6
  40. package/lib/items/skill.impeccable.mjs +6 -6
  41. package/lib/items/skill.karpathy.mjs +5 -5
  42. package/lib/items/skill.mattpocock-skills.mjs +5 -6
  43. package/lib/items/skill.mcp-builder.mjs +5 -5
  44. package/lib/items/skill.officecli.mjs +5 -5
  45. package/lib/items/skill.prompt-master.mjs +5 -5
  46. package/lib/items/skill.remotion.mjs +5 -5
  47. package/lib/items/skill.strix.mjs +5 -6
  48. package/lib/items/skill.superpowers.mjs +6 -7
  49. package/lib/items/skill.taste.mjs +5 -5
  50. package/lib/probe.mjs +111 -0
  51. package/lib/recipe-helpers.mjs +205 -0
  52. package/lib/recipe.mjs +181 -0
  53. package/lib/skills-registry.mjs +93 -0
  54. package/lib/status.mjs +7 -3
  55. package/lib/tui/detail.mjs +5 -25
  56. package/lib/tui/rows.mjs +25 -14
  57. package/lib/tui/run.mjs +35 -8
  58. package/package.json +3 -3
  59. package/lib/claude-plugins.mjs +0 -64
  60. package/lib/global-plugin.mjs +0 -239
  61. package/lib/items/global.ponytail.mjs +0 -56
  62. package/lib/items/global.superpowers.mjs +0 -58
  63. package/lib/tomlfile.mjs +0 -67
@@ -1,103 +1,38 @@
1
- import { existsSync, readdirSync } from 'node:fs'
2
- import { join } from 'node:path'
3
- import { defineSkill } from '../catalog.mjs'
4
- import { CLI_IDS } from '../clis.mjs'
5
- import { LocalizedError, msg } from '../i18n/index.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
6
2
 
7
3
  // 상류(v1.10.0)는 런타임 플래그 18종을 주는데, 그중 이 저장소의 CLI이면서
8
4
  // **프로젝트 스코프(--local)로 설치되고 그 CLI가 실제로 읽는 것**만 배선한다.
9
- // 다섯 자리 전부 2026-08-15에 실측했다:
5
+ // 2026-08-15 실측:
10
6
  // claude `.claude/commands`에 gsd-* (680파일). skills가 아니라 commands다 —
11
7
  // 부트스트랩 저장소의 `.claude/skills` Junction과 무관하다.
12
8
  // codex `.codex/skills`에 gsd-* 71종. `codex debug prompt-input`이 이
13
9
  // 경로를 스킬 루트로 등록하고 전부 나열하는 것을 확인했다.
14
10
  // opencode `.opencode/skills`. `opencode debug skill`이 로드한다.
15
- // copilot `.github/skills`. `copilot skill list`가 전부 표시한다.
16
- // kilo `.kilo/skills` 71종을 @kilocode/cli 7.3.45가 읽는다(2026-08-15).
11
+ // 런타임마다 명령 한 줄이다 — 부분 설치를 완성할 때 빠진 런타임만 돈다.
12
+ // `--uninstall`도 런타임 플래그를 받아 그 런타임만 지운다.
13
+ // Antigravity는 --antigravity 플래그가 있지만 설치 경로를 실측하지 못했다.
17
14
  //
18
- // 플래그는 한 번에 여러 개를 줄 수 있다 — `--claude --codex --local`이 두
19
- // 디렉터리를 만드는 것을 실측했다. 그래서 설치·제거 모두 호출 한 번이다.
20
- // `--uninstall`도 같은 플래그를 받아 그 런타임만 지운다(`--codex --local
21
- // --uninstall`이 .codex만 비우고 나머지 넷을 보존하는 것을 확인).
22
- //
23
- // 미배선 넷의 사유가 전부 다르다:
24
- // gemini 상류가 명시 제거(2026-06-18 종료). `--gemini --local`은 안내만 찍고
25
- // 파일을 하나도 만들지 않는다.
26
- // kimi `--kimi --local`이 "Project-level Kimi install semantics remain
27
- // deferred"를 찍고 거부한다 — 전역 설치만 가능하다.
28
- // kiro·grok·vscode 상류 런타임 목록에 없다.
29
- // antigravity --antigravity 플래그가 있지만 설치 경로를 실측하지 못했다.
30
- const RUNTIMES = [
31
- { cli: 'claude', dirs: ['.claude/commands', '.claude/skills'] },
32
- { cli: 'codex', dirs: ['.codex/skills'] },
33
- { cli: 'opencode', dirs: ['.opencode/skills'] },
34
- { cli: 'copilot', dirs: ['.github/skills'] },
35
- { cli: 'kilo', dirs: ['.kilo/skills'] },
36
- ]
37
- const SUPPORTS = RUNTIMES.map((r) => r.cli)
38
-
39
- // gsd-* 이름을 기준으로 센다. 상류 제거가 `gsd-install-state.json`과 훅 몇
40
- // 개를 남기는 것을 실측했는데(디렉터리는 남고 gsd-* 스킬만 사라진다), 파일
41
- // 존재만 보면 제거한 런타임이 영원히 설치됨으로 읽힌다.
42
- function hasGsdFiles(dir) {
43
- try {
44
- return readdirSync(dir).some((f) => f.startsWith('gsd-'))
45
- } catch {
46
- return false
47
- }
48
- }
49
-
50
- function wiredClis(root) {
51
- return RUNTIMES.filter((r) => r.dirs.some((d) => hasGsdFiles(join(root, ...d.split('/'))))).map((r) => r.cli)
15
+ // 감지는 gsd-* 이름을 기준으로 센다. 상류 제거가 `gsd-install-state.json`과
16
+ // 훅 몇 개를 남기는 것을 실측했는데(디렉터리는 남고 gsd-* 스킬만 사라진다),
17
+ // 파일 존재만 보면 제거한 런타임이 영원히 설치됨으로 읽힌다.
18
+ const RUNTIMES = {
19
+ claude: ['.claude/commands', '.claude/skills'],
20
+ codex: ['.codex/skills'],
21
+ opencode: ['.opencode/skills'],
52
22
  }
23
+ const NPX = ['npx', '-y', '@opengsd/gsd-core@latest']
53
24
 
54
- const flagsFor = (clis) => clis.map((c) => `--${c}`)
55
-
56
- export default defineSkill({
57
- id: 'skill.gsd', label: 'GSD (Get Shit Done)', group: '__flow', scope: 'project',
25
+ export default defineRecipe({
26
+ id: 'skill.gsd', category: 'skill', label: 'GSD (Get Shit Done)', group: '__flow',
58
27
  note: 'item.skill.gsd.note',
59
- supports: SUPPORTS,
60
28
  verified: '2026-08-15',
61
- unsupported: Object.fromEntries(
62
- CLI_IDS.filter((c) => !SUPPORTS.includes(c)).map((c) => [
63
- c,
64
- c === 'gemini' ? msg('item.unsupported.gsdGemini')
65
- : c === 'kimi' ? msg('item.unsupported.gsdKimiLocal')
66
- // --antigravity 플래그가 있지만 어느 경로에 무엇을 쓰는지 실측하지
67
- // 못했다 — 실측 전에는 배선하지 않는다.
68
- : c === 'antigravity' ? msg('item.unsupported.unmeasuredUpstream')
69
- : msg('item.unsupported.upstreamNone'),
70
- ]),
71
- ),
72
-
73
- async detect({ root }) {
74
- const present = wiredClis(root)
75
- if (present.length === 0) return { status: 'absent' }
76
- if (present.length === SUPPORTS.length) return { status: 'installed' }
77
- return {
78
- status: 'partial',
79
- detail: msg('item.mcp.partial', {
80
- present: present.join(', '),
81
- missing: SUPPORTS.filter((c) => !present.includes(c)).join(', '),
82
- }),
83
- }
84
- },
85
-
86
- async install({ root, exec }) {
87
- // 이미 있는 런타임은 빼고 부른다 — 상류가 덮어써도 무해하지만, 부분
88
- // 설치를 완성할 때 3,500개 파일을 다시 쓰는 것은 낭비다.
89
- const missing = SUPPORTS.filter((c) => !wiredClis(root).includes(c))
90
- if (missing.length === 0) return
91
- const r = await exec('npx', ['-y', '@opengsd/gsd-core@latest', ...flagsFor(missing), '--local'], { cwd: root })
92
- if (!r.ok) throw new LocalizedError('error.gsdInstall', { output: r.output })
93
- },
94
-
95
- async uninstall({ root, exec }) {
96
- // 런타임 플래그 없는 `--uninstall`은 기본값 claude만 지운다 — 설치된
97
- // 런타임을 전부 넘겨야 나머지 넷이 남지 않는다.
98
- const present = wiredClis(root)
99
- if (present.length === 0) return
100
- const r = await exec('npx', ['-y', '@opengsd/gsd-core@latest', ...flagsFor(present), '--local', '--uninstall'], { cwd: root })
101
- if (!r.ok) throw new LocalizedError('error.gsdUninstall', { output: r.output })
102
- },
29
+ recipes: Object.fromEntries(Object.keys(RUNTIMES).map((cli) => [cli, {
30
+ project: {
31
+ install: [[...NPX, `--${cli}`, '--local']],
32
+ // 런타임 플래그 없는 --uninstall은 기본값 claude를 지운다 — 늘 플래그를 준다.
33
+ uninstall: [[...NPX, `--${cli}`, '--local', '--uninstall']],
34
+ },
35
+ }])),
36
+ detect: Object.fromEntries(Object.entries(RUNTIMES).map(([cli, dirs]) => [cli, (p) => dirs.some((d) => p.dirHasPrefix(d, 'gsd-'))])),
37
+ reasons: { antigravity: 'item.unsupported.unmeasuredUpstream' },
103
38
  })
@@ -1,74 +1,63 @@
1
- import { existsSync, rmSync } from 'node:fs'
2
- import { join } from 'node:path'
3
- import { defineSkill } from '../catalog.mjs'
4
- import { CLI_IDS } from '../clis.mjs'
5
- import { repoPath, repoPathStrict } from '../context.mjs'
1
+ import { rmSync } from 'node:fs'
2
+ import { defineRecipe } from '../recipe.mjs'
3
+ import { repoPathStrict } from '../context.mjs'
6
4
  import { ensureGitignoreEntries, removeGitignoreEntries } from '../gitignore.mjs'
7
- import { LocalizedError, msg } from '../i18n/index.mjs'
8
5
 
9
- const REL_DIR = '.claude/skills/gstack'
10
- const IGNORE_ENTRIES = ['.claude/skills/gstack', '.agents/skills/gstack']
11
-
12
- // 상류 setup은 --host codex·kiro·opencode(와 factory)도 지원하지만 이 항목은
13
- // 인자 없이 실행하며 setup의 기본값이 claude 단독이다. README 표에 있는
14
- // --host cursor·slate는 setup의 case 문이 거부해 exit 1로 죽는다 —
15
- // 확장한다면 안전한 값은 claude·codex·kiro·factory·opencode·auto뿐이다
16
- // (2026-08-02 검증, 2026-08-15 재확인: case 문과 에러 문구 그대로).
6
+ // 상류 setup은 --host codex·opencode 등도 지원하지만 이 항목은 인자 없이
7
+ // 실행하며 setup의 기본값이 claude 단독이다. README 표에 있는 --host
8
+ // cursor·slate는 setup의 case 문이 거부해 exit 1로 죽는다(2026-08-15 재확인).
17
9
  //
18
- // 그런데 --host를 늘릴 필요가 없다는 것이 2026-08-15 실측으로 드러났다.
19
- // 상류 --host 경로는 홈(~/.codex/skills 등)에 까는 사용자 스코프인데, 이
20
- // 항목이 clone하는 `.claude/skills/gstack`은 부트스트랩 저장소에서 Junction
21
- // 이라 실물이 공유 `.agents/skills/gstack`에 앉는다. 거기서부터는 CLI의 스킬
22
- // 스캔 깊이가 도달 범위를 정한다 — gstack은 클론 루트에 라우터 SKILL.md가
23
- // 있고 개별 스킬이 그 아래 한 단계 더 들어간 2단계 구조다.
24
- // codex·opencode 재귀 스캔이라 개별 스킬까지 전부 인식(중첩 프로브로 실측).
25
- // copilot 1단계만 훑어 라우터 스킬 하나만 보인다(같은 프로브).
26
- // 나머지 CLI의 스캔 깊이는 미실측이라 "상류 경로 없음"으로 남긴다 — Junction
27
- // 도달은 우리 부트스트랩의 부수 효과지 상류 지원이 아니다.
28
- const SHARED_RECURSIVE = ['codex', 'opencode']
10
+ // --host를 늘릴 필요가 없다는 것이 2026-08-15 실측으로 드러났다. 상류 --host
11
+ // 경로는 홈(~/.codex/skills 등)에 까는 사용자 스코프인데, 이 항목이 clone하는
12
+ // `.claude/skills/gstack`은 부트스트랩 저장소에서 Junction이라 실물이 공유
13
+ // `.agents/skills/gstack`에 앉는다. codex·opencode는 스킬을 재귀로 스캔해
14
+ // 클론 루트 아래 개별 스킬까지 인식한다(중첩 프로브로 실측). Antigravity의
15
+ // 스캔 깊이는 미실측이라 "상류 경로 없음"으로 남긴다.
16
+ const DIR = '.claude/skills/gstack'
17
+ // 부트스트랩 저장소에서는 .claude/skills가 .agents/skills Junction이므로 두 경로 모두 무시 처리
18
+ const IGNORE_ENTRIES = ['.claude/skills/gstack', '.agents/skills/gstack']
19
+ // clone·삭제가 일어나는 경로다. 어휘적 검사만으로는 .claude/skills가 저장소
20
+ // 밖을 가리키는 링크일 때를 막지 못한다 — 부트스트랩은 사용자가 관리하는
21
+ // .claude/skills를 보존하므로, 그것이 홈을 가리키면 clone·setup이 저장소 밖에
22
+ // 쓴다. 명령을 돌리기 전에 실제 경로가 저장소 안인지 확인한다.
23
+ const guard = { describe: `check ${DIR} stays inside the repository`, fn: ({ root }) => { repoPathStrict(root, DIR) } }
24
+ const removeDir = ({ root }) => rmSync(repoPathStrict(root, DIR), { recursive: true, force: true })
25
+ // 디렉터리 이동을 bash 안에서 한다 — --print로 복사한 줄을 저장소 루트에서 붙여도
26
+ // 엉뚱한 ./setup이 돌지 않는다.
27
+ const inDir = (command) => ['bash', '-c', `cd ${DIR} && ${command}`]
29
28
 
30
- export default defineSkill({
31
- id: 'skill.gstack', label: 'gstack', group: '__flow', scope: 'project',
29
+ export default defineRecipe({
30
+ id: 'skill.gstack', category: 'skill', label: 'gstack', group: '__flow',
32
31
  note: 'item.skill.gstack.note',
33
32
  verified: '2026-08-15',
34
- unsupported: Object.fromEntries(
35
- CLI_IDS.filter((c) => c !== 'claude').map((c) => [
36
- c,
37
- SHARED_RECURSIVE.includes(c) ? msg('item.unsupported.gstackShared')
38
- : c === 'copilot' ? msg('item.unsupported.gstackSharedShallow')
39
- : c === 'kiro' ? msg('item.unsupported.gstackHost')
40
- : msg('item.unsupported.upstreamNone'),
41
- ]),
42
- ),
43
- async detect({ root }) {
44
- return { status: existsSync(repoPath(root, REL_DIR)) ? 'installed' : 'absent' }
45
- },
46
- async install({ root, dryRun, exec }) {
47
- // clone·삭제가 일어나는 경로다. 어휘적 검사만으로는 .claude/skills가
48
- // 저장소 밖을 가리키는 링크일 때를 막지 못한다(부트스트랩이 만드는
49
- // .agents/skills Junction은 저장소 안이라 그대로 통과한다).
50
- const dir = repoPathStrict(root, REL_DIR)
51
- if (!existsSync(dir)) {
52
- const clone = await exec('git', ['clone', '--single-branch', '--depth', '1', 'https://github.com/garrytan/gstack.git', dir])
53
- if (!clone.ok) throw new LocalizedError('error.gstackClone', { output: clone.output })
54
- const setup = await exec('bash', ['./setup'], { cwd: dir })
55
- if (!setup.ok) {
56
- // setup 실패 잔존물이 detect를 installed로 오판시키지 않도록 정리한다.
57
- rmSync(dir, { recursive: true, force: true })
58
- throw new LocalizedError('error.gstackSetup', { output: setup.output })
59
- }
60
- }
61
- // 부트스트랩 저장소에서는 .claude/skills가 .agents/skills Junction이므로 두 경로 모두 무시 처리
62
- if (!dryRun) ensureGitignoreEntries(root, IGNORE_ENTRIES)
33
+ recipes: {
34
+ claude: {
35
+ project: {
36
+ install: [
37
+ guard,
38
+ ['git', 'clone', '--single-branch', '--depth', '1', 'https://github.com/garrytan/gstack.git', DIR],
39
+ // setup이 실패하면 반쯤 깔린 클론을 지운다 — 남기면 다음 감지가 설치됨으로 읽는다.
40
+ { argv: inDir('bash ./setup'), undo: removeDir },
41
+ { describe: `add ${IGNORE_ENTRIES.join(', ')} to .gitignore`, fn: ({ root }) => ensureGitignoreEntries(root, IGNORE_ENTRIES) },
42
+ ],
43
+ uninstall: [
44
+ guard,
45
+ // 상류 제거 스크립트가 실패해도 디렉터리 삭제로 마무리한다.
46
+ { argv: inDir('bash ./bin/gstack-uninstall --force'), tolerateFail: true },
47
+ {
48
+ // 설치가 넣은 두 줄을 도로 가져간다 — 남겨 두면 제거한 뒤에도 우리가
49
+ // 만든 흔적이 .gitignore에 계속 남는다.
50
+ describe: `remove ${DIR} and its .gitignore entries`,
51
+ fn: (ctx) => { removeDir(ctx); removeGitignoreEntries(ctx.root, IGNORE_ENTRIES) },
52
+ },
53
+ ],
54
+ },
55
+ },
63
56
  },
64
- async uninstall({ root, dryRun, exec }) {
65
- const dir = repoPathStrict(root, REL_DIR)
66
- if (!existsSync(dir)) return
67
- await exec('bash', [join(dir, 'bin', 'gstack-uninstall'), '--force'], { cwd: dir }) // 실패해도 디렉터리 삭제로 폴백
68
- if (dryRun) return
69
- if (existsSync(dir)) rmSync(dir, { recursive: true, force: true })
70
- // 설치가 넣은 두 줄을 도로 가져간다 — 남겨 두면 제거한 뒤에도 우리가 만든
71
- // 흔적이 .gitignore에 계속 남는다.
72
- removeGitignoreEntries(root, IGNORE_ENTRIES)
57
+ detect: { claude: (p) => p.exists(DIR) },
58
+ reasons: {
59
+ codex: 'item.unsupported.gstackShared',
60
+ opencode: 'item.unsupported.gstackShared',
61
+ antigravity: 'item.unsupported.upstreamNone',
73
62
  },
74
63
  })
@@ -1,11 +1,11 @@
1
- import { defineRegistrySkill } from '../catalog.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { skillsAdd } from '../recipe-helpers.mjs'
2
3
  // 상류 저장소는 skills/hallmark/SKILL.md 배치라 레지스트리가 그대로 읽는다 —
3
4
  // SKILL.md의 name도 hallmark라 디렉터리 이름과 어긋나지 않는다(taste와 다른 점).
4
5
  // references/가 100개가 넘지만 레지스트리가 통째로 복사한다(2026-08-10 실측).
5
- export default defineRegistrySkill({
6
- id: 'skill.hallmark', label: 'Hallmark', group: '__style',
7
- source: 'https://github.com/nutlope/hallmark',
8
- skill: 'hallmark',
6
+ export default defineRecipe({
7
+ id: 'skill.hallmark', category: 'skill', label: 'Hallmark', group: '__style',
9
8
  note: 'item.skill.hallmark.note',
10
9
  verified: '2026-08-10',
10
+ ...skillsAdd({ source: 'https://github.com/nutlope/hallmark', skill: 'hallmark' }),
11
11
  })
@@ -1,16 +1,16 @@
1
- import { defineRegistrySkill } from '../catalog.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { skillsAdd } from '../recipe-helpers.mjs'
2
3
  // 상류는 skills/i-have-adhd/에 SKILL.md와 agents/(gemini.toml·openai.yaml)를
3
4
  // 두고 루트에는 SKILL.md가 없다 — 레지스트리가 그 폴더만 복사한다(3파일,
4
5
  // 13K, 2026-09-17 실측). Claude 마켓플레이스 플러그인 판(ayghri/i-have-adhd)도
5
6
  // 있지만 그쪽이 더 주는 것은 SessionStart 훅 하나이고, 그 훅은
6
7
  // ~/.claude/.i-have-adhd-always 플래그가 있을 때만 규칙을 상시 주입한다.
7
- // 스킬의 기본 자세는 /i-have-adhd로 켜는 opt-in이라 공유 스킬 판으로 11개
8
+ // 스킬의 기본 자세는 /i-have-adhd로 켜는 opt-in이라 공유 스킬 판으로 네
8
9
  // CLI를 함께 덮는 쪽을 택했다 — 상시 적용을 원하면 note가 안내하는 대로
9
10
  // 규칙 블록을 각 CLI의 지침 파일에 손으로 넣는다(상류 INSTALL.md).
10
- export default defineRegistrySkill({
11
- id: 'skill.i-have-adhd', label: 'I Have ADHD', group: '__style',
12
- source: 'https://github.com/ayghri/i-have-adhd',
13
- skill: 'i-have-adhd',
11
+ export default defineRecipe({
12
+ id: 'skill.i-have-adhd', category: 'skill', label: 'I Have ADHD', group: '__style',
14
13
  note: 'item.skill.i-have-adhd.note',
15
14
  verified: '2026-09-17',
15
+ ...skillsAdd({ source: 'https://github.com/ayghri/i-have-adhd', skill: 'i-have-adhd' }),
16
16
  })
@@ -1,4 +1,5 @@
1
- import { defineRegistrySkill } from '../catalog.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { skillsAdd } from '../recipe-helpers.mjs'
2
3
  // epoko77-ai/im-not-ai(MIT)의 skills/에 SKILL.md 4종(humanize-korean·humanize·
3
4
  // humanize-scan·humanize-redo)이 있다. humanize-korean이 본체이고 나머지는 그
4
5
  // 진입점·정찰·재윤문 shim이라 함께 받는다. 2026-10-08 스크래치 저장소에서
@@ -6,11 +7,9 @@ import { defineRegistrySkill } from '../catalog.mjs'
6
7
  // 상류 루트의 agents/(서브에이전트 9종)와 플러그인 매니페스트는 스킬 폴더
7
8
  // 밖이라 따라오지 않는다 — 서브에이전트 경로는 Claude 플러그인 판 몫이고,
8
9
  // 여기서는 스킬만 공유 디렉터리로 들어온다(note가 알린다).
9
- export default defineRegistrySkill({
10
- id: 'skill.im-not-ai', label: 'Humanize Korean', group: '__style',
11
- source: 'https://github.com/epoko77-ai/im-not-ai',
12
- skill: '*',
13
- anchor: 'humanize-korean',
10
+ export default defineRecipe({
11
+ id: 'skill.im-not-ai', category: 'skill', label: 'Humanize Korean', group: '__style',
14
12
  note: 'item.skill.im-not-ai.note',
15
13
  verified: '2026-10-08',
14
+ ...skillsAdd({ source: 'https://github.com/epoko77-ai/im-not-ai', skill: '*', anchor: 'humanize-korean' }),
16
15
  })
@@ -1,16 +1,16 @@
1
- import { defineRegistrySkill } from '../catalog.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { skillsAdd } from '../recipe-helpers.mjs'
2
3
  // 같은 상류를 플러그인(plugin.impeccable)으로도 넣을 수 있다. 플러그인은 Claude
3
- // 하나에만 닿고, 이쪽은 공유 .agents/skills라 11개 CLI가 함께 본다. 둘을 함께
4
+ // 하나에만 닿고, 이쪽은 공유 .agents/skills라 네 CLI가 함께 본다. 둘을 함께
4
5
  // 켜면 같은 스킬이 플러그인 캐시와 공유 디렉터리 양쪽에서 잡혀 중복 등록되므로
5
6
  // 배타로 묶는다.
6
7
  // 레지스트리가 pbakaus/impeccable에서 읽는 스킬은 impeccable 하나다
7
8
  // (`skills add --list`, 2026-10-06 확인). 엔진 바이너리는 포함되지 않는다 —
8
9
  // `npx impeccable install`만 플랫폼별 실행 파일을 함께 내려 준다.
9
- export default defineRegistrySkill({
10
- id: 'skill.impeccable', label: 'impeccable (skill)', group: '__style',
11
- source: 'https://github.com/pbakaus/impeccable',
12
- skill: 'impeccable',
10
+ export default defineRecipe({
11
+ id: 'skill.impeccable', category: 'skill', label: 'impeccable (skill)', group: '__style',
13
12
  exclusive: 'impeccable',
14
13
  note: 'item.skill.impeccable.note',
15
14
  verified: '2026-10-06',
15
+ ...skillsAdd({ source: 'https://github.com/pbakaus/impeccable', skill: 'impeccable' }),
16
16
  })
@@ -1,7 +1,7 @@
1
- import { defineRegistrySkill } from '../catalog.mjs'
2
- export default defineRegistrySkill({
3
- id: 'skill.karpathy', label: 'Karpathy guidelines', group: '__flow',
4
- source: 'https://github.com/multica-ai/andrej-karpathy-skills',
5
- skill: 'karpathy-guidelines',
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { skillsAdd } from '../recipe-helpers.mjs'
3
+ export default defineRecipe({
4
+ id: 'skill.karpathy', category: 'skill', label: 'Karpathy guidelines', group: '__flow',
6
5
  note: 'item.skill.karpathy.note',
6
+ ...skillsAdd({ source: 'https://github.com/multica-ai/andrej-karpathy-skills', skill: 'karpathy-guidelines' }),
7
7
  })
@@ -1,4 +1,5 @@
1
- import { defineRegistrySkill } from '../catalog.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { skillsAdd } from '../recipe-helpers.mjs'
2
3
  // 상류가 "Codex, and other agents" 절에서 이 경로를 직접 안내한다 —
3
4
  // `npx skills add mattpocock/skills`다. 그러니 이쪽이 곁길이 아니라 상류가
4
5
  // 의도한 두 경로 중 하나다. 훅이 없는 스킬 묶음이라 플러그인 판에 견줘 잃는
@@ -6,11 +7,9 @@ import { defineRegistrySkill } from '../catalog.mjs'
6
7
  //
7
8
  // anchor는 setup-matt-pocock-skills다. 상류 README가 "이것만은 반드시 고르라"고
8
9
  // 적어 둔 스킬이라 설치 판정의 기준으로도 맞는다.
9
- export default defineRegistrySkill({
10
- id: 'skill.mattpocock-skills', label: 'Matt Pocock (skills)', group: '__flow',
11
- source: 'https://github.com/mattpocock/skills',
12
- skill: '*',
13
- anchor: 'setup-matt-pocock-skills',
10
+ export default defineRecipe({
11
+ id: 'skill.mattpocock-skills', category: 'skill', label: 'Matt Pocock (skills)', group: '__flow',
14
12
  exclusive: 'mattpocock',
15
13
  note: 'item.skill.mattpocock-skills.note',
14
+ ...skillsAdd({ source: 'https://github.com/mattpocock/skills', skill: '*', anchor: 'setup-matt-pocock-skills' }),
16
15
  })
@@ -1,14 +1,14 @@
1
- import { defineRegistrySkill } from '../catalog.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { skillsAdd } from '../recipe-helpers.mjs'
2
3
  // anthropics/skills 17종 중 mcp-builder 하나만 --skill로 고른다. 본문이
3
4
  // reference/*.md 넷을 상대경로로 참조하는데 레지스트리 --copy가 스킬
4
5
  // 디렉터리를 통째로 복사하므로 함께 온다 — 스킬별 LICENSE.txt(Apache-2.0)도
5
6
  // 같은 디렉터리에 실려 고지가 유지된다(2026-08-15 확인, 리포 단위 라이선스는
6
7
  // 없고 스킬별로 갈린다). Python(FastMCP)·Node(MCP SDK) 서버 작성 가이드라
7
8
  // Claude 전용 도구 없이 하네스 중립이다.
8
- export default defineRegistrySkill({
9
- id: 'skill.mcp-builder', label: 'mcp-builder', group: '__service',
10
- source: 'https://github.com/anthropics/skills',
11
- skill: 'mcp-builder',
9
+ export default defineRecipe({
10
+ id: 'skill.mcp-builder', category: 'skill', label: 'mcp-builder', group: '__service',
12
11
  note: 'item.skill.mcp-builder.note',
13
12
  verified: '2026-08-15',
13
+ ...skillsAdd({ source: 'https://github.com/anthropics/skills', skill: 'mcp-builder' }),
14
14
  })
@@ -1,4 +1,5 @@
1
- import { defineRegistrySkill } from '../catalog.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { skillsAdd } from '../recipe-helpers.mjs'
2
3
  // 상류는 루트 SKILL.md(공개 URL이 서빙하는 판)와 skills/officecli/SKILL.md
3
4
  // (레지스트리가 발견하는 spec 준수 판)를 바이트 동일하게 유지한다(상류
4
5
  // skill-parity 워크플로). 저장소 루트를 source로 주면 레지스트리가 루트
@@ -12,10 +13,9 @@ import { defineRegistrySkill } from '../catalog.mjs'
12
13
  // 전제다 — note가 알린다. 같은 폴더의 전문 스킬 10종(officecli-docx·pptx·
13
14
  // xlsx, pitch-deck, morph-ppt 등)은 넣지 않는다 — 상류가 에이전트에 안내하는
14
15
  // 공식 경로는 이 하나다(README "For AI Agents").
15
- export default defineRegistrySkill({
16
- id: 'skill.officecli', label: 'OfficeCLI', group: '__service',
17
- source: 'https://github.com/iOfficeAI/OfficeCLI/tree/main/skills/officecli',
18
- skill: 'officecli',
16
+ export default defineRecipe({
17
+ id: 'skill.officecli', category: 'skill', label: 'OfficeCLI', group: '__service',
19
18
  note: 'item.skill.officecli.note',
20
19
  verified: '2026-09-15',
20
+ ...skillsAdd({ source: 'https://github.com/iOfficeAI/OfficeCLI/tree/main/skills/officecli', skill: 'officecli' }),
21
21
  })
@@ -1,7 +1,7 @@
1
- import { defineRegistrySkill } from '../catalog.mjs'
2
- export default defineRegistrySkill({
3
- id: 'skill.prompt-master', label: 'Prompt Master', group: '__flow',
4
- source: 'https://github.com/nidhinjs/prompt-master',
5
- skill: 'prompt-master',
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { skillsAdd } from '../recipe-helpers.mjs'
3
+ export default defineRecipe({
4
+ id: 'skill.prompt-master', category: 'skill', label: 'Prompt Master', group: '__flow',
6
5
  note: 'item.skill.prompt-master.note',
6
+ ...skillsAdd({ source: 'https://github.com/nidhinjs/prompt-master', skill: 'prompt-master' }),
7
7
  })
@@ -1,4 +1,5 @@
1
- import { defineRegistrySkill } from '../catalog.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { skillsAdd } from '../recipe-helpers.mjs'
2
3
  // remotion-dev/skills에는 최상위 스킬이 12개 있는데, remotion-best-practices가
3
4
  // 나머지 11개(create·markup·studio·render·captions·maps…)를 하위 폴더로 모두
4
5
  // 품는 상위 스킬이다(141개 파일, 1.1MB — 2026-10-06 실측). 하나만 받으면
@@ -6,10 +7,9 @@ import { defineRegistrySkill } from '../catalog.mjs'
6
7
  // 같은 개별 슬래시 명령은 생기지 않는다.
7
8
  // 상류 라이선스는 SPDX가 아닌 Remotion License다 — 개인·직원 3명 이하 영리
8
9
  // 조직·비영리는 무료, 그보다 큰 영리 조직은 회사 라이선스가 필요하다.
9
- export default defineRegistrySkill({
10
- id: 'skill.remotion', label: 'Remotion', group: '__service',
11
- source: 'https://github.com/remotion-dev/skills',
12
- skill: 'remotion-best-practices',
10
+ export default defineRecipe({
11
+ id: 'skill.remotion', category: 'skill', label: 'Remotion', group: '__service',
13
12
  note: 'item.skill.remotion.note',
14
13
  verified: '2026-10-06',
14
+ ...skillsAdd({ source: 'https://github.com/remotion-dev/skills', skill: 'remotion-best-practices' }),
15
15
  })
@@ -1,13 +1,12 @@
1
- import { defineRegistrySkill } from '../catalog.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { skillsAdd } from '../recipe-helpers.mjs'
2
3
  // 상류가 skills/에 SKILL.md 9종을 두고 npx skills add usestrix/strix를 README로
3
4
  // 직접 안내한다. 스킬 본문은 strix CLI를 구동하는 지침이라 바이너리가 사실상
4
5
  // 전제다 — note가 알린다. 2026-09-02 스크래치 저장소에서 9종 설치와
5
6
  // skills-lock.json의 source(usestrix/strix) 기록을 실측했다.
6
- export default defineRegistrySkill({
7
- id: 'skill.strix', label: 'Strix', group: '__service',
8
- source: 'https://github.com/usestrix/strix',
9
- skill: '*',
10
- anchor: 'penetration-testing-with-strix',
7
+ export default defineRecipe({
8
+ id: 'skill.strix', category: 'skill', label: 'Strix', group: '__service',
11
9
  note: 'item.skill.strix.note',
12
10
  verified: '2026-09-02',
11
+ ...skillsAdd({ source: 'https://github.com/usestrix/strix', skill: '*', anchor: 'penetration-testing-with-strix' }),
13
12
  })
@@ -1,7 +1,8 @@
1
- import { defineRegistrySkill } from '../catalog.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { skillsAdd } from '../recipe-helpers.mjs'
2
3
  // 같은 상류를 플러그인(plugin.superpowers)으로도 넣을 수 있다. 그쪽은 Claude
3
4
  // 하나만 닿는 대신 session-start 훅으로 알아서 켜지고, 이쪽은 공유
4
- // .agents/skills라 10개 CLI가 함께 보는 대신 훅이 빠진다 — 스킬은 부르면 되지만
5
+ // .agents/skills라 네 CLI가 함께 보는 대신 훅이 빠진다 — 스킬은 부르면 되지만
5
6
  // "대화 시작 시 using-superpowers 주입"은 오지 않는다.
6
7
  // 둘을 함께 켜면 같은 스킬이 플러그인 캐시와 공유 디렉터리 양쪽에서 잡혀 중복
7
8
  // 등록되므로 배타로 묶는다.
@@ -9,11 +10,9 @@ import { defineRegistrySkill } from '../catalog.mjs'
9
10
  // 상류 배치가 skills/<이름>/SKILL.md라 레지스트리가 그대로 읽는다(14개 실측).
10
11
  // anchor는 using-superpowers다 — 상류가 "대화 시작 시 반드시 읽으라"고 못 박은
11
12
  // 부트스트랩 스킬이라, 이것이 없으면 나머지가 있어도 설치로 볼 수 없다.
12
- export default defineRegistrySkill({
13
- id: 'skill.superpowers', label: 'superpowers (skills)', group: '__flow',
14
- source: 'https://github.com/obra/superpowers',
15
- skill: '*',
16
- anchor: 'using-superpowers',
13
+ export default defineRecipe({
14
+ id: 'skill.superpowers', category: 'skill', label: 'superpowers (skills)', group: '__flow',
17
15
  exclusive: 'superpowers',
18
16
  note: 'item.skill.superpowers.note',
17
+ ...skillsAdd({ source: 'https://github.com/obra/superpowers', skill: '*', anchor: 'using-superpowers' }),
19
18
  })
@@ -1,9 +1,9 @@
1
- import { defineRegistrySkill } from '../catalog.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { skillsAdd } from '../recipe-helpers.mjs'
2
3
  // 저장소의 폴더 이름은 taste-skill이지만 SKILL.md의 name은 design-taste-frontend다.
3
4
  // 레지스트리는 name으로 고르므로 여기에도 name을 적는다.
4
- export default defineRegistrySkill({
5
- id: 'skill.taste', label: 'Taste Skill', group: '__style',
6
- source: 'https://github.com/Leonxlnx/taste-skill',
7
- skill: 'design-taste-frontend',
5
+ export default defineRecipe({
6
+ id: 'skill.taste', category: 'skill', label: 'Taste Skill', group: '__style',
8
7
  note: 'item.skill.taste.note',
8
+ ...skillsAdd({ source: 'https://github.com/Leonxlnx/taste-skill', skill: 'design-taste-frontend' }),
9
9
  })