@team-semicolon/semo-cli 3.0.28 → 3.0.29

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 +231 -231
  2. package/dist/index.js +461 -346
  3. package/package.json +48 -48
package/dist/index.js CHANGED
@@ -766,7 +766,7 @@ async function confirmOverwrite(itemName, itemPath) {
766
766
  type: "confirm",
767
767
  name: "shouldOverwrite",
768
768
  message: chalk_1.default.yellow(`${itemName} 이미 존재합니다. SEMO 기준으로 덮어쓰시겠습니까?`),
769
- default: false,
769
+ default: true,
770
770
  },
771
771
  ]);
772
772
  return shouldOverwrite;
@@ -975,13 +975,15 @@ program
975
975
  if (options.gitignore !== false) {
976
976
  updateGitignore(cwd);
977
977
  }
978
- // 9. CLAUDE.md 생성
978
+ // 9. Hooks 설치 (대화 로깅)
979
+ await setupHooks(cwd, false);
980
+ // 10. CLAUDE.md 생성
979
981
  await setupClaudeMd(cwd, extensionsToInstall, options.force);
980
- // 10. Extensions 심볼릭 링크 (agents/skills 병합)
982
+ // 11. Extensions 심볼릭 링크 (agents/skills 병합)
981
983
  if (extensionsToInstall.length > 0) {
982
984
  await setupExtensionSymlinks(cwd, extensionsToInstall);
983
985
  }
984
- // 11. 설치 검증
986
+ // 12. 설치 검증
985
987
  const verificationResult = verifyInstallation(cwd, extensionsToInstall);
986
988
  printVerificationResult(verificationResult);
987
989
  // 완료 메시지
@@ -1445,89 +1447,89 @@ function createMergedOrchestrator(claudeAgentsDir, orchestratorSources) {
1445
1447
  }
1446
1448
  }
1447
1449
  // 병합된 orchestrator.md 생성
1448
- const mergedContent = `---
1449
- name: orchestrator
1450
- description: |
1451
- SEMO Merged Orchestrator - Routes all user requests to appropriate agents/skills.
1452
- This orchestrator combines routing tables from ${orchestratorSources.length} packages.
1453
- PROACTIVELY delegate on ALL requests. Never process directly.
1454
- tools:
1455
- - read_file
1456
- - list_dir
1457
- - run_command
1458
- - glob
1459
- - grep
1460
- - task
1461
- - skill
1462
- model: inherit
1463
- ---
1464
-
1465
- # SEMO Merged Orchestrator
1466
-
1467
- > 이 파일은 **자동 생성**되었습니다. 직접 수정하지 마세요.
1468
- > 원본 파일: \`_packages/\` 디렉토리 참조
1469
-
1470
- 모든 사용자 요청을 분석하고 적절한 Agent 또는 Skill로 라우팅하는 **Primary Router**입니다.
1471
-
1472
- ## 🔴 설치된 패키지
1473
-
1474
- ${orchestratorSources.map(s => `- **${EXTENSION_PACKAGES[s.pkg]?.name || s.pkg}**: \`semo-system/${s.pkg}\``).join("\n")}
1475
-
1476
- ## �� Quick Routing Table (Merged)
1477
-
1478
- > 키워드 매칭 시 **첫 번째 매칭된 패키지**로 라우팅됩니다.
1479
-
1480
- ${routingTables.join("\n\n---\n\n")}
1481
-
1482
- ## SEMO 메시지 포맷
1483
-
1484
- ### Agent 위임
1485
-
1486
- \`\`\`markdown
1487
- [SEMO] Orchestrator: 의도 분석 완료 → {intent_category}
1488
-
1489
- [SEMO] Agent 위임: {agent_name} (사유: {reason})
1490
- \`\`\`
1491
-
1492
- ### Skill 호출
1493
-
1494
- \`\`\`markdown
1495
- [SEMO] Orchestrator: 의도 분석 완료 → {intent_category}
1496
-
1497
- [SEMO] Skill 호출: {skill_name}
1498
- \`\`\`
1499
-
1500
- ### 라우팅 실패
1501
-
1502
- \`\`\`markdown
1503
- [SEMO] Orchestrator: 라우팅 실패 → 적절한 Agent/Skill 없음
1504
-
1505
- ⚠️ 직접 처리 필요
1506
- \`\`\`
1507
-
1508
- ## Critical Rules
1509
-
1510
- 1. **Routing-Only**: 직접 작업 수행 금지
1511
- 2. **SEMO 메시지 필수**: 모든 위임에 SEMO 메시지 포함
1512
- 3. **Package Priority**: 라우팅 충돌 시 설치 순서대로 우선순위 적용
1513
- 4. **Cross-Package**: 다른 패키지 전문 영역 요청 시 인계 권유
1514
-
1515
- ${crossPackageRouting.length > 0 ? `## 🔄 Cross-Package Routing
1516
-
1517
- ${crossPackageRouting[0]}` : ""}
1518
-
1519
- ${availableAgents.length > 0 ? `## Available Agents (All Packages)
1520
-
1521
- ${availableAgents.join("\n\n")}` : ""}
1522
-
1523
- ${availableSkills.length > 0 ? `## Available Skills (All Packages)
1524
-
1525
- ${availableSkills.join("\n\n")}` : ""}
1526
-
1527
- ## References
1528
-
1529
- - 원본 Orchestrator: \`_packages/\` 디렉토리
1530
- - 병합된 References: \`references/\` 디렉토리
1450
+ const mergedContent = `---
1451
+ name: orchestrator
1452
+ description: |
1453
+ SEMO Merged Orchestrator - Routes all user requests to appropriate agents/skills.
1454
+ This orchestrator combines routing tables from ${orchestratorSources.length} packages.
1455
+ PROACTIVELY delegate on ALL requests. Never process directly.
1456
+ tools:
1457
+ - read_file
1458
+ - list_dir
1459
+ - run_command
1460
+ - glob
1461
+ - grep
1462
+ - task
1463
+ - skill
1464
+ model: inherit
1465
+ ---
1466
+
1467
+ # SEMO Merged Orchestrator
1468
+
1469
+ > 이 파일은 **자동 생성**되었습니다. 직접 수정하지 마세요.
1470
+ > 원본 파일: \`_packages/\` 디렉토리 참조
1471
+
1472
+ 모든 사용자 요청을 분석하고 적절한 Agent 또는 Skill로 라우팅하는 **Primary Router**입니다.
1473
+
1474
+ ## 🔴 설치된 패키지
1475
+
1476
+ ${orchestratorSources.map(s => `- **${EXTENSION_PACKAGES[s.pkg]?.name || s.pkg}**: \`semo-system/${s.pkg}\``).join("\n")}
1477
+
1478
+ ## �� Quick Routing Table (Merged)
1479
+
1480
+ > 키워드 매칭 시 **첫 번째 매칭된 패키지**로 라우팅됩니다.
1481
+
1482
+ ${routingTables.join("\n\n---\n\n")}
1483
+
1484
+ ## SEMO 메시지 포맷
1485
+
1486
+ ### Agent 위임
1487
+
1488
+ \`\`\`markdown
1489
+ [SEMO] Orchestrator: 의도 분석 완료 → {intent_category}
1490
+
1491
+ [SEMO] Agent 위임: {agent_name} (사유: {reason})
1492
+ \`\`\`
1493
+
1494
+ ### Skill 호출
1495
+
1496
+ \`\`\`markdown
1497
+ [SEMO] Orchestrator: 의도 분석 완료 → {intent_category}
1498
+
1499
+ [SEMO] Skill 호출: {skill_name}
1500
+ \`\`\`
1501
+
1502
+ ### 라우팅 실패
1503
+
1504
+ \`\`\`markdown
1505
+ [SEMO] Orchestrator: 라우팅 실패 → 적절한 Agent/Skill 없음
1506
+
1507
+ ⚠️ 직접 처리 필요
1508
+ \`\`\`
1509
+
1510
+ ## Critical Rules
1511
+
1512
+ 1. **Routing-Only**: 직접 작업 수행 금지
1513
+ 2. **SEMO 메시지 필수**: 모든 위임에 SEMO 메시지 포함
1514
+ 3. **Package Priority**: 라우팅 충돌 시 설치 순서대로 우선순위 적용
1515
+ 4. **Cross-Package**: 다른 패키지 전문 영역 요청 시 인계 권유
1516
+
1517
+ ${crossPackageRouting.length > 0 ? `## 🔄 Cross-Package Routing
1518
+
1519
+ ${crossPackageRouting[0]}` : ""}
1520
+
1521
+ ${availableAgents.length > 0 ? `## Available Agents (All Packages)
1522
+
1523
+ ${availableAgents.join("\n\n")}` : ""}
1524
+
1525
+ ${availableSkills.length > 0 ? `## Available Skills (All Packages)
1526
+
1527
+ ${availableSkills.join("\n\n")}` : ""}
1528
+
1529
+ ## References
1530
+
1531
+ - 원본 Orchestrator: \`_packages/\` 디렉토리
1532
+ - 병합된 References: \`references/\` 디렉토리
1531
1533
  `;
1532
1534
  fs.writeFileSync(path.join(orchestratorDir, "orchestrator.md"), mergedContent);
1533
1535
  }
@@ -1882,12 +1884,12 @@ async function mergeExtensionSettings(cwd, packages) {
1882
1884
  function updateGitignore(cwd) {
1883
1885
  console.log(chalk_1.default.cyan("\n📝 .gitignore 업데이트"));
1884
1886
  const gitignorePath = path.join(cwd, ".gitignore");
1885
- const semoIgnoreBlock = `
1886
- # === SEMO ===
1887
- .claude/*
1888
- !.claude/memory/
1889
- !.claude/memory/**
1890
- semo-system/
1887
+ const semoIgnoreBlock = `
1888
+ # === SEMO ===
1889
+ .claude/*
1890
+ !.claude/memory/
1891
+ !.claude/memory/**
1892
+ semo-system/
1891
1893
  `;
1892
1894
  if (fs.existsSync(gitignorePath)) {
1893
1895
  const content = fs.readFileSync(gitignorePath, "utf-8");
@@ -1906,6 +1908,117 @@ semo-system/
1906
1908
  console.log(chalk_1.default.green("✓ .gitignore 생성됨 (SEMO 규칙 포함)"));
1907
1909
  }
1908
1910
  }
1911
+ // === Hooks 설치/업데이트 ===
1912
+ async function setupHooks(cwd, isUpdate = false) {
1913
+ const action = isUpdate ? "업데이트" : "설치";
1914
+ console.log(chalk_1.default.cyan(`\n🪝 Claude Code Hooks ${action}`));
1915
+ console.log(chalk_1.default.gray(" 전체 대화 로깅 시스템\n"));
1916
+ const hooksDir = path.join(cwd, "semo-system", "semo-hooks");
1917
+ // semo-hooks 디렉토리 확인
1918
+ if (!fs.existsSync(hooksDir)) {
1919
+ console.log(chalk_1.default.yellow(" ⚠ semo-hooks 디렉토리 없음 (건너뜀)"));
1920
+ return;
1921
+ }
1922
+ // 1. npm install
1923
+ console.log(chalk_1.default.gray(" → 의존성 설치 중..."));
1924
+ try {
1925
+ (0, child_process_1.execSync)("npm install", {
1926
+ cwd: hooksDir,
1927
+ stdio: ["pipe", "pipe", "pipe"],
1928
+ });
1929
+ }
1930
+ catch {
1931
+ console.log(chalk_1.default.yellow(" ⚠ npm install 실패 (건너뜀)"));
1932
+ return;
1933
+ }
1934
+ // 2. 빌드
1935
+ console.log(chalk_1.default.gray(" → 빌드 중..."));
1936
+ try {
1937
+ (0, child_process_1.execSync)("npm run build", {
1938
+ cwd: hooksDir,
1939
+ stdio: ["pipe", "pipe", "pipe"],
1940
+ });
1941
+ }
1942
+ catch {
1943
+ console.log(chalk_1.default.yellow(" ⚠ 빌드 실패 (건너뜀)"));
1944
+ return;
1945
+ }
1946
+ // 3. settings.local.json 설정
1947
+ const homeDir = process.env.HOME || process.env.USERPROFILE || "";
1948
+ const settingsPath = path.join(homeDir, ".claude", "settings.local.json");
1949
+ const hooksCmd = `node ${path.join(hooksDir, "dist", "index.js")}`;
1950
+ // hooks 설정 객체
1951
+ const hooksConfig = {
1952
+ SessionStart: [
1953
+ {
1954
+ matcher: "",
1955
+ hooks: [
1956
+ {
1957
+ type: "command",
1958
+ command: `${hooksCmd} session-start`,
1959
+ timeout: 10,
1960
+ },
1961
+ ],
1962
+ },
1963
+ ],
1964
+ UserPromptSubmit: [
1965
+ {
1966
+ matcher: "",
1967
+ hooks: [
1968
+ {
1969
+ type: "command",
1970
+ command: `${hooksCmd} user-prompt`,
1971
+ timeout: 5,
1972
+ },
1973
+ ],
1974
+ },
1975
+ ],
1976
+ Stop: [
1977
+ {
1978
+ matcher: "",
1979
+ hooks: [
1980
+ {
1981
+ type: "command",
1982
+ command: `${hooksCmd} stop`,
1983
+ timeout: 10,
1984
+ },
1985
+ ],
1986
+ },
1987
+ ],
1988
+ SessionEnd: [
1989
+ {
1990
+ matcher: "",
1991
+ hooks: [
1992
+ {
1993
+ type: "command",
1994
+ command: `${hooksCmd} session-end`,
1995
+ timeout: 10,
1996
+ },
1997
+ ],
1998
+ },
1999
+ ],
2000
+ };
2001
+ // 기존 설정 로드 또는 새로 생성
2002
+ let existingSettings = {};
2003
+ const claudeConfigDir = path.join(homeDir, ".claude");
2004
+ if (!fs.existsSync(claudeConfigDir)) {
2005
+ fs.mkdirSync(claudeConfigDir, { recursive: true });
2006
+ }
2007
+ if (fs.existsSync(settingsPath)) {
2008
+ try {
2009
+ existingSettings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
2010
+ }
2011
+ catch {
2012
+ existingSettings = {};
2013
+ }
2014
+ }
2015
+ // hooks 설정 병합
2016
+ existingSettings.hooks = hooksConfig;
2017
+ // 설정 저장
2018
+ fs.writeFileSync(settingsPath, JSON.stringify(existingSettings, null, 2));
2019
+ console.log(chalk_1.default.green(` ✓ Hooks ${action} 완료`));
2020
+ console.log(chalk_1.default.gray(` 설정: ${settingsPath}`));
2021
+ }
1909
2022
  // === Context Mesh 초기화 ===
1910
2023
  async function setupContextMesh(cwd) {
1911
2024
  console.log(chalk_1.default.cyan("\n🧠 Context Mesh 초기화"));
@@ -1915,36 +2028,36 @@ async function setupContextMesh(cwd) {
1915
2028
  // context.md
1916
2029
  const contextPath = path.join(memoryDir, "context.md");
1917
2030
  if (!fs.existsSync(contextPath)) {
1918
- const contextContent = `# Project Context
1919
-
1920
- > 세션 간 영속화되는 프로젝트 컨텍스트
1921
- > SEMO의 memory 스킬이 이 파일을 자동으로 업데이트합니다.
1922
-
1923
- ---
1924
-
1925
- ## 프로젝트 정보
1926
-
1927
- | 항목 | 값 |
1928
- |------|-----|
1929
- | **이름** | ${path.basename(cwd)} |
1930
- | **SEMO 버전** | ${VERSION} |
1931
- | **설치일** | ${new Date().toISOString().split("T")[0]} |
1932
-
1933
- ---
1934
-
1935
- ## 현재 작업 상태
1936
-
1937
- _아직 작업 기록이 없습니다._
1938
-
1939
- ---
1940
-
1941
- ## 기술 스택
1942
-
1943
- _프로젝트 분석 후 자동으로 채워집니다._
1944
-
1945
- ---
1946
-
1947
- *마지막 업데이트: ${new Date().toISOString().split("T")[0]}*
2031
+ const contextContent = `# Project Context
2032
+
2033
+ > 세션 간 영속화되는 프로젝트 컨텍스트
2034
+ > SEMO의 memory 스킬이 이 파일을 자동으로 업데이트합니다.
2035
+
2036
+ ---
2037
+
2038
+ ## 프로젝트 정보
2039
+
2040
+ | 항목 | 값 |
2041
+ |------|-----|
2042
+ | **이름** | ${path.basename(cwd)} |
2043
+ | **SEMO 버전** | ${VERSION} |
2044
+ | **설치일** | ${new Date().toISOString().split("T")[0]} |
2045
+
2046
+ ---
2047
+
2048
+ ## 현재 작업 상태
2049
+
2050
+ _아직 작업 기록이 없습니다._
2051
+
2052
+ ---
2053
+
2054
+ ## 기술 스택
2055
+
2056
+ _프로젝트 분석 후 자동으로 채워집니다._
2057
+
2058
+ ---
2059
+
2060
+ *마지막 업데이트: ${new Date().toISOString().split("T")[0]}*
1948
2061
  `;
1949
2062
  fs.writeFileSync(contextPath, contextContent);
1950
2063
  console.log(chalk_1.default.green("✓ .claude/memory/context.md 생성됨"));
@@ -1952,36 +2065,36 @@ _프로젝트 분석 후 자동으로 채워집니다._
1952
2065
  // decisions.md
1953
2066
  const decisionsPath = path.join(memoryDir, "decisions.md");
1954
2067
  if (!fs.existsSync(decisionsPath)) {
1955
- const decisionsContent = `# Architecture Decisions
1956
-
1957
- > 프로젝트 아키텍처 결정 기록 (ADR)
1958
- > 중요한 기술적 결정을 여기에 기록합니다.
1959
-
1960
- ---
1961
-
1962
- ## 결정 목록
1963
-
1964
- _아직 기록된 결정이 없습니다._
1965
-
1966
- ---
1967
-
1968
- ## 템플릿
1969
-
1970
- \`\`\`markdown
1971
- ### ADR-XXX: 결정 제목
1972
-
1973
- **날짜**: YYYY-MM-DD
1974
- **상태**: Proposed | Accepted | Deprecated
1975
-
1976
- #### 배경
1977
- 결정이 필요한 이유
1978
-
1979
- #### 결정
1980
- 선택한 방안
1981
-
1982
- #### 근거
1983
- 선택 이유
1984
- \`\`\`
2068
+ const decisionsContent = `# Architecture Decisions
2069
+
2070
+ > 프로젝트 아키텍처 결정 기록 (ADR)
2071
+ > 중요한 기술적 결정을 여기에 기록합니다.
2072
+
2073
+ ---
2074
+
2075
+ ## 결정 목록
2076
+
2077
+ _아직 기록된 결정이 없습니다._
2078
+
2079
+ ---
2080
+
2081
+ ## 템플릿
2082
+
2083
+ \`\`\`markdown
2084
+ ### ADR-XXX: 결정 제목
2085
+
2086
+ **날짜**: YYYY-MM-DD
2087
+ **상태**: Proposed | Accepted | Deprecated
2088
+
2089
+ #### 배경
2090
+ 결정이 필요한 이유
2091
+
2092
+ #### 결정
2093
+ 선택한 방안
2094
+
2095
+ #### 근거
2096
+ 선택 이유
2097
+ \`\`\`
1985
2098
  `;
1986
2099
  fs.writeFileSync(decisionsPath, decisionsContent);
1987
2100
  console.log(chalk_1.default.green("✓ .claude/memory/decisions.md 생성됨"));
@@ -1989,62 +2102,62 @@ _아직 기록된 결정이 없습니다._
1989
2102
  // projects.md
1990
2103
  const projectsPath = path.join(memoryDir, "projects.md");
1991
2104
  if (!fs.existsSync(projectsPath)) {
1992
- const projectsContent = `# 프로젝트 별칭 매핑
1993
-
1994
- > 외부 프로젝트 배포 및 GitHub Projects 상태 관리
1995
- > SEMO의 deployer, project-status 스킬이 이 파일을 참조합니다.
1996
-
1997
- ---
1998
-
1999
- ## GitHub Projects 설정
2000
-
2001
- > **⚠️ 프로젝트 상태 관리 시 이 설정을 참조합니다.**
2002
-
2003
- ### 기본 프로젝트
2004
-
2005
- | 프로젝트 | 번호 | Project ID | 용도 |
2006
- |---------|------|------------|------|
2007
- | 이슈관리 | #1 | \`PVT_xxx\` | 메인 태스크 관리 (기본값) |
2008
-
2009
- ### Status 옵션
2010
-
2011
- | Status | 설명 |
2012
- |--------|------|
2013
- | 백로그 | 초기 상태 |
2014
- | 작업중 | 개발 진행 중 |
2015
- | 리뷰요청 | 코드 리뷰 대기 |
2016
- | 테스트중 | QA 테스트 단계 |
2017
- | 완료 | 작업 완료 |
2018
-
2019
- ### 🔴 상태값 Alias (한글 ↔ 영문)
2020
-
2021
- > **SEMO는 아래 키워드를 자동으로 Status 필드값으로 매핑합니다.**
2022
-
2023
- | 사용자 입력 | → Status 값 | 비고 |
2024
- |------------|-------------|------|
2025
- | 리뷰요청, 리뷰 요청, review | 리뷰요청 | 코드 리뷰 대기 |
2026
- | 테스트중, 테스트 중, testing, qa | 테스트중 | QA 단계 |
2027
- | 작업중, 작업 중, 진행중, in progress, wip | 작업중 | 개발 중 |
2028
- | 완료, done, closed | 완료 | 완료 처리 |
2029
- | 백로그, 대기, pending, backlog | 백로그 | 초기 상태 |
2030
-
2031
- **예시:**
2032
- \`\`\`
2033
- "리뷰요청 이슈들 테스트중으로 바꿔줘"
2034
- → Status == "리뷰요청" 인 항목들을 Status = "테스트중" 으로 변경
2035
- \`\`\`
2036
-
2037
- ---
2038
-
2039
- ## 프로젝트 별칭
2040
-
2041
- | 별칭 | 레포지토리 | 환경 | 배포 방법 |
2042
- |------|-----------|------|----------|
2043
- | 예시 | owner/repo | stg | Milestone close |
2044
-
2045
- ---
2046
-
2047
- *마지막 업데이트: ${new Date().toISOString().split("T")[0]}*
2105
+ const projectsContent = `# 프로젝트 별칭 매핑
2106
+
2107
+ > 외부 프로젝트 배포 및 GitHub Projects 상태 관리
2108
+ > SEMO의 deployer, project-status 스킬이 이 파일을 참조합니다.
2109
+
2110
+ ---
2111
+
2112
+ ## GitHub Projects 설정
2113
+
2114
+ > **⚠️ 프로젝트 상태 관리 시 이 설정을 참조합니다.**
2115
+
2116
+ ### 기본 프로젝트
2117
+
2118
+ | 프로젝트 | 번호 | Project ID | 용도 |
2119
+ |---------|------|------------|------|
2120
+ | 이슈관리 | #1 | \`PVT_xxx\` | 메인 태스크 관리 (기본값) |
2121
+
2122
+ ### Status 옵션
2123
+
2124
+ | Status | 설명 |
2125
+ |--------|------|
2126
+ | 백로그 | 초기 상태 |
2127
+ | 작업중 | 개발 진행 중 |
2128
+ | 리뷰요청 | 코드 리뷰 대기 |
2129
+ | 테스트중 | QA 테스트 단계 |
2130
+ | 완료 | 작업 완료 |
2131
+
2132
+ ### 🔴 상태값 Alias (한글 ↔ 영문)
2133
+
2134
+ > **SEMO는 아래 키워드를 자동으로 Status 필드값으로 매핑합니다.**
2135
+
2136
+ | 사용자 입력 | → Status 값 | 비고 |
2137
+ |------------|-------------|------|
2138
+ | 리뷰요청, 리뷰 요청, review | 리뷰요청 | 코드 리뷰 대기 |
2139
+ | 테스트중, 테스트 중, testing, qa | 테스트중 | QA 단계 |
2140
+ | 작업중, 작업 중, 진행중, in progress, wip | 작업중 | 개발 중 |
2141
+ | 완료, done, closed | 완료 | 완료 처리 |
2142
+ | 백로그, 대기, pending, backlog | 백로그 | 초기 상태 |
2143
+
2144
+ **예시:**
2145
+ \`\`\`
2146
+ "리뷰요청 이슈들 테스트중으로 바꿔줘"
2147
+ → Status == "리뷰요청" 인 항목들을 Status = "테스트중" 으로 변경
2148
+ \`\`\`
2149
+
2150
+ ---
2151
+
2152
+ ## 프로젝트 별칭
2153
+
2154
+ | 별칭 | 레포지토리 | 환경 | 배포 방법 |
2155
+ |------|-----------|------|----------|
2156
+ | 예시 | owner/repo | stg | Milestone close |
2157
+
2158
+ ---
2159
+
2160
+ *마지막 업데이트: ${new Date().toISOString().split("T")[0]}*
2048
2161
  `;
2049
2162
  fs.writeFileSync(projectsPath, projectsContent);
2050
2163
  console.log(chalk_1.default.green("✓ .claude/memory/projects.md 생성됨"));
@@ -2054,21 +2167,21 @@ _아직 기록된 결정이 없습니다._
2054
2167
  fs.mkdirSync(rulesDir, { recursive: true });
2055
2168
  const rulesPath = path.join(rulesDir, "project-specific.md");
2056
2169
  if (!fs.existsSync(rulesPath)) {
2057
- const rulesContent = `# Project-Specific Rules
2058
-
2059
- > 이 프로젝트에만 적용되는 규칙
2060
-
2061
- ---
2062
-
2063
- ## 코딩 규칙
2064
-
2065
- _프로젝트별 코딩 규칙을 여기에 추가하세요._
2066
-
2067
- ---
2068
-
2069
- ## 예외 사항
2070
-
2071
- _SEMO 기본 규칙의 예외 사항을 여기에 추가하세요._
2170
+ const rulesContent = `# Project-Specific Rules
2171
+
2172
+ > 이 프로젝트에만 적용되는 규칙
2173
+
2174
+ ---
2175
+
2176
+ ## 코딩 규칙
2177
+
2178
+ _프로젝트별 코딩 규칙을 여기에 추가하세요._
2179
+
2180
+ ---
2181
+
2182
+ ## 예외 사항
2183
+
2184
+ _SEMO 기본 규칙의 예외 사항을 여기에 추가하세요._
2072
2185
  `;
2073
2186
  fs.writeFileSync(rulesPath, rulesContent);
2074
2187
  console.log(chalk_1.default.green("✓ .claude/memory/rules/project-specific.md 생성됨"));
@@ -2204,129 +2317,129 @@ async function setupClaudeMd(cwd, extensions, force) {
2204
2317
  orchestratorPaths.unshift("semo-system/semo-core/agents/orchestrator/orchestrator.md");
2205
2318
  // Orchestrator 참조 섹션 생성
2206
2319
  const orchestratorRefSection = orchestratorPaths.length > 1
2207
- ? `**Primary Orchestrator**: \`semo-system/${primaryOrchestratorPath}\`
2208
-
2209
- > Extension 패키지가 설치되어 해당 패키지의 Orchestrator를 우선 참조합니다.
2210
-
2211
- **모든 Orchestrator 파일** (라우팅 테이블 병합됨):
2212
- ${orchestratorPaths.map(p => `- \`${p}\``).join("\n")}
2213
-
2320
+ ? `**Primary Orchestrator**: \`semo-system/${primaryOrchestratorPath}\`
2321
+
2322
+ > Extension 패키지가 설치되어 해당 패키지의 Orchestrator를 우선 참조합니다.
2323
+
2324
+ **모든 Orchestrator 파일** (라우팅 테이블 병합됨):
2325
+ ${orchestratorPaths.map(p => `- \`${p}\``).join("\n")}
2326
+
2214
2327
  이 파일들에서 라우팅 테이블, 의도 분류, 메시지 포맷을 확인하세요.`
2215
- : `**반드시 읽어야 할 파일**: \`semo-system/semo-core/agents/orchestrator/orchestrator.md\`
2216
-
2328
+ : `**반드시 읽어야 할 파일**: \`semo-system/semo-core/agents/orchestrator/orchestrator.md\`
2329
+
2217
2330
  이 파일에서 라우팅 테이블, 의도 분류, 메시지 포맷을 확인하세요.`;
2218
- const claudeMdContent = `# SEMO Project Configuration
2219
-
2220
- > SEMO (Semicolon Orchestrate) - AI Agent Orchestration Framework v${VERSION}
2221
-
2222
- ---
2223
-
2224
- ## 🔴 MANDATORY: Orchestrator-First Execution
2225
-
2226
- > **⚠️ 이 규칙은 모든 사용자 요청에 적용됩니다. 예외 없음.**
2227
-
2228
- ### 실행 흐름 (필수)
2229
-
2230
- \`\`\`
2231
- 1. 사용자 요청 수신
2232
- 2. Orchestrator가 의도 분석 후 적절한 Agent/Skill 라우팅
2233
- 3. Agent/Skill이 작업 수행
2234
- 4. 실행 결과 반환
2235
- \`\`\`
2236
-
2237
- ### Orchestrator 참조
2238
-
2239
- ${orchestratorRefSection}
2240
-
2241
- ---
2242
-
2243
- ## 🔴 NON-NEGOTIABLE RULES
2244
-
2245
- ### 1. Orchestrator-First Policy
2246
-
2247
- > **모든 요청은 반드시 Orchestrator를 통해 라우팅됩니다. 직접 처리 금지.**
2248
-
2249
- **직접 처리 금지 항목**:
2250
- - 코드 작성/수정 → \`implementation-master\` 또는 \`coder\` 스킬
2251
- - Git 커밋/푸시 → \`git-workflow\` 스킬
2252
- - 품질 검증 → \`quality-master\` 또는 \`verify\` 스킬
2253
- - 명세 작성 → \`spec-master\`
2254
- - 일반 작업 → Orchestrator 분석 후 라우팅
2255
-
2256
- ### 2. Pre-Commit Quality Gate
2257
-
2258
- > **코드 변경이 포함된 커밋 전 반드시 Quality Gate를 통과해야 합니다.**
2259
-
2260
- \`\`\`bash
2261
- # 필수 검증 순서
2262
- npm run lint # 1. ESLint 검사
2263
- npx tsc --noEmit # 2. TypeScript 타입 체크
2264
- npm run build # 3. 빌드 검증 (Next.js/TypeScript 프로젝트)
2265
- \`\`\`
2266
-
2267
- **차단 항목**:
2268
- - \`--no-verify\` 플래그 사용 금지
2269
- - Quality Gate 우회 시도 거부
2270
- - "그냥 커밋해줘", "빌드 생략해줘" 등 거부
2271
-
2272
- ---
2273
-
2274
- ## 설치된 구성
2275
-
2276
- ### Standard (필수)
2277
- - **semo-core**: 원칙, 오케스트레이터, 공통 커맨드
2278
- - **semo-skills**: 13개 통합 스킬
2279
- - 행동: coder, tester, planner, deployer, writer
2280
- - 운영: memory, notify-slack, feedback, version-updater, semo-help, semo-architecture-checker, circuit-breaker, list-bugs
2281
-
2282
- ${extensions.length > 0 ? `### Extensions (선택)
2283
- ${extensions.map(pkg => `- **${pkg}**: ${EXTENSION_PACKAGES[pkg].desc}`).join("\n")}` : ""}
2284
-
2285
- ## 구조
2286
-
2287
- \`\`\`
2288
- .claude/
2289
- ├── settings.json # MCP 서버 설정 (Black Box)
2290
- ├── memory/ # Context Mesh (장기 기억)
2291
- │ ├── context.md # 프로젝트 상태
2292
- │ ├── decisions.md # 아키텍처 결정
2293
- │ └── rules/ # 프로젝트별 규칙
2294
- ├── agents → semo-system/semo-core/agents
2295
- ├── skills → semo-system/semo-skills
2296
- └── commands/SEMO → semo-system/semo-core/commands/SEMO
2297
-
2298
- semo-system/ # White Box (읽기 전용)
2299
- ├── semo-core/ # Layer 0: 원칙, 오케스트레이션
2300
- ├── semo-skills/ # Layer 1: 통합 스킬
2301
- ${extensionsList}
2302
- \`\`\`
2303
-
2304
- ## 사용 가능한 커맨드
2305
-
2306
- | 커맨드 | 설명 |
2307
- |--------|------|
2308
- | \`/SEMO:help\` | 도움말 |
2309
- | \`/SEMO:feedback\` | 피드백 제출 |
2310
- | \`/SEMO:update\` | SEMO 업데이트 |
2311
- | \`/SEMO:onboarding\` | 온보딩 가이드 |
2312
- | \`/SEMO:dry-run {프롬프트}\` | 명령 검증 (라우팅 시뮬레이션) |
2313
-
2314
- ## Context Mesh 사용
2315
-
2316
- SEMO는 \`.claude/memory/\`를 통해 세션 간 컨텍스트를 유지합니다:
2317
-
2318
- - **context.md**: 프로젝트 상태, 진행 중인 작업
2319
- - **decisions.md**: 아키텍처 결정 기록 (ADR)
2320
- - **rules/**: 프로젝트별 커스텀 규칙
2321
-
2322
- memory 스킬이 자동으로 이 파일들을 관리합니다.
2323
-
2324
- ## References
2325
-
2326
- - [SEMO Principles](semo-system/semo-core/principles/PRINCIPLES.md)
2327
- - [SEMO Skills](semo-system/semo-skills/)
2328
- ${extensions.length > 0 ? extensions.map(pkg => `- [${EXTENSION_PACKAGES[pkg].name} Package](semo-system/${pkg}/)`).join("\n") : ""}
2329
- ${packageClaudeMdSections}
2331
+ const claudeMdContent = `# SEMO Project Configuration
2332
+
2333
+ > SEMO (Semicolon Orchestrate) - AI Agent Orchestration Framework v${VERSION}
2334
+
2335
+ ---
2336
+
2337
+ ## 🔴 MANDATORY: Orchestrator-First Execution
2338
+
2339
+ > **⚠️ 이 규칙은 모든 사용자 요청에 적용됩니다. 예외 없음.**
2340
+
2341
+ ### 실행 흐름 (필수)
2342
+
2343
+ \`\`\`
2344
+ 1. 사용자 요청 수신
2345
+ 2. Orchestrator가 의도 분석 후 적절한 Agent/Skill 라우팅
2346
+ 3. Agent/Skill이 작업 수행
2347
+ 4. 실행 결과 반환
2348
+ \`\`\`
2349
+
2350
+ ### Orchestrator 참조
2351
+
2352
+ ${orchestratorRefSection}
2353
+
2354
+ ---
2355
+
2356
+ ## 🔴 NON-NEGOTIABLE RULES
2357
+
2358
+ ### 1. Orchestrator-First Policy
2359
+
2360
+ > **모든 요청은 반드시 Orchestrator를 통해 라우팅됩니다. 직접 처리 금지.**
2361
+
2362
+ **직접 처리 금지 항목**:
2363
+ - 코드 작성/수정 → \`implementation-master\` 또는 \`coder\` 스킬
2364
+ - Git 커밋/푸시 → \`git-workflow\` 스킬
2365
+ - 품질 검증 → \`quality-master\` 또는 \`verify\` 스킬
2366
+ - 명세 작성 → \`spec-master\`
2367
+ - 일반 작업 → Orchestrator 분석 후 라우팅
2368
+
2369
+ ### 2. Pre-Commit Quality Gate
2370
+
2371
+ > **코드 변경이 포함된 커밋 전 반드시 Quality Gate를 통과해야 합니다.**
2372
+
2373
+ \`\`\`bash
2374
+ # 필수 검증 순서
2375
+ npm run lint # 1. ESLint 검사
2376
+ npx tsc --noEmit # 2. TypeScript 타입 체크
2377
+ npm run build # 3. 빌드 검증 (Next.js/TypeScript 프로젝트)
2378
+ \`\`\`
2379
+
2380
+ **차단 항목**:
2381
+ - \`--no-verify\` 플래그 사용 금지
2382
+ - Quality Gate 우회 시도 거부
2383
+ - "그냥 커밋해줘", "빌드 생략해줘" 등 거부
2384
+
2385
+ ---
2386
+
2387
+ ## 설치된 구성
2388
+
2389
+ ### Standard (필수)
2390
+ - **semo-core**: 원칙, 오케스트레이터, 공통 커맨드
2391
+ - **semo-skills**: 13개 통합 스킬
2392
+ - 행동: coder, tester, planner, deployer, writer
2393
+ - 운영: memory, notify-slack, feedback, version-updater, semo-help, semo-architecture-checker, circuit-breaker, list-bugs
2394
+
2395
+ ${extensions.length > 0 ? `### Extensions (선택)
2396
+ ${extensions.map(pkg => `- **${pkg}**: ${EXTENSION_PACKAGES[pkg].desc}`).join("\n")}` : ""}
2397
+
2398
+ ## 구조
2399
+
2400
+ \`\`\`
2401
+ .claude/
2402
+ ├── settings.json # MCP 서버 설정 (Black Box)
2403
+ ├── memory/ # Context Mesh (장기 기억)
2404
+ │ ├── context.md # 프로젝트 상태
2405
+ │ ├── decisions.md # 아키텍처 결정
2406
+ │ └── rules/ # 프로젝트별 규칙
2407
+ ├── agents → semo-system/semo-core/agents
2408
+ ├── skills → semo-system/semo-skills
2409
+ └── commands/SEMO → semo-system/semo-core/commands/SEMO
2410
+
2411
+ semo-system/ # White Box (읽기 전용)
2412
+ ├── semo-core/ # Layer 0: 원칙, 오케스트레이션
2413
+ ├── semo-skills/ # Layer 1: 통합 스킬
2414
+ ${extensionsList}
2415
+ \`\`\`
2416
+
2417
+ ## 사용 가능한 커맨드
2418
+
2419
+ | 커맨드 | 설명 |
2420
+ |--------|------|
2421
+ | \`/SEMO:help\` | 도움말 |
2422
+ | \`/SEMO:feedback\` | 피드백 제출 |
2423
+ | \`/SEMO:update\` | SEMO 업데이트 |
2424
+ | \`/SEMO:onboarding\` | 온보딩 가이드 |
2425
+ | \`/SEMO:dry-run {프롬프트}\` | 명령 검증 (라우팅 시뮬레이션) |
2426
+
2427
+ ## Context Mesh 사용
2428
+
2429
+ SEMO는 \`.claude/memory/\`를 통해 세션 간 컨텍스트를 유지합니다:
2430
+
2431
+ - **context.md**: 프로젝트 상태, 진행 중인 작업
2432
+ - **decisions.md**: 아키텍처 결정 기록 (ADR)
2433
+ - **rules/**: 프로젝트별 커스텀 규칙
2434
+
2435
+ memory 스킬이 자동으로 이 파일들을 관리합니다.
2436
+
2437
+ ## References
2438
+
2439
+ - [SEMO Principles](semo-system/semo-core/principles/PRINCIPLES.md)
2440
+ - [SEMO Skills](semo-system/semo-skills/)
2441
+ ${extensions.length > 0 ? extensions.map(pkg => `- [${EXTENSION_PACKAGES[pkg].name} Package](semo-system/${pkg}/)`).join("\n") : ""}
2442
+ ${packageClaudeMdSections}
2330
2443
  `;
2331
2444
  fs.writeFileSync(claudeMdPath, claudeMdContent);
2332
2445
  console.log(chalk_1.default.green("✓ .claude/CLAUDE.md 생성됨"));
@@ -2731,7 +2844,9 @@ program
2731
2844
  }
2732
2845
  }
2733
2846
  }
2734
- // === 설치 검증 ===
2847
+ // === 6. Hooks 업데이트 ===
2848
+ await setupHooks(cwd, true);
2849
+ // === 7. 설치 검증 ===
2735
2850
  const verificationResult = verifyInstallation(cwd, installedExtensions);
2736
2851
  printVerificationResult(verificationResult);
2737
2852
  if (verificationResult.success) {