@su-record/vibe 1.0.3 → 1.0.4

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.
Files changed (2) hide show
  1. package/bin/vibe +96 -9
  2. package/package.json +1 -1
package/bin/vibe CHANGED
@@ -352,13 +352,6 @@ async function init(projectName) {
352
352
  copyDirContents(sourceDir, commandsDir);
353
353
  log(' ✅ 슬래시 커맨드 설치 완료 (7개)\n');
354
354
 
355
- // 설정 파일 생성
356
- const templatePath = path.join(__dirname, '../templates/constitution-template.md');
357
- const constitutionPath = path.join(vibeDir, 'constitution.md');
358
- if (fs.existsSync(templatePath)) {
359
- fs.copyFileSync(templatePath, constitutionPath);
360
- }
361
-
362
355
  // 기술 스택 감지
363
356
  const detectedStacks = detectTechStacks(projectRoot);
364
357
  if (detectedStacks.length > 0) {
@@ -368,6 +361,70 @@ async function init(projectName) {
368
361
  });
369
362
  }
370
363
 
364
+ // constitution.md 생성 (감지된 스택으로 플레이스홀더 업데이트)
365
+ const templatePath = path.join(__dirname, '../templates/constitution-template.md');
366
+ const constitutionPath = path.join(vibeDir, 'constitution.md');
367
+ if (fs.existsSync(templatePath)) {
368
+ let constitution = fs.readFileSync(templatePath, 'utf-8');
369
+
370
+ // 기술 스택 정보 생성
371
+ const backendStack = detectedStacks.find(s =>
372
+ s.type.includes('python') || s.type.includes('node') ||
373
+ s.type.includes('go') || s.type.includes('java') || s.type.includes('rust')
374
+ );
375
+ const frontendStack = detectedStacks.find(s =>
376
+ s.type.includes('react') || s.type.includes('vue') ||
377
+ s.type.includes('flutter') || s.type.includes('swift') || s.type.includes('android')
378
+ );
379
+
380
+ // 스택 이름 매핑
381
+ const stackNames = {
382
+ 'python-fastapi': { lang: 'Python 3.11+', framework: 'FastAPI' },
383
+ 'python-django': { lang: 'Python 3.11+', framework: 'Django' },
384
+ 'python': { lang: 'Python 3.11+', framework: '-' },
385
+ 'typescript-node': { lang: 'TypeScript/Node.js', framework: 'Express/Fastify' },
386
+ 'typescript-nextjs': { lang: 'TypeScript', framework: 'Next.js' },
387
+ 'typescript-react': { lang: 'TypeScript', framework: 'React' },
388
+ 'typescript-vue': { lang: 'TypeScript', framework: 'Vue.js' },
389
+ 'typescript-react-native': { lang: 'TypeScript', framework: 'React Native' },
390
+ 'dart-flutter': { lang: 'Dart', framework: 'Flutter' },
391
+ 'go': { lang: 'Go', framework: '-' },
392
+ 'rust': { lang: 'Rust', framework: '-' },
393
+ 'java-spring': { lang: 'Java 17+', framework: 'Spring Boot' },
394
+ 'kotlin-android': { lang: 'Kotlin', framework: 'Android' },
395
+ 'swift-ios': { lang: 'Swift', framework: 'iOS/SwiftUI' }
396
+ };
397
+
398
+ // 플레이스홀더 업데이트
399
+ if (backendStack && stackNames[backendStack.type]) {
400
+ const info = stackNames[backendStack.type];
401
+ constitution = constitution.replace(
402
+ '- Language: {Python 3.11+ / Node.js / etc.}',
403
+ `- Language: ${info.lang}`
404
+ );
405
+ constitution = constitution.replace(
406
+ '- Framework: {FastAPI / Express / etc.}',
407
+ `- Framework: ${info.framework}`
408
+ );
409
+ }
410
+
411
+ if (frontendStack && stackNames[frontendStack.type]) {
412
+ const info = stackNames[frontendStack.type];
413
+ constitution = constitution.replace(
414
+ '- Framework: {Flutter / React / etc.}',
415
+ `- Framework: ${info.framework}`
416
+ );
417
+ }
418
+
419
+ // 날짜 업데이트
420
+ const today = new Date().toISOString().split('T')[0];
421
+ constitution = constitution.replace('{날짜}', today);
422
+ constitution = constitution.replace('{이름}', 'vibe init');
423
+ constitution = constitution.replace('토큰 유효 기간: {기간}', '토큰 유효 기간: 1시간');
424
+
425
+ fs.writeFileSync(constitutionPath, constitution);
426
+ }
427
+
371
428
  const config = {
372
429
  language: 'ko',
373
430
  quality: { strict: true, autoVerify: true },
@@ -398,10 +455,40 @@ async function init(projectName) {
398
455
  log(' ✅ CLAUDE.md 생성\n');
399
456
  }
400
457
 
401
- // .vibe/rules/ 복사 (코딩 규칙)
458
+ // .vibe/rules/ 복사 (감지된 스택에 해당하는 언어 규칙만)
402
459
  const rulesSource = path.join(__dirname, '../.vibe/rules');
403
460
  const rulesTarget = path.join(vibeDir, 'rules');
404
- copyDirRecursive(rulesSource, rulesTarget);
461
+
462
+ // core, quality, standards, tools는 전체 복사
463
+ const coreDirs = ['core', 'quality', 'standards', 'tools'];
464
+ coreDirs.forEach(dir => {
465
+ const src = path.join(rulesSource, dir);
466
+ const dst = path.join(rulesTarget, dir);
467
+ if (fs.existsSync(src)) {
468
+ copyDirRecursive(src, dst);
469
+ }
470
+ });
471
+
472
+ // languages는 감지된 스택만 복사
473
+ const langSource = path.join(rulesSource, 'languages');
474
+ const langTarget = path.join(rulesTarget, 'languages');
475
+ ensureDir(langTarget);
476
+
477
+ const detectedTypes = detectedStacks.map(s => s.type);
478
+ if (fs.existsSync(langSource)) {
479
+ const langFiles = fs.readdirSync(langSource);
480
+ langFiles.forEach(file => {
481
+ const langType = file.replace('.md', '');
482
+ // 감지된 스택에 해당하는 파일만 복사
483
+ if (detectedTypes.includes(langType)) {
484
+ fs.copyFileSync(path.join(langSource, file), path.join(langTarget, file));
485
+ }
486
+ });
487
+ }
488
+
489
+ const copiedLangs = detectedTypes.filter(t =>
490
+ fs.existsSync(path.join(langTarget, `${t}.md`))
491
+ );
405
492
  log(' ✅ 코딩 규칙 설치 완료 (.vibe/rules/)\n');
406
493
 
407
494
  // .claude/agents/ 복사 (서브에이전트)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@su-record/vibe",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Vibe - Claude Code exclusive SPEC-driven AI coding framework",
5
5
  "bin": {
6
6
  "vibe": "./bin/vibe"