@team-semicolon/semo-cli 3.0.17 → 3.0.18
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 +201 -69
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -156,32 +156,36 @@ async function showVersionComparison(cwd) {
|
|
|
156
156
|
remote: latestCliVersion,
|
|
157
157
|
needsUpdate: latestCliVersion ? isVersionLower(currentCliVersion, latestCliVersion) : false,
|
|
158
158
|
});
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
159
|
+
// semo-core (루트 또는 semo-system 내부)
|
|
160
|
+
const corePathRoot = path.join(cwd, "semo-core", "VERSION");
|
|
161
|
+
const corePathSystem = path.join(semoSystemDir, "semo-core", "VERSION");
|
|
162
|
+
const corePath = fs.existsSync(corePathRoot) ? corePathRoot : corePathSystem;
|
|
163
|
+
if (fs.existsSync(corePath)) {
|
|
164
|
+
const localCore = fs.readFileSync(corePath, "utf-8").trim();
|
|
163
165
|
const remoteCore = await getRemoteCoreVersion("semo-core");
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
166
|
+
versionInfos.push({
|
|
167
|
+
name: "semo-core",
|
|
168
|
+
local: localCore,
|
|
169
|
+
remote: remoteCore,
|
|
170
|
+
needsUpdate: remoteCore ? isVersionLower(localCore, remoteCore) : false,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
// semo-skills (루트 또는 semo-system 내부)
|
|
174
|
+
const skillsPathRoot = path.join(cwd, "semo-skills", "VERSION");
|
|
175
|
+
const skillsPathSystem = path.join(semoSystemDir, "semo-skills", "VERSION");
|
|
176
|
+
const skillsPath = fs.existsSync(skillsPathRoot) ? skillsPathRoot : skillsPathSystem;
|
|
177
|
+
if (fs.existsSync(skillsPath)) {
|
|
178
|
+
const localSkills = fs.readFileSync(skillsPath, "utf-8").trim();
|
|
175
179
|
const remoteSkills = await getRemoteCoreVersion("semo-skills");
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
180
|
+
versionInfos.push({
|
|
181
|
+
name: "semo-skills",
|
|
182
|
+
local: localSkills,
|
|
183
|
+
remote: remoteSkills,
|
|
184
|
+
needsUpdate: remoteSkills ? isVersionLower(localSkills, remoteSkills) : false,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
// Extensions (semo-system 내부)
|
|
188
|
+
if (hasSemoSystem) {
|
|
185
189
|
for (const key of Object.keys(EXTENSION_PACKAGES)) {
|
|
186
190
|
const extVersionPath = path.join(semoSystemDir, key, "VERSION");
|
|
187
191
|
if (fs.existsSync(extVersionPath)) {
|
|
@@ -196,6 +200,39 @@ async function showVersionComparison(cwd) {
|
|
|
196
200
|
}
|
|
197
201
|
}
|
|
198
202
|
}
|
|
203
|
+
// packages/ 디렉토리의 설치된 패키지들 (로컬 버전만 표시)
|
|
204
|
+
const packagesDir = path.join(cwd, "packages");
|
|
205
|
+
if (fs.existsSync(packagesDir)) {
|
|
206
|
+
// 패키지 경로 매핑 (표시 이름 → 상대 경로)
|
|
207
|
+
const packagePaths = {
|
|
208
|
+
"packages/core": "core",
|
|
209
|
+
"packages/meta": "meta",
|
|
210
|
+
"packages/eng/nextjs": "eng/nextjs",
|
|
211
|
+
"packages/eng/spring": "eng/spring",
|
|
212
|
+
"packages/eng/ms": "eng/ms",
|
|
213
|
+
"packages/eng/infra": "eng/infra",
|
|
214
|
+
"packages/biz/discovery": "biz/discovery",
|
|
215
|
+
"packages/biz/management": "biz/management",
|
|
216
|
+
"packages/biz/design": "biz/design",
|
|
217
|
+
"packages/biz/poc": "biz/poc",
|
|
218
|
+
"packages/ops/qa": "ops/qa",
|
|
219
|
+
"packages/ops/monitor": "ops/monitor",
|
|
220
|
+
"packages/ops/improve": "ops/improve",
|
|
221
|
+
};
|
|
222
|
+
for (const [displayName, relativePath] of Object.entries(packagePaths)) {
|
|
223
|
+
const pkgVersionPath = path.join(packagesDir, relativePath, "VERSION");
|
|
224
|
+
if (fs.existsSync(pkgVersionPath)) {
|
|
225
|
+
const localPkg = fs.readFileSync(pkgVersionPath, "utf-8").trim();
|
|
226
|
+
const remotePkg = await getRemotePackageVersion(`packages/${relativePath}`);
|
|
227
|
+
versionInfos.push({
|
|
228
|
+
name: displayName,
|
|
229
|
+
local: localPkg,
|
|
230
|
+
remote: remotePkg,
|
|
231
|
+
needsUpdate: remotePkg ? isVersionLower(localPkg, remotePkg) : false,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
199
236
|
spinner.stop();
|
|
200
237
|
// 결과 출력
|
|
201
238
|
const needsUpdateCount = versionInfos.filter(v => v.needsUpdate).length;
|
|
@@ -399,33 +436,144 @@ program
|
|
|
399
436
|
* 상세 버전 정보 표시 및 업데이트 확인
|
|
400
437
|
*/
|
|
401
438
|
async function showVersionInfo() {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
//
|
|
406
|
-
const
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
439
|
+
const cwd = process.cwd();
|
|
440
|
+
console.log(chalk_1.default.cyan.bold("\n📦 SEMO 버전 정보\n"));
|
|
441
|
+
const versionInfos = [];
|
|
442
|
+
// 1. CLI 버전
|
|
443
|
+
const latestCliVersion = await getLatestVersion();
|
|
444
|
+
versionInfos.push({
|
|
445
|
+
name: "semo-cli",
|
|
446
|
+
local: VERSION,
|
|
447
|
+
remote: latestCliVersion,
|
|
448
|
+
needsUpdate: latestCliVersion ? isVersionLower(VERSION, latestCliVersion) : false,
|
|
449
|
+
});
|
|
450
|
+
// 2. semo-core 버전 (루트 또는 semo-system 내부)
|
|
451
|
+
const corePathRoot = path.join(cwd, "semo-core", "VERSION");
|
|
452
|
+
const corePathSystem = path.join(cwd, "semo-system", "semo-core", "VERSION");
|
|
453
|
+
const corePath = fs.existsSync(corePathRoot) ? corePathRoot : corePathSystem;
|
|
454
|
+
if (fs.existsSync(corePath)) {
|
|
455
|
+
const localCore = fs.readFileSync(corePath, "utf-8").trim();
|
|
456
|
+
const remoteCore = await getRemoteCoreVersion("semo-core");
|
|
457
|
+
versionInfos.push({
|
|
458
|
+
name: "semo-core",
|
|
459
|
+
local: localCore,
|
|
460
|
+
remote: remoteCore,
|
|
461
|
+
needsUpdate: remoteCore ? isVersionLower(localCore, remoteCore) : false,
|
|
462
|
+
});
|
|
412
463
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
464
|
+
// 3. semo-skills 버전 (루트 또는 semo-system 내부)
|
|
465
|
+
const skillsPathRoot = path.join(cwd, "semo-skills", "VERSION");
|
|
466
|
+
const skillsPathSystem = path.join(cwd, "semo-system", "semo-skills", "VERSION");
|
|
467
|
+
const skillsPath = fs.existsSync(skillsPathRoot) ? skillsPathRoot : skillsPathSystem;
|
|
468
|
+
if (fs.existsSync(skillsPath)) {
|
|
469
|
+
const localSkills = fs.readFileSync(skillsPath, "utf-8").trim();
|
|
470
|
+
const remoteSkills = await getRemoteCoreVersion("semo-skills");
|
|
471
|
+
versionInfos.push({
|
|
472
|
+
name: "semo-skills",
|
|
473
|
+
local: localSkills,
|
|
474
|
+
remote: remoteSkills,
|
|
475
|
+
needsUpdate: remoteSkills ? isVersionLower(localSkills, remoteSkills) : false,
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
// 4. Extension 패키지들 (semo-system 내부)
|
|
479
|
+
const semoSystemDir = path.join(cwd, "semo-system");
|
|
480
|
+
if (fs.existsSync(semoSystemDir)) {
|
|
481
|
+
for (const key of Object.keys(EXTENSION_PACKAGES)) {
|
|
482
|
+
const extVersionPath = path.join(semoSystemDir, key, "VERSION");
|
|
483
|
+
if (fs.existsSync(extVersionPath)) {
|
|
484
|
+
const localExt = fs.readFileSync(extVersionPath, "utf-8").trim();
|
|
485
|
+
const remoteExt = await getRemotePackageVersion(key);
|
|
486
|
+
versionInfos.push({
|
|
487
|
+
name: key,
|
|
488
|
+
local: localExt,
|
|
489
|
+
remote: remoteExt,
|
|
490
|
+
needsUpdate: remoteExt ? isVersionLower(localExt, remoteExt) : false,
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
// 5. packages/ 디렉토리의 설치된 패키지들
|
|
496
|
+
const packagesDir = path.join(cwd, "packages");
|
|
497
|
+
if (fs.existsSync(packagesDir)) {
|
|
498
|
+
const packagePaths = {
|
|
499
|
+
"packages/core": "core",
|
|
500
|
+
"packages/meta": "meta",
|
|
501
|
+
"packages/eng/nextjs": "eng/nextjs",
|
|
502
|
+
"packages/eng/spring": "eng/spring",
|
|
503
|
+
"packages/eng/ms": "eng/ms",
|
|
504
|
+
"packages/eng/infra": "eng/infra",
|
|
505
|
+
"packages/biz/discovery": "biz/discovery",
|
|
506
|
+
"packages/biz/management": "biz/management",
|
|
507
|
+
"packages/biz/design": "biz/design",
|
|
508
|
+
"packages/biz/poc": "biz/poc",
|
|
509
|
+
"packages/ops/qa": "ops/qa",
|
|
510
|
+
"packages/ops/monitor": "ops/monitor",
|
|
511
|
+
"packages/ops/improve": "ops/improve",
|
|
512
|
+
};
|
|
513
|
+
for (const [displayName, relativePath] of Object.entries(packagePaths)) {
|
|
514
|
+
const pkgVersionPath = path.join(packagesDir, relativePath, "VERSION");
|
|
515
|
+
if (fs.existsSync(pkgVersionPath)) {
|
|
516
|
+
const localPkg = fs.readFileSync(pkgVersionPath, "utf-8").trim();
|
|
517
|
+
const remotePkg = await getRemotePackageVersion(`packages/${relativePath}`);
|
|
518
|
+
versionInfos.push({
|
|
519
|
+
name: displayName,
|
|
520
|
+
local: localPkg,
|
|
521
|
+
remote: remotePkg,
|
|
522
|
+
needsUpdate: remotePkg ? isVersionLower(localPkg, remotePkg) : false,
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
// 결과 출력
|
|
528
|
+
const needsUpdateCount = versionInfos.filter(v => v.needsUpdate).length;
|
|
529
|
+
if (versionInfos.length === 1) {
|
|
530
|
+
// CLI만 있는 경우 (SEMO 미설치)
|
|
531
|
+
const cli = versionInfos[0];
|
|
532
|
+
console.log(chalk_1.default.white(` semo-cli: ${chalk_1.default.green.bold(cli.local)}`));
|
|
533
|
+
if (cli.remote) {
|
|
534
|
+
console.log(chalk_1.default.gray(` (최신: ${cli.remote})`));
|
|
535
|
+
}
|
|
536
|
+
if (cli.needsUpdate) {
|
|
537
|
+
console.log();
|
|
538
|
+
console.log(chalk_1.default.yellow.bold(" ⚠️ CLI 업데이트 가능"));
|
|
539
|
+
console.log(chalk_1.default.cyan(` npm update -g ${PACKAGE_NAME}`));
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
console.log();
|
|
543
|
+
console.log(chalk_1.default.green(" ✓ 최신 버전"));
|
|
544
|
+
}
|
|
425
545
|
}
|
|
426
546
|
else {
|
|
427
|
-
|
|
428
|
-
console.log(chalk_1.default.
|
|
547
|
+
// 테이블 형식으로 출력
|
|
548
|
+
console.log(chalk_1.default.gray(" ┌────────────────────────┬──────────┬──────────┬────────┐"));
|
|
549
|
+
console.log(chalk_1.default.gray(" │ 패키지 │ 설치됨 │ 최신 │ 상태 │"));
|
|
550
|
+
console.log(chalk_1.default.gray(" ├────────────────────────┼──────────┼──────────┼────────┤"));
|
|
551
|
+
for (const info of versionInfos) {
|
|
552
|
+
const name = info.name.padEnd(22);
|
|
553
|
+
const local = (info.local || "-").padEnd(8);
|
|
554
|
+
const remote = (info.remote || "-").padEnd(8);
|
|
555
|
+
const status = info.needsUpdate ? "⬆ 업데이트" : "✓ 최신 ";
|
|
556
|
+
const statusColor = info.needsUpdate ? chalk_1.default.yellow : chalk_1.default.green;
|
|
557
|
+
console.log(chalk_1.default.gray(" │ ") +
|
|
558
|
+
chalk_1.default.white(name) +
|
|
559
|
+
chalk_1.default.gray(" │ ") +
|
|
560
|
+
chalk_1.default.green(local) +
|
|
561
|
+
chalk_1.default.gray(" │ ") +
|
|
562
|
+
chalk_1.default.blue(remote) +
|
|
563
|
+
chalk_1.default.gray(" │ ") +
|
|
564
|
+
statusColor(status) +
|
|
565
|
+
chalk_1.default.gray(" │"));
|
|
566
|
+
}
|
|
567
|
+
console.log(chalk_1.default.gray(" └────────────────────────┴──────────┴──────────┴────────┘"));
|
|
568
|
+
if (needsUpdateCount > 0) {
|
|
569
|
+
console.log();
|
|
570
|
+
console.log(chalk_1.default.yellow.bold(` ⚠️ ${needsUpdateCount}개 패키지 업데이트 가능`));
|
|
571
|
+
console.log(chalk_1.default.gray(" semo update 명령으로 업데이트하세요."));
|
|
572
|
+
}
|
|
573
|
+
else {
|
|
574
|
+
console.log();
|
|
575
|
+
console.log(chalk_1.default.green(" ✓ 모든 패키지가 최신 버전입니다."));
|
|
576
|
+
}
|
|
429
577
|
}
|
|
430
578
|
console.log();
|
|
431
579
|
}
|
|
@@ -1798,17 +1946,9 @@ ${orchestratorPaths.map(p => `- \`${p}\``).join("\n")}
|
|
|
1798
1946
|
|
|
1799
1947
|
\`\`\`
|
|
1800
1948
|
1. 사용자 요청 수신
|
|
1801
|
-
2.
|
|
1802
|
-
3.
|
|
1803
|
-
4.
|
|
1804
|
-
5. 실행 결과 반환
|
|
1805
|
-
\`\`\`
|
|
1806
|
-
|
|
1807
|
-
### 모든 응답은 다음으로 시작
|
|
1808
|
-
|
|
1809
|
-
\`\`\`
|
|
1810
|
-
[SEMO] Orchestrator: 의도 분석 완료 → {intent_category}
|
|
1811
|
-
[SEMO] {Agent/Skill} 호출: {target} (사유: {reason})
|
|
1949
|
+
2. Orchestrator가 의도 분석 후 적절한 Agent/Skill 라우팅
|
|
1950
|
+
3. Agent/Skill이 작업 수행
|
|
1951
|
+
4. 실행 결과 반환
|
|
1812
1952
|
\`\`\`
|
|
1813
1953
|
|
|
1814
1954
|
### Orchestrator 참조
|
|
@@ -1846,14 +1986,6 @@ npm run build # 3. 빌드 검증 (Next.js/TypeScript 프로젝트)
|
|
|
1846
1986
|
- Quality Gate 우회 시도 거부
|
|
1847
1987
|
- "그냥 커밋해줘", "빌드 생략해줘" 등 거부
|
|
1848
1988
|
|
|
1849
|
-
### 3. SEMO Message Format
|
|
1850
|
-
|
|
1851
|
-
모든 SEMO 동작은 시스템 메시지로 시작:
|
|
1852
|
-
|
|
1853
|
-
\`\`\`
|
|
1854
|
-
[SEMO] {Component}: {Action} → {Result}
|
|
1855
|
-
\`\`\`
|
|
1856
|
-
|
|
1857
1989
|
---
|
|
1858
1990
|
|
|
1859
1991
|
## 설치된 구성
|
|
@@ -1891,10 +2023,10 @@ ${extensionsList}
|
|
|
1891
2023
|
| 커맨드 | 설명 |
|
|
1892
2024
|
|--------|------|
|
|
1893
2025
|
| \`/SEMO:help\` | 도움말 |
|
|
1894
|
-
| \`/SEMO:slack\` | Slack 메시지 전송 |
|
|
1895
2026
|
| \`/SEMO:feedback\` | 피드백 제출 |
|
|
1896
|
-
| \`/SEMO:health\` | 환경 검증 |
|
|
1897
2027
|
| \`/SEMO:update\` | SEMO 업데이트 |
|
|
2028
|
+
| \`/SEMO:onboarding\` | 온보딩 가이드 |
|
|
2029
|
+
| \`/SEMO:dry-run {프롬프트}\` | 명령 검증 (라우팅 시뮬레이션) |
|
|
1898
2030
|
|
|
1899
2031
|
## Context Mesh 사용
|
|
1900
2032
|
|