@team-semicolon/semo-cli 4.1.1 → 4.1.3
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/dist/commands/sessions.js +7 -0
- package/dist/index.js +127 -173
- package/package.json +1 -1
|
@@ -189,6 +189,13 @@ function registerSessionsCommands(program) {
|
|
|
189
189
|
last_activity = NOW(),
|
|
190
190
|
message_count = COALESCE(EXCLUDED.message_count, semo.bot_sessions.message_count),
|
|
191
191
|
synced_at = NOW()`, [botId, sessionKey, label, options.kind, messageCount ?? null]);
|
|
192
|
+
// bot_status.session_count 갱신
|
|
193
|
+
await client.query(`UPDATE semo.bot_status
|
|
194
|
+
SET session_count = (
|
|
195
|
+
SELECT COUNT(*) FROM semo.bot_sessions WHERE bot_id = $1
|
|
196
|
+
),
|
|
197
|
+
synced_at = NOW()
|
|
198
|
+
WHERE bot_id = $1`, [botId]);
|
|
192
199
|
}
|
|
193
200
|
client.release();
|
|
194
201
|
console.log(chalk_1.default.green(`✔ sessions push [${event}] ${botId}/${sessionKey.slice(0, 8)}`));
|
package/dist/index.js
CHANGED
|
@@ -676,6 +676,11 @@ async function confirmOverwrite(itemName, itemPath) {
|
|
|
676
676
|
if (!fs.existsSync(itemPath)) {
|
|
677
677
|
return true;
|
|
678
678
|
}
|
|
679
|
+
// 비인터랙티브 환경(CI, 파이프) — 덮어쓰지 않고 기존 파일 유지
|
|
680
|
+
if (!process.stdin.isTTY) {
|
|
681
|
+
console.log(chalk_1.default.gray(` → ${itemName} 이미 존재 (비인터랙티브 모드: 건너뜀)`));
|
|
682
|
+
return false;
|
|
683
|
+
}
|
|
679
684
|
const { shouldOverwrite } = await inquirer_1.default.prompt([
|
|
680
685
|
{
|
|
681
686
|
type: "confirm",
|
|
@@ -776,7 +781,6 @@ program
|
|
|
776
781
|
.option("--credentials-gist <gistId>", "Private GitHub Gist에서 팀 DB 접속정보 자동 가져오기")
|
|
777
782
|
.action(async (options) => {
|
|
778
783
|
console.log(chalk_1.default.cyan.bold("\n🚀 SEMO 설치 시작\n"));
|
|
779
|
-
console.log(chalk_1.default.gray("Gemini 하이브리드 전략: White Box + Black Box\n"));
|
|
780
784
|
const cwd = process.cwd();
|
|
781
785
|
// 0.1. 버전 비교
|
|
782
786
|
await showVersionComparison(cwd);
|
|
@@ -810,6 +814,8 @@ program
|
|
|
810
814
|
fs.mkdirSync(claudeDir, { recursive: true });
|
|
811
815
|
console.log(chalk_1.default.green("\n✓ .claude/ 디렉토리 생성됨"));
|
|
812
816
|
}
|
|
817
|
+
// 2.5. ~/.semo.env DB 접속 설정 (자동 감지 → Gist → 프롬프트) — DB 연결 전에 먼저
|
|
818
|
+
await setupSemoEnv(options.credentialsGist);
|
|
813
819
|
// 3. Standard 설치 (semo-core + semo-skills)
|
|
814
820
|
await setupStandard(cwd, options.force);
|
|
815
821
|
// 4. MCP 설정
|
|
@@ -822,10 +828,8 @@ program
|
|
|
822
828
|
if (options.gitignore !== false) {
|
|
823
829
|
updateGitignore(cwd);
|
|
824
830
|
}
|
|
825
|
-
// 7. Hooks 설치
|
|
831
|
+
// 7. Hooks 설치
|
|
826
832
|
await setupHooks(cwd, false);
|
|
827
|
-
// 7.5. ~/.semo.env DB 접속 설정 (자동 감지 → Gist → 프롬프트)
|
|
828
|
-
await setupSemoEnv(options.credentialsGist);
|
|
829
833
|
// 8. CLAUDE.md 생성
|
|
830
834
|
await setupClaudeMd(cwd, [], options.force);
|
|
831
835
|
// 9. 설치 검증
|
|
@@ -845,11 +849,11 @@ program
|
|
|
845
849
|
console.log(chalk_1.default.yellow.bold("\n⚠️ SEMO 설치 완료 (일부 문제 발견)\n"));
|
|
846
850
|
}
|
|
847
851
|
console.log(chalk_1.default.cyan("설치된 구성:"));
|
|
848
|
-
console.log(chalk_1.default.gray("
|
|
849
|
-
console.log(chalk_1.default.gray("
|
|
850
|
-
console.log(chalk_1.default.gray("
|
|
851
|
-
console.log(chalk_1.default.gray("
|
|
852
|
-
console.log(chalk_1.default.gray("
|
|
852
|
+
console.log(chalk_1.default.gray(" ✓ .claude/skills/ (DB 기반 스킬)"));
|
|
853
|
+
console.log(chalk_1.default.gray(" ✓ .claude/agents/ (DB 기반 에이전트)"));
|
|
854
|
+
console.log(chalk_1.default.gray(" ✓ .claude/commands/ (슬래시 커맨드)"));
|
|
855
|
+
console.log(chalk_1.default.gray(" ✓ .claude/memory/ (컨텍스트 동기화)"));
|
|
856
|
+
console.log(chalk_1.default.gray(" ✓ ~/.claude/settings.local.json (훅 등록)"));
|
|
853
857
|
console.log(chalk_1.default.cyan("\n다음 단계:"));
|
|
854
858
|
console.log(chalk_1.default.gray(" 1. Claude Code에서 프로젝트 열기 (SessionStart 훅이 자동 sync)"));
|
|
855
859
|
console.log(chalk_1.default.gray(" 2. 자연어로 요청하기 (예: \"댓글 기능 구현해줘\")"));
|
|
@@ -929,8 +933,6 @@ async function setupStandard(cwd, force) {
|
|
|
929
933
|
}
|
|
930
934
|
console.log(chalk_1.default.green(` ✓ agents 설치 완료 (${agents.length}개)`));
|
|
931
935
|
spinner.succeed("Standard 설치 완료 (DB 기반)");
|
|
932
|
-
// CLAUDE.md 생성
|
|
933
|
-
await generateClaudeMd(cwd);
|
|
934
936
|
}
|
|
935
937
|
catch (error) {
|
|
936
938
|
spinner.fail("Standard 설치 실패");
|
|
@@ -1629,54 +1631,11 @@ semo-system/
|
|
|
1629
1631
|
async function setupHooks(cwd, isUpdate = false) {
|
|
1630
1632
|
const action = isUpdate ? "업데이트" : "설치";
|
|
1631
1633
|
console.log(chalk_1.default.cyan(`\n🪝 Claude Code Hooks ${action}`));
|
|
1632
|
-
console.log(chalk_1.default.gray(" 전체 대화 로깅 시스템\n"));
|
|
1633
|
-
const hooksDir = path.join(cwd, "semo-system", "semo-hooks");
|
|
1634
|
-
// semo-hooks 디렉토리 확인
|
|
1635
|
-
if (!fs.existsSync(hooksDir)) {
|
|
1636
|
-
console.log(chalk_1.default.yellow(" ⚠ semo-hooks 디렉토리 없음 (건너뜀)"));
|
|
1637
|
-
return;
|
|
1638
|
-
}
|
|
1639
|
-
// 1. npm install
|
|
1640
|
-
console.log(chalk_1.default.gray(" → 의존성 설치 중..."));
|
|
1641
|
-
try {
|
|
1642
|
-
(0, child_process_1.execSync)("npm install", {
|
|
1643
|
-
cwd: hooksDir,
|
|
1644
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
1645
|
-
});
|
|
1646
|
-
}
|
|
1647
|
-
catch {
|
|
1648
|
-
console.log(chalk_1.default.yellow(" ⚠ npm install 실패 (건너뜀)"));
|
|
1649
|
-
return;
|
|
1650
|
-
}
|
|
1651
|
-
// 2. 빌드
|
|
1652
|
-
console.log(chalk_1.default.gray(" → 빌드 중..."));
|
|
1653
|
-
try {
|
|
1654
|
-
(0, child_process_1.execSync)("npm run build", {
|
|
1655
|
-
cwd: hooksDir,
|
|
1656
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
1657
|
-
});
|
|
1658
|
-
}
|
|
1659
|
-
catch {
|
|
1660
|
-
console.log(chalk_1.default.yellow(" ⚠ 빌드 실패 (건너뜀)"));
|
|
1661
|
-
return;
|
|
1662
|
-
}
|
|
1663
|
-
// 3. settings.local.json 설정
|
|
1664
1634
|
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
1665
1635
|
const settingsPath = path.join(homeDir, ".claude", "settings.local.json");
|
|
1666
|
-
|
|
1667
|
-
// hooks 설정 객체
|
|
1636
|
+
// Core 훅: semo context sync/push — semo-hooks 유무와 무관하게 항상 등록
|
|
1668
1637
|
const hooksConfig = {
|
|
1669
1638
|
SessionStart: [
|
|
1670
|
-
{
|
|
1671
|
-
matcher: "",
|
|
1672
|
-
hooks: [
|
|
1673
|
-
{
|
|
1674
|
-
type: "command",
|
|
1675
|
-
command: `${hooksCmd} session-start`,
|
|
1676
|
-
timeout: 10,
|
|
1677
|
-
},
|
|
1678
|
-
],
|
|
1679
|
-
},
|
|
1680
1639
|
{
|
|
1681
1640
|
matcher: "",
|
|
1682
1641
|
hooks: [
|
|
@@ -1688,29 +1647,7 @@ async function setupHooks(cwd, isUpdate = false) {
|
|
|
1688
1647
|
],
|
|
1689
1648
|
},
|
|
1690
1649
|
],
|
|
1691
|
-
UserPromptSubmit: [
|
|
1692
|
-
{
|
|
1693
|
-
matcher: "",
|
|
1694
|
-
hooks: [
|
|
1695
|
-
{
|
|
1696
|
-
type: "command",
|
|
1697
|
-
command: `${hooksCmd} user-prompt`,
|
|
1698
|
-
timeout: 5,
|
|
1699
|
-
},
|
|
1700
|
-
],
|
|
1701
|
-
},
|
|
1702
|
-
],
|
|
1703
1650
|
Stop: [
|
|
1704
|
-
{
|
|
1705
|
-
matcher: "",
|
|
1706
|
-
hooks: [
|
|
1707
|
-
{
|
|
1708
|
-
type: "command",
|
|
1709
|
-
command: `${hooksCmd} stop`,
|
|
1710
|
-
timeout: 10,
|
|
1711
|
-
},
|
|
1712
|
-
],
|
|
1713
|
-
},
|
|
1714
1651
|
{
|
|
1715
1652
|
matcher: "",
|
|
1716
1653
|
hooks: [
|
|
@@ -1722,19 +1659,37 @@ async function setupHooks(cwd, isUpdate = false) {
|
|
|
1722
1659
|
],
|
|
1723
1660
|
},
|
|
1724
1661
|
],
|
|
1725
|
-
SessionEnd: [
|
|
1726
|
-
{
|
|
1727
|
-
matcher: "",
|
|
1728
|
-
hooks: [
|
|
1729
|
-
{
|
|
1730
|
-
type: "command",
|
|
1731
|
-
command: `${hooksCmd} session-end`,
|
|
1732
|
-
timeout: 10,
|
|
1733
|
-
},
|
|
1734
|
-
],
|
|
1735
|
-
},
|
|
1736
|
-
],
|
|
1737
1662
|
};
|
|
1663
|
+
// semo-hooks 빌드 (선택적 — semo-system 레포에서만 동작)
|
|
1664
|
+
const hooksDir = path.join(cwd, "semo-system", "semo-hooks");
|
|
1665
|
+
if (fs.existsSync(hooksDir)) {
|
|
1666
|
+
let hooksBuilt = false;
|
|
1667
|
+
try {
|
|
1668
|
+
(0, child_process_1.execSync)("npm install", { cwd: hooksDir, stdio: ["pipe", "pipe", "pipe"] });
|
|
1669
|
+
(0, child_process_1.execSync)("npm run build", { cwd: hooksDir, stdio: ["pipe", "pipe", "pipe"] });
|
|
1670
|
+
hooksBuilt = true;
|
|
1671
|
+
}
|
|
1672
|
+
catch {
|
|
1673
|
+
console.log(chalk_1.default.yellow(" ⚠ semo-hooks 빌드 실패 (core 훅만 등록)"));
|
|
1674
|
+
}
|
|
1675
|
+
if (hooksBuilt) {
|
|
1676
|
+
const hooksCmd = `node ${path.join(hooksDir, "dist", "index.js")}`;
|
|
1677
|
+
hooksConfig.SessionStart.unshift({
|
|
1678
|
+
matcher: "",
|
|
1679
|
+
hooks: [{ type: "command", command: `${hooksCmd} session-start`, timeout: 10 }],
|
|
1680
|
+
});
|
|
1681
|
+
hooksConfig.UserPromptSubmit = [
|
|
1682
|
+
{ matcher: "", hooks: [{ type: "command", command: `${hooksCmd} user-prompt`, timeout: 5 }] },
|
|
1683
|
+
];
|
|
1684
|
+
hooksConfig.Stop.unshift({
|
|
1685
|
+
matcher: "",
|
|
1686
|
+
hooks: [{ type: "command", command: `${hooksCmd} stop`, timeout: 10 }],
|
|
1687
|
+
});
|
|
1688
|
+
hooksConfig.SessionEnd = [
|
|
1689
|
+
{ matcher: "", hooks: [{ type: "command", command: `${hooksCmd} session-end`, timeout: 10 }] },
|
|
1690
|
+
];
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1738
1693
|
// 기존 설정 로드 또는 새로 생성
|
|
1739
1694
|
let existingSettings = {};
|
|
1740
1695
|
const claudeConfigDir = path.join(homeDir, ".claude");
|
|
@@ -1935,133 +1890,132 @@ async function setupClaudeMd(cwd, _extensions, force) {
|
|
|
1935
1890
|
return;
|
|
1936
1891
|
}
|
|
1937
1892
|
}
|
|
1938
|
-
const
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
const claudeMdContent = `# SEMO Project Configuration
|
|
1893
|
+
const projectName = path.basename(cwd);
|
|
1894
|
+
const installDate = new Date().toISOString().split("T")[0];
|
|
1895
|
+
const claudeMdContent = `# ${projectName} — Claude Configuration
|
|
1942
1896
|
|
|
1943
|
-
> SEMO
|
|
1897
|
+
> SEMO v${VERSION} 설치됨 (${installDate})
|
|
1944
1898
|
|
|
1945
1899
|
---
|
|
1946
1900
|
|
|
1947
|
-
##
|
|
1948
|
-
|
|
1949
|
-
> **⚠️ 세션 시작 시 반드시 \`.claude/memory/\` 폴더의 파일들을 먼저 읽으세요. 예외 없음.**
|
|
1901
|
+
## SEMO란?
|
|
1950
1902
|
|
|
1951
|
-
|
|
1903
|
+
**SEMO (Semicolon Orchestrate)** 는 OpenClaw 봇팀과 로컬 Claude Code 세션이
|
|
1904
|
+
**팀 Core DB를 단일 진실 공급원(Single Source of Truth)으로 공유**하는 컨텍스트 동기화 시스템이다.
|
|
1952
1905
|
|
|
1953
1906
|
\`\`\`
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1907
|
+
로컬 Claude Code 세션
|
|
1908
|
+
↕ semo context sync / push
|
|
1909
|
+
팀 Core DB (PostgreSQL, semo 스키마)
|
|
1910
|
+
↕ 봇 세션 시작/종료 훅
|
|
1911
|
+
OpenClaw 봇팀 (7개 봇)
|
|
1912
|
+
workclaw · reviewclaw · planclaw · designclaw
|
|
1913
|
+
infraclaw · growthclaw · semiclaw
|
|
1959
1914
|
\`\`\`
|
|
1960
1915
|
|
|
1961
|
-
**이
|
|
1916
|
+
**이 CLAUDE.md가 설치된 프로젝트는 OpenClaw 봇팀의 컨텍스트를 실시간으로 공유받는다.**
|
|
1962
1917
|
|
|
1963
1918
|
---
|
|
1964
1919
|
|
|
1965
|
-
##
|
|
1920
|
+
## 자동 동기화
|
|
1966
1921
|
|
|
1967
|
-
|
|
1922
|
+
세션 시작/종료 시 팀 Core DB와 자동 동기화됩니다.
|
|
1968
1923
|
|
|
1969
|
-
|
|
1924
|
+
| 시점 | 동작 |
|
|
1925
|
+
|------|------|
|
|
1926
|
+
| 세션 시작 | \`semo context sync\` → \`.claude/memory/\` 최신화 |
|
|
1927
|
+
| 세션 종료 | \`semo context push\` → \`decisions.md\` 변경분 DB 저장 |
|
|
1928
|
+
|
|
1929
|
+
---
|
|
1930
|
+
|
|
1931
|
+
## Memory Context
|
|
1932
|
+
|
|
1933
|
+
\`.claude/memory/\` 파일들은 **팀 Core DB (\`semo\` 스키마)에서 자동으로 채워집니다**.
|
|
1934
|
+
직접 편집하지 마세요 — 세션 시작 시 덮어씌워집니다.
|
|
1935
|
+
|
|
1936
|
+
| 파일 | DB 소스 | 방향 |
|
|
1937
|
+
|------|---------|------|
|
|
1938
|
+
| \`team.md\` | \`kb WHERE domain='team'\` | DB → 로컬 (읽기 전용) |
|
|
1939
|
+
| \`projects.md\` | \`kb WHERE domain='project'\` | DB → 로컬 (읽기 전용) |
|
|
1940
|
+
| \`decisions.md\` | \`kb WHERE domain='decision'\` | **양방향** (편집 가능, Stop 시 DB 저장) |
|
|
1941
|
+
| \`infra.md\` | \`kb WHERE domain='infra'\` | DB → 로컬 (읽기 전용) |
|
|
1942
|
+
| \`process.md\` | \`kb WHERE domain='process'\` | DB → 로컬 (읽기 전용) |
|
|
1943
|
+
| \`bots.md\` | \`semo.bot_status\` | DB → 로컬 (봇 상태) |
|
|
1944
|
+
| \`ontology.md\` | \`semo.ontology\` | DB → 로컬 (읽기 전용) |
|
|
1945
|
+
|
|
1946
|
+
**decisions.md 만 편집 가능합니다.** 아키텍처 결정(ADR)을 여기에 기록하세요.
|
|
1947
|
+
|
|
1948
|
+
---
|
|
1949
|
+
|
|
1950
|
+
## 설치된 구성
|
|
1970
1951
|
|
|
1971
1952
|
\`\`\`
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1953
|
+
.claude/
|
|
1954
|
+
├── CLAUDE.md # 이 파일
|
|
1955
|
+
├── settings.json # MCP 서버 설정 + SessionStart/Stop 훅
|
|
1956
|
+
├── memory/ # Core DB → 로컬 자동 동기화 컨텍스트
|
|
1957
|
+
├── skills/ # SEMO 스킬 (semo-system/semo-skills/ 링크)
|
|
1958
|
+
├── agents/ # SEMO 에이전트 (semo-system/meta/agents/ 링크)
|
|
1959
|
+
└── commands/SEMO # 슬래시 커맨드 (semo-system/semo-core/commands/)
|
|
1976
1960
|
\`\`\`
|
|
1977
1961
|
|
|
1978
|
-
|
|
1962
|
+
---
|
|
1979
1963
|
|
|
1980
|
-
|
|
1964
|
+
## 프로젝트 규칙 (팀이 채워야 함)
|
|
1981
1965
|
|
|
1982
|
-
|
|
1966
|
+
> 아래 섹션은 이 프로젝트 고유의 규칙을 기록하세요.
|
|
1967
|
+
> 팀 공통 규칙은 \`memory/process.md\`에 있습니다.
|
|
1983
1968
|
|
|
1984
|
-
|
|
1969
|
+
### 기술 스택
|
|
1985
1970
|
|
|
1986
|
-
|
|
1971
|
+
<!-- 예: Next.js 14, PostgreSQL, TypeScript strict mode -->
|
|
1987
1972
|
|
|
1988
|
-
|
|
1973
|
+
### 브랜치 전략
|
|
1989
1974
|
|
|
1990
|
-
|
|
1991
|
-
- 코드 작성/수정 → \`implementation-master\` 또는 \`coder\` 스킬
|
|
1992
|
-
- Git 커밋/푸시 → \`git-workflow\` 스킬
|
|
1993
|
-
- 품질 검증 → \`quality-master\` 또는 \`verify\` 스킬
|
|
1994
|
-
- 명세 작성 → \`spec-master\`
|
|
1995
|
-
- 일반 작업 → Orchestrator 분석 후 라우팅
|
|
1975
|
+
<!-- 예: main(prod) / dev(staging) / feat/* -->
|
|
1996
1976
|
|
|
1997
|
-
###
|
|
1977
|
+
### 코딩 컨벤션
|
|
1998
1978
|
|
|
1999
|
-
|
|
1979
|
+
<!-- 예: ESLint airbnb, 함수형 컴포넌트 필수, any 금지 -->
|
|
2000
1980
|
|
|
2001
|
-
|
|
2002
|
-
# 필수 검증 순서
|
|
2003
|
-
npm run lint # 1. ESLint 검사
|
|
2004
|
-
npx tsc --noEmit # 2. TypeScript 타입 체크
|
|
2005
|
-
npm run build # 3. 빌드 검증 (Next.js/TypeScript 프로젝트)
|
|
2006
|
-
\`\`\`
|
|
1981
|
+
### 아키텍처 특이사항
|
|
2007
1982
|
|
|
2008
|
-
|
|
2009
|
-
- \`--no-verify\` 플래그 사용 금지
|
|
2010
|
-
- Quality Gate 우회 시도 거부
|
|
2011
|
-
- "그냥 커밋해줘", "빌드 생략해줘" 등 거부
|
|
1983
|
+
<!-- 예: DB 직접 접근 금지 — 반드시 API route 통해야 함 -->
|
|
2012
1984
|
|
|
2013
1985
|
---
|
|
2014
1986
|
|
|
2015
|
-
##
|
|
2016
|
-
|
|
2017
|
-
### Standard (필수)
|
|
2018
|
-
- **semo-core**: 원칙, 오케스트레이터, 공통 커맨드
|
|
2019
|
-
- **semo-skills**: 13개 통합 스킬
|
|
2020
|
-
- 행동: coder, tester, planner, deployer, writer
|
|
2021
|
-
- 운영: memory, notify-slack, feedback, version-updater, semo-help, semo-architecture-checker, circuit-breaker, list-bugs
|
|
1987
|
+
## Quality Gate
|
|
2022
1988
|
|
|
2023
|
-
|
|
1989
|
+
코드 변경 커밋 전 필수:
|
|
2024
1990
|
|
|
2025
|
-
\`\`\`
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
│ ├── context.md # 프로젝트 상태
|
|
2030
|
-
│ ├── decisions.md # 아키텍처 결정
|
|
2031
|
-
│ └── rules/ # 프로젝트별 규칙
|
|
2032
|
-
├── agents → semo-system/semo-core/agents
|
|
2033
|
-
├── skills → semo-system/semo-skills
|
|
2034
|
-
└── commands/SEMO → semo-system/semo-core/commands/SEMO
|
|
2035
|
-
|
|
2036
|
-
semo-system/ # White Box (읽기 전용)
|
|
2037
|
-
├── semo-core/ # Layer 0: 원칙, 오케스트레이션
|
|
2038
|
-
└── semo-skills/ # Layer 1: 통합 스킬
|
|
1991
|
+
\`\`\`bash
|
|
1992
|
+
npm run lint # ESLint
|
|
1993
|
+
npx tsc --noEmit # TypeScript
|
|
1994
|
+
npm run build # 빌드 검증
|
|
2039
1995
|
\`\`\`
|
|
2040
1996
|
|
|
2041
|
-
|
|
1997
|
+
\`--no-verify\` 사용 금지.
|
|
1998
|
+
|
|
1999
|
+
---
|
|
2000
|
+
|
|
2001
|
+
## 슬래시 커맨드
|
|
2042
2002
|
|
|
2043
2003
|
| 커맨드 | 설명 |
|
|
2044
2004
|
|--------|------|
|
|
2045
2005
|
| \`/SEMO:help\` | 도움말 |
|
|
2046
2006
|
| \`/SEMO:feedback\` | 피드백 제출 |
|
|
2047
|
-
| \`/SEMO:
|
|
2048
|
-
| \`/SEMO:onboarding\` | 온보딩 가이드 |
|
|
2049
|
-
| \`/SEMO:dry-run {프롬프트}\` | 명령 검증 (라우팅 시뮬레이션) |
|
|
2050
|
-
|
|
2051
|
-
## Context Mesh 사용
|
|
2052
|
-
|
|
2053
|
-
SEMO는 \`.claude/memory/\`를 통해 세션 간 컨텍스트를 유지합니다:
|
|
2007
|
+
| \`/SEMO:health\` | 환경 헬스체크 |
|
|
2054
2008
|
|
|
2055
|
-
|
|
2056
|
-
- **decisions.md**: 아키텍처 결정 기록 (ADR)
|
|
2057
|
-
- **rules/**: 프로젝트별 커스텀 규칙
|
|
2058
|
-
|
|
2059
|
-
memory 스킬이 자동으로 이 파일들을 관리합니다.
|
|
2009
|
+
---
|
|
2060
2010
|
|
|
2061
|
-
##
|
|
2011
|
+
## 복구 명령어
|
|
2062
2012
|
|
|
2063
|
-
|
|
2064
|
-
|
|
2013
|
+
\`\`\`bash
|
|
2014
|
+
semo doctor # 환경 진단 (DB 연결, 설치 상태)
|
|
2015
|
+
semo config db # DB URL 재설정
|
|
2016
|
+
semo context sync # memory/ 수동 최신화
|
|
2017
|
+
semo bots status # 봇 상태 조회
|
|
2018
|
+
\`\`\`
|
|
2065
2019
|
`;
|
|
2066
2020
|
fs.writeFileSync(claudeMdPath, claudeMdContent);
|
|
2067
2021
|
console.log(chalk_1.default.green("✓ .claude/CLAUDE.md 생성됨"));
|