@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.
- package/.claude/agents/explorer.md +48 -0
- package/.claude/agents/implementer.md +53 -0
- package/.claude/agents/tester.md +49 -0
- package/.claude/commands/vibe.run.md +130 -5
- package/.claude/commands/vibe.spec.md +28 -0
- package/.claude/settings.json +52 -0
- package/.claude/settings.local.json +1 -42
- package/CLAUDE.md +17 -0
- package/README.md +10 -3
- package/bin/vibe +289 -23
- package/package.json +1 -1
- package/templates/hooks-template.json +90 -1
|
@@ -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
|
-
|
|
57
|
-
|
|
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(
|
|
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
|
|
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
|
|
217
|
+
log(' ℹ️ Context7 MCP 이미 등록됨\n');
|
|
182
218
|
} else {
|
|
183
|
-
log(' ⚠️ MCP 수동 등록
|
|
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.
|
|
253
|
-
const settingsPath = path.join(claudeDir, 'settings.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
315
|
-
vibe init [project]
|
|
316
|
-
vibe update
|
|
317
|
-
vibe
|
|
318
|
-
vibe
|
|
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.
|
|
449
|
-
const settingsPath = path.join(claudeDir, 'settings.
|
|
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
|
|
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,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
|
}
|