@su-record/vibe 3.2.31 → 3.2.32
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/.claude-plugin/plugin.json +22 -0
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +29 -8
- package/dist/cli/commands/plugin.d.ts.map +1 -1
- package/dist/cli/commands/plugin.js +77 -3
- package/dist/cli/commands/plugin.js.map +1 -1
- package/dist/cli/postinstall/claude-agents.d.ts +10 -0
- package/dist/cli/postinstall/claude-agents.d.ts.map +1 -1
- package/dist/cli/postinstall/claude-agents.js +20 -2
- package/dist/cli/postinstall/claude-agents.js.map +1 -1
- package/hooks/claude-plugin-hooks.json +123 -0
- package/hooks/plugin-hooks.json +13 -13
- package/hooks/scripts/plugin-hook-entry.js +57 -0
- package/package.json +7 -2
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vibe",
|
|
3
|
+
"displayName": "Vibe",
|
|
4
|
+
"version": "3.2.32",
|
|
5
|
+
"description": "Verification harness for AI coding agents — \"done\" is decided by deterministic gates (test exit codes, run-ledger, regression memory), not the model self-report.",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "su-record",
|
|
8
|
+
"url": "https://github.com/su-record"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/su-record/vibe",
|
|
11
|
+
"repository": "https://github.com/su-record/vibe",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"verification",
|
|
15
|
+
"spec",
|
|
16
|
+
"testing",
|
|
17
|
+
"code-review",
|
|
18
|
+
"loop",
|
|
19
|
+
"harness"
|
|
20
|
+
],
|
|
21
|
+
"hooks": "./hooks/claude-plugin-hooks.json"
|
|
22
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibe",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.32",
|
|
4
4
|
"description": "Verification harness for AI coding agents — \"done\" is decided by deterministic gates (test exit codes, run-ledger, regression memory), not the model self-report.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "su-record",
|
package/README.md
CHANGED
|
@@ -197,26 +197,47 @@ codex
|
|
|
197
197
|
|
|
198
198
|
## 플러그인으로 설치 (실험적)
|
|
199
199
|
|
|
200
|
-
npm 전역
|
|
200
|
+
npm 전역 설치의 **대안** 경로다. Claude Code · Codex · ChatGPT 세 곳에 같은 배포 트리(`plugins/vibe`)가 올라간다.
|
|
201
201
|
|
|
202
|
-
**
|
|
202
|
+
**Claude Code — 저장소에서 바로** (npm 설치 불필요)
|
|
203
203
|
|
|
204
204
|
```bash
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
205
|
+
claude plugin marketplace add su-record/vibe
|
|
206
|
+
claude plugin install vibe@vibe
|
|
207
|
+
claude plugin details vibe # Skills 52 · Agents 11 · Hooks 6
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**npm 으로 이미 설치한 경우**
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
vibe plugin install # 배포 트리 조립 + 마켓플레이스 두 벌 등록
|
|
214
|
+
vibe plugin status # 조립·등록 상태 확인
|
|
215
|
+
|
|
216
|
+
claude plugin marketplace add ~/.vibe/plugin
|
|
217
|
+
claude plugin install vibe@vibe
|
|
218
|
+
|
|
219
|
+
codex plugin marketplace add ~
|
|
220
|
+
codex plugin add vibe@vibe
|
|
210
221
|
```
|
|
211
222
|
|
|
212
223
|
**저장소를 클론한 경우** (개발·검증용)
|
|
213
224
|
|
|
214
225
|
```bash
|
|
215
|
-
npm run build:plugin
|
|
226
|
+
npm run build:plugin # plugins/vibe/ 로 조립 (package.json files 기준)
|
|
227
|
+
claude plugin validate plugins/vibe
|
|
216
228
|
codex plugin marketplace add .
|
|
217
229
|
codex plugin add vibe@vibe-local
|
|
218
230
|
```
|
|
219
231
|
|
|
232
|
+
> **훅 이중 실행은 자동으로 막힌다.** npm 설치본의 프로젝트 훅이 이미 있으면 플러그인 훅은
|
|
233
|
+
> 스스로 물러난다 (`plugin-hook-entry.js`). 그러지 않으면 같은 게이트가 2회 돌고
|
|
234
|
+
> Stop 의 auto-commit 도 2회 돈다.
|
|
235
|
+
>
|
|
236
|
+
> **`plugins/vibe/` 는 커밋되는 생성물이다.** Claude Code 마켓플레이스는 저장소를 클론해 읽는데
|
|
237
|
+
> `dist/` 는 gitignore 대상이고 `agents/*.md` 의 frontmatter 는 postinstall 이 만든다 —
|
|
238
|
+
> 즉 저장소를 그대로 가리키면 기능이 빠진 플러그인이 된다 (실측: 에이전트 11개 중 7개만,
|
|
239
|
+
> 그나마 description 없이 로드). 드리프트는 CI 의 `validate:plugin-tree` 가 막는다.
|
|
240
|
+
|
|
220
241
|
ChatGPT 데스크톱 앱에서는 앱을 **재시작**한 뒤 Plugins Directory 에서 "Vibe (local)" → `vibe` 를 설치한다.
|
|
221
242
|
|
|
222
243
|
> 마켓플레이스 파일만 만들어두면 잡히지 않는다 — `marketplace add` 로 **등록**해야 한다.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/plugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/plugin.ts"],"names":[],"mappings":"AAqKA,oCAAoC;AACpC,wBAAgB,aAAa,IAAI,IAAI,CA4CpC;AAGD,gCAAgC;AAChC,wBAAgB,YAAY,IAAI,IAAI,CAyBnC"}
|
|
@@ -14,9 +14,10 @@ import os from 'os';
|
|
|
14
14
|
import path from 'path';
|
|
15
15
|
import { log } from '../utils.js';
|
|
16
16
|
import { getCoreConfigDir } from '../setup/GlobalInstaller.js';
|
|
17
|
+
import { convertAgentToClaude } from '../postinstall/claude-agents.js';
|
|
17
18
|
/** 조립 대상 — package.json `files` 와 같은 목록을 쓴다 (배포 내용의 SSOT) */
|
|
18
19
|
const PLUGIN_ENTRIES = [
|
|
19
|
-
'.codex-plugin', 'dist', 'vibe', 'languages', 'agents', 'skills', 'hooks',
|
|
20
|
+
'.codex-plugin', '.claude-plugin', 'dist', 'vibe', 'languages', 'agents', 'skills', 'hooks',
|
|
20
21
|
'CLAUDE.md', 'README.md', 'LICENSE',
|
|
21
22
|
];
|
|
22
23
|
/** 조립본에 넣지 않는다 — 테스트와 의존성은 플러그인 런타임에 불필요하다 */
|
|
@@ -24,6 +25,10 @@ const SKIP = new Set(['node_modules', '__tests__']);
|
|
|
24
25
|
function pluginTreeDir() {
|
|
25
26
|
return path.join(getCoreConfigDir(), 'plugin', 'vibe');
|
|
26
27
|
}
|
|
28
|
+
/** Claude Code 마켓플레이스 — 플러그인 트리의 **부모**에 둔다 (source 가 `./vibe`) */
|
|
29
|
+
function claudeMarketplacePath() {
|
|
30
|
+
return path.join(pluginTreeDir(), '..', '.claude-plugin', 'marketplace.json');
|
|
31
|
+
}
|
|
27
32
|
function marketplacePath() {
|
|
28
33
|
return path.join(marketplaceRoot(), '.agents', 'plugins', 'marketplace.json');
|
|
29
34
|
}
|
|
@@ -85,6 +90,67 @@ function writeMarketplace(pluginDir) {
|
|
|
85
90
|
fs.writeFileSync(file, JSON.stringify(doc, null, 2) + '\n');
|
|
86
91
|
return file;
|
|
87
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Claude Code 마켓플레이스를 쓴다 — 스키마가 Codex 쪽과 다르다.
|
|
95
|
+
*
|
|
96
|
+
* `owner` 는 문자열이 아니라 객체여야 하고(`claude plugin validate` 가 거부한다),
|
|
97
|
+
* `source` 는 마켓플레이스 루트 기준 상대 경로 문자열이다.
|
|
98
|
+
*/
|
|
99
|
+
function writeClaudeMarketplace(pluginDir) {
|
|
100
|
+
const file = claudeMarketplacePath();
|
|
101
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
102
|
+
fs.writeFileSync(file, JSON.stringify({
|
|
103
|
+
$schema: 'https://anthropic.com/claude-code/marketplace.schema.json',
|
|
104
|
+
name: 'vibe',
|
|
105
|
+
description: 'Verification harness for AI coding agents — deterministic gates decide "done".',
|
|
106
|
+
owner: { name: 'su-record', url: 'https://github.com/su-record' },
|
|
107
|
+
plugins: [{
|
|
108
|
+
name: 'vibe',
|
|
109
|
+
displayName: 'Vibe',
|
|
110
|
+
description: 'Natural-language requirement to a SPEC you approve once, then an'
|
|
111
|
+
+ ' ANCHOR→ACT→JUDGE→RECORD loop until deterministic gates pass.',
|
|
112
|
+
author: { name: 'su-record' },
|
|
113
|
+
category: 'productivity',
|
|
114
|
+
homepage: 'https://github.com/su-record/vibe',
|
|
115
|
+
source: `./${path.basename(pluginDir)}`,
|
|
116
|
+
}],
|
|
117
|
+
}, null, 2) + '\n');
|
|
118
|
+
return file;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* 에이전트에 frontmatter 를 굽고 평면으로 다시 쓴다.
|
|
122
|
+
*
|
|
123
|
+
* 저장소·npm tarball 의 `agents/*.md` 에는 frontmatter 가 없다 — postinstall 이
|
|
124
|
+
* 설치 시점에 만든다. 플러그인은 그 단계를 거치지 않으므로 여기서 굽지 않으면
|
|
125
|
+
* description·model·tools 없이 로드된다. 평면화는 Claude Code 가 `agents/*.md` 만
|
|
126
|
+
* 스캔하기 때문이다(실측: 하위 디렉토리의 4개가 경고 없이 사라졌다).
|
|
127
|
+
*/
|
|
128
|
+
function bakeAgents(dir) {
|
|
129
|
+
if (!fs.existsSync(dir))
|
|
130
|
+
return;
|
|
131
|
+
const agents = [];
|
|
132
|
+
const walk = (current, rel) => {
|
|
133
|
+
for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
|
|
134
|
+
if (entry.isDirectory()) {
|
|
135
|
+
if (rel === '' && entry.name === 'teams')
|
|
136
|
+
continue;
|
|
137
|
+
walk(path.join(current, entry.name), rel ? `${rel}/${entry.name}` : entry.name);
|
|
138
|
+
}
|
|
139
|
+
else if (entry.name.endsWith('.md')) {
|
|
140
|
+
agents.push({
|
|
141
|
+
name: entry.name,
|
|
142
|
+
content: fs.readFileSync(path.join(current, entry.name), 'utf-8'),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
walk(dir, '');
|
|
148
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
149
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
150
|
+
for (const { name, content } of agents) {
|
|
151
|
+
fs.writeFileSync(path.join(dir, name), convertAgentToClaude(content, name), 'utf-8');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
88
154
|
/** 플러그인 트리를 조립하고 개인 마켓플레이스에 등록한다 */
|
|
89
155
|
export function pluginInstall() {
|
|
90
156
|
const root = packageRoot();
|
|
@@ -105,19 +171,27 @@ export function pluginInstall() {
|
|
|
105
171
|
process.exitCode = 1;
|
|
106
172
|
return;
|
|
107
173
|
}
|
|
174
|
+
bakeAgents(path.join(out, 'agents'));
|
|
108
175
|
const file = writeMarketplace(out);
|
|
176
|
+
const claudeFile = writeClaudeMarketplace(out);
|
|
109
177
|
log(`
|
|
110
178
|
✅ vibe 플러그인 준비 완료
|
|
111
179
|
|
|
112
|
-
플러그인
|
|
180
|
+
플러그인 ${out}
|
|
113
181
|
마켓플레이스 ${file}
|
|
114
|
-
|
|
182
|
+
${claudeFile}
|
|
183
|
+
포함 ${copied.join(', ')}
|
|
115
184
|
|
|
116
185
|
다음 단계:
|
|
186
|
+
Claude Code claude plugin marketplace add ${path.dirname(path.dirname(claudeFile))}
|
|
187
|
+
claude plugin install vibe@vibe
|
|
117
188
|
Codex codex plugin marketplace add ${marketplaceRoot()}
|
|
118
189
|
codex plugin add vibe@vibe
|
|
119
190
|
(훅은 설치만으로 신뢰되지 않습니다 — Codex 가 정의를 검토·승인해야 실행됩니다)
|
|
120
191
|
ChatGPT 앱 앱을 재시작한 뒤 Plugins Directory 에서 Vibe 설치
|
|
192
|
+
|
|
193
|
+
⚠️ npm 설치본의 프로젝트 훅이 이미 있으면 플러그인 훅은 스스로 물러납니다
|
|
194
|
+
(같은 게이트가 두 번 도는 것을 막습니다).
|
|
121
195
|
`);
|
|
122
196
|
}
|
|
123
197
|
/** 조립 상태와 마켓플레이스 등록 여부를 보고한다 */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../src/cli/commands/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../src/cli/commands/plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,16 @@
|
|
|
4
4
|
* VIBE 에이전트 마크다운 파일을 Claude Code 네이티브 서브에이전트 형식
|
|
5
5
|
* (YAML frontmatter 포함)으로 변환하여 ~/.claude/agents/에 설치
|
|
6
6
|
*/
|
|
7
|
+
/**
|
|
8
|
+
* VIBE 에이전트를 Claude Code 네이티브 서브에이전트 형식으로 변환
|
|
9
|
+
*
|
|
10
|
+
* export 인 이유: 플러그인 배포 트리(`scripts/build-plugin.ts`)도 같은 변환을 써야
|
|
11
|
+
* 한다. 저장소의 `agents/*.md` 에는 frontmatter 가 없고 — 설치 시점에 여기서
|
|
12
|
+
* 생성된다 — 플러그인은 postinstall 을 거치지 않으므로 빌드 때 미리 굽지 않으면
|
|
13
|
+
* description·model·tools 없이 로드된다(실측: `claude plugin validate` 경고 11건).
|
|
14
|
+
* 변환 로직을 두 벌로 만들면 그 순간부터 갈라진다.
|
|
15
|
+
*/
|
|
16
|
+
export declare function convertAgentToClaude(content: string, filename: string): string;
|
|
7
17
|
export interface InstallClaudeAgentsOptions {
|
|
8
18
|
/** 최상위 디렉토리명 기준 제외 목록 (예: 조건부 그룹 'ui'/'figma'/'event') */
|
|
9
19
|
skipDirs?: ReadonlyArray<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-agents.d.ts","sourceRoot":"","sources":["../../../src/cli/postinstall/claude-agents.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"claude-agents.d.ts","sourceRoot":"","sources":["../../../src/cli/postinstall/claude-agents.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAqDH;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA4D9E;AAED,MAAM,WAAW,0BAA0B;IACzC,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACjC,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAClC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,EACvB,OAAO,GAAE,0BAA+B,GACvC,IAAI,CAiEN"}
|
|
@@ -31,10 +31,28 @@ function generateDescription(name, title, roleLines) {
|
|
|
31
31
|
};
|
|
32
32
|
return descriptions[name] || `${title}. ${roleDesc}. Use proactively when relevant.`;
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* YAML 스칼라로 안전하게 감싼다.
|
|
36
|
+
*
|
|
37
|
+
* WHY: description 에 `: ` 가 들어가면 — `caller passes focus: correctness` 처럼
|
|
38
|
+
* 자연스럽게 생긴다 — 평문 스칼라가 매핑으로 해석돼 frontmatter 전체가 파싱에
|
|
39
|
+
* 실패한다. 그러면 name·model·tools·permissionMode 까지 **통째로 조용히 버려지고**
|
|
40
|
+
* 에이전트는 메타데이터 없이 로드된다. 실측: 설치본 11개 중 4개가 이 상태였고
|
|
41
|
+
* (`code-reviewer`·`e2e-tester`·`event-ops`·`security-reviewer`) 아무 경고도 없었다.
|
|
42
|
+
*/
|
|
43
|
+
function yamlString(value) {
|
|
44
|
+
return `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
|
|
45
|
+
}
|
|
34
46
|
/**
|
|
35
47
|
* VIBE 에이전트를 Claude Code 네이티브 서브에이전트 형식으로 변환
|
|
48
|
+
*
|
|
49
|
+
* export 인 이유: 플러그인 배포 트리(`scripts/build-plugin.ts`)도 같은 변환을 써야
|
|
50
|
+
* 한다. 저장소의 `agents/*.md` 에는 frontmatter 가 없고 — 설치 시점에 여기서
|
|
51
|
+
* 생성된다 — 플러그인은 postinstall 을 거치지 않으므로 빌드 때 미리 굽지 않으면
|
|
52
|
+
* description·model·tools 없이 로드된다(실측: `claude plugin validate` 경고 11건).
|
|
53
|
+
* 변환 로직을 두 벌로 만들면 그 순간부터 갈라진다.
|
|
36
54
|
*/
|
|
37
|
-
function convertAgentToClaude(content, filename) {
|
|
55
|
+
export function convertAgentToClaude(content, filename) {
|
|
38
56
|
const normalizedContent = content.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
39
57
|
const name = path.basename(filename, '.md');
|
|
40
58
|
// 미등록 에이전트는 세션 모델을 상속한다 — 매핑 누락이 조용한 다운그레이드가
|
|
@@ -66,7 +84,7 @@ function convertAgentToClaude(content, filename) {
|
|
|
66
84
|
// YAML frontmatter 조립
|
|
67
85
|
let frontmatter = '---\n';
|
|
68
86
|
frontmatter += `name: ${name}\n`;
|
|
69
|
-
frontmatter += `description: ${description}\n`;
|
|
87
|
+
frontmatter += `description: ${yamlString(description)}\n`;
|
|
70
88
|
frontmatter += `model: ${model}\n`;
|
|
71
89
|
frontmatter += `tools: ${tools.join(', ')}\n`;
|
|
72
90
|
frontmatter += `permissionMode: ${permissionMode}\n`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-agents.js","sourceRoot":"","sources":["../../../src/cli/postinstall/claude-agents.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,0BAA0B,EAC1B,4BAA4B,EAC5B,6BAA6B,EAC7B,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AAExB;;GAEG;AACH,SAAS,mBAAmB,CAAC,IAAY,EAAE,KAAa,EAAE,SAAmB;IAC3E,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEtC,MAAM,YAAY,GAA2B;QAC3C,WAAW,EAAE,8CAA8C,QAAQ,kGAAkG;QACrK,aAAa,EAAE,mCAAmC,QAAQ,+DAA+D;QACzH,QAAQ,EAAE,gGAAgG,QAAQ,oFAAoF;QACtM,YAAY,EAAE,2CAA2C,QAAQ,+EAA+E;QAChJ,sBAAsB,EAAE,mCAAmC,QAAQ,mDAAmD;QACtH,iEAAiE;QACjE,eAAe,EAAE,8JAA8J,QAAQ,yEAAyE;QAChQ,mBAAmB,EAAE,yCAAyC,QAAQ,kKAAkK;QACxO,gCAAgC;QAChC,iBAAiB,EAAE,4GAA4G,QAAQ,gBAAgB;QACvJ,mBAAmB,EAAE,4BAA4B,QAAQ,+DAA+D;QACxH,mCAAmC;QACnC,eAAe,EAAE,uDAAuD,QAAQ,6CAA6C;QAC7H,WAAW,EAAE,wDAAwD,QAAQ,yCAAyC;KACvH,CAAC;IAEF,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,GAAG,KAAK,KAAK,QAAQ,kCAAkC,CAAC;AACvF,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"claude-agents.js","sourceRoot":"","sources":["../../../src/cli/postinstall/claude-agents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "Claude Code 플러그인용 훅 정의. hooks/hooks.json 에서 생성된다 (scripts/gen-plugin-hooks.ts) — 손으로 고치지 말 것. Claude Code 가 주입하는 ${CLAUDE_PLUGIN_ROOT} 를 쓰며, plugin-hook-entry.js 를 거쳐 npm 설치본과의 이중 실행을 막는다.",
|
|
3
|
+
"hooks": {
|
|
4
|
+
"SessionStart": [
|
|
5
|
+
{
|
|
6
|
+
"matcher": "startup|resume|clear",
|
|
7
|
+
"hooks": [
|
|
8
|
+
{
|
|
9
|
+
"type": "command",
|
|
10
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js session-start.js"
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"PreToolUse": [
|
|
16
|
+
{
|
|
17
|
+
"matcher": "Bash",
|
|
18
|
+
"hooks": [
|
|
19
|
+
{
|
|
20
|
+
"type": "command",
|
|
21
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js pre-tool-dispatcher.js Bash"
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"matcher": "Edit",
|
|
27
|
+
"hooks": [
|
|
28
|
+
{
|
|
29
|
+
"type": "command",
|
|
30
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js pre-tool-dispatcher.js Edit"
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"matcher": "Write",
|
|
36
|
+
"hooks": [
|
|
37
|
+
{
|
|
38
|
+
"type": "command",
|
|
39
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js pre-tool-dispatcher.js Write"
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"matcher": "mcp__github__create_pull_request",
|
|
45
|
+
"hooks": [
|
|
46
|
+
{
|
|
47
|
+
"type": "command",
|
|
48
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js pr-test-gate.js"
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"PostToolUse": [
|
|
54
|
+
{
|
|
55
|
+
"matcher": "Write|Edit",
|
|
56
|
+
"hooks": [
|
|
57
|
+
{
|
|
58
|
+
"type": "command",
|
|
59
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js post-edit-dispatcher.js"
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"matcher": "Edit|Write|Bash|Task|SlashCommand|NotebookEdit",
|
|
65
|
+
"hooks": [
|
|
66
|
+
{
|
|
67
|
+
"type": "command",
|
|
68
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js step-counter.js"
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
"UserPromptSubmit": [
|
|
74
|
+
{
|
|
75
|
+
"hooks": [
|
|
76
|
+
{
|
|
77
|
+
"type": "command",
|
|
78
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js prompt-dispatcher.js"
|
|
79
|
+
}
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
"Notification": [
|
|
84
|
+
{
|
|
85
|
+
"matcher": "context_window_80",
|
|
86
|
+
"hooks": [
|
|
87
|
+
{
|
|
88
|
+
"type": "command",
|
|
89
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js context-save.js medium"
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"matcher": "context_window_90",
|
|
95
|
+
"hooks": [
|
|
96
|
+
{
|
|
97
|
+
"type": "command",
|
|
98
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js context-save.js high"
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"matcher": "context_window_95",
|
|
104
|
+
"hooks": [
|
|
105
|
+
{
|
|
106
|
+
"type": "command",
|
|
107
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js context-save.js critical"
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
"Stop": [
|
|
113
|
+
{
|
|
114
|
+
"hooks": [
|
|
115
|
+
{
|
|
116
|
+
"type": "command",
|
|
117
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js stop-dispatcher.js"
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
}
|
package/hooks/plugin-hooks.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_comment": "
|
|
2
|
+
"_comment": "Codex 플러그인용 훅 정의. hooks/hooks.json 에서 생성된다 (scripts/gen-plugin-hooks.ts) — 손으로 고치지 말 것. npm 경로는 postinstall 이 {{VIBE_PATH}} 를 치환하지만 플러그인은 치환 단계가 없어 런타임 변수 ${PLUGIN_ROOT} 를 쓴다. 커맨드가 plugin-hook-entry.js 를 거치는 이유는 npm 설치본과 겹칠 때 같은 훅이 두 번 도는 것을 막기 위해서다.",
|
|
3
3
|
"hooks": {
|
|
4
4
|
"SessionStart": [
|
|
5
5
|
{
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"hooks": [
|
|
8
8
|
{
|
|
9
9
|
"type": "command",
|
|
10
|
-
"command": "node ${PLUGIN_ROOT}/hooks/scripts/session-start.js"
|
|
10
|
+
"command": "node ${PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js session-start.js"
|
|
11
11
|
}
|
|
12
12
|
]
|
|
13
13
|
}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"hooks": [
|
|
19
19
|
{
|
|
20
20
|
"type": "command",
|
|
21
|
-
"command": "node ${PLUGIN_ROOT}/hooks/scripts/pre-tool-dispatcher.js Bash"
|
|
21
|
+
"command": "node ${PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js pre-tool-dispatcher.js Bash"
|
|
22
22
|
}
|
|
23
23
|
]
|
|
24
24
|
},
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"hooks": [
|
|
28
28
|
{
|
|
29
29
|
"type": "command",
|
|
30
|
-
"command": "node ${PLUGIN_ROOT}/hooks/scripts/pre-tool-dispatcher.js Edit"
|
|
30
|
+
"command": "node ${PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js pre-tool-dispatcher.js Edit"
|
|
31
31
|
}
|
|
32
32
|
]
|
|
33
33
|
},
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"hooks": [
|
|
37
37
|
{
|
|
38
38
|
"type": "command",
|
|
39
|
-
"command": "node ${PLUGIN_ROOT}/hooks/scripts/pre-tool-dispatcher.js Write"
|
|
39
|
+
"command": "node ${PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js pre-tool-dispatcher.js Write"
|
|
40
40
|
}
|
|
41
41
|
]
|
|
42
42
|
},
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"hooks": [
|
|
46
46
|
{
|
|
47
47
|
"type": "command",
|
|
48
|
-
"command": "node ${PLUGIN_ROOT}/hooks/scripts/pr-test-gate.js"
|
|
48
|
+
"command": "node ${PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js pr-test-gate.js"
|
|
49
49
|
}
|
|
50
50
|
]
|
|
51
51
|
}
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"hooks": [
|
|
57
57
|
{
|
|
58
58
|
"type": "command",
|
|
59
|
-
"command": "node ${PLUGIN_ROOT}/hooks/scripts/post-edit-dispatcher.js"
|
|
59
|
+
"command": "node ${PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js post-edit-dispatcher.js"
|
|
60
60
|
}
|
|
61
61
|
]
|
|
62
62
|
},
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"hooks": [
|
|
66
66
|
{
|
|
67
67
|
"type": "command",
|
|
68
|
-
"command": "node ${PLUGIN_ROOT}/hooks/scripts/step-counter.js"
|
|
68
|
+
"command": "node ${PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js step-counter.js"
|
|
69
69
|
}
|
|
70
70
|
]
|
|
71
71
|
}
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"hooks": [
|
|
76
76
|
{
|
|
77
77
|
"type": "command",
|
|
78
|
-
"command": "node ${PLUGIN_ROOT}/hooks/scripts/prompt-dispatcher.js"
|
|
78
|
+
"command": "node ${PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js prompt-dispatcher.js"
|
|
79
79
|
}
|
|
80
80
|
]
|
|
81
81
|
}
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"hooks": [
|
|
87
87
|
{
|
|
88
88
|
"type": "command",
|
|
89
|
-
"command": "node ${PLUGIN_ROOT}/hooks/scripts/context-save.js medium"
|
|
89
|
+
"command": "node ${PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js context-save.js medium"
|
|
90
90
|
}
|
|
91
91
|
]
|
|
92
92
|
},
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
"hooks": [
|
|
96
96
|
{
|
|
97
97
|
"type": "command",
|
|
98
|
-
"command": "node ${PLUGIN_ROOT}/hooks/scripts/context-save.js high"
|
|
98
|
+
"command": "node ${PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js context-save.js high"
|
|
99
99
|
}
|
|
100
100
|
]
|
|
101
101
|
},
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
"hooks": [
|
|
105
105
|
{
|
|
106
106
|
"type": "command",
|
|
107
|
-
"command": "node ${PLUGIN_ROOT}/hooks/scripts/context-save.js critical"
|
|
107
|
+
"command": "node ${PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js context-save.js critical"
|
|
108
108
|
}
|
|
109
109
|
]
|
|
110
110
|
}
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
"hooks": [
|
|
115
115
|
{
|
|
116
116
|
"type": "command",
|
|
117
|
-
"command": "node ${PLUGIN_ROOT}/hooks/scripts/stop-dispatcher.js"
|
|
117
|
+
"command": "node ${PLUGIN_ROOT}/hooks/scripts/plugin-hook-entry.js stop-dispatcher.js"
|
|
118
118
|
}
|
|
119
119
|
]
|
|
120
120
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 플러그인 훅의 단일 진입점 — 이중 실행을 막는다.
|
|
3
|
+
*
|
|
4
|
+
* 실측한 사건: vibe 를 npm 으로 설치하면 프로젝트에 `.claude/settings.local.json`
|
|
5
|
+
* 훅 6개가 설치된다. 여기에 플러그인까지 설치하면 **같은 6개 이벤트가 두 벌** 등록돼
|
|
6
|
+
* 모든 게이트가 2회 돌고, Stop 의 auto-commit·devlog 도 2회 돈다. 게이트가 두 번
|
|
7
|
+
* 도는 건 느린 정도지만 커밋이 두 번 나는 건 되돌릴 일이 생긴다.
|
|
8
|
+
*
|
|
9
|
+
* 그래서 플러그인 훅은 전부 이 진입점을 거친다. 프로젝트에 vibe 훅이 이미 있으면
|
|
10
|
+
* **플러그인 쪽이 물러난다** — 프로젝트 설정이 사용자가 명시적으로 설치한 것이고,
|
|
11
|
+
* 경로도 그쪽이 정확하기 때문이다(플러그인 트리에는 node_modules 가 없다).
|
|
12
|
+
*
|
|
13
|
+
* 실행은 spawn 이 아니라 in-process `import` 다 — 훅 레이턴시 규약(CLAUDE.md
|
|
14
|
+
* "dispatcher in-process 평탄화")을 플러그인 경로에서도 깨지 않는다.
|
|
15
|
+
*/
|
|
16
|
+
import fs from 'fs';
|
|
17
|
+
import path from 'path';
|
|
18
|
+
import { pathToFileURL } from 'url';
|
|
19
|
+
|
|
20
|
+
/** 프로젝트에 vibe 훅이 이미 설치돼 있는가 — 있으면 플러그인은 실행하지 않는다 */
|
|
21
|
+
export function projectHooksInstalled(projectDir) {
|
|
22
|
+
const settings = path.join(projectDir, '.claude', 'settings.local.json');
|
|
23
|
+
try {
|
|
24
|
+
const parsed = JSON.parse(fs.readFileSync(settings, 'utf-8'));
|
|
25
|
+
const hooks = parsed?.hooks;
|
|
26
|
+
if (!hooks || typeof hooks !== 'object') return false;
|
|
27
|
+
// vibe 훅인지까지 확인한다 — 사용자가 자기 훅만 넣어둔 경우에는 물러날 이유가 없다
|
|
28
|
+
return JSON.stringify(hooks).includes('hooks/scripts/');
|
|
29
|
+
} catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function main() {
|
|
35
|
+
const [, , script, ...rest] = process.argv;
|
|
36
|
+
if (!script) {
|
|
37
|
+
process.stderr.write('plugin-hook-entry: 실행할 스크립트가 지정되지 않았다\n');
|
|
38
|
+
process.exit(0); // 훅은 사용자 작업을 막지 않는다
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (projectHooksInstalled(process.cwd())) process.exit(0);
|
|
42
|
+
|
|
43
|
+
const target = path.resolve(import.meta.dirname, script);
|
|
44
|
+
if (!fs.existsSync(target)) {
|
|
45
|
+
process.stderr.write(`plugin-hook-entry: 스크립트를 찾지 못했다 — ${target}\n`);
|
|
46
|
+
process.exit(0);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 대상 스크립트가 자기 argv 를 그대로 읽도록 맞춘다 (pre-tool-dispatcher.js Bash 등)
|
|
50
|
+
process.argv = [process.argv[0], target, ...rest];
|
|
51
|
+
await import(pathToFileURL(target).href);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 테스트에서 import 할 때는 실행하지 않는다
|
|
55
|
+
if (process.argv[1] && path.resolve(process.argv[1]) === path.resolve(import.meta.filename)) {
|
|
56
|
+
await main();
|
|
57
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@su-record/vibe",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.32",
|
|
4
4
|
"description": "AI Coding Framework for Claude Code — 7+ agents, 52 skills, multi-LLM orchestration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/cli/index.js",
|
|
@@ -37,7 +37,10 @@
|
|
|
37
37
|
"release": "bash scripts/release.sh",
|
|
38
38
|
"sync:plugin-version": "npx tsx scripts/sync-plugin-version.ts",
|
|
39
39
|
"version": "npx tsx scripts/sync-plugin-version.ts && git add .codex-plugin/plugin.json",
|
|
40
|
-
"build:plugin": "npx tsx scripts/build-plugin.ts"
|
|
40
|
+
"build:plugin": "npx tsx scripts/build-plugin.ts",
|
|
41
|
+
"gen:plugin-hooks": "npx tsx scripts/gen-plugin-hooks.ts",
|
|
42
|
+
"gen:plugin-hooks:check": "npx tsx scripts/gen-plugin-hooks.ts --check",
|
|
43
|
+
"validate:plugin-tree": "npx tsx scripts/build-plugin.ts && git diff --exit-code --stat plugins/"
|
|
41
44
|
},
|
|
42
45
|
"keywords": [
|
|
43
46
|
"ai",
|
|
@@ -97,6 +100,8 @@
|
|
|
97
100
|
"vitest": "^4.1.10"
|
|
98
101
|
},
|
|
99
102
|
"files": [
|
|
103
|
+
".claude-plugin/",
|
|
104
|
+
"!.claude-plugin/marketplace.json",
|
|
100
105
|
".codex-plugin/",
|
|
101
106
|
"dist/",
|
|
102
107
|
"vibe/",
|