@su-record/vibe 0.4.3 → 0.4.5
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/.agent/rules/languages/go.md +396 -0
- package/.agent/rules/languages/java-spring.md +586 -0
- package/.agent/rules/languages/kotlin-android.md +491 -0
- package/.agent/rules/languages/python-django.md +371 -0
- package/.agent/rules/languages/rust.md +425 -0
- package/.agent/rules/languages/swift-ios.md +516 -0
- package/.agent/rules/languages/typescript-node.md +375 -0
- package/.agent/rules/languages/typescript-vue.md +353 -0
- package/.claude/commands/vibe.analyze.md +166 -54
- package/.claude/settings.local.json +4 -1
- package/bin/vibe +140 -24
- package/package.json +1 -1
|
@@ -1,123 +1,235 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Analyze project
|
|
3
|
-
argument-hint: --code or --deps or --arch (optional)
|
|
2
|
+
description: Analyze project or specific feature/module
|
|
3
|
+
argument-hint: "기능명" or --code or --deps or --arch (optional)
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# /vibe.analyze
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
프로젝트 또는 특정 기능/모듈을 분석합니다.
|
|
9
9
|
|
|
10
10
|
## Usage
|
|
11
11
|
|
|
12
12
|
```
|
|
13
|
-
/vibe.analyze
|
|
14
|
-
/vibe.analyze
|
|
15
|
-
/vibe.analyze --
|
|
16
|
-
/vibe.analyze --
|
|
13
|
+
/vibe.analyze # 프로젝트 전체 품질 분석
|
|
14
|
+
/vibe.analyze "로그인" # 로그인 관련 코드 탐색 + 컨텍스트 수집
|
|
15
|
+
/vibe.analyze --code # 코드 품질 분석만
|
|
16
|
+
/vibe.analyze --deps # 의존성 분석만
|
|
17
|
+
/vibe.analyze --arch # 아키텍처 분석만
|
|
17
18
|
```
|
|
18
19
|
|
|
19
|
-
##
|
|
20
|
+
## ⚠️ 컨텍스트 리셋
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
**이 명령어가 실행되면 이전 대화 내용은 무시합니다.**
|
|
23
|
+
- 새 세션처럼 처음부터 코드를 탐색하고 분석
|
|
24
|
+
- 오직 이 분석에서 새로 수집한 정보만 기반으로 대화
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Mode 1: 기능/모듈 분석 (`/vibe.analyze "기능명"`)
|
|
29
|
+
|
|
30
|
+
### 목표
|
|
31
|
+
|
|
32
|
+
사용자가 요청한 기능/모듈과 관련된 **모든 소스코드를 탐색**하고 **플로우를 분석**하여:
|
|
33
|
+
1. 현재 구현 상태 파악
|
|
34
|
+
2. 코드 구조와 의존성 이해
|
|
35
|
+
3. 이후 개발/수정 요청에 즉시 대응 가능한 컨텍스트 확보
|
|
36
|
+
|
|
37
|
+
### Process
|
|
38
|
+
|
|
39
|
+
#### 1. 요청 분석
|
|
40
|
+
|
|
41
|
+
사용자 요청에서 핵심 키워드 추출:
|
|
42
|
+
- 기능명 (예: 로그인, 피드, 결제)
|
|
43
|
+
- 동작 (예: 작성, 조회, 수정, 삭제)
|
|
44
|
+
- 범위 (예: 백엔드만, 프론트엔드만, 전체)
|
|
45
|
+
|
|
46
|
+
#### 2. 프로젝트 구조 파악
|
|
47
|
+
|
|
48
|
+
`CLAUDE.md`, `package.json`, `pyproject.toml` 등을 읽어 기술 스택 확인:
|
|
49
|
+
|
|
50
|
+
**백엔드:**
|
|
51
|
+
- FastAPI/Django: `app/api/`, `app/services/`, `app/models/`
|
|
52
|
+
- Express/NestJS: `src/controllers/`, `src/services/`, `src/models/`
|
|
53
|
+
|
|
54
|
+
**프론트엔드:**
|
|
55
|
+
- React/Next.js: `src/components/`, `src/pages/`, `src/hooks/`
|
|
56
|
+
- Flutter: `lib/screens/`, `lib/services/`, `lib/providers/`
|
|
57
|
+
|
|
58
|
+
#### 3. 관련 코드 탐색
|
|
59
|
+
|
|
60
|
+
**탐색 전략:**
|
|
61
|
+
1. **Glob**으로 관련 파일 목록 수집
|
|
62
|
+
2. **Grep**으로 키워드 기반 코드 위치 파악
|
|
63
|
+
3. **Read**로 핵심 파일 상세 분석
|
|
64
|
+
4. 필요시 **Task (Explore)** 에이전트로 병렬 탐색
|
|
65
|
+
|
|
66
|
+
#### 4. 플로우 분석
|
|
67
|
+
|
|
68
|
+
**API 플로우:**
|
|
69
|
+
- 엔드포인트 URL 및 HTTP 메서드
|
|
70
|
+
- 요청/응답 스키마
|
|
71
|
+
- 인증/권한 요구사항
|
|
72
|
+
|
|
73
|
+
**비즈니스 로직:**
|
|
74
|
+
- 핵심 메서드와 역할
|
|
75
|
+
- 유효성 검증 규칙
|
|
76
|
+
- 외부 서비스 연동
|
|
77
|
+
|
|
78
|
+
**데이터 플로우:**
|
|
79
|
+
- 관련 테이블/모델
|
|
80
|
+
- 관계 (1:N, N:M)
|
|
81
|
+
- 주요 쿼리 패턴
|
|
82
|
+
|
|
83
|
+
#### 5. 분석 결과 출력
|
|
84
|
+
|
|
85
|
+
```markdown
|
|
86
|
+
## 📊 [기능명] 분석 결과
|
|
87
|
+
|
|
88
|
+
### 개요
|
|
89
|
+
- **기능 설명**: [한 줄 요약]
|
|
90
|
+
- **구현 상태**: [완료/진행중/미구현]
|
|
91
|
+
- **관련 파일 수**: N개
|
|
92
|
+
|
|
93
|
+
### 구조
|
|
94
|
+
|
|
95
|
+
#### API 엔드포인트
|
|
96
|
+
| 메서드 | 경로 | 설명 | 인증 |
|
|
97
|
+
|--------|------|------|------|
|
|
98
|
+
| POST | /api/v1/auth/login | 로그인 | - |
|
|
99
|
+
|
|
100
|
+
#### 핵심 서비스
|
|
101
|
+
- `auth_service.py`: 인증 로직
|
|
102
|
+
- `login()`: 로그인 처리
|
|
103
|
+
- `verify_token()`: 토큰 검증
|
|
104
|
+
|
|
105
|
+
#### 데이터 모델
|
|
106
|
+
- `User`: 사용자 테이블
|
|
107
|
+
- 주요 필드: id, email, password_hash
|
|
108
|
+
- 관계: Session (1:N)
|
|
109
|
+
|
|
110
|
+
### 플로우 다이어그램
|
|
111
|
+
[텍스트 기반 플로우 설명]
|
|
112
|
+
|
|
113
|
+
### 참고 파일 목록
|
|
114
|
+
- src/api/auth/router.py:L10-50
|
|
115
|
+
- src/services/auth_service.py:L1-100
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### 6. 개발 규칙 확인
|
|
119
|
+
|
|
120
|
+
`.agent/rules/`에서 관련 규칙 로드:
|
|
121
|
+
- `core/quick-start.md` - 5가지 핵심 원칙
|
|
122
|
+
- `standards/complexity-metrics.md` - 복잡도 기준
|
|
123
|
+
- `quality/checklist.md` - 품질 체크리스트
|
|
124
|
+
|
|
125
|
+
규칙 위반 사항이 있으면 함께 출력.
|
|
126
|
+
|
|
127
|
+
#### 7. 완료
|
|
128
|
+
|
|
129
|
+
분석 완료 후:
|
|
130
|
+
1. 분석 결과 요약 출력
|
|
131
|
+
2. "이제 어떤 작업을 도와드릴까요?" 질문
|
|
132
|
+
3. 이후 개발/수정 요청에 수집된 컨텍스트 활용
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Mode 2: 프로젝트 품질 분석 (옵션 없음 또는 --code/--deps/--arch)
|
|
137
|
+
|
|
138
|
+
### 분석 범위
|
|
24
139
|
|
|
25
140
|
- **기본** (`/vibe.analyze`): 전체 분석 (코드 + 의존성 + 아키텍처)
|
|
26
141
|
- **--code**: 코드 품질 분석만
|
|
27
142
|
- **--deps**: 의존성 분석만
|
|
28
143
|
- **--arch**: 아키텍처 분석만
|
|
29
144
|
|
|
30
|
-
###
|
|
145
|
+
### MCP 도구 사용
|
|
31
146
|
|
|
32
|
-
|
|
147
|
+
`@su-record/hi-ai` 기반:
|
|
33
148
|
|
|
34
149
|
#### 코드 품질 분석 (--code)
|
|
35
|
-
- `
|
|
36
|
-
- `
|
|
37
|
-
- `
|
|
150
|
+
- `analyze_complexity`: 복잡도 분석
|
|
151
|
+
- `validate_code_quality`: 코드 품질 검증
|
|
152
|
+
- `check_coupling_cohesion`: 결합도/응집도 체크
|
|
38
153
|
|
|
39
154
|
#### 의존성 분석 (--deps)
|
|
40
155
|
- `package.json` / `pyproject.toml` / `pubspec.yaml` 읽기
|
|
41
156
|
- 버전 충돌, 보안 취약점, 업데이트 필요 패키지 분석
|
|
42
157
|
|
|
43
158
|
#### 아키텍처 분석 (--arch)
|
|
44
|
-
- `
|
|
45
|
-
- `
|
|
159
|
+
- `find_symbol`: 핵심 모듈 찾기
|
|
160
|
+
- `find_references`: 모듈 간 의존성 파악
|
|
46
161
|
- 순환 의존성, 레이어 위반 검출
|
|
47
162
|
|
|
48
|
-
###
|
|
163
|
+
### 분석 리포트
|
|
49
164
|
|
|
50
|
-
`.vibe/reports/analysis-{date}.md
|
|
165
|
+
`.vibe/reports/analysis-{date}.md`:
|
|
51
166
|
|
|
52
167
|
```markdown
|
|
53
168
|
# 프로젝트 분석 리포트
|
|
54
169
|
|
|
55
170
|
## 개요
|
|
56
|
-
- 분석 일시: 2025-
|
|
57
|
-
- 분석 범위: 전체
|
|
171
|
+
- 분석 일시: 2025-01-06 12:00
|
|
172
|
+
- 분석 범위: 전체
|
|
58
173
|
|
|
59
174
|
## 코드 품질 (85/100)
|
|
60
175
|
- 평균 복잡도: 8.2 (양호)
|
|
61
176
|
- 높은 복잡도 파일: 3개
|
|
62
|
-
- src/service.py (CC: 15)
|
|
63
|
-
- src/utils.py (CC: 12)
|
|
64
177
|
|
|
65
178
|
## 의존성 (92/100)
|
|
66
179
|
- 총 패키지: 42개
|
|
67
180
|
- 업데이트 필요: 3개
|
|
68
|
-
- express: 4.17.1 → 4.18.2
|
|
69
|
-
- lodash: 4.17.20 → 4.17.21 (보안)
|
|
70
181
|
|
|
71
182
|
## 아키텍처 (78/100)
|
|
72
183
|
- 순환 의존성: 2개 발견
|
|
73
|
-
- A → B → C → A
|
|
74
184
|
- 레이어 위반: 1개
|
|
75
|
-
- Controller가 직접 DB 접근
|
|
76
185
|
|
|
77
186
|
## 개선 제안
|
|
78
|
-
1. service.py 리팩토링
|
|
187
|
+
1. service.py 리팩토링
|
|
79
188
|
2. lodash 보안 패치 적용
|
|
80
|
-
3. 순환 의존성 제거
|
|
81
189
|
```
|
|
82
190
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
분석 결과를 바탕으로 구체적인 개선 방안 제시:
|
|
86
|
-
- 리팩토링이 필요한 파일 목록
|
|
87
|
-
- 의존성 업데이트 명령어
|
|
88
|
-
- 아키텍처 개선 방향
|
|
191
|
+
---
|
|
89
192
|
|
|
90
193
|
## Example
|
|
91
194
|
|
|
195
|
+
### 기능 분석
|
|
92
196
|
```
|
|
93
|
-
User: /vibe.analyze
|
|
197
|
+
User: /vibe.analyze "로그인"
|
|
94
198
|
|
|
95
|
-
Claude:
|
|
199
|
+
Claude: 로그인 관련 코드를 분석합니다...
|
|
96
200
|
|
|
97
|
-
[
|
|
98
|
-
- analyze_complexity 실행 중...
|
|
99
|
-
- validate_code_quality 실행 중...
|
|
100
|
-
- check_coupling_cohesion 실행 중...
|
|
201
|
+
[Glob, Grep, Read 도구로 코드 탐색]
|
|
101
202
|
|
|
102
|
-
|
|
203
|
+
📊 로그인 분석 결과
|
|
204
|
+
|
|
205
|
+
### 개요
|
|
206
|
+
- 기능 설명: JWT 기반 사용자 인증
|
|
207
|
+
- 구현 상태: 완료
|
|
208
|
+
- 관련 파일: 8개
|
|
209
|
+
|
|
210
|
+
### API 엔드포인트
|
|
211
|
+
| POST | /api/v1/auth/login | 로그인 | - |
|
|
212
|
+
| POST | /api/v1/auth/refresh | 토큰 갱신 | Required |
|
|
213
|
+
|
|
214
|
+
[분석 계속...]
|
|
215
|
+
|
|
216
|
+
이제 어떤 작업을 도와드릴까요?
|
|
217
|
+
- 리팩토링
|
|
218
|
+
- 신규 기능 추가
|
|
219
|
+
- 버그 수정
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### 품질 분석
|
|
223
|
+
```
|
|
224
|
+
User: /vibe.analyze --code
|
|
225
|
+
|
|
226
|
+
Claude: 코드 품질 분석을 시작합니다...
|
|
103
227
|
|
|
104
228
|
📊 코드 품질 점수: 85/100 (B+)
|
|
105
229
|
|
|
106
230
|
**주요 발견사항:**
|
|
107
231
|
- 높은 복잡도: src/service.py (CC: 15)
|
|
108
|
-
- 낮은 응집도: src/utils.py (응집도: 0.3)
|
|
109
|
-
- 강한 결합: Controller ↔ Service (결합도: 0.8)
|
|
110
232
|
|
|
111
233
|
**개선 제안:**
|
|
112
234
|
1. src/service.py를 3개 모듈로 분리
|
|
113
|
-
2. src/utils.py의 관련 없는 함수 분리
|
|
114
|
-
3. Dependency Injection 패턴 도입
|
|
115
|
-
|
|
116
|
-
상세 리포트: .vibe/reports/analysis-2025-11-17.md
|
|
117
235
|
```
|
|
118
|
-
|
|
119
|
-
## Notes
|
|
120
|
-
|
|
121
|
-
- MCP 서버(`@su-record/hi-ai`)가 설치되어 있어야 합니다
|
|
122
|
-
- 대규모 프로젝트는 분석에 시간이 걸릴 수 있습니다 (1-5분)
|
|
123
|
-
- 분석 결과는 `.vibe/reports/` 폴더에 저장됩니다
|
|
@@ -37,7 +37,10 @@
|
|
|
37
37
|
"Bash(node:*)",
|
|
38
38
|
"Bash(xargs basename:*)",
|
|
39
39
|
"Bash(git restore:*)",
|
|
40
|
-
"Bash(npm version:*)"
|
|
40
|
+
"Bash(npm version:*)",
|
|
41
|
+
"Bash(npx @su-record/vibe@latest update)",
|
|
42
|
+
"Bash(gh release:*)",
|
|
43
|
+
"Bash(npx @su-record/vibe@latest init:*)"
|
|
41
44
|
],
|
|
42
45
|
"deny": [],
|
|
43
46
|
"ask": []
|
package/bin/vibe
CHANGED
|
@@ -11,6 +11,18 @@ const fs = require('fs');
|
|
|
11
11
|
const args = process.argv.slice(2);
|
|
12
12
|
const command = args[0];
|
|
13
13
|
|
|
14
|
+
// 옵션 파싱
|
|
15
|
+
const options = {
|
|
16
|
+
silent: args.includes('--silent') || args.includes('-s')
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// 로그 함수 (silent 모드 지원)
|
|
20
|
+
function log(message) {
|
|
21
|
+
if (!options.silent) {
|
|
22
|
+
console.log(message);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
14
26
|
// 유틸리티 함수
|
|
15
27
|
function ensureDir(dir) {
|
|
16
28
|
if (!fs.existsSync(dir)) {
|
|
@@ -43,6 +55,94 @@ function copyDirRecursive(sourceDir, targetDir) {
|
|
|
43
55
|
});
|
|
44
56
|
}
|
|
45
57
|
|
|
58
|
+
// 협업자 자동 설치 설정
|
|
59
|
+
function setupCollaboratorAutoInstall(projectRoot) {
|
|
60
|
+
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
61
|
+
const vibeDir = path.join(projectRoot, '.vibe');
|
|
62
|
+
const packageJson = require('../package.json');
|
|
63
|
+
const vibeVersion = packageJson.version;
|
|
64
|
+
|
|
65
|
+
// 1. Node.js 프로젝트: package.json에 devDependency + postinstall 추가
|
|
66
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
67
|
+
try {
|
|
68
|
+
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
69
|
+
|
|
70
|
+
let modified = false;
|
|
71
|
+
|
|
72
|
+
// devDependencies에 vibe 추가
|
|
73
|
+
if (!pkg.devDependencies) {
|
|
74
|
+
pkg.devDependencies = {};
|
|
75
|
+
}
|
|
76
|
+
if (!pkg.devDependencies['@su-record/vibe']) {
|
|
77
|
+
pkg.devDependencies['@su-record/vibe'] = `^${vibeVersion}`;
|
|
78
|
+
modified = true;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// scripts에 postinstall 추가
|
|
82
|
+
if (!pkg.scripts) {
|
|
83
|
+
pkg.scripts = {};
|
|
84
|
+
}
|
|
85
|
+
if (!pkg.scripts.postinstall) {
|
|
86
|
+
pkg.scripts.postinstall = 'vibe update --silent';
|
|
87
|
+
modified = true;
|
|
88
|
+
} else if (!pkg.scripts.postinstall.includes('vibe update')) {
|
|
89
|
+
// 기존 postinstall이 있으면 vibe update 추가
|
|
90
|
+
pkg.scripts.postinstall = `${pkg.scripts.postinstall} && vibe update --silent`;
|
|
91
|
+
modified = true;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (modified) {
|
|
95
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
96
|
+
log(' ✅ package.json에 협업자 자동 설치 설정 추가\n');
|
|
97
|
+
} else {
|
|
98
|
+
log(' ℹ️ package.json 협업 설정 이미 존재\n');
|
|
99
|
+
}
|
|
100
|
+
} catch (e) {
|
|
101
|
+
log(' ⚠️ package.json 수정 실패: ' + e.message + '\n');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// 2. 범용: .vibe/setup.sh 생성 (비-Node 프로젝트 또는 추가 지원)
|
|
106
|
+
const setupShPath = path.join(vibeDir, 'setup.sh');
|
|
107
|
+
if (!fs.existsSync(setupShPath)) {
|
|
108
|
+
const setupScript = `#!/bin/bash
|
|
109
|
+
# Vibe 협업자 자동 설치 스크립트
|
|
110
|
+
# 사용법: ./.vibe/setup.sh
|
|
111
|
+
|
|
112
|
+
set -e
|
|
113
|
+
|
|
114
|
+
echo "🔧 Vibe 설치 확인 중..."
|
|
115
|
+
|
|
116
|
+
# npm/npx 확인
|
|
117
|
+
if ! command -v npx &> /dev/null; then
|
|
118
|
+
echo "❌ Node.js/npm이 설치되어 있지 않습니다."
|
|
119
|
+
echo " https://nodejs.org 에서 설치해주세요."
|
|
120
|
+
exit 1
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
# vibe 설치 확인 및 업데이트
|
|
124
|
+
if command -v vibe &> /dev/null; then
|
|
125
|
+
echo "✅ Vibe가 이미 설치되어 있습니다."
|
|
126
|
+
vibe update --silent
|
|
127
|
+
echo "✅ Vibe 업데이트 완료!"
|
|
128
|
+
else
|
|
129
|
+
echo "📦 Vibe 설치 중..."
|
|
130
|
+
npm install -g @su-record/vibe
|
|
131
|
+
vibe update --silent
|
|
132
|
+
echo "✅ Vibe 설치 및 설정 완료!"
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
echo ""
|
|
136
|
+
echo "다음 명령어로 시작하세요:"
|
|
137
|
+
echo " /vibe.spec \\"기능명\\" SPEC 작성"
|
|
138
|
+
echo " /vibe.run \\"기능명\\" 구현 실행"
|
|
139
|
+
`;
|
|
140
|
+
fs.writeFileSync(setupShPath, setupScript);
|
|
141
|
+
fs.chmodSync(setupShPath, '755');
|
|
142
|
+
log(' ✅ 협업자 설치 스크립트 생성 (.vibe/setup.sh)\n');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
46
146
|
// 프로젝트 초기화
|
|
47
147
|
async function init(projectName) {
|
|
48
148
|
try {
|
|
@@ -53,34 +153,34 @@ async function init(projectName) {
|
|
|
53
153
|
projectRoot = path.join(process.cwd(), projectName);
|
|
54
154
|
|
|
55
155
|
if (fs.existsSync(projectRoot)) {
|
|
56
|
-
|
|
156
|
+
log(`❌ 폴더가 이미 존재합니다: ${projectName}/`);
|
|
57
157
|
return;
|
|
58
158
|
}
|
|
59
159
|
|
|
60
|
-
|
|
160
|
+
log(`📁 새 프로젝트 생성: ${projectName}/\n`);
|
|
61
161
|
fs.mkdirSync(projectRoot, { recursive: true });
|
|
62
162
|
isNewProject = true;
|
|
63
163
|
}
|
|
64
164
|
|
|
65
165
|
const vibeDir = path.join(projectRoot, '.vibe');
|
|
66
166
|
if (fs.existsSync(vibeDir)) {
|
|
67
|
-
|
|
167
|
+
log('❌ .vibe/ 폴더가 이미 존재합니다.');
|
|
68
168
|
return;
|
|
69
169
|
}
|
|
70
170
|
|
|
71
171
|
// MCP 서버 등록 (Claude Code)
|
|
72
172
|
const mcpPath = path.join(__dirname, '..', 'node_modules', '@su-record', 'hi-ai', 'dist', 'index.js');
|
|
73
173
|
|
|
74
|
-
|
|
174
|
+
log('🔧 Claude Code MCP 서버 등록 중...\n');
|
|
75
175
|
const { execSync } = require('child_process');
|
|
76
176
|
try {
|
|
77
177
|
execSync(`claude mcp add vibe node "${mcpPath}"`, { stdio: 'pipe' });
|
|
78
|
-
|
|
178
|
+
log(' ✅ MCP 서버 등록 완료\n');
|
|
79
179
|
} catch (e) {
|
|
80
180
|
if (e.message.includes('already exists')) {
|
|
81
|
-
|
|
181
|
+
log(' ℹ️ MCP 서버 이미 등록됨\n');
|
|
82
182
|
} else {
|
|
83
|
-
|
|
183
|
+
log(' ⚠️ MCP 수동 등록 필요\n');
|
|
84
184
|
}
|
|
85
185
|
}
|
|
86
186
|
|
|
@@ -98,7 +198,7 @@ async function init(projectName) {
|
|
|
98
198
|
|
|
99
199
|
const sourceDir = path.join(__dirname, '../.claude/commands');
|
|
100
200
|
copyDirContents(sourceDir, commandsDir);
|
|
101
|
-
|
|
201
|
+
log(' ✅ 슬래시 커맨드 설치 완료 (7개)\n');
|
|
102
202
|
|
|
103
203
|
// 설정 파일 생성
|
|
104
204
|
const templatePath = path.join(__dirname, '../templates/constitution-template.md');
|
|
@@ -126,28 +226,28 @@ async function init(projectName) {
|
|
|
126
226
|
// vibe 섹션이 없으면 끝에 추가
|
|
127
227
|
const mergedContent = existingContent.trim() + '\n\n---\n\n' + vibeContent;
|
|
128
228
|
fs.writeFileSync(projectClaudeMd, mergedContent);
|
|
129
|
-
|
|
229
|
+
log(' ✅ CLAUDE.md에 vibe 섹션 추가\n');
|
|
130
230
|
} else {
|
|
131
|
-
|
|
231
|
+
log(' ℹ️ CLAUDE.md에 vibe 섹션 이미 존재\n');
|
|
132
232
|
}
|
|
133
233
|
} else {
|
|
134
234
|
// 없으면 새로 생성
|
|
135
235
|
fs.copyFileSync(vibeClaudeMd, projectClaudeMd);
|
|
136
|
-
|
|
236
|
+
log(' ✅ CLAUDE.md 생성\n');
|
|
137
237
|
}
|
|
138
238
|
|
|
139
239
|
// .agent/rules/ 복사 (코딩 규칙)
|
|
140
240
|
const rulesSource = path.join(__dirname, '../.agent/rules');
|
|
141
241
|
const rulesTarget = path.join(projectRoot, '.agent/rules');
|
|
142
242
|
copyDirRecursive(rulesSource, rulesTarget);
|
|
143
|
-
|
|
243
|
+
log(' ✅ 코딩 규칙 설치 완료 (.agent/rules/)\n');
|
|
144
244
|
|
|
145
245
|
// .claude/agents/ 복사 (서브에이전트)
|
|
146
246
|
const agentsDir = path.join(claudeDir, 'agents');
|
|
147
247
|
ensureDir(agentsDir);
|
|
148
248
|
const agentsSourceDir = path.join(__dirname, '../.claude/agents');
|
|
149
249
|
copyDirContents(agentsSourceDir, agentsDir);
|
|
150
|
-
|
|
250
|
+
log(' ✅ 서브에이전트 설치 완료 (.claude/agents/)\n');
|
|
151
251
|
|
|
152
252
|
// .claude/settings.local.json 생성 (Hooks 설정)
|
|
153
253
|
const settingsPath = path.join(claudeDir, 'settings.local.json');
|
|
@@ -155,14 +255,17 @@ async function init(projectName) {
|
|
|
155
255
|
const hooksTemplate = path.join(__dirname, '../templates/hooks-template.json');
|
|
156
256
|
if (fs.existsSync(hooksTemplate)) {
|
|
157
257
|
fs.copyFileSync(hooksTemplate, settingsPath);
|
|
158
|
-
|
|
258
|
+
log(' ✅ Hooks 설정 설치 완료 (.claude/settings.local.json)\n');
|
|
159
259
|
}
|
|
160
260
|
} else {
|
|
161
|
-
|
|
261
|
+
log(' ℹ️ Hooks 설정 이미 존재\n');
|
|
162
262
|
}
|
|
163
263
|
|
|
264
|
+
// 협업자 자동 설치 설정
|
|
265
|
+
setupCollaboratorAutoInstall(projectRoot);
|
|
266
|
+
|
|
164
267
|
// 완료 메시지
|
|
165
|
-
|
|
268
|
+
log(`
|
|
166
269
|
✅ vibe 초기화 완료!
|
|
167
270
|
|
|
168
271
|
${isNewProject ? `프로젝트 위치:
|
|
@@ -181,10 +284,12 @@ ${isNewProject ? `프로젝트 위치:
|
|
|
181
284
|
.vibe/
|
|
182
285
|
├── config.json # 프로젝트 설정
|
|
183
286
|
├── constitution.md # 프로젝트 원칙
|
|
287
|
+
├── setup.sh # 협업자 설치 스크립트
|
|
184
288
|
├── specs/ # SPEC 문서들
|
|
185
289
|
└── features/ # BDD Feature 파일들
|
|
186
290
|
|
|
187
291
|
MCP 서버 (hi-ai): ✓
|
|
292
|
+
협업자 자동 설치: ✓
|
|
188
293
|
|
|
189
294
|
사용법:
|
|
190
295
|
/vibe.spec "기능명" SPEC 작성 (대화형)
|
|
@@ -244,27 +349,27 @@ async function update() {
|
|
|
244
349
|
return;
|
|
245
350
|
}
|
|
246
351
|
|
|
247
|
-
|
|
352
|
+
log('🔄 vibe 업데이트 중...\n');
|
|
248
353
|
|
|
249
354
|
// .claude/commands 업데이트
|
|
250
355
|
const commandsDir = path.join(claudeDir, 'commands');
|
|
251
356
|
ensureDir(commandsDir);
|
|
252
357
|
const sourceDir = path.join(__dirname, '../.claude/commands');
|
|
253
358
|
copyDirContents(sourceDir, commandsDir);
|
|
254
|
-
|
|
359
|
+
log(' ✅ 슬래시 커맨드 업데이트 완료 (7개)\n');
|
|
255
360
|
|
|
256
361
|
// .agent/rules/ 업데이트
|
|
257
362
|
const rulesSource = path.join(__dirname, '../.agent/rules');
|
|
258
363
|
const rulesTarget = path.join(projectRoot, '.agent/rules');
|
|
259
364
|
copyDirRecursive(rulesSource, rulesTarget);
|
|
260
|
-
|
|
365
|
+
log(' ✅ 코딩 규칙 업데이트 완료 (.agent/rules/)\n');
|
|
261
366
|
|
|
262
367
|
// .claude/agents/ 업데이트
|
|
263
368
|
const agentsDir = path.join(claudeDir, 'agents');
|
|
264
369
|
ensureDir(agentsDir);
|
|
265
370
|
const agentsSourceDir = path.join(__dirname, '../.claude/agents');
|
|
266
371
|
copyDirContents(agentsSourceDir, agentsDir);
|
|
267
|
-
|
|
372
|
+
log(' ✅ 서브에이전트 업데이트 완료 (.claude/agents/)\n');
|
|
268
373
|
|
|
269
374
|
// settings.local.json에 hooks 병합
|
|
270
375
|
const settingsPath = path.join(claudeDir, 'settings.local.json');
|
|
@@ -280,19 +385,29 @@ async function update() {
|
|
|
280
385
|
if (!existingSettings.hooks) {
|
|
281
386
|
existingSettings.hooks = vibeHooks.hooks;
|
|
282
387
|
fs.writeFileSync(settingsPath, JSON.stringify(existingSettings, null, 2));
|
|
283
|
-
|
|
388
|
+
log(' ✅ Hooks 설정 추가 완료\n');
|
|
284
389
|
} else {
|
|
285
|
-
|
|
390
|
+
log(' ℹ️ Hooks 설정 이미 존재\n');
|
|
286
391
|
}
|
|
287
392
|
} else {
|
|
288
393
|
// 새로 생성
|
|
289
394
|
fs.copyFileSync(hooksTemplate, settingsPath);
|
|
290
|
-
|
|
395
|
+
log(' ✅ Hooks 설정 생성 완료\n');
|
|
291
396
|
}
|
|
292
397
|
}
|
|
293
398
|
|
|
399
|
+
// MCP 서버 등록 확인
|
|
400
|
+
const mcpPath = path.join(__dirname, '..', 'node_modules', '@su-record', 'hi-ai', 'dist', 'index.js');
|
|
401
|
+
const { execSync } = require('child_process');
|
|
402
|
+
try {
|
|
403
|
+
execSync(`claude mcp add vibe node "${mcpPath}"`, { stdio: 'pipe' });
|
|
404
|
+
log(' ✅ MCP 서버 등록 완료\n');
|
|
405
|
+
} catch (e) {
|
|
406
|
+
// 이미 등록됨 - silent
|
|
407
|
+
}
|
|
408
|
+
|
|
294
409
|
const packageJson = require('../package.json');
|
|
295
|
-
|
|
410
|
+
log(`
|
|
296
411
|
✅ vibe 업데이트 완료! (v${packageJson.version})
|
|
297
412
|
|
|
298
413
|
업데이트된 항목:
|
|
@@ -300,6 +415,7 @@ async function update() {
|
|
|
300
415
|
- 코딩 규칙 (.agent/rules/)
|
|
301
416
|
- 서브에이전트 (.claude/agents/)
|
|
302
417
|
- Hooks 설정
|
|
418
|
+
- MCP 서버
|
|
303
419
|
`);
|
|
304
420
|
|
|
305
421
|
} catch (error) {
|