@rch4com/agent-setup 1.28.0 → 2.2.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 (66) 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 +21 -47
  6. package/lib/bootstrap/templates.mjs +7 -60
  7. package/lib/catalog.mjs +22 -241
  8. package/lib/clis.mjs +11 -118
  9. package/lib/commands.mjs +47 -0
  10. package/lib/engine.mjs +16 -11
  11. package/lib/i18n/catalog/en.mjs +58 -49
  12. package/lib/i18n/catalog/ko.mjs +58 -49
  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 +18 -15
  22. package/lib/items/plugin.ecc.mjs +22 -20
  23. package/lib/items/plugin.hyperframes.mjs +17 -13
  24. package/lib/items/plugin.impeccable.mjs +19 -22
  25. package/lib/items/plugin.mattpocock-skills.mjs +23 -17
  26. package/lib/items/plugin.ponytail.mjs +24 -106
  27. package/lib/items/plugin.superpowers.mjs +20 -24
  28. package/lib/items/plugin.understand-anything.mjs +21 -19
  29. package/lib/items/skill.agent-browser.mjs +6 -6
  30. package/lib/items/skill.agent-handoff-manager.mjs +14 -0
  31. package/lib/items/skill.archify.mjs +5 -5
  32. package/lib/items/skill.caveman.mjs +5 -5
  33. package/lib/items/skill.diagram-design.mjs +5 -5
  34. package/lib/items/skill.eli5.mjs +6 -6
  35. package/lib/items/skill.find-skills.mjs +5 -5
  36. package/lib/items/skill.gsd.mjs +28 -89
  37. package/lib/items/skill.gstack.mjs +58 -65
  38. package/lib/items/skill.hallmark.mjs +5 -5
  39. package/lib/items/skill.html-plan.mjs +15 -0
  40. package/lib/items/skill.i-have-adhd.mjs +6 -6
  41. package/lib/items/skill.im-not-ai.mjs +5 -6
  42. package/lib/items/skill.impeccable.mjs +6 -6
  43. package/lib/items/skill.karpathy.mjs +5 -5
  44. package/lib/items/skill.mattpocock-skills.mjs +5 -6
  45. package/lib/items/skill.mcp-builder.mjs +5 -5
  46. package/lib/items/skill.officecli.mjs +5 -5
  47. package/lib/items/skill.prompt-master.mjs +5 -5
  48. package/lib/items/skill.remotion.mjs +5 -5
  49. package/lib/items/skill.strix.mjs +5 -6
  50. package/lib/items/skill.superpowers.mjs +6 -7
  51. package/lib/items/skill.taste.mjs +5 -5
  52. package/lib/items/skill.unslop.mjs +12 -0
  53. package/lib/probe.mjs +136 -0
  54. package/lib/recipe-helpers.mjs +281 -0
  55. package/lib/recipe.mjs +181 -0
  56. package/lib/skills-registry.mjs +93 -0
  57. package/lib/status.mjs +7 -3
  58. package/lib/tui/detail.mjs +5 -25
  59. package/lib/tui/rows.mjs +25 -14
  60. package/lib/tui/run.mjs +35 -8
  61. package/package.json +4 -3
  62. package/lib/claude-plugins.mjs +0 -64
  63. package/lib/global-plugin.mjs +0 -239
  64. package/lib/items/global.ponytail.mjs +0 -56
  65. package/lib/items/global.superpowers.mjs +0 -58
  66. package/lib/tomlfile.mjs +0 -67
@@ -1,23 +1,26 @@
1
- import { definePlugin } from '../catalog.mjs'
2
- import { CLI_IDS } from '../clis.mjs'
3
- import { msg } from '../i18n/index.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { marketplacePlugin } from '../recipe-helpers.mjs'
3
+
4
4
  // HKUDS/CLI-Anything(Apache-2.0)의 마켓플레이스는 .claude-plugin/marketplace.json
5
5
  // 하나에 플러그인 cli-anything(./cli-anything-plugin)만 싣는다. 명령은
6
6
  // /cli-anything·list·refine·test·validate 다섯 개다(2026-10-06 확인).
7
- // 다른 CLI는 상류 README 기준: Codex는 설치기가 $CODEX_HOME/skills(사용자
8
- // 스코프), OpenCode는 설치기 없이 commands 파일 수동 복사, 나머지는 없다.
9
- // (Cursor·Pi·Hermes·Qoder 설치기는 이 저장소의 CLI 목록 밖이다.)
7
+ // 다른 CLI는 상류 README 기준: Codex는 설치 스크립트가 $CODEX_HOME/skills에
8
+ // 쓰고(CLI 명령이 아니다), OpenCode는 설치기 없이 commands 파일 수동 복사,
9
+ // Antigravity는 경로가 없다.
10
10
  // 같은 리포의 skills/cli-hub-meta-skill은 별개 항목이다 — 이미 만들어진 CLI를
11
11
  // 허브에서 찾아 설치하게 하는 스킬이고, 이 항목은 CLI를 새로 만드는 쪽이다.
12
- const WHY = { codex: 'item.unsupported.cliAnythingCodex', opencode: 'item.unsupported.cliAnythingManual' }
13
- export default definePlugin({
14
- id: 'plugin.cli-anything', label: 'CLI-Anything', group: '__service',
15
- installId: 'cli-anything@cli-anything',
16
- detectIds: ['cli-anything@cli-anything'],
17
- marketplace: { name: 'cli-anything', repo: 'HKUDS/CLI-Anything' },
12
+ export default defineRecipe({
13
+ id: 'plugin.cli-anything', category: 'plugin', label: 'CLI-Anything', group: '__service',
18
14
  note: 'item.plugin.cli-anything.note',
19
15
  verified: '2026-10-06',
20
- unsupported: Object.fromEntries(
21
- CLI_IDS.filter((c) => c !== 'claude').map((c) => [c, msg(WHY[c] ?? 'item.unsupported.upstreamNone')]),
22
- ),
16
+ ...marketplacePlugin({
17
+ claude: { marketplace: 'HKUDS/CLI-Anything', id: 'cli-anything@cli-anything' },
18
+ }),
19
+ reasons: {
20
+ codex: 'item.unsupported.cliAnythingCodex',
21
+ opencode: 'item.unsupported.cliAnythingManual',
22
+ antigravity: 'item.unsupported.upstreamNone',
23
+ copilot: 'item.unsupported.cliAnythingCopilot',
24
+ vscode: 'item.unsupported.vscodePlugin',
25
+ },
23
26
  })
@@ -1,27 +1,29 @@
1
- import { definePlugin } from '../catalog.mjs'
2
- import { CLI_IDS } from '../clis.mjs'
3
- import { msg } from '../i18n/index.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { marketplacePlugin } from '../recipe-helpers.mjs'
3
+
4
4
  // 레지스트리 경로(`npx skills add`)도 열려 있지만 쓰지 않는다 — ECC의 skills/에는
5
5
  // 284개가 들어 있어 `--skill` 없이 넣으면 공유 스킬 디렉터리를 통째로 덮는다
6
6
  // (2026-08-15 저장소 트리로 실측). 플러그인은 프로필을 상류가 관리하므로
7
7
  // 저장소에 남는 파일이 없다.
8
8
  //
9
- // 미배선 사유는 CLI마다 갈린다. Codex만 상류가 네이티브 플러그인을 주는데,
10
- // README가 못을 박는다 — "Codex stores one enabled plugin state in the active
11
- // CODEX_HOME; it does not offer Claude's user, project, and local scopes."
12
- // 나머지는 ./install.sh --target으로 열려 있고 Gemini(.gemini/)·Kimi(.kimi-code/)는
13
- // 프로젝트 로컬이기까지 하다. 그쪽을 막는 것은 스코프가 아니라 284개라는 규모다.
14
- export default definePlugin({
15
- id: 'plugin.ecc', label: 'ECC', group: '__flow',
16
- installId: 'ecc@ecc',
17
- detectIds: ['ecc@ecc'],
18
- marketplace: { name: 'ecc', repo: 'affaan-m/ECC' },
9
+ // Codex는 상류가 네이티브 플러그인을 준다(README: `codex plugin marketplace add
10
+ // affaan-m/ECC` + `codex plugin add ecc@ecc`, 두 명령 모두 멱등). 활성 CODEX_HOME
11
+ // 하나에 깔리므로 전역 전용이고, 네이티브 훅은 명시적 신뢰가 필요하다(hooks).
12
+ // OpenCode·Antigravity는 ./install.sh --target 경로뿐이라 284개 규모 문제가 같다.
13
+ export default defineRecipe({
14
+ id: 'plugin.ecc', category: 'plugin', label: 'ECC', group: '__flow',
19
15
  note: 'item.plugin.ecc.note',
20
- verified: '2026-08-15',
21
- unsupported: Object.fromEntries(
22
- CLI_IDS.filter((c) => c !== 'claude').map((c) => [
23
- c,
24
- c === 'codex' ? msg('item.unsupported.eccCodexHome') : msg('item.unsupported.eccScale'),
25
- ]),
26
- ),
16
+ verified: '2026-10-24',
17
+ hooks: true,
18
+ ...marketplacePlugin({
19
+ claude: { marketplace: 'affaan-m/ECC', id: 'ecc@ecc' },
20
+ codex: { marketplace: 'affaan-m/ECC', id: 'ecc@ecc' },
21
+ }),
22
+ // Copilot CLI도 ./install.sh --target copilot 경로뿐이라 규모 문제가 같다.
23
+ reasons: {
24
+ opencode: 'item.unsupported.eccScale',
25
+ antigravity: 'item.unsupported.eccScale',
26
+ copilot: 'item.unsupported.eccScale',
27
+ vscode: 'item.unsupported.vscodePlugin',
28
+ },
27
29
  })
@@ -1,23 +1,27 @@
1
- import { definePlugin } from '../catalog.mjs'
2
- import { CLI_IDS } from '../clis.mjs'
3
- import { msg } from '../i18n/index.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { marketplacePlugin } from '../recipe-helpers.mjs'
3
+
4
4
  // heygen-com/hyperframes(Apache-2.0)의 마켓플레이스는 플러그인 둘을 싣는다:
5
5
  // hyperframes(전체 스킬 번들, 상류 권장)와 core-skills(구판 코어만 — 상류가
6
6
  // 전자로 옮기라고 안내한다). 여기서는 전자를 쓴다. 번들은 스킬 21종과 CLI
7
7
  // 버전을 한 스냅숏으로 묶고, /hyperframes 라우터가 제작 워크플로를 그때그때
8
8
  // 불러온다(2026-10-06 확인).
9
- // 다른 CLI는 모두 상류가 CLI별 별도 설치로 안내한다 — Copilot·Gemini·Codex·
10
- // VS Code·Cursor는 각자 플러그인/확장, 나머지는 `npx skills add`의 단독 스킬.
9
+ // 다른 CLI는 모두 상류가 CLI별 별도 설치로 안내한다 — Codex는 플러그인,
10
+ // 나머지는 `npx skills add`의 단독 스킬.
11
11
  // 같은 상류를 스킬로 넣지 않는 것은 코어만 고르려면 대화형 선택기가 필요해서다
12
12
  // (비대화형 실행은 21종 전부를 설치한다).
13
- export default definePlugin({
14
- id: 'plugin.hyperframes', label: 'HyperFrames', group: '__service',
15
- installId: 'hyperframes@hyperframes',
16
- detectIds: ['hyperframes@hyperframes'],
17
- marketplace: { name: 'hyperframes', repo: 'heygen-com/hyperframes' },
13
+ export default defineRecipe({
14
+ id: 'plugin.hyperframes', category: 'plugin', label: 'HyperFrames', group: '__service',
18
15
  note: 'item.plugin.hyperframes.note',
19
16
  verified: '2026-10-06',
20
- unsupported: Object.fromEntries(
21
- CLI_IDS.filter((c) => c !== 'claude').map((c) => [c, msg('item.unsupported.superpowersSeparate')]),
22
- ),
17
+ ...marketplacePlugin({
18
+ claude: { marketplace: 'heygen-com/hyperframes', id: 'hyperframes@hyperframes' },
19
+ }),
20
+ reasons: {
21
+ codex: 'item.unsupported.superpowersSeparate',
22
+ opencode: 'item.unsupported.superpowersSeparate',
23
+ antigravity: 'item.unsupported.superpowersSeparate',
24
+ copilot: 'item.unsupported.superpowersSeparate',
25
+ vscode: 'item.unsupported.vscodePlugin',
26
+ },
23
27
  })
@@ -1,28 +1,25 @@
1
- import { definePlugin } from '../catalog.mjs'
2
- import { CLI_IDS } from '../clis.mjs'
3
- import { msg } from '../i18n/index.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { marketplacePlugin } from '../recipe-helpers.mjs'
3
+
4
4
  // 같은 상류를 공유 스킬(skill.impeccable)로도 넣을 수 있다. 플러그인은 Claude
5
- // 하나에만 닿고 스킬 판은 11개 CLI가 함께 본다. 둘을 함께 켜면 같은 스킬이 두
5
+ // 하나에만 닿고 스킬 판은 네 CLI가 함께 본다. 둘을 함께 켜면 같은 스킬이 두
6
6
  // 경로에서 잡혀 중복 등록되므로 배타로 묶는다.
7
- // 예전에는 `npx impeccable install`이 `.claude/skills` Junction을 실제
8
- // 디렉터리로 갈아치운다는 이유(3.6.0 측정)로 스킬 경로를 막았지만, 4.1.0을
9
- // 2026-10-06에 다시 재 보니 claude·kiro(Junction)와 codex·antigravity·gemini
10
- // ·opencode·grok·copilot(symlink)에서 링크가 그대로 남았다. 그 사유는 폐기한다.
11
- // 다만 그 명령은 provider마다 엔진 바이너리(약 19MB)를 따로 복사하고 비TTY에서
12
- // 범위를 묻지 않으므로, 이 저장소는 레지스트리 스킬 경로를 쓴다.
13
- const UPSTREAM = ['codex', 'gemini', 'opencode', 'kiro', 'grok', 'copilot', 'antigravity']
14
- export default definePlugin({
15
- id: 'plugin.impeccable', label: 'impeccable', group: '__style',
16
- installId: 'impeccable@impeccable',
17
- detectIds: ['impeccable@impeccable'],
18
- marketplace: { name: 'impeccable', repo: 'pbakaus/impeccable' },
7
+ // `npx impeccable install`은 provider마다 엔진 바이너리(약 19MB)를 따로 복사하고
8
+ // 비TTY에서 범위를 묻지 않으므로(4.1.0, 2026-10-06), 이 저장소는 레지스트리
9
+ // 스킬 경로를 쓴다.
10
+ export default defineRecipe({
11
+ id: 'plugin.impeccable', category: 'plugin', label: 'impeccable', group: '__style',
19
12
  exclusive: 'impeccable',
20
13
  note: 'item.plugin.impeccable.note',
21
14
  verified: '2026-10-06',
22
- unsupported: Object.fromEntries(
23
- CLI_IDS.filter((c) => c !== 'claude').map((c) => [
24
- c,
25
- UPSTREAM.includes(c) ? msg('item.unsupported.impeccableSkill') : msg('item.unsupported.upstreamNone'),
26
- ]),
27
- ),
15
+ ...marketplacePlugin({
16
+ claude: { marketplace: 'pbakaus/impeccable', id: 'impeccable@impeccable' },
17
+ }),
18
+ reasons: {
19
+ codex: 'item.unsupported.impeccableSkill',
20
+ opencode: 'item.unsupported.impeccableSkill',
21
+ antigravity: 'item.unsupported.impeccableSkill',
22
+ copilot: 'item.unsupported.impeccableSkill',
23
+ vscode: 'item.unsupported.impeccableSkill',
24
+ },
28
25
  })
@@ -1,20 +1,26 @@
1
- import { definePlugin } from '../catalog.mjs'
2
- import { CLI_IDS } from '../clis.mjs'
3
- import { msg } from '../i18n/index.mjs'
4
- // 상류가 "Codex, and other agents" 절에서 `npx skills add mattpocock/skills`를
5
- // 안내한다 — 이 저장소의 레지스트리 스킬 항목이 쓰는 바로 그 경로다(레지스트리로
6
- // 35개가 보이는 것을 실측, 2026-08-15). 그러니 미배선 사유는 "상류에 없다"가
7
- // 아니라 "우리가 플러그인 쪽을 골랐다"이고, 사유가 그렇게 말해야 레지스트리
8
- // 항목으로 옮길 수 있다는 것도 화면에서 읽힌다.
9
- export default definePlugin({
10
- id: 'plugin.mattpocock-skills', label: 'Matt Pocock', group: '__flow',
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { marketplacePlugin } from '../recipe-helpers.mjs'
3
+
4
+ // 상류 README가 Claude 마켓플레이스와 함께 Codex 플러그인(`codex plugin
5
+ // marketplace add mattpocock/skills` + `codex plugin add
6
+ // mattpocock-skills@mattpocock`)을 안내한다(2026-10-24 확인). Copilot CLI도 README가 같은 두 명령을 안내한다
7
+ // (2026-11-06 확인) — `~/.copilot/settings.json`의 extraKnownMarketplaces는 자동
8
+ // 갱신 설정이라 건드리지 않는다. 그 밖의 에이전트는
9
+ // `npx skills add mattpocock/skills` — 이 저장소의 레지스트리 스킬 항목
10
+ // (skill.mattpocock-skills)이 쓰는 바로 그 경로라 배타로 묶는다.
11
+ export default defineRecipe({
12
+ id: 'plugin.mattpocock-skills', category: 'plugin', label: 'Matt Pocock', group: '__flow',
11
13
  exclusive: 'mattpocock',
12
- installId: 'mattpocock-skills@mattpocock',
13
- detectIds: ['mattpocock-skills@mattpocock'],
14
- marketplace: { name: 'mattpocock', repo: 'mattpocock/skills' },
15
14
  note: 'item.plugin.mattpocock-skills.note',
16
- verified: '2026-08-15',
17
- unsupported: Object.fromEntries(
18
- CLI_IDS.filter((c) => c !== 'claude').map((c) => [c, msg('item.unsupported.mattpocockRegistry')]),
19
- ),
15
+ verified: '2026-11-06',
16
+ ...marketplacePlugin({
17
+ claude: { marketplace: 'mattpocock/skills', id: 'mattpocock-skills@mattpocock' },
18
+ codex: { marketplace: 'mattpocock/skills', id: 'mattpocock-skills@mattpocock' },
19
+ copilot: { marketplace: 'mattpocock/skills', id: 'mattpocock-skills@mattpocock' },
20
+ }),
21
+ reasons: {
22
+ opencode: 'item.unsupported.mattpocockRegistry',
23
+ antigravity: 'item.unsupported.mattpocockRegistry',
24
+ vscode: 'item.unsupported.vscodePlugin',
25
+ },
20
26
  })
@@ -1,107 +1,25 @@
1
- import { CLI_IDS } from '../clis.mjs'
2
- import { isPluginEnabled, enablePlugin, disablePlugin } from '../claude-plugins.mjs'
3
- import { repoPath, repoPathStrict } from '../context.mjs'
4
- import { readJson, setKey, removeKey } from '../jsonfile.mjs'
5
- import { msg, LocalizedError } from '../i18n/index.mjs'
6
-
7
- // 상류 안내는 `--scope user`지만 이 저장소의 항목은 전부 프로젝트 스코프다.
8
- // 같은 규칙 묶음이 두 경로로 들어간다 — Claude Code는 플러그인 CLI(실패하면
9
- // .claude/settings.json 기록), OpenCode는 프로젝트 설정의 plugin 배열.
10
- // 두 경로 모두 저장소 안에만 쓴다.
11
- const INSTALL_ID = 'ponytail@ponytail'
12
- const MARKETPLACE = { name: 'ponytail', repo: 'DietrichGebert/ponytail' }
13
- const OPENCODE_FILE = 'opencode.jsonc'
14
- const OPENCODE_ENTRY = '@dietrichgebert/ponytail'
15
- const SUPPORTS = ['claude', 'opencode']
16
-
17
- // plugin 키가 배열이 아니면 손대지 않는다 — 통째로 덮어쓰면 사용자가 적어 둔
18
- // 설정이 조용히 사라진다. 없는 것(undefined)과 다른 타입을 구분해서 돌려준다.
19
- function opencodePlugins(root) {
20
- const value = readJson(repoPath(root, OPENCODE_FILE))?.plugin
21
- if (value === undefined) return []
22
- if (!Array.isArray(value)) return null
23
- return value
24
- }
25
-
26
- function opencodeListOrThrow(root) {
27
- const list = opencodePlugins(root)
28
- if (list === null) throw new LocalizedError('error.ponytailOpencodePlugin', { file: OPENCODE_FILE })
29
- return list
30
- }
31
-
32
- function hasOpencode(root) {
33
- return (opencodePlugins(root) ?? []).includes(OPENCODE_ENTRY)
34
- }
35
-
36
- export default {
37
- id: 'plugin.ponytail', category: 'plugin', label: 'Ponytail', scope: 'project',
38
- group: '__token',
39
- supports: SUPPORTS,
40
- unsupported: Object.fromEntries(
41
- CLI_IDS.filter((c) => !SUPPORTS.includes(c)).map((c) => [
42
- c,
43
- // codex·copilot·grok·gemini는 상류에 설치 경로가 있지만 전부 사용자
44
- // 스코프다. grok은 `grok plugin install DietrichGebert/ponytail --trust`로
45
- // 플러그인 기구가 엄연히 있다 — "기구가 없다" 쪽에 두면 거짓이다
46
- // (2026-08-15 재측정). 나머지는 상류의 규칙 파일을 손으로 옮겨야 한다.
47
- ['codex', 'copilot', 'gemini', 'grok'].includes(c)
48
- ? msg('item.unsupported.ponytailUser')
49
- : msg('item.unsupported.ponytailRules'),
50
- ]),
51
- ),
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { marketplacePlugin } from '../recipe-helpers.mjs'
3
+
4
+ // DietrichGebert/ponytail. 하니스별 공식 경로(상류 README·INSTALL.md, 2026-10-24):
5
+ // Claude·Codex는 마켓플레이스, OpenCode는 opencode plugin, Antigravity는
6
+ // agy plugin install <git URL>, Copilot CLI는 마켓플레이스(이 머신에서 설치·감지
7
+ // 확인, 2026-11-06). VS Code Copilot에는 플러그인 설치 명령이 없다. Codex는 설치 후 /hooks에서 라이프사이클 훅
8
+ // 두 개를 신뢰해야 켜진다 — hooks: true가 활성화 안내에 그 단계를 싣는다.
9
+ // 상류는 플러그인 제거 전에 scripts/uninstall.js로 ~/.config/ponytail 설정을
10
+ // 정리하라고 안내한다 — 하니스마다 스크립트 위치가 달라 note로만 알린다.
11
+ export default defineRecipe({
12
+ id: 'plugin.ponytail', category: 'plugin', label: 'Ponytail', group: '__token',
52
13
  note: 'item.plugin.ponytail.note',
53
- verified: '2026-08-15',
54
-
55
- async detect({ root }) {
56
- const present = []
57
- if (isPluginEnabled(root, [INSTALL_ID])) present.push('claude')
58
- if (hasOpencode(root)) present.push('opencode')
59
- if (present.length === 0) return { status: 'absent' }
60
- if (present.length === SUPPORTS.length) return { status: 'installed' }
61
- return {
62
- status: 'partial',
63
- detail: msg('item.plugin.partial', {
64
- present: present.join(', '),
65
- missing: SUPPORTS.filter((c) => !present.includes(c)).join(', '),
66
- }),
67
- }
68
- },
69
-
70
- async install({ root, dryRun, exec, log = () => {}, t }) {
71
- let deferred = false
72
- if (!isPluginEnabled(root, [INSTALL_ID])) {
73
- await exec('claude', ['plugin', 'marketplace', 'add', MARKETPLACE.repo], { cwd: root })
74
- const r = await exec('claude', ['plugin', 'install', INSTALL_ID, '--scope', 'project'], { cwd: root })
75
- if (!r.ok) {
76
- if (!dryRun) enablePlugin(root, INSTALL_ID, MARKETPLACE)
77
- deferred = true
78
- }
79
- }
80
- if (!hasOpencode(root)) {
81
- const list = opencodeListOrThrow(root)
82
- if (dryRun) log(t('log.plugin.add', { cli: 'OpenCode', name: OPENCODE_ENTRY }))
83
- // 파일이 없거나 plugin 키가 없으면 배열째 만들고, 있으면 끝에 덧붙인다.
84
- else if (list.length === 0) setKey(repoPathStrict(root, OPENCODE_FILE), ['plugin'], [OPENCODE_ENTRY])
85
- else setKey(repoPathStrict(root, OPENCODE_FILE), ['plugin', list.length], OPENCODE_ENTRY)
86
- }
87
- if (deferred) return { fallback: true, message: msg('item.plugin.deferred') }
88
- },
89
-
90
- async uninstall({ root, dryRun, exec, log = () => {}, t }) {
91
- if (isPluginEnabled(root, [INSTALL_ID])) {
92
- const r = await exec('claude', ['plugin', 'uninstall', INSTALL_ID], { cwd: root })
93
- if (!r.ok && !dryRun) disablePlugin(root, [INSTALL_ID])
94
- }
95
- if (!hasOpencode(root)) return
96
- if (dryRun) {
97
- log(t('log.plugin.remove', { cli: 'OpenCode', name: OPENCODE_ENTRY }))
98
- return
99
- }
100
- const kept = opencodeListOrThrow(root).filter((p) => p !== OPENCODE_ENTRY)
101
- const file = repoPathStrict(root, OPENCODE_FILE)
102
- // 우리가 넣은 항목만 빼고 비면 키째 지운다 — 빈 배열을 남기면 우리가
103
- // 만든 흔적이 설정에 계속 남는다.
104
- if (kept.length === 0) removeKey(file, ['plugin'])
105
- else setKey(file, ['plugin'], kept)
106
- },
107
- }
14
+ verified: '2026-11-06',
15
+ hooks: true,
16
+ postInstall: 'item.plugin.ponytail.post',
17
+ ...marketplacePlugin({
18
+ claude: { marketplace: 'DietrichGebert/ponytail', id: 'ponytail@ponytail' },
19
+ codex: { marketplace: 'DietrichGebert/ponytail', id: 'ponytail@ponytail' },
20
+ opencode: { module: '@dietrichgebert/ponytail' },
21
+ antigravity: { source: 'https://github.com/DietrichGebert/ponytail', name: 'ponytail' },
22
+ copilot: { marketplace: 'DietrichGebert/ponytail', id: 'ponytail@ponytail' },
23
+ }),
24
+ reasons: { vscode: 'item.unsupported.vscodePlugin' },
25
+ })
@@ -1,28 +1,24 @@
1
- import { definePlugin } from '../catalog.mjs'
2
- import { CLI_IDS } from '../clis.mjs'
3
- import { msg } from '../i18n/index.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { marketplacePlugin } from '../recipe-helpers.mjs'
4
3
 
5
- // 상류(obra/superpowers v6.3.0)는 Codex·Antigravity·Copilot CLI 등 14개
6
- // 하니스를 지원하지만 설치 명령이 하니스마다 전부 달라 공유 경로가 없다
7
- // (README: "install Superpowers separately for each one"). 이 항목이 배선하는
8
- // 것은 Claude Code 플러그인 판뿐이다. Kilo·Kiro·VS Code는 상류에 공식 설치
9
- // 경로가 없다(2026-08-15 재측정).
10
- // Grok은 6.2.0에는 없다가 6.3.0에서 들어왔다 — `### Grok Build CLI`의
11
- // `grok plugin install superpowers@xai-official --trust`다. Devin·Hermes도 같이
12
- // 늘었지만 둘 다 이 저장소가 다루는 CLI가 아니다.
13
- const SEPARATE = ['codex', 'gemini', 'opencode', 'kimi', 'copilot', 'grok', 'antigravity']
14
-
15
- export default definePlugin({
16
- id: 'plugin.superpowers', label: 'superpowers', group: '__flow',
4
+ // obra/superpowers. 상류는 하니스마다 설치 명령이 다르다(README: "install
5
+ // Superpowers separately for each one"). Claude는 공식 마켓플레이스
6
+ // (claude-plugins-official, 추가 등록 불필요), Codex는 obra/superpowers-marketplace
7
+ // (2026-08-15 헤드리스 실측), OpenCode는 git 모듈(.opencode/INSTALL.md),
8
+ // Antigravity는 agy plugin install <git URL>(README), Copilot CLI는 같은 마켓플레이스
9
+ // (README "GitHub Copilot CLI" 절). VS Code Copilot은 공식 경로가 없다. 같은 상류를 공유 스킬
10
+ // (skill.superpowers)로도 넣을 수 있어 배타로 묶는다.
11
+ export default defineRecipe({
12
+ id: 'plugin.superpowers', category: 'plugin', label: 'superpowers', group: '__flow',
17
13
  exclusive: 'superpowers',
18
- installId: 'superpowers@claude-plugins-official',
19
- detectIds: ['superpowers@claude-plugins-official', 'superpowers@superpowers-marketplace'],
20
14
  note: 'item.plugin.superpowers.note',
21
- verified: '2026-08-15',
22
- unsupported: Object.fromEntries(
23
- CLI_IDS.filter((c) => c !== 'claude').map((c) => [
24
- c,
25
- SEPARATE.includes(c) ? msg('item.unsupported.superpowersSeparate') : msg('item.unsupported.upstreamNone'),
26
- ]),
27
- ),
15
+ verified: '2026-11-06',
16
+ ...marketplacePlugin({
17
+ claude: { id: 'superpowers@claude-plugins-official', detectIds: ['superpowers@claude-plugins-official', 'superpowers@superpowers-marketplace'] },
18
+ codex: { marketplace: 'obra/superpowers-marketplace', id: 'superpowers@superpowers-marketplace' },
19
+ opencode: { module: 'superpowers@git+https://github.com/obra/superpowers.git' },
20
+ antigravity: { source: 'https://github.com/obra/superpowers', name: 'superpowers' },
21
+ copilot: { marketplace: 'obra/superpowers-marketplace', id: 'superpowers@superpowers-marketplace' },
22
+ }),
23
+ reasons: { vscode: 'item.unsupported.vscodePlugin' },
28
24
  })
@@ -1,22 +1,24 @@
1
- import { definePlugin } from '../catalog.mjs'
2
- import { CLI_IDS } from '../clis.mjs'
3
- import { msg } from '../i18n/index.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { marketplacePlugin } from '../recipe-helpers.mjs'
3
+
4
4
  // 상류는 Claude 전용이 아니다 — README의 "Multi-Platform Installation"이
5
- // codex·opencode·gemini·vscode·kimi·kiro를 install.sh -s <platform>으로 안내한다.
6
- // 그 경로가 ~/.understand-anything/repo에 클론하고 홈에 심볼릭 링크를 거는
7
- // 사용자 스코프라 이 저장소의 항목이 될 수 없다.
8
- // Copilot CLI만 갈래가 다르다 —
9
- // `copilot plugin install Egonex-AI/Understand-Anything:understand-anything-plugin`
10
- // 이라는 플러그인 직접 설치인데, `copilot plugin install`에 스코프 플래그가
11
- // 없어 결국 사용자 스코프다(2026-08-15 재측정).
12
- export default definePlugin({
13
- id: 'plugin.understand-anything', label: 'Understand Anything', group: '__context',
14
- installId: 'understand-anything@understand-anything',
15
- detectIds: ['understand-anything@understand-anything'],
16
- marketplace: { name: 'understand-anything', repo: 'Egonex-AI/Understand-Anything' },
5
+ // codex·opencode·antigravity 등을 install.sh <platform>으로 안내한다. 그 경로는
6
+ // ~/.understand-anything/repo에 클론하고 홈에 심볼릭 링크를 거는 스크립트라
7
+ // CLI 명령이 아니고, 이 설치기가 감지·제거할 근거도 없다(2026-08-15 재측정).
8
+ export default defineRecipe({
9
+ id: 'plugin.understand-anything', category: 'plugin', label: 'Understand Anything', group: '__context',
17
10
  note: 'item.plugin.understand-anything.note',
18
- verified: '2026-08-15',
19
- unsupported: Object.fromEntries(
20
- CLI_IDS.filter((c) => c !== 'claude').map((c) => [c, msg('item.unsupported.uaUser')]),
21
- ),
11
+ verified: '2026-11-06',
12
+ ...marketplacePlugin({
13
+ claude: { marketplace: 'Egonex-AI/Understand-Anything', id: 'understand-anything@understand-anything' },
14
+ // README "Copilot CLI" 절의 명령(2026-11-06). 마켓 없이 하위 경로를 직접 설치하므로
15
+ // 목록에는 마켓 없는 이름으로 나올 것이다 — 직접 설치의 목록 모양은 실측하지 못했다.
16
+ copilot: { source: 'Egonex-AI/Understand-Anything:understand-anything-plugin', id: 'understand-anything' },
17
+ }),
18
+ reasons: {
19
+ codex: 'item.unsupported.uaUser',
20
+ opencode: 'item.unsupported.uaUser',
21
+ antigravity: 'item.unsupported.uaUser',
22
+ vscode: 'item.unsupported.vscodePlugin',
23
+ },
22
24
  })
@@ -1,17 +1,17 @@
1
- import { defineRegistrySkill } from '../catalog.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { skillsAdd } from '../recipe-helpers.mjs'
2
3
  // SKILL.md는 안내 스텁이다 — 실제 워크플로 지침은 설치된 CLI가 런타임에 준다
3
4
  // (`agent-browser skills get core`). 그래서 스킬 복사만으로는 반쪽이고, PATH의
4
5
  // agent-browser 바이너리(npm i -g agent-browser)와 최초 1회
5
6
  // `agent-browser install`(Chrome for Testing 다운로드)이 사실상 전제다 —
6
7
  // note가 알린다. 본문은 Bash로 agent-browser를 부르라는 하네스 중립 문서라
7
- // 공유 디렉터리의 10개 CLI가 함께 쓴다. frontmatter의 allowed-tools와
8
+ // 공유 디렉터리의 네 CLI가 함께 쓴다. frontmatter의 allowed-tools와
8
9
  // hidden: true는 Claude Code 문법이라 다른 CLI는 무시한다.
9
10
  // (2026-08-15 확인: skills/agent-browser/SKILL.md 단일 스킬, npm agent-browser
10
11
  // 0.34.0 = vercel-labs 리포, 네이티브 바이너리는 Windows x64 포함.)
11
- export default defineRegistrySkill({
12
- id: 'skill.agent-browser', label: 'agent-browser', group: '__service',
13
- source: 'https://github.com/vercel-labs/agent-browser',
14
- skill: 'agent-browser',
12
+ export default defineRecipe({
13
+ id: 'skill.agent-browser', category: 'skill', label: 'agent-browser', group: '__service',
15
14
  note: 'item.skill.agent-browser.note',
16
15
  verified: '2026-08-15',
16
+ ...skillsAdd({ source: 'https://github.com/vercel-labs/agent-browser', skill: 'agent-browser' }),
17
17
  })
@@ -0,0 +1,14 @@
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { skillsAdd } from '../recipe-helpers.mjs'
3
+ // rch4com/agent-handoff-manager(MIT). 에이전트 사이 작업 인계를 저장·재개하는
4
+ // 스킬 하나(skills/agent-handoff-manager). 본체는 스킬 폴더의 scripts/handoff.py
5
+ // (표준 라이브러리만, Python 3.10+)라 PATH에 Python이 있어야 한다. 상류는
6
+ // Claude·Copilot 플러그인 매니페스트도 두지만 담긴 것이 같은 스킬 하나라
7
+ // 여섯 CLI가 함께 보는 공유 스킬 판을 택했다. 데이터는 대상 저장소의
8
+ // .handoffs/에 쌓인다.
9
+ export default defineRecipe({
10
+ id: 'skill.agent-handoff-manager', category: 'skill', label: 'Agent Handoff Manager', group: '__context',
11
+ note: 'item.skill.agent-handoff-manager.note',
12
+ verified: '2026-11-12',
13
+ ...skillsAdd({ source: 'https://github.com/rch4com/agent-handoff-manager', skill: 'agent-handoff-manager' }),
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
  // 상류 스킬은 archify/SKILL.md(MIT)이고, 저장소에는 기여자용
3
4
  // .agents/skills/archify-review도 있다. 레지스트리 경로가 늘 --skill archify를
4
5
  // 넘기므로 루트를 source로 줘도 archify 하나만 들어온다 — 상류 README가
@@ -10,10 +11,9 @@ import { defineRegistrySkill } from '../catalog.mjs'
10
11
  // 복사본에서 validate가 그대로 통과한다(2026-09-27 스크래치 저장소 실측).
11
12
  // 본문이 첫 산출물 뒤 scripts/check-update.mjs로 상류 매니페스트를 한 번
12
13
  // GET한다 — ARCHIFY_UPDATE_CHECK_DISABLED=1로 끈다. note가 알린다.
13
- export default defineRegistrySkill({
14
- id: 'skill.archify', label: 'Archify', group: '__style',
15
- source: 'https://github.com/tt-a1i/archify',
16
- skill: 'archify',
14
+ export default defineRecipe({
15
+ id: 'skill.archify', category: 'skill', label: 'Archify', group: '__style',
17
16
  note: 'item.skill.archify.note',
18
17
  verified: '2026-09-27',
18
+ ...skillsAdd({ source: 'https://github.com/tt-a1i/archify', skill: 'archify' }),
19
19
  })
@@ -1,7 +1,7 @@
1
- import { defineRegistrySkill } from '../catalog.mjs'
2
- export default defineRegistrySkill({
3
- id: 'skill.caveman', label: 'caveman', group: '__token',
4
- source: 'https://github.com/JuliusBrussee/caveman',
5
- skill: 'caveman',
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { skillsAdd } from '../recipe-helpers.mjs'
3
+ export default defineRecipe({
4
+ id: 'skill.caveman', category: 'skill', label: 'caveman', group: '__token',
6
5
  note: 'item.skill.caveman.note',
6
+ ...skillsAdd({ source: 'https://github.com/JuliusBrussee/caveman', skill: 'caveman' }),
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
  // 상류는 .claude-plugin·.codex-plugin 매니페스트를 함께 두지만 알맹이는
3
4
  // skills/diagram-design/SKILL.md 배치라, 기존 레지스트리 경로가 그대로 읽는다 —
4
5
  // 배선은 한 줄도 새로 만들지 않았다. SKILL.md의 name이 디렉터리 이름과 같아
@@ -6,9 +7,8 @@ import { defineRegistrySkill } from '../catalog.mjs'
6
7
  // 플러그인 경로만 주는 것은 commands/ 3개(/export-diagram·/import-drawio·
7
8
  // /import-mermaid)인데, 본문을 skills/.../references/에 위임하는 얇은 래퍼라
8
9
  // 규칙의 알맹이는 스킬 쪽에 전부 온다.
9
- export default defineRegistrySkill({
10
- id: 'skill.diagram-design', label: 'Diagram Design', group: '__style',
11
- source: 'https://github.com/cathrynlavery/diagram-design',
12
- skill: 'diagram-design',
10
+ export default defineRecipe({
11
+ id: 'skill.diagram-design', category: 'skill', label: 'Diagram Design', group: '__style',
13
12
  note: 'item.skill.diagram-design.note',
13
+ ...skillsAdd({ source: 'https://github.com/cathrynlavery/diagram-design', skill: 'diagram-design' }),
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
  // Anthropic 커뮤니티 마켓플레이스(anthropics/claude-plugins-community)의 eli5
3
4
  // 플러그인이 담은 스킬 하나(eli5/skills/eli5/SKILL.md, MIT). `/eli5 <주제>`를
4
5
  // 큰 그림과 짧은 글의 HTML 설명서로 만든다. 저장소 전체가 아니라 eli5/ 하위
@@ -7,13 +8,12 @@ import { defineRegistrySkill } from '../catalog.mjs'
7
8
  // (1K)만 들어온다(2026-09-18 스크래치 저장소 실측).
8
9
  //
9
10
  // 상류의 본래 경로는 Claude 플러그인(eli5@claude-community)이지만, 플러그인이
10
- // 더 주는 것이 없고(훅·명령 없이 스킬 하나) 공유 스킬 판은 11개 CLI가 함께
11
+ // 더 주는 것이 없고(훅·명령 없이 스킬 하나) 공유 스킬 판은 네 CLI가 함께
11
12
  // 보므로 이쪽을 택했다. 본문은 $ARGUMENTS를 쓰는 슬래시 호출 형식이라
12
13
  // 인자 치환이 없는 CLI에서는 대화로 주제를 주면 된다.
13
- export default defineRegistrySkill({
14
- id: 'skill.eli5', label: 'ELI5', group: '__style',
15
- source: 'https://github.com/anthropics/claude-plugins-community/tree/main/eli5',
16
- skill: 'eli5',
14
+ export default defineRecipe({
15
+ id: 'skill.eli5', category: 'skill', label: 'ELI5', group: '__style',
17
16
  note: 'item.skill.eli5.note',
18
17
  verified: '2026-09-18',
18
+ ...skillsAdd({ source: 'https://github.com/anthropics/claude-plugins-community/tree/main/eli5', skill: 'eli5' }),
19
19
  })
@@ -1,13 +1,13 @@
1
- import { defineRegistrySkill } from '../catalog.mjs'
1
+ import { defineRecipe } from '../recipe.mjs'
2
+ import { skillsAdd } from '../recipe-helpers.mjs'
2
3
  // vercel-labs/skills는 이 저장소의 레지스트리 항목들이 쓰는 `npx skills` CLI
3
4
  // 본체 리포인데, 자체 배포 스킬은 find-skills 하나다(skills/find-skills/
4
5
  // SKILL.md, 2026-08-15 확인). 본문은 npx skills find/add/update 명령만
5
6
  // 지시하는 하네스 중립 문서다. README 예시에 나오는 web-design-guidelines
6
7
  // 등은 별도 리포(vercel-labs/agent-skills) 소속이라 이 항목과 무관하다.
7
- export default defineRegistrySkill({
8
- id: 'skill.find-skills', label: 'find-skills', group: '__flow',
9
- source: 'https://github.com/vercel-labs/skills',
10
- skill: 'find-skills',
8
+ export default defineRecipe({
9
+ id: 'skill.find-skills', category: 'skill', label: 'find-skills', group: '__flow',
11
10
  note: 'item.skill.find-skills.note',
12
11
  verified: '2026-08-15',
12
+ ...skillsAdd({ source: 'https://github.com/vercel-labs/skills', skill: 'find-skills' }),
13
13
  })