@team-semicolon/semo-cli 2.0.4 → 3.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.
Files changed (3) hide show
  1. package/README.md +118 -118
  2. package/dist/index.js +299 -245
  3. package/package.json +48 -48
package/README.md CHANGED
@@ -1,118 +1,118 @@
1
- # @team-semicolon/semo-cli
2
-
3
- > SEMO CLI - AI Agent Orchestration Framework Installer
4
-
5
- ## 개요
6
-
7
- Gemini의 하이브리드 전략에 따라 SEMO를 자동 설치하는 CLI 도구입니다.
8
-
9
- ```bash
10
- npx @team-semicolon/semo-cli init
11
- ```
12
-
13
- ## 동작 방식
14
-
15
- `semo init` 명령어는 다음을 자동으로 수행합니다:
16
-
17
- ### 1. White Box 설정 (Git Subtree)
18
-
19
- 에이전트가 **읽고 학습**해야 하는 지식 베이스:
20
-
21
- ```
22
- semo-system/
23
- ├── semo-core/ # Layer 0: 원칙, 오케스트레이션
24
- └── semo-skills/ # Layer 1: coder, tester, planner
25
- ```
26
-
27
- ### 2. Black Box 설정 (MCP Server)
28
-
29
- 토큰이 격리된 **외부 연동 도구**:
30
-
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
- }
41
- ```
42
-
43
- ### 3. Context Mesh 초기화
44
-
45
- 세션 간 **컨텍스트 영속화**:
46
-
47
- ```
48
- .claude/memory/
49
- ├── context.md # 프로젝트 상태
50
- ├── decisions.md # 아키텍처 결정
51
- └── rules/ # 프로젝트별 규칙
52
- ```
53
-
54
- ## 명령어
55
-
56
- ### init
57
-
58
- 현재 프로젝트에 SEMO를 설치합니다.
59
-
60
- ```bash
61
- semo init # 기본 설치
62
- semo init --force # 기존 설정 덮어쓰기
63
- semo init --skip-mcp # MCP 설정 생략
64
- semo init --skip-subtree # Git Subtree 생략
65
- ```
66
-
67
- ### status
68
-
69
- SEMO 설치 상태를 확인합니다.
70
-
71
- ```bash
72
- semo status
73
- ```
74
-
75
- ### update
76
-
77
- SEMO를 최신 버전으로 업데이트합니다.
78
-
79
- ```bash
80
- semo update
81
- ```
82
-
83
- ## 설치 후 구조
84
-
85
- ```
86
- your-project/
87
- ├── .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
93
-
94
- └── semo-system/ # White Box (읽기 전용)
95
- ├── semo-core/
96
- └── semo-skills/
97
- ```
98
-
99
- ## 환경변수
100
-
101
- MCP 연동을 위해 다음 환경변수를 설정하세요:
102
-
103
- | 변수 | 설명 |
104
- |------|------|
105
- | `GITHUB_TOKEN` | GitHub API 토큰 |
106
- | `SLACK_BOT_TOKEN` | Slack Bot 토큰 |
107
- | `SUPABASE_URL` | Supabase 프로젝트 URL |
108
- | `SUPABASE_KEY` | Supabase 서비스 키 |
109
-
110
- ## 참조
111
-
112
- - [SEMO 레포지토리](https://github.com/semicolon-devteam/semo)
113
- - [SEMO MCP Server](../mcp-server/README.md)
114
- - [Gemini 하이브리드 전략](../../docs/SEMO_ARCHITECTURE_REVIEW.md)
115
-
116
- ## 라이선스
117
-
118
- MIT
1
+ # @team-semicolon/semo-cli
2
+
3
+ > SEMO CLI - AI Agent Orchestration Framework Installer
4
+
5
+ ## 개요
6
+
7
+ Gemini의 하이브리드 전략에 따라 SEMO를 자동 설치하는 CLI 도구입니다.
8
+
9
+ ```bash
10
+ npx @team-semicolon/semo-cli init
11
+ ```
12
+
13
+ ## 동작 방식
14
+
15
+ `semo init` 명령어는 다음을 자동으로 수행합니다:
16
+
17
+ ### 1. White Box 설정 (Git Subtree)
18
+
19
+ 에이전트가 **읽고 학습**해야 하는 지식 베이스:
20
+
21
+ ```
22
+ semo-system/
23
+ ├── semo-core/ # Layer 0: 원칙, 오케스트레이션
24
+ └── semo-skills/ # Layer 1: coder, tester, planner
25
+ ```
26
+
27
+ ### 2. Black Box 설정 (MCP Server)
28
+
29
+ 토큰이 격리된 **외부 연동 도구**:
30
+
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
+ }
41
+ ```
42
+
43
+ ### 3. Context Mesh 초기화
44
+
45
+ 세션 간 **컨텍스트 영속화**:
46
+
47
+ ```
48
+ .claude/memory/
49
+ ├── context.md # 프로젝트 상태
50
+ ├── decisions.md # 아키텍처 결정
51
+ └── rules/ # 프로젝트별 규칙
52
+ ```
53
+
54
+ ## 명령어
55
+
56
+ ### init
57
+
58
+ 현재 프로젝트에 SEMO를 설치합니다.
59
+
60
+ ```bash
61
+ semo init # 기본 설치
62
+ semo init --force # 기존 설정 덮어쓰기
63
+ semo init --skip-mcp # MCP 설정 생략
64
+ semo init --skip-subtree # Git Subtree 생략
65
+ ```
66
+
67
+ ### status
68
+
69
+ SEMO 설치 상태를 확인합니다.
70
+
71
+ ```bash
72
+ semo status
73
+ ```
74
+
75
+ ### update
76
+
77
+ SEMO를 최신 버전으로 업데이트합니다.
78
+
79
+ ```bash
80
+ semo update
81
+ ```
82
+
83
+ ## 설치 후 구조
84
+
85
+ ```
86
+ your-project/
87
+ ├── .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
93
+
94
+ └── semo-system/ # White Box (읽기 전용)
95
+ ├── semo-core/
96
+ └── semo-skills/
97
+ ```
98
+
99
+ ## 환경변수
100
+
101
+ MCP 연동을 위해 다음 환경변수를 설정하세요:
102
+
103
+ | 변수 | 설명 |
104
+ |------|------|
105
+ | `GITHUB_TOKEN` | GitHub API 토큰 |
106
+ | `SLACK_BOT_TOKEN` | Slack Bot 토큰 |
107
+ | `SUPABASE_URL` | Supabase 프로젝트 URL |
108
+ | `SUPABASE_KEY` | Supabase 서비스 키 |
109
+
110
+ ## 참조
111
+
112
+ - [SEMO 레포지토리](https://github.com/semicolon-devteam/semo)
113
+ - [SEMO MCP Server](../mcp-server/README.md)
114
+ - [Gemini 하이브리드 전략](../../docs/SEMO_ARCHITECTURE_REVIEW.md)
115
+
116
+ ## 라이선스
117
+
118
+ MIT
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 = "2.0.2";
62
+ const VERSION = "3.0.0-alpha";
63
63
  // === Windows 지원 유틸리티 ===
64
64
  const isWindows = os.platform() === "win32";
65
65
  /**
@@ -122,18 +122,36 @@ function copyRecursive(src, dest) {
122
122
  }
123
123
  }
124
124
  const SEMO_REPO = "https://github.com/semicolon-devteam/semo.git";
125
- // 확장 패키지 정의
125
+ // 확장 패키지 정의 (v3.0 구조)
126
126
  const EXTENSION_PACKAGES = {
127
- next: { name: "Next.js", desc: "Next.js 프론트엔드 개발 (13 agents, 33 skills)", detect: ["next.config.js", "next.config.mjs", "next.config.ts"] },
128
- backend: { name: "Backend", desc: "Spring/Node.js 백엔드 개발 (8 agents, 15 skills)", detect: ["pom.xml", "build.gradle"] },
129
- po: { name: "PO", desc: "Product Owner - 태스크/에픽 관리 (5 agents, 19 skills)", detect: [] },
130
- qa: { name: "QA", desc: "QA 테스트 관리 (4 agents, 13 skills)", detect: [] },
131
- pm: { name: "PM", desc: "프로젝트/스프린트 관리 (5 agents, 16 skills)", detect: [] },
132
- infra: { name: "Infra", desc: "인프라/배포 관리 (6 agents, 10 skills)", detect: ["docker-compose.yml", "Dockerfile"] },
133
- design: { name: "Design", desc: "디자인 핸드오프 (3 agents, 4 skills)", detect: [] },
134
- ms: { name: "Microservice", desc: "마이크로서비스 아키텍처 (5 agents, 5 skills)", detect: [] },
135
- mvp: { name: "MVP", desc: "MVP 빠른 개발 (4 agents, 6 skills)", detect: [] },
136
- meta: { name: "Meta", desc: "SEMO 프레임워크 자체 개발/관리 (6 agents, 7 skills)", detect: ["semo-core", "semo-skills", "packages/meta"] },
127
+ // Business Layer
128
+ "biz/discovery": { name: "Discovery", desc: "아이템 발굴, 시장 조사, Epic/Task", layer: "biz", detect: [] },
129
+ "biz/design": { name: "Design", desc: "컨셉 설계, 목업, UX", layer: "biz", detect: [] },
130
+ "biz/management": { name: "Management", desc: "일정/인력/스프린트 관리", layer: "biz", detect: [] },
131
+ "biz/poc": { name: "PoC", desc: "빠른 PoC, 패스트트랙", layer: "biz", detect: [] },
132
+ // Engineering Layer
133
+ "eng/nextjs": { name: "Next.js", desc: "Next.js 프론트엔드 개발", layer: "eng", detect: ["next.config.js", "next.config.mjs", "next.config.ts"] },
134
+ "eng/spring": { name: "Spring", desc: "Spring Boot 백엔드 개발", layer: "eng", detect: ["pom.xml", "build.gradle"] },
135
+ "eng/ms": { name: "Microservice", desc: "마이크로서비스 아키텍처", layer: "eng", detect: [] },
136
+ "eng/infra": { name: "Infra", desc: "인프라/배포 관리", layer: "eng", detect: ["docker-compose.yml", "Dockerfile"] },
137
+ // Operations Layer
138
+ "ops/qa": { name: "QA", desc: "테스트/품질 관리", layer: "ops", detect: [] },
139
+ "ops/monitor": { name: "Monitor", desc: "서비스 현황 모니터링", layer: "ops", detect: [] },
140
+ "ops/improve": { name: "Improve", desc: "개선 제안", layer: "ops", detect: [] },
141
+ // Meta
142
+ meta: { name: "Meta", desc: "SEMO 프레임워크 자체 개발/관리", layer: "meta", detect: ["semo-core", "semo-skills"] },
143
+ };
144
+ // 레거시 패키지 → 새 패키지 매핑 (하위호환성)
145
+ const LEGACY_MAPPING = {
146
+ next: "eng/nextjs",
147
+ backend: "eng/spring",
148
+ ms: "eng/ms",
149
+ infra: "eng/infra",
150
+ qa: "ops/qa",
151
+ po: "biz/discovery",
152
+ pm: "biz/management",
153
+ design: "biz/design",
154
+ mvp: "biz/poc",
137
155
  };
138
156
  const program = new commander_1.Command();
139
157
  program
@@ -452,25 +470,17 @@ const BASE_MCP_SERVERS = [
452
470
  // === Claude MCP 등록 함수 ===
453
471
  function registerMCPServer(server) {
454
472
  try {
455
- // 환경변수가 있는 경우 --env 옵션 추가
456
- const envArgs = [];
473
+ // claude mcp add 명령어 구성
474
+ // 형식: claude mcp add <name> [-e KEY=value...] -- <command> [args...]
475
+ const args = ["mcp", "add", server.name];
476
+ // 환경변수가 있는 경우 -e 옵션 추가
457
477
  if (server.env) {
458
478
  for (const [key, value] of Object.entries(server.env)) {
459
- envArgs.push("-e", `${key}=${value}`);
479
+ args.push("-e", `${key}=${value}`);
460
480
  }
461
481
  }
462
- // claude mcp add 명령어 실행
463
- const args = [
464
- "mcp", "add",
465
- server.name,
466
- "--",
467
- server.command,
468
- ...server.args,
469
- ];
470
- // 환경변수가 있으면 명령어 앞에 추가
471
- if (envArgs.length > 0) {
472
- args.splice(2, 0, ...envArgs);
473
- }
482
+ // -- 구분자 명령어와 인자 추가
483
+ args.push("--", server.command, ...server.args);
474
484
  (0, child_process_1.execSync)(`claude ${args.join(" ")}`, { stdio: "pipe" });
475
485
  return { success: true };
476
486
  }
@@ -686,36 +696,36 @@ async function setupContextMesh(cwd) {
686
696
  // context.md
687
697
  const contextPath = path.join(memoryDir, "context.md");
688
698
  if (!fs.existsSync(contextPath)) {
689
- const contextContent = `# Project Context
690
-
691
- > 세션 간 영속화되는 프로젝트 컨텍스트
692
- > SEMO의 memory 스킬이 이 파일을 자동으로 업데이트합니다.
693
-
694
- ---
695
-
696
- ## 프로젝트 정보
697
-
698
- | 항목 | 값 |
699
- |------|-----|
700
- | **이름** | ${path.basename(cwd)} |
701
- | **SEMO 버전** | ${VERSION} |
702
- | **설치일** | ${new Date().toISOString().split("T")[0]} |
703
-
704
- ---
705
-
706
- ## 현재 작업 상태
707
-
708
- _아직 작업 기록이 없습니다._
709
-
710
- ---
711
-
712
- ## 기술 스택
713
-
714
- _프로젝트 분석 후 자동으로 채워집니다._
715
-
716
- ---
717
-
718
- *마지막 업데이트: ${new Date().toISOString().split("T")[0]}*
699
+ const contextContent = `# Project Context
700
+
701
+ > 세션 간 영속화되는 프로젝트 컨텍스트
702
+ > SEMO의 memory 스킬이 이 파일을 자동으로 업데이트합니다.
703
+
704
+ ---
705
+
706
+ ## 프로젝트 정보
707
+
708
+ | 항목 | 값 |
709
+ |------|-----|
710
+ | **이름** | ${path.basename(cwd)} |
711
+ | **SEMO 버전** | ${VERSION} |
712
+ | **설치일** | ${new Date().toISOString().split("T")[0]} |
713
+
714
+ ---
715
+
716
+ ## 현재 작업 상태
717
+
718
+ _아직 작업 기록이 없습니다._
719
+
720
+ ---
721
+
722
+ ## 기술 스택
723
+
724
+ _프로젝트 분석 후 자동으로 채워집니다._
725
+
726
+ ---
727
+
728
+ *마지막 업데이트: ${new Date().toISOString().split("T")[0]}*
719
729
  `;
720
730
  fs.writeFileSync(contextPath, contextContent);
721
731
  console.log(chalk_1.default.green("✓ .claude/memory/context.md 생성됨"));
@@ -723,36 +733,36 @@ _프로젝트 분석 후 자동으로 채워집니다._
723
733
  // decisions.md
724
734
  const decisionsPath = path.join(memoryDir, "decisions.md");
725
735
  if (!fs.existsSync(decisionsPath)) {
726
- const decisionsContent = `# Architecture Decisions
727
-
728
- > 프로젝트 아키텍처 결정 기록 (ADR)
729
- > 중요한 기술적 결정을 여기에 기록합니다.
730
-
731
- ---
732
-
733
- ## 결정 목록
734
-
735
- _아직 기록된 결정이 없습니다._
736
-
737
- ---
738
-
739
- ## 템플릿
740
-
741
- \`\`\`markdown
742
- ### ADR-XXX: 결정 제목
743
-
744
- **날짜**: YYYY-MM-DD
745
- **상태**: Proposed | Accepted | Deprecated
746
-
747
- #### 배경
748
- 결정이 필요한 이유
749
-
750
- #### 결정
751
- 선택한 방안
752
-
753
- #### 근거
754
- 선택 이유
755
- \`\`\`
736
+ const decisionsContent = `# Architecture Decisions
737
+
738
+ > 프로젝트 아키텍처 결정 기록 (ADR)
739
+ > 중요한 기술적 결정을 여기에 기록합니다.
740
+
741
+ ---
742
+
743
+ ## 결정 목록
744
+
745
+ _아직 기록된 결정이 없습니다._
746
+
747
+ ---
748
+
749
+ ## 템플릿
750
+
751
+ \`\`\`markdown
752
+ ### ADR-XXX: 결정 제목
753
+
754
+ **날짜**: YYYY-MM-DD
755
+ **상태**: Proposed | Accepted | Deprecated
756
+
757
+ #### 배경
758
+ 결정이 필요한 이유
759
+
760
+ #### 결정
761
+ 선택한 방안
762
+
763
+ #### 근거
764
+ 선택 이유
765
+ \`\`\`
756
766
  `;
757
767
  fs.writeFileSync(decisionsPath, decisionsContent);
758
768
  console.log(chalk_1.default.green("✓ .claude/memory/decisions.md 생성됨"));
@@ -762,27 +772,27 @@ _아직 기록된 결정이 없습니다._
762
772
  fs.mkdirSync(rulesDir, { recursive: true });
763
773
  const rulesPath = path.join(rulesDir, "project-specific.md");
764
774
  if (!fs.existsSync(rulesPath)) {
765
- const rulesContent = `# Project-Specific Rules
766
-
767
- > 이 프로젝트에만 적용되는 규칙
768
-
769
- ---
770
-
771
- ## 코딩 규칙
772
-
773
- _프로젝트별 코딩 규칙을 여기에 추가하세요._
774
-
775
- ---
776
-
777
- ## 예외 사항
778
-
779
- _SEMO 기본 규칙의 예외 사항을 여기에 추가하세요._
775
+ const rulesContent = `# Project-Specific Rules
776
+
777
+ > 이 프로젝트에만 적용되는 규칙
778
+
779
+ ---
780
+
781
+ ## 코딩 규칙
782
+
783
+ _프로젝트별 코딩 규칙을 여기에 추가하세요._
784
+
785
+ ---
786
+
787
+ ## 예외 사항
788
+
789
+ _SEMO 기본 규칙의 예외 사항을 여기에 추가하세요._
780
790
  `;
781
791
  fs.writeFileSync(rulesPath, rulesContent);
782
792
  console.log(chalk_1.default.green("✓ .claude/memory/rules/project-specific.md 생성됨"));
783
793
  }
784
794
  }
785
- // === CLAUDE.md 생성 ===
795
+ // === CLAUDE.md 생성 (패키지 CLAUDE.md 병합 지원) ===
786
796
  async function setupClaudeMd(cwd, extensions, force) {
787
797
  console.log(chalk_1.default.cyan("\n📄 CLAUDE.md 설정"));
788
798
  const claudeMdPath = path.join(cwd, ".claude", "CLAUDE.md");
@@ -793,141 +803,160 @@ async function setupClaudeMd(cwd, extensions, force) {
793
803
  return;
794
804
  }
795
805
  }
806
+ const semoSystemDir = path.join(cwd, "semo-system");
796
807
  const extensionsList = extensions.length > 0
797
808
  ? extensions.map(pkg => `├── ${pkg}/ # ${EXTENSION_PACKAGES[pkg].name}`).join("\n")
798
809
  : "";
799
- const claudeMdContent = `# SEMO Project Configuration
800
-
801
- > SEMO (Semicolon Orchestrate) - AI Agent Orchestration Framework v${VERSION}
802
-
803
- ---
804
-
805
- ## 🔴 MANDATORY: Orchestrator-First Execution
806
-
807
- > **⚠️ 규칙은 모든 사용자 요청에 적용됩니다. 예외 없음.**
808
-
809
- ### 실행 흐름 (필수)
810
-
811
- \`\`\`
812
- 1. 사용자 요청 수신
813
- 2. [SEMO] Orchestrator 메시지 출력 (의도 분석)
814
- 3. Orchestrator가 적절한 Agent/Skill 라우팅
815
- 4. [SEMO] Agent/Skill 메시지 출력
816
- 5. 실행 결과 반환
817
- \`\`\`
818
-
819
- ### 모든 응답은 다음으로 시작
820
-
821
- \`\`\`
822
- [SEMO] Orchestrator: 의도 분석 완료 → {intent_category}
823
- [SEMO] {Agent/Skill} 호출: {target} (사유: {reason})
824
- \`\`\`
825
-
826
- ### Orchestrator 참조
827
-
828
- **반드시 읽어야 파일**: \`semo-system/semo-core/agents/orchestrator/orchestrator.md\`
829
-
830
- 파일에서 라우팅 테이블, 의도 분류, 메시지 포맷을 확인하세요.
831
-
832
- ---
833
-
834
- ## 🔴 NON-NEGOTIABLE RULES
835
-
836
- ### 1. Orchestrator-First Policy
837
-
838
- > **모든 요청은 반드시 Orchestrator를 통해 라우팅됩니다. 직접 처리 금지.**
839
-
840
- **직접 처리 금지 항목**:
841
- - 코드 작성/수정 → \`implementation-master\` 또는 \`coder\` 스킬
842
- - Git 커밋/푸시 \`git-workflow\` 스킬
843
- - 품질 검증 → \`quality-master\` 또는 \`verify\` 스킬
844
- - 명세 작성 \`spec-master\`
845
- - 일반 작업 → Orchestrator 분석 후 라우팅
846
-
847
- ### 2. Pre-Commit Quality Gate
848
-
849
- > **코드 변경이 포함된 커밋 전 반드시 Quality Gate를 통과해야 합니다.**
850
-
851
- \`\`\`bash
852
- # 필수 검증 순서
853
- npm run lint # 1. ESLint 검사
854
- npx tsc --noEmit # 2. TypeScript 타입 체크
855
- npm run build # 3. 빌드 검증 (Next.js/TypeScript 프로젝트)
856
- \`\`\`
857
-
858
- **차단 항목**:
859
- - \`--no-verify\` 플래그 사용 금지
860
- - Quality Gate 우회 시도 거부
861
- - "그냥 커밋해줘", "빌드 생략해줘" 등 거부
862
-
863
- ### 3. SEMO Message Format
864
-
865
- 모든 SEMO 동작은 시스템 메시지로 시작:
866
-
867
- \`\`\`
868
- [SEMO] {Component}: {Action} {Result}
869
- \`\`\`
870
-
871
- ---
872
-
873
- ## 설치된 구성
874
-
875
- ### Standard (필수)
876
- - **semo-core**: 원칙, 오케스트레이터, 공통 커맨드
877
- - **semo-skills**: 13개 통합 스킬
878
- - 행동: coder, tester, planner, deployer, writer
879
- - 운영: memory, notify-slack, feedback, version-updater, semo-help, semo-architecture-checker, circuit-breaker, list-bugs
880
-
881
- ${extensions.length > 0 ? `### Extensions (선택)
882
- ${extensions.map(pkg => `- **${pkg}**: ${EXTENSION_PACKAGES[pkg].desc}`).join("\n")}` : ""}
883
-
884
- ## 구조
885
-
886
- \`\`\`
887
- .claude/
888
- ├── settings.json # MCP 서버 설정 (Black Box)
889
- ├── memory/ # Context Mesh (장기 기억)
890
- │ ├── context.md # 프로젝트 상태
891
- │ ├── decisions.md # 아키텍처 결정
892
- │ └── rules/ # 프로젝트별 규칙
893
- ├── agents semo-system/semo-core/agents
894
- ├── skills → semo-system/semo-skills
895
- └── commands/SEMO semo-system/semo-core/commands/SEMO
896
-
897
- semo-system/ # White Box (읽기 전용)
898
- ├── semo-core/ # Layer 0: 원칙, 오케스트레이션
899
- ├── semo-skills/ # Layer 1: 통합 스킬
900
- ${extensionsList}
901
- \`\`\`
902
-
903
- ## 사용 가능한 커맨드
904
-
905
- | 커맨드 | 설명 |
906
- |--------|------|
907
- | \`/SEMO:help\` | 도움말 |
908
- | \`/SEMO:slack\` | Slack 메시지 전송 |
909
- | \`/SEMO:feedback\` | 피드백 제출 |
910
- | \`/SEMO:health\` | 환경 검증 |
911
- | \`/SEMO:update\` | SEMO 업데이트 |
912
-
913
- ## Context Mesh 사용
914
-
915
- SEMO는 \`.claude/memory/\`를 통해 세션 간 컨텍스트를 유지합니다:
916
-
917
- - **context.md**: 프로젝트 상태, 진행 중인 작업
918
- - **decisions.md**: 아키텍처 결정 기록 (ADR)
919
- - **rules/**: 프로젝트별 커스텀 규칙
920
-
921
- memory 스킬이 자동으로 파일들을 관리합니다.
922
-
923
- ## References
924
-
925
- - [SEMO Principles](semo-system/semo-core/principles/PRINCIPLES.md)
926
- - [SEMO Skills](semo-system/semo-skills/)
927
- ${extensions.length > 0 ? extensions.map(pkg => `- [${EXTENSION_PACKAGES[pkg].name} Package](semo-system/${pkg}/)`).join("\n") : ""}
810
+ // 패키지별 CLAUDE.md 병합 섹션 생성
811
+ let packageClaudeMdSections = "";
812
+ for (const pkg of extensions) {
813
+ const pkgClaudeMdPath = path.join(semoSystemDir, pkg, "CLAUDE.md");
814
+ if (fs.existsSync(pkgClaudeMdPath)) {
815
+ const pkgContent = fs.readFileSync(pkgClaudeMdPath, "utf-8");
816
+ // 헤더(#)를 ##로 변경하여 하위 섹션으로 만듦
817
+ const adjustedContent = pkgContent
818
+ .replace(/^# /gm, "### ")
819
+ .replace(/^## /gm, "#### ");
820
+ packageClaudeMdSections += `\n\n---\n\n## ${EXTENSION_PACKAGES[pkg].name} 패키지 컨텍스트\n\n${adjustedContent}`;
821
+ console.log(chalk_1.default.gray(` + ${pkg}/CLAUDE.md 병합됨`));
822
+ }
823
+ }
824
+ const claudeMdContent = `# SEMO Project Configuration
825
+
826
+ > SEMO (Semicolon Orchestrate) - AI Agent Orchestration Framework v${VERSION}
827
+
828
+ ---
829
+
830
+ ## 🔴 MANDATORY: Orchestrator-First Execution
831
+
832
+ > **⚠️ 이 규칙은 모든 사용자 요청에 적용됩니다. 예외 없음.**
833
+
834
+ ### 실행 흐름 (필수)
835
+
836
+ \`\`\`
837
+ 1. 사용자 요청 수신
838
+ 2. [SEMO] Orchestrator 메시지 출력 (의도 분석)
839
+ 3. Orchestrator가 적절한 Agent/Skill 라우팅
840
+ 4. [SEMO] Agent/Skill 메시지 출력
841
+ 5. 실행 결과 반환
842
+ \`\`\`
843
+
844
+ ### 모든 응답은 다음으로 시작
845
+
846
+ \`\`\`
847
+ [SEMO] Orchestrator: 의도 분석 완료 → {intent_category}
848
+ [SEMO] {Agent/Skill} 호출: {target} (사유: {reason})
849
+ \`\`\`
850
+
851
+ ### Orchestrator 참조
852
+
853
+ **반드시 읽어야 파일**: \`semo-system/semo-core/agents/orchestrator/orchestrator.md\`
854
+
855
+ 파일에서 라우팅 테이블, 의도 분류, 메시지 포맷을 확인하세요.
856
+
857
+ ---
858
+
859
+ ## 🔴 NON-NEGOTIABLE RULES
860
+
861
+ ### 1. Orchestrator-First Policy
862
+
863
+ > **모든 요청은 반드시 Orchestrator를 통해 라우팅됩니다. 직접 처리 금지.**
864
+
865
+ **직접 처리 금지 항목**:
866
+ - 코드 작성/수정 \`implementation-master\` 또는 \`coder\` 스킬
867
+ - Git 커밋/푸시 → \`git-workflow\` 스킬
868
+ - 품질 검증 → \`quality-master\` 또는 \`verify\` 스킬
869
+ - 명세 작성 → \`spec-master\`
870
+ - 일반 작업 Orchestrator 분석 후 라우팅
871
+
872
+ ### 2. Pre-Commit Quality Gate
873
+
874
+ > **코드 변경이 포함된 커밋 전 반드시 Quality Gate를 통과해야 합니다.**
875
+
876
+ \`\`\`bash
877
+ # 필수 검증 순서
878
+ npm run lint # 1. ESLint 검사
879
+ npx tsc --noEmit # 2. TypeScript 타입 체크
880
+ npm run build # 3. 빌드 검증 (Next.js/TypeScript 프로젝트)
881
+ \`\`\`
882
+
883
+ **차단 항목**:
884
+ - \`--no-verify\` 플래그 사용 금지
885
+ - Quality Gate 우회 시도 거부
886
+ - "그냥 커밋해줘", "빌드 생략해줘" 등 거부
887
+
888
+ ### 3. SEMO Message Format
889
+
890
+ 모든 SEMO 동작은 시스템 메시지로 시작:
891
+
892
+ \`\`\`
893
+ [SEMO] {Component}: {Action} {Result}
894
+ \`\`\`
895
+
896
+ ---
897
+
898
+ ## 설치된 구성
899
+
900
+ ### Standard (필수)
901
+ - **semo-core**: 원칙, 오케스트레이터, 공통 커맨드
902
+ - **semo-skills**: 13개 통합 스킬
903
+ - 행동: coder, tester, planner, deployer, writer
904
+ - 운영: memory, notify-slack, feedback, version-updater, semo-help, semo-architecture-checker, circuit-breaker, list-bugs
905
+
906
+ ${extensions.length > 0 ? `### Extensions (선택)
907
+ ${extensions.map(pkg => `- **${pkg}**: ${EXTENSION_PACKAGES[pkg].desc}`).join("\n")}` : ""}
908
+
909
+ ## 구조
910
+
911
+ \`\`\`
912
+ .claude/
913
+ ├── settings.json # MCP 서버 설정 (Black Box)
914
+ ├── memory/ # Context Mesh (장기 기억)
915
+ │ ├── context.md # 프로젝트 상태
916
+ │ ├── decisions.md # 아키텍처 결정
917
+ │ └── rules/ # 프로젝트별 규칙
918
+ ├── agents semo-system/semo-core/agents
919
+ ├── skills semo-system/semo-skills
920
+ └── commands/SEMO semo-system/semo-core/commands/SEMO
921
+
922
+ semo-system/ # White Box (읽기 전용)
923
+ ├── semo-core/ # Layer 0: 원칙, 오케스트레이션
924
+ ├── semo-skills/ # Layer 1: 통합 스킬
925
+ ${extensionsList}
926
+ \`\`\`
927
+
928
+ ## 사용 가능한 커맨드
929
+
930
+ | 커맨드 | 설명 |
931
+ |--------|------|
932
+ | \`/SEMO:help\` | 도움말 |
933
+ | \`/SEMO:slack\` | Slack 메시지 전송 |
934
+ | \`/SEMO:feedback\` | 피드백 제출 |
935
+ | \`/SEMO:health\` | 환경 검증 |
936
+ | \`/SEMO:update\` | SEMO 업데이트 |
937
+
938
+ ## Context Mesh 사용
939
+
940
+ SEMO는 \`.claude/memory/\`를 통해 세션 간 컨텍스트를 유지합니다:
941
+
942
+ - **context.md**: 프로젝트 상태, 진행 중인 작업
943
+ - **decisions.md**: 아키텍처 결정 기록 (ADR)
944
+ - **rules/**: 프로젝트별 커스텀 규칙
945
+
946
+ memory 스킬이 자동으로 이 파일들을 관리합니다.
947
+
948
+ ## References
949
+
950
+ - [SEMO Principles](semo-system/semo-core/principles/PRINCIPLES.md)
951
+ - [SEMO Skills](semo-system/semo-skills/)
952
+ ${extensions.length > 0 ? extensions.map(pkg => `- [${EXTENSION_PACKAGES[pkg].name} Package](semo-system/${pkg}/)`).join("\n") : ""}
953
+ ${packageClaudeMdSections}
928
954
  `;
929
955
  fs.writeFileSync(claudeMdPath, claudeMdContent);
930
956
  console.log(chalk_1.default.green("✓ .claude/CLAUDE.md 생성됨"));
957
+ if (packageClaudeMdSections) {
958
+ console.log(chalk_1.default.green(` + ${extensions.length}개 패키지 CLAUDE.md 병합 완료`));
959
+ }
931
960
  }
932
961
  // === add 명령어 ===
933
962
  program
@@ -941,11 +970,19 @@ program
941
970
  console.log(chalk_1.default.red("\nSEMO가 설치되어 있지 않습니다. 'semo init'을 먼저 실행하세요.\n"));
942
971
  process.exit(1);
943
972
  }
944
- if (!(packageName in EXTENSION_PACKAGES)) {
973
+ // 레거시 패키지 이름 → 새 이름 변환
974
+ let resolvedPackage = packageName;
975
+ if (packageName in LEGACY_MAPPING) {
976
+ resolvedPackage = LEGACY_MAPPING[packageName];
977
+ console.log(chalk_1.default.yellow(`\n💡 '${packageName}' → '${resolvedPackage}' (v3.0 구조)`));
978
+ }
979
+ if (!(resolvedPackage in EXTENSION_PACKAGES)) {
945
980
  console.log(chalk_1.default.red(`\n알 수 없는 패키지: ${packageName}`));
946
- console.log(chalk_1.default.gray(`사용 가능한 패키지: ${Object.keys(EXTENSION_PACKAGES).join(", ")}\n`));
981
+ console.log(chalk_1.default.gray(`사용 가능한 패키지: ${Object.keys(EXTENSION_PACKAGES).join(", ")}`));
982
+ console.log(chalk_1.default.gray(`레거시 별칭: ${Object.keys(LEGACY_MAPPING).join(", ")}\n`));
947
983
  process.exit(1);
948
984
  }
985
+ packageName = resolvedPackage;
949
986
  const pkgPath = path.join(semoSystemDir, packageName);
950
987
  if (fs.existsSync(pkgPath) && !options.force) {
951
988
  console.log(chalk_1.default.yellow(`\n${EXTENSION_PACKAGES[packageName].name} 패키지가 이미 설치되어 있습니다.`));
@@ -969,24 +1006,41 @@ program
969
1006
  .action(() => {
970
1007
  const cwd = process.cwd();
971
1008
  const semoSystemDir = path.join(cwd, "semo-system");
972
- console.log(chalk_1.default.cyan.bold("\n📦 SEMO 패키지 목록\n"));
1009
+ console.log(chalk_1.default.cyan.bold("\n📦 SEMO 패키지 목록 (v3.0)\n"));
973
1010
  // Standard
974
1011
  console.log(chalk_1.default.white.bold("Standard (필수)"));
975
1012
  const coreInstalled = fs.existsSync(path.join(semoSystemDir, "semo-core"));
976
1013
  const skillsInstalled = fs.existsSync(path.join(semoSystemDir, "semo-skills"));
977
1014
  console.log(` ${coreInstalled ? chalk_1.default.green("✓") : chalk_1.default.gray("○")} semo-core - 원칙, 오케스트레이터`);
978
- console.log(` ${skillsInstalled ? chalk_1.default.green("✓") : chalk_1.default.gray("○")} semo-skills - 13개 통합 스킬`);
1015
+ console.log(` ${skillsInstalled ? chalk_1.default.green("✓") : chalk_1.default.gray("○")} semo-skills - 통합 스킬`);
979
1016
  console.log();
980
- // Extensions
981
- console.log(chalk_1.default.white.bold("Extensions (선택)"));
982
- for (const [key, pkg] of Object.entries(EXTENSION_PACKAGES)) {
983
- const isInstalled = fs.existsSync(path.join(semoSystemDir, key));
984
- const status = isInstalled ? chalk_1.default.green("✓") : chalk_1.default.gray("");
985
- console.log(` ${status} ${key} - ${pkg.desc}`);
1017
+ // Extensions - 레이어별 그룹화
1018
+ const layers = {
1019
+ biz: { title: "Business Layer", emoji: "💼" },
1020
+ eng: { title: "Engineering Layer", emoji: "⚙️" },
1021
+ ops: { title: "Operations Layer", emoji: "📊" },
1022
+ meta: { title: "Meta", emoji: "🔧" },
1023
+ };
1024
+ for (const [layerKey, layerInfo] of Object.entries(layers)) {
1025
+ const layerPackages = Object.entries(EXTENSION_PACKAGES).filter(([, pkg]) => pkg.layer === layerKey);
1026
+ if (layerPackages.length === 0)
1027
+ continue;
1028
+ console.log(chalk_1.default.white.bold(`${layerInfo.emoji} ${layerInfo.title}`));
1029
+ for (const [key, pkg] of layerPackages) {
1030
+ const isInstalled = fs.existsSync(path.join(semoSystemDir, key));
1031
+ const status = isInstalled ? chalk_1.default.green("✓") : chalk_1.default.gray("○");
1032
+ const displayKey = key.includes("/") ? key.split("/")[1] : key;
1033
+ console.log(` ${status} ${chalk_1.default.cyan(displayKey)} - ${pkg.desc}`);
1034
+ console.log(chalk_1.default.gray(` semo add ${key}`));
1035
+ }
1036
+ console.log();
986
1037
  }
987
- console.log();
988
- console.log(chalk_1.default.gray("설치: semo add <package>"));
989
- console.log(chalk_1.default.gray("예시: semo add next\n"));
1038
+ // 레거시 호환성 안내
1039
+ console.log(chalk_1.default.gray("".repeat(50)));
1040
+ console.log(chalk_1.default.gray("레거시 명령어도 지원됩니다:"));
1041
+ console.log(chalk_1.default.gray(" semo add next → eng/nextjs"));
1042
+ console.log(chalk_1.default.gray(" semo add backend → eng/spring"));
1043
+ console.log(chalk_1.default.gray(" semo add mvp → biz/poc\n"));
990
1044
  });
991
1045
  // === status 명령어 ===
992
1046
  program
package/package.json CHANGED
@@ -1,48 +1,48 @@
1
- {
2
- "name": "@team-semicolon/semo-cli",
3
- "version": "2.0.4",
4
- "description": "SEMO CLI - AI Agent Orchestration Framework Installer",
5
- "main": "dist/index.js",
6
- "bin": {
7
- "semo": "./dist/index.js",
8
- "semo-cli": "./dist/index.js"
9
- },
10
- "scripts": {
11
- "build": "tsc",
12
- "start": "node dist/index.js",
13
- "dev": "ts-node src/index.ts"
14
- },
15
- "keywords": [
16
- "semo",
17
- "cli",
18
- "ai-agent",
19
- "claude",
20
- "semicolon"
21
- ],
22
- "author": "Semicolon DevTeam",
23
- "license": "MIT",
24
- "repository": {
25
- "type": "git",
26
- "url": "https://github.com/semicolon-devteam/semo.git",
27
- "directory": "packages/cli"
28
- },
29
- "dependencies": {
30
- "chalk": "^5.3.0",
31
- "commander": "^12.0.0",
32
- "ora": "^8.0.0",
33
- "inquirer": "^9.2.0"
34
- },
35
- "devDependencies": {
36
- "@types/node": "^20.0.0",
37
- "@types/inquirer": "^9.0.0",
38
- "typescript": "^5.0.0",
39
- "ts-node": "^10.0.0"
40
- },
41
- "engines": {
42
- "node": ">=18.0.0"
43
- },
44
- "files": [
45
- "dist",
46
- "README.md"
47
- ]
48
- }
1
+ {
2
+ "name": "@team-semicolon/semo-cli",
3
+ "version": "3.0.0",
4
+ "description": "SEMO CLI - AI Agent Orchestration Framework Installer",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "semo": "./dist/index.js",
8
+ "semo-cli": "./dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "node dist/index.js",
13
+ "dev": "ts-node src/index.ts"
14
+ },
15
+ "keywords": [
16
+ "semo",
17
+ "cli",
18
+ "ai-agent",
19
+ "claude",
20
+ "semicolon"
21
+ ],
22
+ "author": "Semicolon DevTeam",
23
+ "license": "MIT",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/semicolon-devteam/semo.git",
27
+ "directory": "packages/cli"
28
+ },
29
+ "dependencies": {
30
+ "chalk": "^5.3.0",
31
+ "commander": "^12.0.0",
32
+ "ora": "^8.0.0",
33
+ "inquirer": "^9.2.0"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^20.0.0",
37
+ "@types/inquirer": "^9.0.0",
38
+ "typescript": "^5.0.0",
39
+ "ts-node": "^10.0.0"
40
+ },
41
+ "engines": {
42
+ "node": ">=18.0.0"
43
+ },
44
+ "files": [
45
+ "dist",
46
+ "README.md"
47
+ ]
48
+ }