@team-semicolon/semo-cli 3.0.6 → 3.0.9

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 (3) hide show
  1. package/README.md +168 -55
  2. package/dist/index.js +174 -10
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,70 +1,71 @@
1
1
  # @team-semicolon/semo-cli
2
2
 
3
- > SEMO CLI - AI Agent Orchestration Framework Installer
3
+ > SEMO CLI v3.0 - AI Agent Orchestration Framework Installer
4
4
 
5
- ## 개요
6
-
7
- Gemini의 하이브리드 전략에 따라 SEMO를 자동 설치하는 CLI 도구입니다.
5
+ ## 설치
8
6
 
9
7
  ```bash
10
- npx @team-semicolon/semo-cli init
8
+ npm install -g @team-semicolon/semo-cli
11
9
  ```
12
10
 
13
- ## 동작 방식
14
-
15
- `semo init` 명령어는 다음을 자동으로 수행합니다:
11
+ ## 빠른 시작
16
12
 
17
- ### 1. White Box 설정 (Git Subtree)
13
+ ```bash
14
+ # 프로젝트에 SEMO 설치
15
+ semo init
18
16
 
19
- 에이전트가 **읽고 학습**해야 하는 지식 베이스:
17
+ # Extension 패키지 추가
18
+ semo add eng/nextjs
20
19
 
20
+ # 버전 확인 및 업데이트 체크
21
+ semo -v
21
22
  ```
22
- semo-system/
23
- ├── semo-core/ # Layer 0: 원칙, 오케스트레이션
24
- └── semo-skills/ # Layer 1: coder, tester, planner
25
- ```
26
23
 
27
- ### 2. Black Box 설정 (MCP Server)
24
+ ## 명령어
25
+
26
+ ### `semo init`
28
27
 
29
- 토큰이 격리된 **외부 연동 도구**:
28
+ 현재 프로젝트에 SEMO를 설치합니다.
30
29
 
31
- ```json
32
- // .claude/settings.json
33
- {
34
- "mcpServers": {
35
- "semo-integrations": {
36
- "command": "npx",
37
- "args": ["-y", "@team-semicolon/semo-mcp"]
38
- }
39
- }
40
- }
30
+ ```bash
31
+ semo init # 기본 설치 (프로젝트 유형 자동 감지)
32
+ semo init --force # 기존 설정 덮어쓰기
33
+ semo init --skip-mcp # MCP 설정 생략
34
+ semo init --with next,infra # 특정 패키지와 함께 설치
41
35
  ```
42
36
 
43
- ### 3. Context Mesh 초기화
37
+ ### `semo add <packages>`
44
38
 
45
- 세션 **컨텍스트 영속화**:
39
+ Extension 패키지를 추가로 설치합니다.
46
40
 
41
+ ```bash
42
+ # 개별 패키지 설치
43
+ semo add eng/nextjs
44
+ semo add biz/discovery
45
+
46
+ # 그룹 일괄 설치
47
+ semo add biz # Business 전체 (discovery, design, management, poc)
48
+ semo add eng # Engineering 전체 (nextjs, spring, ms, infra)
49
+ semo add ops # Operations 전체 (qa, monitor, improve)
50
+
51
+ # 여러 패키지 동시 설치
52
+ semo add eng/nextjs,eng/infra
53
+
54
+ # 레거시 별칭 지원
55
+ semo add next # → eng/nextjs
56
+ semo add backend # → eng/spring
57
+ semo add mvp # → biz/poc
47
58
  ```
48
- .claude/memory/
49
- ├── context.md # 프로젝트 상태
50
- ├── decisions.md # 아키텍처 결정
51
- └── rules/ # 프로젝트별 규칙
52
- ```
53
-
54
- ## 명령어
55
59
 
56
- ### init
60
+ ### `semo list`
57
61
 
58
- 현재 프로젝트에 SEMO를 설치합니다.
62
+ 사용 가능한 모든 패키지를 표시합니다.
59
63
 
60
64
  ```bash
61
- semo init # 기본 설치
62
- semo init --force # 기존 설정 덮어쓰기
63
- semo init --skip-mcp # MCP 설정 생략
64
- semo init --skip-subtree # Git Subtree 생략
65
+ semo list
65
66
  ```
66
67
 
67
- ### status
68
+ ### `semo status`
68
69
 
69
70
  SEMO 설치 상태를 확인합니다.
70
71
 
@@ -72,31 +73,117 @@ SEMO 설치 상태를 확인합니다.
72
73
  semo status
73
74
  ```
74
75
 
75
- ### update
76
+ ### `semo version` / `semo -v`
77
+
78
+ 버전 정보 및 업데이트 확인을 표시합니다.
79
+
80
+ ```bash
81
+ semo version
82
+ semo -v
83
+ ```
84
+
85
+ 출력 예시:
86
+ ```
87
+ 📦 SEMO CLI 버전 정보
88
+
89
+ 현재 버전: 3.0.7
90
+ 최신 버전: 3.0.7
91
+
92
+ ✓ 최신 버전을 사용 중입니다.
93
+ ```
94
+
95
+ ### `semo update`
76
96
 
77
97
  SEMO를 최신 버전으로 업데이트합니다.
78
98
 
79
99
  ```bash
80
- semo update
100
+ semo update # CLI + semo-system 전체 업데이트
101
+ semo update --self # CLI만 업데이트
102
+ semo update --system # semo-system만 업데이트
103
+ semo update --skip-cli # CLI 업데이트 건너뛰기
81
104
  ```
82
105
 
106
+ ## 패키지 구조
107
+
108
+ ### Standard (필수)
109
+
110
+ 모든 프로젝트에 기본 설치됩니다.
111
+
112
+ | 패키지 | 설명 |
113
+ |--------|------|
114
+ | `semo-core` | 원칙, 오케스트레이터, 공통 커맨드 |
115
+ | `semo-skills` | 13개 통합 스킬 (coder, tester, planner, deployer 등) |
116
+
117
+ ### Extensions (선택)
118
+
119
+ 프로젝트 유형에 맞게 선택적으로 설치합니다.
120
+
121
+ #### Business Layer (`biz`)
122
+
123
+ | 패키지 | 설명 | 설치 |
124
+ |--------|------|------|
125
+ | `biz/discovery` | 아이템 발굴, 시장 조사, Epic/Task | `semo add biz/discovery` |
126
+ | `biz/design` | 컨셉 설계, 목업, UX | `semo add biz/design` |
127
+ | `biz/management` | 일정/인력/스프린트 관리 | `semo add biz/management` |
128
+ | `biz/poc` | 빠른 PoC, 패스트트랙 | `semo add biz/poc` |
129
+
130
+ #### Engineering Layer (`eng`)
131
+
132
+ | 패키지 | 설명 | 자동 감지 | 설치 |
133
+ |--------|------|----------|------|
134
+ | `eng/nextjs` | Next.js 프론트엔드 개발 | `next.config.*` | `semo add eng/nextjs` |
135
+ | `eng/spring` | Spring Boot 백엔드 개발 | `pom.xml`, `build.gradle` | `semo add eng/spring` |
136
+ | `eng/ms` | 마이크로서비스 아키텍처 | - | `semo add eng/ms` |
137
+ | `eng/infra` | 인프라/배포 관리 | `Dockerfile`, `docker-compose.yml` | `semo add eng/infra` |
138
+
139
+ #### Operations Layer (`ops`)
140
+
141
+ | 패키지 | 설명 | 설치 |
142
+ |--------|------|------|
143
+ | `ops/qa` | 테스트/품질 관리 | `semo add ops/qa` |
144
+ | `ops/monitor` | 서비스 현황 모니터링 | `semo add ops/monitor` |
145
+ | `ops/improve` | 개선 제안 | `semo add ops/improve` |
146
+
147
+ #### Meta
148
+
149
+ | 패키지 | 설명 | 설치 |
150
+ |--------|------|------|
151
+ | `meta` | SEMO 프레임워크 자체 개발/관리 | `semo add meta` |
152
+
83
153
  ## 설치 후 구조
84
154
 
85
155
  ```
86
156
  your-project/
87
157
  ├── .claude/
88
- │ ├── CLAUDE.md # 프로젝트 설정
89
- │ ├── settings.json # MCP 서버 설정
90
- │ ├── memory/ # Context Mesh
91
- │ ├── agents semo-system/semo-core/agents
92
- └── skills semo-system/semo-skills
158
+ │ ├── CLAUDE.md # 프로젝트 설정 (Extension CLAUDE.md 병합)
159
+ │ ├── settings.json # MCP 서버 설정
160
+ │ ├── memory/ # Context Mesh (세션 간 컨텍스트)
161
+ ├── context.md # 프로젝트 상태
162
+ │ ├── decisions.md # 아키텍처 결정
163
+ │ │ └── rules/ # 프로젝트별 규칙
164
+ │ ├── agents/ # 에이전트 심볼릭 링크
165
+ │ ├── skills/ # 스킬 심볼릭 링크
166
+ │ └── commands/SEMO/ # SEMO 커맨드
93
167
 
94
- └── semo-system/ # White Box (읽기 전용)
95
- ├── semo-core/
96
- └── semo-skills/
168
+ └── semo-system/ # White Box (읽기 전용)
169
+ ├── semo-core/ # Layer 0: 원칙, 오케스트레이션
170
+ ├── semo-skills/ # Layer 1: 통합 스킬
171
+ ├── biz/ # Business Layer (선택)
172
+ ├── eng/ # Engineering Layer (선택)
173
+ └── ops/ # Operations Layer (선택)
97
174
  ```
98
175
 
99
- ## 환경변수
176
+ ## MCP 서버
177
+
178
+ SEMO CLI는 다음 MCP 서버를 자동으로 등록합니다:
179
+
180
+ | 서버 | 설명 |
181
+ |------|------|
182
+ | `semo-integrations` | GitHub, Slack, Supabase 연동 |
183
+ | `context7` | 라이브러리 문서 조회 |
184
+ | `sequential-thinking` | 순차적 사고 지원 |
185
+
186
+ ### 환경변수
100
187
 
101
188
  MCP 연동을 위해 다음 환경변수를 설정하세요:
102
189
 
@@ -107,11 +194,37 @@ MCP 연동을 위해 다음 환경변수를 설정하세요:
107
194
  | `SUPABASE_URL` | Supabase 프로젝트 URL |
108
195
  | `SUPABASE_KEY` | Supabase 서비스 키 |
109
196
 
197
+ ## 프로젝트 유형 자동 감지
198
+
199
+ `semo init` 실행 시 프로젝트 파일을 분석하여 적절한 패키지를 추천합니다:
200
+
201
+ | 감지 파일 | 추천 패키지 |
202
+ |----------|-------------|
203
+ | `next.config.js`, `next.config.mjs`, `next.config.ts` | `eng/nextjs` |
204
+ | `pom.xml`, `build.gradle` | `eng/spring` |
205
+ | `Dockerfile`, `docker-compose.yml` | `eng/infra` |
206
+ | `semo-core`, `semo-skills` | `meta` |
207
+
208
+ ## 레거시 명령어 호환
209
+
210
+ 이전 버전 사용자를 위해 레거시 패키지명도 지원합니다:
211
+
212
+ | 레거시 | 현재 |
213
+ |--------|------|
214
+ | `semo add next` | `semo add eng/nextjs` |
215
+ | `semo add backend` | `semo add eng/spring` |
216
+ | `semo add ms` | `semo add eng/ms` |
217
+ | `semo add infra` | `semo add eng/infra` |
218
+ | `semo add qa` | `semo add ops/qa` |
219
+ | `semo add po` | `semo add biz/discovery` |
220
+ | `semo add pm` | `semo add biz/management` |
221
+ | `semo add design` | `semo add biz/design` |
222
+ | `semo add mvp` | `semo add biz/poc` |
223
+
110
224
  ## 참조
111
225
 
112
226
  - [SEMO 레포지토리](https://github.com/semicolon-devteam/semo)
113
- - [SEMO MCP Server](../mcp-server/README.md)
114
- - [Gemini 하이브리드 전략](../../docs/SEMO_ARCHITECTURE_REVIEW.md)
227
+ - [SEMO MCP Server](https://www.npmjs.com/package/@team-semicolon/semo-mcp)
115
228
 
116
229
  ## 라이선스
117
230
 
package/dist/index.js CHANGED
@@ -59,7 +59,7 @@ const child_process_1 = require("child_process");
59
59
  const fs = __importStar(require("fs"));
60
60
  const path = __importStar(require("path"));
61
61
  const os = __importStar(require("os"));
62
- const VERSION = "3.0.6";
62
+ const VERSION = "3.0.9";
63
63
  const PACKAGE_NAME = "@team-semicolon/semo-cli";
64
64
  // === 버전 비교 유틸리티 ===
65
65
  /**
@@ -313,17 +313,92 @@ function detectProjectType(cwd) {
313
313
  }
314
314
  return detected;
315
315
  }
316
+ function checkRequiredTools() {
317
+ const tools = [
318
+ {
319
+ name: "GitHub CLI (gh)",
320
+ installed: false,
321
+ installCmd: isWindows ? "winget install GitHub.cli" : "brew install gh",
322
+ description: "GitHub API 연동 (이슈, PR, 배포)",
323
+ },
324
+ {
325
+ name: "Supabase CLI",
326
+ installed: false,
327
+ installCmd: isWindows ? "npm install -g supabase" : "brew install supabase/tap/supabase",
328
+ description: "Supabase 데이터베이스 연동",
329
+ },
330
+ ];
331
+ // GitHub CLI 확인
332
+ try {
333
+ const ghVersion = (0, child_process_1.execSync)("gh --version", { stdio: "pipe", encoding: "utf-8" });
334
+ tools[0].installed = true;
335
+ tools[0].version = ghVersion.split("\n")[0].replace("gh version ", "").trim();
336
+ }
337
+ catch {
338
+ // gh not installed
339
+ }
340
+ // Supabase CLI 확인
341
+ try {
342
+ const supabaseVersion = (0, child_process_1.execSync)("supabase --version", { stdio: "pipe", encoding: "utf-8" });
343
+ tools[1].installed = true;
344
+ tools[1].version = supabaseVersion.trim();
345
+ }
346
+ catch {
347
+ // supabase not installed
348
+ }
349
+ return tools;
350
+ }
351
+ async function showToolsStatus() {
352
+ console.log(chalk_1.default.cyan("\n🔍 필수 도구 확인"));
353
+ const tools = checkRequiredTools();
354
+ const missingTools = tools.filter(t => !t.installed);
355
+ for (const tool of tools) {
356
+ if (tool.installed) {
357
+ console.log(chalk_1.default.green(` ✓ ${tool.name} ${tool.version ? `(${tool.version})` : ""}`));
358
+ }
359
+ else {
360
+ console.log(chalk_1.default.yellow(` ✗ ${tool.name} - 미설치`));
361
+ console.log(chalk_1.default.gray(` ${tool.description}`));
362
+ }
363
+ }
364
+ if (missingTools.length > 0) {
365
+ console.log(chalk_1.default.yellow("\n⚠ 일부 도구가 설치되어 있지 않습니다."));
366
+ console.log(chalk_1.default.gray(" SEMO의 일부 기능이 제한될 수 있습니다.\n"));
367
+ console.log(chalk_1.default.cyan("📋 설치 명령어:"));
368
+ for (const tool of missingTools) {
369
+ console.log(chalk_1.default.white(` ${tool.installCmd}`));
370
+ }
371
+ console.log();
372
+ const { continueWithout } = await inquirer_1.default.prompt([
373
+ {
374
+ type: "confirm",
375
+ name: "continueWithout",
376
+ message: "도구 없이 계속 설치를 진행할까요?",
377
+ default: true,
378
+ },
379
+ ]);
380
+ return continueWithout;
381
+ }
382
+ return true;
383
+ }
316
384
  // === init 명령어 ===
317
385
  program
318
386
  .command("init")
319
387
  .description("현재 프로젝트에 SEMO를 설치합니다")
320
388
  .option("-f, --force", "기존 설정 덮어쓰기")
321
389
  .option("--skip-mcp", "MCP 설정 생략")
390
+ .option("--no-gitignore", ".gitignore 수정 생략")
322
391
  .option("--with <packages>", "추가 설치할 패키지 (쉼표 구분: next,backend)")
323
392
  .action(async (options) => {
324
393
  console.log(chalk_1.default.cyan.bold("\n🚀 SEMO 설치 시작\n"));
325
394
  console.log(chalk_1.default.gray("Gemini 하이브리드 전략: White Box + Black Box\n"));
326
395
  const cwd = process.cwd();
396
+ // 0. 필수 도구 확인
397
+ const shouldContinue = await showToolsStatus();
398
+ if (!shouldContinue) {
399
+ console.log(chalk_1.default.yellow("\n설치가 취소되었습니다. 필수 도구 설치 후 다시 시도하세요.\n"));
400
+ process.exit(0);
401
+ }
327
402
  // 1. Git 레포지토리 확인
328
403
  const spinner = (0, ora_1.default)("Git 레포지토리 확인 중...").start();
329
404
  try {
@@ -375,9 +450,13 @@ program
375
450
  }
376
451
  // 7. Context Mesh 초기화
377
452
  await setupContextMesh(cwd);
378
- // 8. CLAUDE.md 생성
453
+ // 8. .gitignore 업데이트
454
+ if (options.gitignore !== false) {
455
+ updateGitignore(cwd);
456
+ }
457
+ // 9. CLAUDE.md 생성
379
458
  await setupClaudeMd(cwd, extensionsToInstall, options.force);
380
- // 9. Extensions 심볼릭 링크 (agents/skills 병합)
459
+ // 10. Extensions 심볼릭 링크 (agents/skills 병합)
381
460
  if (extensionsToInstall.length > 0) {
382
461
  await setupExtensionSymlinks(cwd, extensionsToInstall);
383
462
  }
@@ -488,13 +567,20 @@ async function createStandardSymlinks(cwd) {
488
567
  const commandsDir = path.join(claudeDir, "commands");
489
568
  fs.mkdirSync(commandsDir, { recursive: true });
490
569
  const semoCommandsLink = path.join(commandsDir, "SEMO");
491
- if (!fs.existsSync(semoCommandsLink)) {
492
- const commandsTarget = path.join(semoSystemDir, "semo-core", "commands", "SEMO");
493
- if (fs.existsSync(commandsTarget)) {
494
- createSymlinkOrJunction(commandsTarget, semoCommandsLink);
495
- console.log(chalk_1.default.green(" ✓ .claude/commands/SEMO → semo-system/semo-core/commands/SEMO"));
570
+ const commandsTarget = path.join(semoSystemDir, "semo-core", "commands", "SEMO");
571
+ // 기존 링크가 있으면 삭제 후 재생성 (업데이트 시에도 최신 반영)
572
+ if (fs.existsSync(semoCommandsLink)) {
573
+ if (fs.lstatSync(semoCommandsLink).isSymbolicLink()) {
574
+ fs.unlinkSync(semoCommandsLink);
575
+ }
576
+ else {
577
+ removeRecursive(semoCommandsLink);
496
578
  }
497
579
  }
580
+ if (fs.existsSync(commandsTarget)) {
581
+ createSymlinkOrJunction(commandsTarget, semoCommandsLink);
582
+ console.log(chalk_1.default.green(" ✓ .claude/commands/SEMO → semo-system/semo-core/commands/SEMO"));
583
+ }
498
584
  }
499
585
  // === Extensions 다운로드 (심볼릭 링크 제외) ===
500
586
  async function downloadExtensions(cwd, packages, force) {
@@ -511,6 +597,27 @@ async function downloadExtensions(cwd, packages, force) {
511
597
  (0, child_process_1.execSync)(`git clone --depth 1 ${SEMO_REPO} "${tempDir}"`, { stdio: "pipe" });
512
598
  }
513
599
  const semoSystemDir = path.join(cwd, "semo-system");
600
+ // 그룹 추출 (중복 제거) - 그룹 레벨 CLAUDE.md 복사용
601
+ const groups = [...new Set(packages.map(pkg => pkg.split("/")[0]).filter(g => ["biz", "eng", "ops"].includes(g)))];
602
+ // 그룹 레벨 파일 복사 (CLAUDE.md, VERSION 등)
603
+ for (const group of groups) {
604
+ const groupSrcDir = path.join(tempDir, "packages", group);
605
+ const groupDestDir = path.join(semoSystemDir, group);
606
+ // 그룹 디렉토리의 루트 파일만 복사 (CLAUDE.md, VERSION)
607
+ if (fs.existsSync(groupSrcDir)) {
608
+ fs.mkdirSync(groupDestDir, { recursive: true });
609
+ const groupFiles = fs.readdirSync(groupSrcDir);
610
+ for (const file of groupFiles) {
611
+ const srcFile = path.join(groupSrcDir, file);
612
+ const destFile = path.join(groupDestDir, file);
613
+ if (fs.statSync(srcFile).isFile()) {
614
+ fs.copyFileSync(srcFile, destFile);
615
+ }
616
+ }
617
+ console.log(chalk_1.default.green(` ✓ ${group}/ 그룹 파일 복사 (CLAUDE.md 등)`));
618
+ }
619
+ }
620
+ // 개별 패키지 복사
514
621
  for (const pkg of packages) {
515
622
  const srcPath = path.join(tempDir, "packages", pkg);
516
623
  const destPath = path.join(semoSystemDir, pkg);
@@ -520,6 +627,8 @@ async function downloadExtensions(cwd, packages, force) {
520
627
  continue;
521
628
  }
522
629
  removeRecursive(destPath);
630
+ // 상위 디렉토리 생성 (biz/discovery -> biz/ 먼저 생성)
631
+ fs.mkdirSync(path.dirname(destPath), { recursive: true });
523
632
  copyRecursive(srcPath, destPath);
524
633
  }
525
634
  }
@@ -1020,6 +1129,33 @@ async function mergeExtensionSettings(cwd, packages) {
1020
1129
  }
1021
1130
  }
1022
1131
  }
1132
+ // === .gitignore 업데이트 ===
1133
+ function updateGitignore(cwd) {
1134
+ console.log(chalk_1.default.cyan("\n📝 .gitignore 업데이트"));
1135
+ const gitignorePath = path.join(cwd, ".gitignore");
1136
+ const semoIgnoreBlock = `
1137
+ # === SEMO ===
1138
+ .claude/*
1139
+ !.claude/memory/
1140
+ !.claude/memory/**
1141
+ `;
1142
+ if (fs.existsSync(gitignorePath)) {
1143
+ const content = fs.readFileSync(gitignorePath, "utf-8");
1144
+ // 이미 SEMO 블록이 있으면 스킵
1145
+ if (content.includes("# === SEMO ===")) {
1146
+ console.log(chalk_1.default.gray(" → SEMO 블록 이미 존재 (건너뜀)"));
1147
+ return;
1148
+ }
1149
+ // 기존 파일에 추가
1150
+ fs.appendFileSync(gitignorePath, semoIgnoreBlock);
1151
+ console.log(chalk_1.default.green("✓ .gitignore에 SEMO 규칙 추가됨"));
1152
+ }
1153
+ else {
1154
+ // 새로 생성
1155
+ fs.writeFileSync(gitignorePath, semoIgnoreBlock.trim() + "\n");
1156
+ console.log(chalk_1.default.green("✓ .gitignore 생성됨 (SEMO 규칙 포함)"));
1157
+ }
1158
+ }
1023
1159
  // === Context Mesh 초기화 ===
1024
1160
  async function setupContextMesh(cwd) {
1025
1161
  console.log(chalk_1.default.cyan("\n🧠 Context Mesh 초기화"));
@@ -1140,8 +1276,25 @@ async function setupClaudeMd(cwd, extensions, force) {
1140
1276
  const extensionsList = extensions.length > 0
1141
1277
  ? extensions.map(pkg => `├── ${pkg}/ # ${EXTENSION_PACKAGES[pkg].name}`).join("\n")
1142
1278
  : "";
1143
- // 패키지별 CLAUDE.md 병합 섹션 생성
1279
+ // 그룹 및 패키지별 CLAUDE.md 병합 섹션 생성
1144
1280
  let packageClaudeMdSections = "";
1281
+ // 1. 설치된 패키지에서 그룹 추출 (중복 제거)
1282
+ const installedGroups = [...new Set(extensions.map(pkg => pkg.split("/")[0]).filter(g => PACKAGE_GROUPS.includes(g)))];
1283
+ // 2. 그룹 레벨 CLAUDE.md 먼저 병합 (biz, eng, ops)
1284
+ for (const group of installedGroups) {
1285
+ const groupClaudeMdPath = path.join(semoSystemDir, group, "CLAUDE.md");
1286
+ if (fs.existsSync(groupClaudeMdPath)) {
1287
+ const groupContent = fs.readFileSync(groupClaudeMdPath, "utf-8");
1288
+ // 그룹 CLAUDE.md 헤더 레벨 조정 (# → ##, ## → ###)
1289
+ const adjustedContent = groupContent
1290
+ .replace(/^# /gm, "## ")
1291
+ .replace(/^## /gm, "### ")
1292
+ .replace(/^### /gm, "#### ");
1293
+ packageClaudeMdSections += `\n\n---\n\n${adjustedContent}`;
1294
+ console.log(chalk_1.default.green(` + ${group}/ 그룹 CLAUDE.md 병합됨`));
1295
+ }
1296
+ }
1297
+ // 3. 개별 패키지 CLAUDE.md 병합
1145
1298
  for (const pkg of extensions) {
1146
1299
  const pkgClaudeMdPath = path.join(semoSystemDir, pkg, "CLAUDE.md");
1147
1300
  if (fs.existsSync(pkgClaudeMdPath)) {
@@ -1592,7 +1745,18 @@ program
1592
1745
  }
1593
1746
  }
1594
1747
  }
1595
- // Standard 심볼릭 링크 재생성
1748
+ // commands 링크도 정리 (신규 commands 반영 위해)
1749
+ const claudeCommandsDir = path.join(claudeDir, "commands");
1750
+ const semoCommandsLink = path.join(claudeCommandsDir, "SEMO");
1751
+ if (fs.existsSync(semoCommandsLink)) {
1752
+ if (fs.lstatSync(semoCommandsLink).isSymbolicLink()) {
1753
+ fs.unlinkSync(semoCommandsLink);
1754
+ }
1755
+ else {
1756
+ removeRecursive(semoCommandsLink);
1757
+ }
1758
+ }
1759
+ // Standard 심볼릭 링크 재생성 (agents, skills, commands 포함)
1596
1760
  await createStandardSymlinks(cwd);
1597
1761
  // Extensions 심볼릭 링크 재생성
1598
1762
  if (installedExtensions.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@team-semicolon/semo-cli",
3
- "version": "3.0.6",
3
+ "version": "3.0.9",
4
4
  "description": "SEMO CLI - AI Agent Orchestration Framework Installer",
5
5
  "main": "dist/index.js",
6
6
  "bin": {