@su-record/vibe 0.4.8 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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) {
@@ -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.8",
3
+ "version": "1.0.0",
4
4
  "description": "Vibe - Claude Code exclusive SPEC-driven AI coding framework",
5
5
  "bin": {
6
6
  "vibe": "./bin/vibe"