@team-semicolon/semo-cli 3.7.2 → 3.7.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/index.js +146 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1499,6 +1499,26 @@ function createMergedOrchestrator(claudeAgentsDir, orchestratorSources) {
|
|
|
1499
1499
|
}
|
|
1500
1500
|
}
|
|
1501
1501
|
}
|
|
1502
|
+
// meta 패키지 포함 여부 확인
|
|
1503
|
+
const hasMetaInSources = orchestratorSources.some(s => s.pkg === "meta");
|
|
1504
|
+
// Meta 자동 체이닝 섹션
|
|
1505
|
+
const metaAutoChainSection = hasMetaInSources ? `
|
|
1506
|
+
## 🔴 Meta 환경 자동 체이닝 (NON-NEGOTIABLE)
|
|
1507
|
+
|
|
1508
|
+
> **조건**: semo-system/ 내 파일 수정이 감지되면
|
|
1509
|
+
> **동작**: 작업 종료 전 자동으로 \`skill:meta-workflow\` 호출
|
|
1510
|
+
|
|
1511
|
+
\`\`\`text
|
|
1512
|
+
semo-system/ 파일 수정 감지
|
|
1513
|
+
↓
|
|
1514
|
+
[자동] skill:meta-workflow 호출
|
|
1515
|
+
↓
|
|
1516
|
+
버저닝 → 배포 → 로컬 동기화
|
|
1517
|
+
\`\`\`
|
|
1518
|
+
|
|
1519
|
+
**이 규칙은 우회할 수 없습니다.**
|
|
1520
|
+
|
|
1521
|
+
` : "";
|
|
1502
1522
|
// 병합된 orchestrator.md 생성
|
|
1503
1523
|
const mergedContent = `---
|
|
1504
1524
|
name: orchestrator
|
|
@@ -1567,7 +1587,7 @@ ${routingTables.join("\n\n---\n\n")}
|
|
|
1567
1587
|
3. **Package Priority**: 라우팅 충돌 시 설치 순서대로 우선순위 적용
|
|
1568
1588
|
4. **Cross-Package**: 다른 패키지 전문 영역 요청 시 인계 권유
|
|
1569
1589
|
|
|
1570
|
-
${crossPackageRouting.length > 0 ? `## 🔄 Cross-Package Routing
|
|
1590
|
+
${metaAutoChainSection}${crossPackageRouting.length > 0 ? `## 🔄 Cross-Package Routing
|
|
1571
1591
|
|
|
1572
1592
|
${crossPackageRouting[0]}` : ""}
|
|
1573
1593
|
|
|
@@ -2348,6 +2368,8 @@ async function setupClaudeMd(cwd, extensions, force) {
|
|
|
2348
2368
|
: "";
|
|
2349
2369
|
// 패키지별 CLAUDE.md 병합 섹션 생성
|
|
2350
2370
|
let packageClaudeMdSections = "";
|
|
2371
|
+
// meta 패키지 설치 여부 확인
|
|
2372
|
+
const hasMetaPackage = extensions.includes("meta");
|
|
2351
2373
|
// 개별 패키지 CLAUDE.md 병합 - 중복 제거 적용
|
|
2352
2374
|
for (const pkg of extensions) {
|
|
2353
2375
|
const pkgClaudeMdPath = path.join(semoSystemDir, pkg, "CLAUDE.md");
|
|
@@ -2393,6 +2415,47 @@ ${orchestratorPaths.map(p => `- \`${p}\``).join("\n")}
|
|
|
2393
2415
|
: `**반드시 읽어야 할 파일**: \`semo-system/semo-core/agents/orchestrator/orchestrator.md\`
|
|
2394
2416
|
|
|
2395
2417
|
이 파일에서 라우팅 테이블, 의도 분류, 메시지 포맷을 확인하세요.`;
|
|
2418
|
+
// Meta 패키지 설치 시 자동 워크플로우 강제 규칙
|
|
2419
|
+
const metaWorkflowSection = hasMetaPackage ? `
|
|
2420
|
+
### 3. Meta 환경 자동 워크플로우 (NON-NEGOTIABLE)
|
|
2421
|
+
|
|
2422
|
+
> **⚠️ Meta 패키지가 설치된 환경에서는 반드시 아래 규칙이 적용됩니다.**
|
|
2423
|
+
> **이 규칙을 우회하거나 무시하는 것은 금지됩니다.**
|
|
2424
|
+
|
|
2425
|
+
#### 자동 트리거 조건
|
|
2426
|
+
|
|
2427
|
+
\`semo-system/\` 디렉토리 내 파일이 수정되면:
|
|
2428
|
+
1. 작업 종료 전 반드시 \`skill:meta-workflow\` 호출
|
|
2429
|
+
2. 버저닝 → 배포 → 로컬 동기화 체인 자동 실행
|
|
2430
|
+
|
|
2431
|
+
#### 감지 패턴
|
|
2432
|
+
|
|
2433
|
+
다음 경로의 파일 수정 시 자동 트리거:
|
|
2434
|
+
- \`semo-system/semo-core/**\`
|
|
2435
|
+
- \`semo-system/semo-skills/**\`
|
|
2436
|
+
- \`semo-system/meta/**\`
|
|
2437
|
+
- \`semo-system/semo-remote/**\`
|
|
2438
|
+
- \`semo-system/semo-hooks/**\`
|
|
2439
|
+
- \`packages/cli/**\` (CLI 수정 시)
|
|
2440
|
+
|
|
2441
|
+
#### 강제 동작 흐름
|
|
2442
|
+
|
|
2443
|
+
\`\`\`text
|
|
2444
|
+
[작업 완료 감지]
|
|
2445
|
+
↓
|
|
2446
|
+
semo-system/ 또는 packages/ 파일 수정 여부 확인
|
|
2447
|
+
↓
|
|
2448
|
+
수정됨? → [SEMO] Skill 호출: meta-workflow
|
|
2449
|
+
버저닝 → 배포 → 동기화 자동 실행
|
|
2450
|
+
↓
|
|
2451
|
+
수정 안됨? → 정상 종료
|
|
2452
|
+
\`\`\`
|
|
2453
|
+
|
|
2454
|
+
**금지 사항**:
|
|
2455
|
+
- semo-system/ 수정 후 버저닝 없이 종료
|
|
2456
|
+
- "버저닝 나중에 해줘" 요청 수락
|
|
2457
|
+
- meta-workflow 스킬 호출 건너뛰기
|
|
2458
|
+
` : "";
|
|
2396
2459
|
const claudeMdContent = `# SEMO Project Configuration
|
|
2397
2460
|
|
|
2398
2461
|
> SEMO (Semicolon Orchestrate) - AI Agent Orchestration Framework v${VERSION}
|
|
@@ -2446,7 +2509,7 @@ npm run build # 3. 빌드 검증 (Next.js/TypeScript 프로젝트)
|
|
|
2446
2509
|
- \`--no-verify\` 플래그 사용 금지
|
|
2447
2510
|
- Quality Gate 우회 시도 거부
|
|
2448
2511
|
- "그냥 커밋해줘", "빌드 생략해줘" 등 거부
|
|
2449
|
-
|
|
2512
|
+
${metaWorkflowSection}
|
|
2450
2513
|
---
|
|
2451
2514
|
|
|
2452
2515
|
## 설치된 구성
|
|
@@ -3037,8 +3100,87 @@ program
|
|
|
3037
3100
|
else {
|
|
3038
3101
|
console.log(chalk_1.default.red(" ❌ .claude/ 디렉토리 없음"));
|
|
3039
3102
|
}
|
|
3040
|
-
// 4.
|
|
3041
|
-
console.log(chalk_1.default.cyan("\n4.
|
|
3103
|
+
// 4. semo-hooks 상태 확인
|
|
3104
|
+
console.log(chalk_1.default.cyan("\n4. semo-hooks (Claude Code Hooks)"));
|
|
3105
|
+
const hooksDir = path.join(semoSystemDir, "semo-hooks");
|
|
3106
|
+
const hooksDistDir = path.join(hooksDir, "dist");
|
|
3107
|
+
const hooksIndexJs = path.join(hooksDistDir, "index.js");
|
|
3108
|
+
if (!fs.existsSync(hooksDir)) {
|
|
3109
|
+
console.log(chalk_1.default.gray(" ⏭️ semo-hooks 미설치 (선택 패키지)"));
|
|
3110
|
+
console.log(chalk_1.default.gray(" 💡 설치: semo add hooks"));
|
|
3111
|
+
}
|
|
3112
|
+
else {
|
|
3113
|
+
// hooks 버전 확인
|
|
3114
|
+
const hooksVersionPath = path.join(hooksDir, "VERSION");
|
|
3115
|
+
const hooksVersion = fs.existsSync(hooksVersionPath)
|
|
3116
|
+
? fs.readFileSync(hooksVersionPath, "utf-8").trim()
|
|
3117
|
+
: "?";
|
|
3118
|
+
console.log(chalk_1.default.green(` ✅ semo-hooks v${hooksVersion} 설치됨`));
|
|
3119
|
+
// 빌드 상태 확인
|
|
3120
|
+
if (!fs.existsSync(hooksDistDir) || !fs.existsSync(hooksIndexJs)) {
|
|
3121
|
+
console.log(chalk_1.default.red(" ❌ 빌드되지 않음 (dist/index.js 없음)"));
|
|
3122
|
+
console.log(chalk_1.default.gray(" 💡 해결: semo hooks enable"));
|
|
3123
|
+
}
|
|
3124
|
+
else {
|
|
3125
|
+
console.log(chalk_1.default.green(" ✅ 빌드 완료 (dist/index.js 존재)"));
|
|
3126
|
+
}
|
|
3127
|
+
// settings.local.json hooks 설정 확인
|
|
3128
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
3129
|
+
const settingsPath = path.join(homeDir, ".claude", "settings.local.json");
|
|
3130
|
+
if (!fs.existsSync(settingsPath)) {
|
|
3131
|
+
console.log(chalk_1.default.yellow(" ⚠️ settings.local.json 없음"));
|
|
3132
|
+
console.log(chalk_1.default.gray(" 💡 해결: semo hooks enable"));
|
|
3133
|
+
}
|
|
3134
|
+
else {
|
|
3135
|
+
try {
|
|
3136
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
|
|
3137
|
+
const hooksConfig = settings.hooks;
|
|
3138
|
+
if (!hooksConfig) {
|
|
3139
|
+
console.log(chalk_1.default.yellow(" ⚠️ hooks 설정 없음"));
|
|
3140
|
+
console.log(chalk_1.default.gray(" 💡 해결: semo hooks enable"));
|
|
3141
|
+
}
|
|
3142
|
+
else {
|
|
3143
|
+
const requiredHooks = ["SessionStart", "UserPromptSubmit", "Stop", "SessionEnd"];
|
|
3144
|
+
const missingHooks = [];
|
|
3145
|
+
const invalidPathHooks = [];
|
|
3146
|
+
for (const hookName of requiredHooks) {
|
|
3147
|
+
const hookArray = hooksConfig[hookName];
|
|
3148
|
+
if (!hookArray || !Array.isArray(hookArray) || hookArray.length === 0) {
|
|
3149
|
+
missingHooks.push(hookName);
|
|
3150
|
+
}
|
|
3151
|
+
else {
|
|
3152
|
+
// 경로 검증
|
|
3153
|
+
const hookEntry = hookArray[0];
|
|
3154
|
+
const innerHooks = hookEntry?.hooks;
|
|
3155
|
+
if (innerHooks && Array.isArray(innerHooks) && innerHooks.length > 0) {
|
|
3156
|
+
const command = innerHooks[0]?.command || "";
|
|
3157
|
+
// 현재 프로젝트의 semo-hooks 경로와 비교
|
|
3158
|
+
if (!command.includes(hooksDir) && !command.includes("semo-hooks")) {
|
|
3159
|
+
invalidPathHooks.push(hookName);
|
|
3160
|
+
}
|
|
3161
|
+
}
|
|
3162
|
+
}
|
|
3163
|
+
}
|
|
3164
|
+
if (missingHooks.length > 0) {
|
|
3165
|
+
console.log(chalk_1.default.yellow(` ⚠️ 누락된 hooks: ${missingHooks.join(", ")}`));
|
|
3166
|
+
console.log(chalk_1.default.gray(" 💡 해결: semo hooks enable"));
|
|
3167
|
+
}
|
|
3168
|
+
else if (invalidPathHooks.length > 0) {
|
|
3169
|
+
console.log(chalk_1.default.yellow(` ⚠️ 경로 불일치: ${invalidPathHooks.join(", ")}`));
|
|
3170
|
+
console.log(chalk_1.default.gray(" 💡 해결: semo hooks enable (다른 프로젝트 설정 감지)"));
|
|
3171
|
+
}
|
|
3172
|
+
else {
|
|
3173
|
+
console.log(chalk_1.default.green(" ✅ hooks 설정 완료 (4개 hook 등록됨)"));
|
|
3174
|
+
}
|
|
3175
|
+
}
|
|
3176
|
+
}
|
|
3177
|
+
catch {
|
|
3178
|
+
console.log(chalk_1.default.red(" ❌ settings.local.json 파싱 오류"));
|
|
3179
|
+
}
|
|
3180
|
+
}
|
|
3181
|
+
}
|
|
3182
|
+
// 5. 전체 설치 검증
|
|
3183
|
+
console.log(chalk_1.default.cyan("\n5. 전체 설치 검증"));
|
|
3042
3184
|
const verificationResult = verifyInstallation(cwd, []);
|
|
3043
3185
|
if (verificationResult.success) {
|
|
3044
3186
|
console.log(chalk_1.default.green(" ✅ 설치 상태 정상"));
|