@su-record/vibe 0.4.9 → 1.0.1

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.
@@ -0,0 +1,48 @@
1
+ # Explorer Agent (Haiku 4.5)
2
+
3
+ 코드베이스 탐색 전문 서브에이전트입니다.
4
+
5
+ ## Role
6
+
7
+ - 코드베이스 분석
8
+ - 파일/패턴 검색
9
+ - 의존성 확인
10
+ - 관련 코드 수집
11
+
12
+ ## Model
13
+
14
+ **Haiku 4.5** - 빠른 탐색에 최적화
15
+
16
+ ## Usage
17
+
18
+ Task 도구로 호출:
19
+ ```
20
+ Task(model: "haiku", subagent_type: "Explore")
21
+ ```
22
+
23
+ ## Process
24
+
25
+ 1. 프로젝트 구조 파악
26
+ 2. 관련 파일 검색 (Glob, Grep)
27
+ 3. 코드 읽기 및 분석
28
+ 4. 패턴/컨벤션 파악
29
+ 5. 결과 요약 반환
30
+
31
+ ## Output
32
+
33
+ ```markdown
34
+ ## 탐색 결과
35
+
36
+ ### 관련 파일
37
+ - src/components/Button.tsx (UI 컴포넌트)
38
+ - src/hooks/useAuth.ts (인증 훅)
39
+
40
+ ### 발견된 패턴
41
+ - 컴포넌트: 함수형 + TypeScript
42
+ - 상태관리: Zustand 사용
43
+ - 스타일: Tailwind CSS
44
+
45
+ ### 의존성
46
+ - react: ^18.2.0
47
+ - zustand: ^4.4.0
48
+ ```
@@ -0,0 +1,53 @@
1
+ # Implementer Agent (Sonnet 4)
2
+
3
+ 핵심 구현 전문 서브에이전트입니다.
4
+
5
+ ## Role
6
+
7
+ - 코드 구현
8
+ - 파일 생성/수정
9
+ - 리팩토링
10
+ - 버그 수정
11
+
12
+ ## Model
13
+
14
+ **Sonnet 4** - 구현 품질과 속도의 균형
15
+
16
+ ## Usage
17
+
18
+ Task 도구로 호출:
19
+ ```
20
+ Task(model: "sonnet", prompt: "SPEC에 따라 구현하세요")
21
+ ```
22
+
23
+ ## Rules Reference
24
+
25
+ 반드시 `.vibe/rules/` 규칙을 따릅니다:
26
+ - `core/development-philosophy.md` - 수술적 정밀도
27
+ - `standards/complexity-metrics.md` - 함수 ≤20줄, 중첩 ≤3단계
28
+ - `quality/checklist.md` - 품질 체크리스트
29
+
30
+ ## Process
31
+
32
+ 1. SPEC 및 탐색 결과 확인
33
+ 2. 구현 계획 수립
34
+ 3. 코드 작성 (Edit/Write)
35
+ 4. 자체 검증
36
+ 5. 결과 반환
37
+
38
+ ## Output
39
+
40
+ ```markdown
41
+ ## 구현 결과
42
+
43
+ ### 생성된 파일
44
+ - src/components/LoginForm.tsx ✅
45
+ - src/hooks/useLogin.ts ✅
46
+
47
+ ### 수정된 파일
48
+ - src/App.tsx (라우트 추가)
49
+
50
+ ### 검증
51
+ - TypeScript 컴파일: ✅
52
+ - 린트: ✅
53
+ ```
@@ -0,0 +1,49 @@
1
+ # Tester Agent (Haiku 4.5)
2
+
3
+ 테스트 작성 전문 서브에이전트입니다.
4
+
5
+ ## Role
6
+
7
+ - 테스트 코드 작성
8
+ - BDD Feature 기반 테스트
9
+ - 엣지 케이스 검증
10
+ - 테스트 실행
11
+
12
+ ## Model
13
+
14
+ **Haiku 4.5** - 빠른 테스트 생성
15
+
16
+ ## Usage
17
+
18
+ Task 도구로 호출:
19
+ ```
20
+ Task(model: "haiku", prompt: "구현된 코드의 테스트를 작성하세요")
21
+ ```
22
+
23
+ ## Process
24
+
25
+ 1. `.vibe/features/{기능명}.feature` 확인
26
+ 2. 구현된 코드 분석
27
+ 3. 테스트 케이스 작성
28
+ 4. 테스트 실행
29
+ 5. 결과 반환
30
+
31
+ ## Output
32
+
33
+ ```markdown
34
+ ## 테스트 결과
35
+
36
+ ### 생성된 테스트
37
+ - src/__tests__/LoginForm.test.tsx
38
+ - src/__tests__/useLogin.test.ts
39
+
40
+ ### 커버리지
41
+ - Statements: 85%
42
+ - Branches: 80%
43
+ - Functions: 90%
44
+
45
+ ### 실행 결과
46
+ ✅ 12 passed
47
+ ⏭️ 0 skipped
48
+ ❌ 0 failed
49
+ ```
@@ -5,7 +5,7 @@ argument-hint: "feature name" or --phase N
5
5
 
6
6
  # /vibe.run
7
7
 
8
- SPEC을 기반으로 구현합니다 (Implementation Agent).
8
+ SPEC을 기반으로 구현합니다 (Implementation Agent with Multi-Model Orchestration).
9
9
 
10
10
  ## Usage
11
11
 
@@ -28,9 +28,92 @@ PTCF 구조의 SPEC 문서를 읽고 바로 구현을 실행합니다.
28
28
 
29
29
  > **PLAN, TASKS 문서 불필요** - SPEC이 곧 실행 가능한 프롬프트
30
30
 
31
+ ## 모델 오케스트레이션
32
+
33
+ 작업 유형에 따라 최적의 모델을 자동 선택합니다:
34
+
35
+ ```
36
+ ┌─────────────────────────────────────────────────────────────┐
37
+ │ Opus 4.5 (오케스트레이터) │
38
+ │ - 전체 흐름 조율 │
39
+ │ - 최종 결정/검토 │
40
+ └─────────────────────────┬───────────────────────────────────┘
41
+
42
+ ┌─────────────────────┼─────────────────────┐
43
+ ↓ ↓ ↓
44
+ ┌─────────┐ ┌─────────┐ ┌─────────┐
45
+ │ Haiku │ │ Sonnet │ │ Haiku │
46
+ │ (탐색) │ │ (구현) │ │(테스트) │
47
+ └─────────┘ └─────────┘ └─────────┘
48
+ ```
49
+
50
+ ### 역할별 Task 호출
51
+
52
+ | 작업 유형 | 모델 | Task 파라미터 |
53
+ |----------|------|---------------|
54
+ | 코드베이스 탐색 | Haiku 4.5 | `model: "haiku"` |
55
+ | 핵심 구현 | Sonnet 4 | `model: "sonnet"` |
56
+ | 테스트 작성 | Haiku 4.5 | `model: "haiku"` |
57
+ | 아키텍처 결정 | Opus 4.5 | 메인 세션 |
58
+ | 최종 검토 | Opus 4.5 | 메인 세션 |
59
+
60
+ ### 외부 LLM 활용 (활성화 시)
61
+
62
+ `.vibe/config.json`에서 외부 LLM이 활성화된 경우:
63
+
64
+ | 역할 | 모델 | 조건 |
65
+ |------|------|------|
66
+ | 아키텍처/디버깅 | GPT 5.2 | `vibe gpt <key>` 실행 시 |
67
+ | UI/UX 설계 | Gemini 3 | `vibe gemini <key>` 실행 시 |
68
+
69
+ 외부 LLM 활성화 시 해당 역할은 MCP를 통해 자동 호출됩니다:
70
+ - `mcp__vibe-gpt__chat` - GPT 5.2 아키텍처 자문
71
+ - `mcp__vibe-gemini__chat` - Gemini 3 UI/UX 자문
72
+
73
+ ## 시맨틱 코드 분석 (hi-ai MCP)
74
+
75
+ 구현 전 코드베이스를 정확히 파악하기 위해 hi-ai MCP의 시맨틱 도구를 활용합니다:
76
+
77
+ | MCP 도구 | 용도 | 활용 시점 |
78
+ |----------|------|----------|
79
+ | `mcp__vibe__find_symbol` | 심볼 정의 찾기 | 클래스/함수 위치 파악 |
80
+ | `mcp__vibe__find_references` | 참조 찾기 | 영향 범위 분석 |
81
+ | `mcp__vibe__analyze_complexity` | 복잡도 분석 | 리팩토링 필요 여부 판단 |
82
+ | `mcp__vibe__validate_code_quality` | 품질 검증 | 구현 후 품질 확인 |
83
+
84
+ ### 시맨틱 분석 흐름
85
+
86
+ ```
87
+ 구현 시작
88
+
89
+ ├─→ find_symbol: 수정할 함수/클래스 정확한 위치 파악
90
+
91
+ ├─→ find_references: 해당 심볼을 사용하는 모든 곳 확인
92
+
93
+ ├─→ analyze_complexity: 기존 코드 복잡도 확인
94
+
95
+
96
+ 구현 (영향 범위를 정확히 파악한 상태에서)
97
+
98
+
99
+ validate_code_quality: 구현 후 품질 검증
100
+ ```
101
+
102
+ ### 컨텍스트 관리 (세션 연속성)
103
+
104
+ | MCP 도구 | 용도 |
105
+ |----------|------|
106
+ | `mcp__vibe__start_session` | 세션 시작, 이전 컨텍스트 복원 |
107
+ | `mcp__vibe__auto_save_context` | 현재 상태 자동 저장 |
108
+ | `mcp__vibe__restore_session_context` | 이전 세션 컨텍스트 복원 |
109
+ | `mcp__vibe__save_memory` | 중요 결정사항/패턴 저장 |
110
+
111
+ **세션 시작 시**: `mcp__vibe__start_session`으로 이전 컨텍스트 자동 복원
112
+ **세션 종료 시**: Hook이 `mcp__vibe__auto_save_context` 자동 실행
113
+
31
114
  ## Process
32
115
 
33
- ### 1. SPEC 읽기
116
+ ### 1. SPEC 및 설정 읽기
34
117
 
35
118
  `.vibe/specs/{기능명}.md` 파싱:
36
119
 
@@ -43,18 +126,60 @@ PTCF 구조의 SPEC 문서를 읽고 바로 구현을 실행합니다.
43
126
  | `<output_format>` | 생성/수정할 파일 |
44
127
  | `<acceptance>` | 검증 기준 |
45
128
 
129
+ `.vibe/config.json` 확인:
130
+ - 외부 LLM 활성화 여부 (`models.gpt.enabled`, `models.gemini.enabled`)
131
+
46
132
  ### 2. Feature 파일 확인
47
133
 
48
134
  `.vibe/features/{기능명}.feature`:
49
135
  - BDD Scenarios 확인
50
136
  - 테스트 케이스로 활용
51
137
 
52
- ### 3. Phase별 구현
138
+ ### 3. Phase별 구현 (Task 병렬 호출)
53
139
 
54
140
  `<task>` 섹션의 Phase 순서대로:
55
141
 
56
- 1. **관련 코드 분석**: `<context>`의 관련 코드 읽기
57
- 2. **파일 생성/수정**: `<output_format>` 기준
142
+ ```
143
+ Phase 시작
144
+
145
+ ├─→ Task(haiku): 코드베이스 분석
146
+ │ "관련 파일과 패턴을 분석하세요"
147
+
148
+ ├─→ [GPT 활성화 시] MCP(vibe-gpt): 아키텍처 검토
149
+ │ "이 설계가 적절한지 검토해주세요"
150
+
151
+ ├─→ [Gemini 활성화 시] MCP(vibe-gemini): UI/UX 자문
152
+ │ "UI 구현 방향을 제안해주세요"
153
+
154
+
155
+ Opus: 분석 결과 종합, 구현 방향 결정
156
+
157
+
158
+ Task(sonnet): 핵심 구현
159
+ "SPEC에 따라 코드를 구현하세요"
160
+
161
+
162
+ Task(haiku): 테스트 작성
163
+ "구현된 코드의 테스트를 작성하세요"
164
+
165
+
166
+ Opus: 최종 검토 및 다음 Phase
167
+ ```
168
+
169
+ **병렬 실행 예시:**
170
+ ```javascript
171
+ // 독립적인 작업은 병렬로 Task 호출
172
+ Task(haiku) - 코드 분석
173
+ Task(haiku) - 의존성 확인
174
+ // → 동시 실행
175
+
176
+ // 순차적 작업
177
+ Task(sonnet) - 구현 (분석 완료 후)
178
+ Task(haiku) - 테스트 (구현 완료 후)
179
+ ```
180
+
181
+ 1. **관련 코드 분석**: Task(haiku)로 `<context>`의 관련 코드 탐색
182
+ 2. **파일 생성/수정**: Task(sonnet)로 `<output_format>` 기준 구현
58
183
  3. **제약 조건 준수**: `<constraints>` 확인
59
184
  4. **검증 실행**: 검증 명령어 실행
60
185
 
@@ -26,6 +26,34 @@ SPEC 문서를 작성합니다 (Specification Agent).
26
26
 
27
27
  > **PTCF**: Persona, Task, Context, Format - Google Gemini 프롬프트 최적화 프레임워크
28
28
 
29
+ ## 외부 LLM 연동 (선택적)
30
+
31
+ `.vibe/config.json`에서 외부 LLM이 활성화된 경우 SPEC 작성 시 자동 활용:
32
+
33
+ ```
34
+ /vibe.spec "복잡한 기능"
35
+
36
+ [Claude Opus] SPEC 초안 작성
37
+
38
+ [GPT 활성화?] → MCP(vibe-gpt)로 설계 교차 검토
39
+
40
+ [Gemini 활성화?] → MCP(vibe-gemini)로 UI/UX 자문
41
+
42
+ [Claude] 최종 SPEC 확정
43
+ ```
44
+
45
+ | 외부 LLM | 역할 | 활용 시점 |
46
+ |----------|------|----------|
47
+ | GPT 5.2 | 아키텍처/설계 검토 | SPEC 초안 완성 후 |
48
+ | Gemini 3 | UI/UX 자문 | 디자인 레퍼런스 논의 시 |
49
+
50
+ **활성화 방법:**
51
+ ```bash
52
+ vibe gpt <api-key> # GPT 활성화
53
+ vibe gemini <api-key> # Gemini 활성화
54
+ vibe status # 현재 설정 확인
55
+ ```
56
+
29
57
  ## Process
30
58
 
31
59
  ### 1. 프로젝트 분석
@@ -0,0 +1,52 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(cat:*)",
5
+ "Bash(mv:*)",
6
+ "Bash(sed:*)",
7
+ "Bash(git add:*)",
8
+ "Bash(git commit:*)",
9
+ "Bash(npm publish:*)",
10
+ "Bash(git push:*)",
11
+ "Bash(npm pack)",
12
+ "Bash(npm install:*)",
13
+ "Read(//private/tmp/test-vibe-bdd/.vibe/**)",
14
+ "Read(//private/tmp/test-vibe-bdd/.claude/commands/**)",
15
+ "Bash(npm view:*)",
16
+ "Bash(gh release create:*)",
17
+ "Bash(gh release view:*)",
18
+ "Bash(npm run build:*)",
19
+ "Bash(pbcopy)",
20
+ "Bash(openskills --help:*)",
21
+ "Bash(mkdir:*)",
22
+ "Bash(openskills sync:*)",
23
+ "Bash(openskills list:*)",
24
+ "Bash(openskills read:*)",
25
+ "Bash(./bin/vibe list:*)",
26
+ "Bash(./bin/vibe read:*)",
27
+ "Bash(./bin/vibe sync:*)",
28
+ "Bash(npm link:*)",
29
+ "Bash(vibe list:*)",
30
+ "Bash(vibe read:*)",
31
+ "Bash(vibe init:*)",
32
+ "SlashCommand(/vibe.spec \"로그인 기능\")",
33
+ "SlashCommand(/vibe.spec:*)",
34
+ "Bash(node bin/vibe:*)",
35
+ "Bash(npm pack:*)",
36
+ "Bash(npm config set:*)",
37
+ "Bash(node:*)",
38
+ "Bash(xargs basename:*)",
39
+ "Bash(git restore:*)",
40
+ "Bash(npm version:*)",
41
+ "Bash(npx @su-record/vibe@latest update)",
42
+ "Bash(gh release:*)",
43
+ "Bash(npx @su-record/vibe@latest init:*)",
44
+ "Bash(vibe version:*)",
45
+ "Bash(vibe update:*)",
46
+ "Bash(vibe status:*)",
47
+ "Bash(git rm:*)"
48
+ ],
49
+ "deny": [],
50
+ "ask": []
51
+ }
52
+ }
@@ -1,48 +1,7 @@
1
1
  {
2
2
  "permissions": {
3
3
  "allow": [
4
- "Bash(cat:*)",
5
- "Bash(mv:*)",
6
- "Bash(sed:*)",
7
- "Bash(git add:*)",
8
- "Bash(git commit:*)",
9
- "Bash(npm publish:*)",
10
- "Bash(git push:*)",
11
- "Bash(npm pack)",
12
- "Bash(npm install:*)",
13
- "Read(//private/tmp/test-vibe-bdd/.vibe/**)",
14
- "Read(//private/tmp/test-vibe-bdd/.claude/commands/**)",
15
- "Bash(npm view:*)",
16
- "Bash(gh release create:*)",
17
- "Bash(gh release view:*)",
18
- "Bash(npm run build:*)",
19
- "Bash(pbcopy)",
20
- "Bash(openskills --help:*)",
21
- "Bash(mkdir:*)",
22
- "Bash(openskills sync:*)",
23
- "Bash(openskills list:*)",
24
- "Bash(openskills read:*)",
25
- "Bash(./bin/vibe list:*)",
26
- "Bash(./bin/vibe read:*)",
27
- "Bash(./bin/vibe sync:*)",
28
- "Bash(npm link:*)",
29
- "Bash(vibe list:*)",
30
- "Bash(vibe read:*)",
31
- "Bash(vibe init:*)",
32
- "SlashCommand(/vibe.spec \"로그인 기능\")",
33
- "SlashCommand(/vibe.spec:*)",
34
- "Bash(node bin/vibe:*)",
35
- "Bash(npm pack:*)",
36
- "Bash(npm config set:*)",
37
- "Bash(node:*)",
38
- "Bash(xargs basename:*)",
39
- "Bash(git restore:*)",
40
- "Bash(npm version:*)",
41
- "Bash(npx @su-record/vibe@latest update)",
42
- "Bash(gh release:*)",
43
- "Bash(npx @su-record/vibe@latest init:*)",
44
- "Bash(vibe version:*)",
45
- "Bash(vibe update:*)"
4
+ "Bash(git tag:*)"
46
5
  ],
47
6
  "deny": [],
48
7
  "ask": []
package/CLAUDE.md CHANGED
@@ -33,6 +33,23 @@ SPEC 문서는 AI가 바로 실행 가능한 프롬프트 형태:
33
33
  <acceptance> 검증 기준
34
34
  ```
35
35
 
36
+ ## MCP 도구 (hi-ai)
37
+
38
+ ### 시맨틱 코드 분석
39
+ | 도구 | 용도 |
40
+ |------|------|
41
+ | `mcp__vibe__find_symbol` | 심볼 정의 찾기 |
42
+ | `mcp__vibe__find_references` | 참조 찾기 |
43
+ | `mcp__vibe__analyze_complexity` | 복잡도 분석 |
44
+ | `mcp__vibe__validate_code_quality` | 품질 검증 |
45
+
46
+ ### 컨텍스트 관리
47
+ | 도구 | 용도 |
48
+ |------|------|
49
+ | `mcp__vibe__start_session` | 세션 시작 (이전 컨텍스트 복원) |
50
+ | `mcp__vibe__auto_save_context` | 현재 상태 저장 |
51
+ | `mcp__vibe__save_memory` | 중요 결정사항 저장 |
52
+
36
53
  ## Getting Started
37
54
 
38
55
  ```bash
package/README.md CHANGED
@@ -76,12 +76,13 @@ cd my-project
76
76
 
77
77
  ## Commands
78
78
 
79
- ### 터미널 (초기화만)
79
+ ### 터미널 명령어
80
80
 
81
81
  | 명령어 | 설명 |
82
82
  |--------|------|
83
83
  | `vibe init` | 현재 폴더에 vibe 초기화 |
84
84
  | `vibe init <name>` | 새 프로젝트 생성 |
85
+ | `vibe update` | 설정 업데이트 (커맨드, 규칙, Hooks) |
85
86
  | `vibe help` | 도움말 |
86
87
  | `vibe version` | 버전 정보 |
87
88
 
@@ -100,10 +101,16 @@ cd my-project
100
101
 
101
102
  | 명령어 | 설명 |
102
103
  |--------|------|
103
- | `/vibe.analyze` | 프로젝트 분석 |
104
+ | `/vibe.analyze` | 프로젝트 전체 분석 |
105
+ | `/vibe.analyze "기능명"` | 특정 기능/모듈 분석 |
106
+ | `/vibe.analyze --code` | 코드 품질 분석만 |
107
+ | `/vibe.analyze --deps` | 의존성 분석만 |
108
+ | `/vibe.analyze --arch` | 아키텍처 분석만 |
104
109
  | `/vibe.reason "문제"` | 체계적 추론 (9단계) |
105
110
  | `/vibe.ui "설명"` | ASCII UI 미리보기 |
106
- | `/vibe.diagram` | 다이어그램 생성 |
111
+ | `/vibe.diagram` | 아키텍처 다이어그램 |
112
+ | `/vibe.diagram --er` | ERD 다이어그램 |
113
+ | `/vibe.diagram --flow` | 플로우차트 |
107
114
 
108
115
  ---
109
116
 
package/bin/vibe CHANGED
@@ -16,6 +16,29 @@ const options = {
16
16
  silent: args.includes('--silent') || args.includes('-s')
17
17
  };
18
18
 
19
+ // MCP 설정
20
+ const DEFAULT_MCPS = [
21
+ { name: 'vibe', type: 'node', local: true },
22
+ { name: 'context7', type: 'npx', package: '@upstash/context7-mcp@latest' }
23
+ ];
24
+
25
+ const EXTERNAL_LLMS = {
26
+ gpt: {
27
+ name: 'vibe-gpt',
28
+ role: 'architecture',
29
+ description: '아키텍처/디버깅 (GPT 5.2)',
30
+ package: '@anthropics/openai-mcp',
31
+ envKey: 'OPENAI_API_KEY'
32
+ },
33
+ gemini: {
34
+ name: 'vibe-gemini',
35
+ role: 'ui-ux',
36
+ description: 'UI/UX 설계 (Gemini 3)',
37
+ package: '@anthropics/gemini-mcp',
38
+ envKey: 'GOOGLE_API_KEY'
39
+ }
40
+ };
41
+
19
42
  // 로그 함수 (silent 모드 지원)
20
43
  function log(message) {
21
44
  if (!options.silent) {
@@ -83,11 +106,11 @@ function setupCollaboratorAutoInstall(projectRoot) {
83
106
  pkg.scripts = {};
84
107
  }
85
108
  if (!pkg.scripts.postinstall) {
86
- pkg.scripts.postinstall = 'vibe update --silent';
109
+ pkg.scripts.postinstall = 'npx @su-record/vibe update --silent';
87
110
  modified = true;
88
111
  } else if (!pkg.scripts.postinstall.includes('vibe update')) {
89
112
  // 기존 postinstall이 있으면 vibe update 추가
90
- pkg.scripts.postinstall = `${pkg.scripts.postinstall} && vibe update --silent`;
113
+ pkg.scripts.postinstall = `${pkg.scripts.postinstall} && npx @su-record/vibe update --silent`;
91
114
  modified = true;
92
115
  }
93
116
 
@@ -169,21 +192,38 @@ async function init(projectName) {
169
192
  }
170
193
 
171
194
  // MCP 서버 등록 (Claude Code)
172
- const mcpPath = path.join(__dirname, '..', 'node_modules', '@su-record', 'hi-ai', 'dist', 'index.js');
173
-
174
195
  log('🔧 Claude Code MCP 서버 등록 중...\n');
175
196
  const { execSync } = require('child_process');
197
+
198
+ // 1. hi-ai MCP (기존)
199
+ const mcpPath = path.join(__dirname, '..', 'node_modules', '@su-record', 'hi-ai', 'dist', 'index.js');
176
200
  try {
177
201
  execSync(`claude mcp add vibe node "${mcpPath}"`, { stdio: 'pipe' });
178
- log(' ✅ MCP 서버 등록 완료\n');
202
+ log(' ✅ vibe MCP 등록 완료\n');
203
+ } catch (e) {
204
+ if (e.message.includes('already exists')) {
205
+ log(' ℹ️ vibe MCP 이미 등록됨\n');
206
+ } else {
207
+ log(' ⚠️ vibe MCP 수동 등록 필요\n');
208
+ }
209
+ }
210
+
211
+ // 2. Context7 MCP (라이브러리 문서 검색)
212
+ try {
213
+ execSync('claude mcp add context7 -- npx -y @upstash/context7-mcp@latest', { stdio: 'pipe' });
214
+ log(' ✅ Context7 MCP 등록 완료 (라이브러리 문서 검색)\n');
179
215
  } catch (e) {
180
216
  if (e.message.includes('already exists')) {
181
- log(' ℹ️ MCP 서버 이미 등록됨\n');
217
+ log(' ℹ️ Context7 MCP 이미 등록됨\n');
182
218
  } else {
183
- log(' ⚠️ MCP 수동 등록 필요\n');
219
+ log(' ⚠️ Context7 MCP 수동 등록 필요: claude mcp add context7 -- npx -y @upstash/context7-mcp@latest\n');
184
220
  }
185
221
  }
186
222
 
223
+ // 3. Exa MCP (AI 웹 검색) - API 키 필요
224
+ log(' ℹ️ Exa MCP (AI 웹 검색): EXA_API_KEY 환경변수 설정 후 아래 명령어로 등록\n');
225
+ log(' claude mcp add exa -e EXA_API_KEY=$EXA_API_KEY -- npx -y exa-mcp-server\n');
226
+
187
227
  // .vibe 폴더 구조 생성
188
228
  const dirs = ['', 'specs', 'features'];
189
229
  dirs.forEach(dir => {
@@ -249,18 +289,30 @@ async function init(projectName) {
249
289
  copyDirContents(agentsSourceDir, agentsDir);
250
290
  log(' ✅ 서브에이전트 설치 완료 (.claude/agents/)\n');
251
291
 
252
- // .claude/settings.local.json 생성 (Hooks 설정)
253
- const settingsPath = path.join(claudeDir, 'settings.local.json');
292
+ // .claude/settings.json 생성 (Hooks 설정 - 저장소 공유용)
293
+ const settingsPath = path.join(claudeDir, 'settings.json');
254
294
  if (!fs.existsSync(settingsPath)) {
255
295
  const hooksTemplate = path.join(__dirname, '../templates/hooks-template.json');
256
296
  if (fs.existsSync(hooksTemplate)) {
257
297
  fs.copyFileSync(hooksTemplate, settingsPath);
258
- log(' ✅ Hooks 설정 설치 완료 (.claude/settings.local.json)\n');
298
+ log(' ✅ Hooks 설정 설치 완료 (.claude/settings.json)\n');
259
299
  }
260
300
  } else {
261
301
  log(' ℹ️ Hooks 설정 이미 존재\n');
262
302
  }
263
303
 
304
+ // .gitignore에서 settings.local.json 제거 (저장소 공유 필요)
305
+ const gitignorePath = path.join(projectRoot, '.gitignore');
306
+ if (fs.existsSync(gitignorePath)) {
307
+ let gitignore = fs.readFileSync(gitignorePath, 'utf-8');
308
+ if (gitignore.includes('settings.local.json')) {
309
+ gitignore = gitignore.replace(/\.claude\/settings\.local\.json\n?/g, '');
310
+ gitignore = gitignore.replace(/settings\.local\.json\n?/g, '');
311
+ fs.writeFileSync(gitignorePath, gitignore);
312
+ log(' ✅ .gitignore에서 settings.local.json 제거 (저장소 공유)\n');
313
+ }
314
+ }
315
+
264
316
  // 협업자 자동 설치 설정
265
317
  setupCollaboratorAutoInstall(projectRoot);
266
318
 
@@ -276,7 +328,7 @@ ${isNewProject ? `프로젝트 위치:
276
328
  .claude/
277
329
  ├── commands/ # 슬래시 커맨드 (7개)
278
330
  ├── agents/ # 서브에이전트 (simplifier)
279
- └── settings.local.json # Hooks 설정 (자동 품질 검증)
331
+ └── settings.json # Hooks 설정 (저장소 공유)
280
332
  .vibe/
281
333
  ├── config.json # 프로젝트 설정
282
334
  ├── constitution.md # 프로젝트 원칙
@@ -311,11 +363,18 @@ function showHelp() {
311
363
  console.log(`
312
364
  📖 Vibe - SPEC-driven AI coding framework (Claude Code 전용)
313
365
 
314
- Commands:
315
- vibe init [project] Initialize vibe in current/new project
316
- vibe update Update vibe settings (commands, rules, hooks)
317
- vibe help Show this message
318
- vibe version Show version
366
+ 기본 명령어:
367
+ vibe init [project] 프로젝트 초기화
368
+ vibe update 설정 업데이트
369
+ vibe status 현재 설정 상태
370
+ vibe help 도움말
371
+ vibe version 버전 정보
372
+
373
+ 외부 LLM (선택적):
374
+ vibe gpt <api-key> GPT 활성화 (아키텍처/디버깅)
375
+ vibe gemini <api-key> Gemini 활성화 (UI/UX)
376
+ vibe gpt --remove GPT 비활성화
377
+ vibe gemini --remove Gemini 비활성화
319
378
 
320
379
  Claude Code 슬래시 커맨드:
321
380
  /vibe.spec "기능명" SPEC 작성 (PTCF 구조)
@@ -326,12 +385,16 @@ Claude Code 슬래시 커맨드:
326
385
  /vibe.ui "설명" UI 미리보기
327
386
  /vibe.diagram 다이어그램 생성
328
387
 
388
+ 모델 오케스트레이션:
389
+ Opus 4.5 오케스트레이터 (메인)
390
+ Sonnet 4 구현
391
+ Haiku 4.5 코드 탐색
392
+ GPT 5.2 아키텍처/디버깅 (선택적)
393
+ Gemini 3 UI/UX 설계 (선택적)
394
+
329
395
  Workflow:
330
396
  /vibe.spec → /vibe.run → /vibe.verify
331
397
 
332
- 설치:
333
- npm install -g @su-record/vibe
334
-
335
398
  문서:
336
399
  https://github.com/su-record/vibe
337
400
  `);
@@ -445,8 +508,8 @@ async function update() {
445
508
  copyDirContents(agentsSourceDir, agentsDir);
446
509
  log(' ✅ 서브에이전트 업데이트 완료 (.claude/agents/)\n');
447
510
 
448
- // settings.local.json에 hooks 병합
449
- const settingsPath = path.join(claudeDir, 'settings.local.json');
511
+ // settings.json에 hooks 병합 (저장소 공유용)
512
+ const settingsPath = path.join(claudeDir, 'settings.json');
450
513
  const hooksTemplate = path.join(__dirname, '../templates/hooks-template.json');
451
514
 
452
515
  if (fs.existsSync(hooksTemplate)) {
@@ -470,12 +533,34 @@ async function update() {
470
533
  }
471
534
  }
472
535
 
536
+ // .gitignore에서 settings.local.json 제거 (저장소 공유 필요)
537
+ const gitignorePath = path.join(projectRoot, '.gitignore');
538
+ if (fs.existsSync(gitignorePath)) {
539
+ let gitignore = fs.readFileSync(gitignorePath, 'utf-8');
540
+ if (gitignore.includes('settings.local.json')) {
541
+ gitignore = gitignore.replace(/\.claude\/settings\.local\.json\n?/g, '');
542
+ gitignore = gitignore.replace(/settings\.local\.json\n?/g, '');
543
+ fs.writeFileSync(gitignorePath, gitignore);
544
+ log(' ✅ .gitignore에서 settings.local.json 제거 (저장소 공유)\n');
545
+ }
546
+ }
547
+
473
548
  // MCP 서버 등록 확인
474
- const mcpPath = path.join(__dirname, '..', 'node_modules', '@su-record', 'hi-ai', 'dist', 'index.js');
475
549
  const { execSync } = require('child_process');
550
+
551
+ // 1. hi-ai MCP
552
+ const mcpPath = path.join(__dirname, '..', 'node_modules', '@su-record', 'hi-ai', 'dist', 'index.js');
476
553
  try {
477
554
  execSync(`claude mcp add vibe node "${mcpPath}"`, { stdio: 'pipe' });
478
- log(' ✅ MCP 서버 등록 완료\n');
555
+ log(' ✅ vibe MCP 등록 완료\n');
556
+ } catch (e) {
557
+ // 이미 등록됨 - silent
558
+ }
559
+
560
+ // 2. Context7 MCP
561
+ try {
562
+ execSync('claude mcp add context7 -- npx -y @upstash/context7-mcp@latest', { stdio: 'pipe' });
563
+ log(' ✅ Context7 MCP 등록 완료\n');
479
564
  } catch (e) {
480
565
  // 이미 등록됨 - silent
481
566
  }
@@ -490,6 +575,9 @@ async function update() {
490
575
  - 서브에이전트 (.claude/agents/)
491
576
  - Hooks 설정
492
577
  - MCP 서버
578
+
579
+ 추가 MCP (선택적):
580
+ Exa (AI 웹 검색): claude mcp add exa -e EXA_API_KEY=$EXA_API_KEY -- npx -y exa-mcp-server
493
581
  `);
494
582
 
495
583
  } catch (error) {
@@ -498,6 +586,161 @@ async function update() {
498
586
  }
499
587
  }
500
588
 
589
+ // 외부 LLM 설정 (GPT, Gemini)
590
+ function setupExternalLLM(llmType, apiKey) {
591
+ if (!apiKey) {
592
+ console.log(`
593
+ ❌ API 키가 필요합니다.
594
+
595
+ 사용법:
596
+ vibe ${llmType} <api-key>
597
+
598
+ ${llmType === 'gpt' ? 'OpenAI API 키: https://platform.openai.com/api-keys' : 'Google API 키: https://aistudio.google.com/apikey'}
599
+ `);
600
+ return;
601
+ }
602
+
603
+ const projectRoot = process.cwd();
604
+ const vibeDir = path.join(projectRoot, '.vibe');
605
+ const configPath = path.join(vibeDir, 'config.json');
606
+
607
+ if (!fs.existsSync(vibeDir)) {
608
+ console.log('❌ vibe 프로젝트가 아닙니다. 먼저 vibe init을 실행하세요.');
609
+ return;
610
+ }
611
+
612
+ // config.json 업데이트
613
+ let config = {};
614
+ if (fs.existsSync(configPath)) {
615
+ config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
616
+ }
617
+
618
+ if (!config.models) {
619
+ config.models = {};
620
+ }
621
+
622
+ const llmConfig = EXTERNAL_LLMS[llmType];
623
+ config.models[llmType] = {
624
+ enabled: true,
625
+ role: llmConfig.role,
626
+ description: llmConfig.description
627
+ };
628
+
629
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
630
+
631
+ // MCP 서버 등록 (환경변수와 함께)
632
+ const { execSync } = require('child_process');
633
+ const envKey = llmConfig.envKey;
634
+
635
+ try {
636
+ // 기존 MCP 제거 후 재등록
637
+ try {
638
+ execSync(`claude mcp remove ${llmConfig.name}`, { stdio: 'pipe' });
639
+ } catch (e) {
640
+ // 없으면 무시
641
+ }
642
+
643
+ // 환경변수와 함께 MCP 등록
644
+ execSync(`claude mcp add ${llmConfig.name} -e ${envKey}=${apiKey} -- npx -y ${llmConfig.package}`, { stdio: 'pipe' });
645
+
646
+ console.log(`
647
+ ✅ ${llmType.toUpperCase()} 활성화 완료!
648
+
649
+ 역할: ${llmConfig.description}
650
+ MCP: ${llmConfig.name}
651
+
652
+ /vibe.run 실행 시 자동으로 활용됩니다.
653
+
654
+ 비활성화: vibe ${llmType} --remove
655
+ `);
656
+ } catch (e) {
657
+ console.log(`
658
+ ⚠️ MCP 등록 실패. 수동으로 등록하세요:
659
+
660
+ claude mcp add ${llmConfig.name} -e ${envKey}=<your-key> -- npx -y ${llmConfig.package}
661
+ `);
662
+ }
663
+ }
664
+
665
+ function removeExternalLLM(llmType) {
666
+ const projectRoot = process.cwd();
667
+ const vibeDir = path.join(projectRoot, '.vibe');
668
+ const configPath = path.join(vibeDir, 'config.json');
669
+
670
+ if (!fs.existsSync(vibeDir)) {
671
+ console.log('❌ vibe 프로젝트가 아닙니다.');
672
+ return;
673
+ }
674
+
675
+ // config.json 업데이트
676
+ if (fs.existsSync(configPath)) {
677
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
678
+ if (config.models && config.models[llmType]) {
679
+ config.models[llmType].enabled = false;
680
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
681
+ }
682
+ }
683
+
684
+ // MCP 서버 제거
685
+ const { execSync } = require('child_process');
686
+ const llmConfig = EXTERNAL_LLMS[llmType];
687
+
688
+ try {
689
+ execSync(`claude mcp remove ${llmConfig.name}`, { stdio: 'pipe' });
690
+ console.log(`✅ ${llmType.toUpperCase()} 비활성화 완료`);
691
+ } catch (e) {
692
+ console.log(`ℹ️ ${llmType.toUpperCase()} MCP가 등록되어 있지 않습니다.`);
693
+ }
694
+ }
695
+
696
+ function showStatus() {
697
+ const projectRoot = process.cwd();
698
+ const vibeDir = path.join(projectRoot, '.vibe');
699
+ const configPath = path.join(vibeDir, 'config.json');
700
+
701
+ if (!fs.existsSync(vibeDir)) {
702
+ console.log('❌ vibe 프로젝트가 아닙니다. 먼저 vibe init을 실행하세요.');
703
+ return;
704
+ }
705
+
706
+ const packageJson = require('../package.json');
707
+ let config = { language: 'ko', models: {} };
708
+ if (fs.existsSync(configPath)) {
709
+ config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
710
+ }
711
+
712
+ const gptStatus = config.models?.gpt?.enabled ? '✅ 활성' : '⬚ 비활성';
713
+ const geminiStatus = config.models?.gemini?.enabled ? '✅ 활성' : '⬚ 비활성';
714
+
715
+ console.log(`
716
+ 📊 Vibe 상태 (v${packageJson.version})
717
+
718
+ 프로젝트: ${projectRoot}
719
+ 언어: ${config.language || 'ko'}
720
+
721
+ 모델 오케스트레이션:
722
+ ┌─────────────────────────────────────────┐
723
+ │ Opus 4.5 오케스트레이터 │
724
+ ├─────────────────────────────────────────┤
725
+ │ Sonnet 4 구현 │
726
+ │ Haiku 4.5 코드 탐색 │
727
+ ├─────────────────────────────────────────┤
728
+ │ GPT 5.2 ${gptStatus} 아키텍처/디버깅 │
729
+ │ Gemini 3 ${geminiStatus} UI/UX 설계 │
730
+ └─────────────────────────────────────────┘
731
+
732
+ MCP 서버:
733
+ vibe (hi-ai) 기본 도구
734
+ context7 라이브러리 문서 검색
735
+
736
+ 외부 LLM 설정:
737
+ vibe gpt <key> GPT 활성화 (아키텍처/디버깅)
738
+ vibe gemini <key> Gemini 활성화 (UI/UX)
739
+ vibe gpt --remove GPT 비활성화
740
+ vibe gemini --remove Gemini 비활성화
741
+ `);
742
+ }
743
+
501
744
  // 버전 정보
502
745
  function showVersion() {
503
746
  const packageJson = require('../package.json');
@@ -514,6 +757,26 @@ switch (command) {
514
757
  update();
515
758
  break;
516
759
 
760
+ case 'gpt':
761
+ if (args[1] === '--remove') {
762
+ removeExternalLLM('gpt');
763
+ } else {
764
+ setupExternalLLM('gpt', args[1]);
765
+ }
766
+ break;
767
+
768
+ case 'gemini':
769
+ if (args[1] === '--remove') {
770
+ removeExternalLLM('gemini');
771
+ } else {
772
+ setupExternalLLM('gemini', args[1]);
773
+ }
774
+ break;
775
+
776
+ case 'status':
777
+ showStatus();
778
+ break;
779
+
517
780
  case 'version':
518
781
  case '-v':
519
782
  case '--version':
@@ -534,6 +797,9 @@ switch (command) {
534
797
  사용 가능한 명령어:
535
798
  vibe init 프로젝트 초기화
536
799
  vibe update 설정 업데이트
800
+ vibe gpt GPT 활성화/비활성화
801
+ vibe gemini Gemini 활성화/비활성화
802
+ vibe status 현재 설정 상태
537
803
  vibe help 도움말
538
804
  vibe version 버전 정보
539
805
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@su-record/vibe",
3
- "version": "0.4.9",
3
+ "version": "1.0.1",
4
4
  "description": "Vibe - Claude Code exclusive SPEC-driven AI coding framework",
5
5
  "bin": {
6
6
  "vibe": "./bin/vibe"
@@ -1,12 +1,101 @@
1
1
  {
2
2
  "hooks": {
3
+ "PreToolUse": [
4
+ {
5
+ "matcher": "Read",
6
+ "hooks": [
7
+ {
8
+ "type": "prompt",
9
+ "prompt": "파일 읽기 전: 1) 전체 파일이 필요한가? offset/limit 파라미터로 필요한 부분만 읽기 2) 이미 읽은 파일인가? 중복 읽기 방지 3) Grep으로 특정 부분만 검색 가능한가?"
10
+ }
11
+ ]
12
+ },
13
+ {
14
+ "matcher": "Grep|Glob",
15
+ "hooks": [
16
+ {
17
+ "type": "prompt",
18
+ "prompt": "검색 전: head_limit 파라미터를 활용하여 결과 수를 제한하세요. 너무 많은 결과는 컨텍스트를 낭비합니다."
19
+ }
20
+ ]
21
+ }
22
+ ],
3
23
  "PostToolUse": [
4
24
  {
5
25
  "matcher": "Write|Edit",
6
26
  "hooks": [
7
27
  {
8
28
  "type": "prompt",
9
- "prompt": ".vibe/rules/quality/checklist.md 기준으로 방금 수정한 코드를 검토해주세요. 문제가 있으면 간단히 알려주세요."
29
+ "prompt": ".vibe/rules/quality/checklist.md 기준으로 방금 수정한 코드를 검토하세요. 과도한 주석이 있으면 제거하세요. 문제가 있으면 간단히 알려주세요."
30
+ }
31
+ ]
32
+ },
33
+ {
34
+ "matcher": "Task",
35
+ "hooks": [
36
+ {
37
+ "type": "prompt",
38
+ "prompt": "Task 완료 후: 핵심 결과만 요약하여 mcp__vibe__save_memory로 저장하세요. 전체 출력이 아닌 중요한 결정사항/발견 패턴/다음 단계만 기록하세요."
39
+ }
40
+ ]
41
+ },
42
+ {
43
+ "matcher": "Read",
44
+ "hooks": [
45
+ {
46
+ "type": "prompt",
47
+ "prompt": "파일 읽기 후: 전체 내용을 기억하지 마세요. 필요한 정보만 추출하고 나머지는 필요시 다시 읽으세요. 중복 읽기 감지: 같은 파일을 다시 읽었다면 이전 내용은 무시하세요."
48
+ }
49
+ ]
50
+ }
51
+ ],
52
+ "Notification": [
53
+ {
54
+ "matcher": "context_window_70",
55
+ "hooks": [
56
+ {
57
+ "type": "prompt",
58
+ "prompt": "📊 컨텍스트 70% 도달. 아직 충분한 여유가 있습니다. 작업을 서두르지 말고 품질에 집중하세요. 불필요한 파일 전체 읽기를 피하고 필요한 부분만 참조하세요."
59
+ }
60
+ ]
61
+ },
62
+ {
63
+ "matcher": "context_window_85",
64
+ "hooks": [
65
+ {
66
+ "type": "prompt",
67
+ "prompt": "⚠️ 컨텍스트 85% 도달 (선제적 압축 권고). 1) mcp__vibe__auto_save_context로 현재 상태 저장 2) 오래된 도구 출력은 요약으로 대체 3) 중복 읽은 파일 내용 정리 4) 핵심 정보만 유지하면서 작업 계속"
68
+ }
69
+ ]
70
+ },
71
+ {
72
+ "matcher": "context_window_95",
73
+ "hooks": [
74
+ {
75
+ "type": "prompt",
76
+ "prompt": "🚨 컨텍스트 95% 도달! 즉시: 1) mcp__vibe__auto_save_context 실행 2) TodoWrite로 현재 진행 상황과 다음 단계 기록 3) CLAUDE.md, .vibe/specs/ 등 핵심 컨텍스트만 유지 4) 세션 전환 준비"
77
+ }
78
+ ]
79
+ }
80
+ ],
81
+ "Stop": [
82
+ {
83
+ "matcher": ".*",
84
+ "hooks": [
85
+ {
86
+ "type": "prompt",
87
+ "prompt": "세션 종료 전 체크리스트: 1) TodoWrite로 미완료 작업 기록 (구체적인 다음 단계 포함) 2) mcp__vibe__auto_save_context로 현재 상태 저장 3) 다음 세션 시작 시 mcp__vibe__start_session으로 복원 안내"
88
+ }
89
+ ]
90
+ }
91
+ ],
92
+ "UserPromptSubmit": [
93
+ {
94
+ "matcher": ".*",
95
+ "hooks": [
96
+ {
97
+ "type": "prompt",
98
+ "prompt": "세션 시작 시: mcp__vibe__start_session을 호출하여 이전 세션 컨텍스트를 복원하세요. 저장된 메모리와 미완료 작업을 확인하세요."
10
99
  }
11
100
  ]
12
101
  }