@team-semicolon/semo-cli 3.0.17 → 3.0.19

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 (2) hide show
  1. package/dist/index.js +212 -69
  2. 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
- if (hasSemoSystem) {
160
- // semo-core semo-system 바깥에 있음
161
- const corePath = path.join(cwd, "semo-core", "VERSION");
162
- const localCore = fs.existsSync(corePath) ? fs.readFileSync(corePath, "utf-8").trim() : null;
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
- if (localCore) {
165
- versionInfos.push({
166
- name: "semo-core",
167
- local: localCore,
168
- remote: remoteCore,
169
- needsUpdate: remoteCore ? isVersionLower(localCore, remoteCore) : false,
170
- });
171
- }
172
- // semo-skills
173
- const skillsPath = path.join(cwd, "semo-skills", "VERSION");
174
- const localSkills = fs.existsSync(skillsPath) ? fs.readFileSync(skillsPath, "utf-8").trim() : null;
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
- if (localSkills) {
177
- versionInfos.push({
178
- name: "semo-skills",
179
- local: localSkills,
180
- remote: remoteSkills,
181
- needsUpdate: remoteSkills ? isVersionLower(localSkills, remoteSkills) : false,
182
- });
183
- }
184
- // Extensions (semo-system 내부)
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,155 @@ program
399
436
  * 상세 버전 정보 표시 및 업데이트 확인
400
437
  */
401
438
  async function showVersionInfo() {
402
- console.log(chalk_1.default.cyan.bold("\n📦 SEMO CLI 버전 정보\n"));
403
- // 현재 버전 표시
404
- console.log(chalk_1.default.white(` 현재 버전: ${chalk_1.default.green.bold(VERSION)}`));
405
- // 최신 버전 확인
406
- const spinner = (0, ora_1.default)(" 최신 버전 확인 중...").start();
407
- const latestVersion = await getLatestVersion();
408
- if (latestVersion === null) {
409
- spinner.warn(" 최신 버전 확인 실패 (네트워크 오류)");
410
- console.log(chalk_1.default.gray(" npm registry에 접속할 수 없습니다.\n"));
411
- return;
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
- spinner.stop();
414
- console.log(chalk_1.default.white(` 최신 버전: ${chalk_1.default.blue.bold(latestVersion)}`));
415
- // 버전 비교 업데이트 권유
416
- if (isVersionLower(VERSION, latestVersion)) {
417
- console.log();
418
- console.log(chalk_1.default.yellow.bold(" ⚠️ 새로운 버전이 있습니다!"));
419
- console.log();
420
- console.log(chalk_1.default.white(" 업데이트 방법:"));
421
- console.log(chalk_1.default.cyan(` npm update -g ${PACKAGE_NAME}`));
422
- console.log();
423
- console.log(chalk_1.default.gray(" 또는 프로젝트 내 SEMO 업데이트:"));
424
- console.log(chalk_1.default.gray(" semo update"));
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
- console.log();
428
- console.log(chalk_1.default.green(" ✓ 최신 버전을 사용 중입니다."));
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
+ // CLI와 다른 패키지 업데이트 가이드 분리
569
+ const cliNeedsUpdate = versionInfos[0]?.needsUpdate;
570
+ const otherNeedsUpdateCount = versionInfos.slice(1).filter((v) => v.needsUpdate).length;
571
+ if (cliNeedsUpdate || otherNeedsUpdateCount > 0) {
572
+ console.log();
573
+ if (cliNeedsUpdate) {
574
+ console.log(chalk_1.default.yellow.bold(" ⚠️ CLI 업데이트 가능"));
575
+ console.log(chalk_1.default.cyan(` npm update -g ${PACKAGE_NAME}`));
576
+ }
577
+ if (otherNeedsUpdateCount > 0) {
578
+ if (cliNeedsUpdate)
579
+ console.log();
580
+ console.log(chalk_1.default.yellow.bold(` ⚠️ ${otherNeedsUpdateCount}개 패키지 업데이트 가능`));
581
+ console.log(chalk_1.default.gray(" semo update 명령으로 업데이트하세요."));
582
+ }
583
+ }
584
+ else {
585
+ console.log();
586
+ console.log(chalk_1.default.green(" ✓ 모든 패키지가 최신 버전입니다."));
587
+ }
429
588
  }
430
589
  console.log();
431
590
  }
@@ -1798,17 +1957,9 @@ ${orchestratorPaths.map(p => `- \`${p}\``).join("\n")}
1798
1957
 
1799
1958
  \`\`\`
1800
1959
  1. 사용자 요청 수신
1801
- 2. [SEMO] Orchestrator 메시지 출력 (의도 분석)
1802
- 3. Orchestrator가 적절한 Agent/Skill 라우팅
1803
- 4. [SEMO] Agent/Skill 메시지 출력
1804
- 5. 실행 결과 반환
1805
- \`\`\`
1806
-
1807
- ### 모든 응답은 다음으로 시작
1808
-
1809
- \`\`\`
1810
- [SEMO] Orchestrator: 의도 분석 완료 → {intent_category}
1811
- [SEMO] {Agent/Skill} 호출: {target} (사유: {reason})
1960
+ 2. Orchestrator 의도 분석 적절한 Agent/Skill 라우팅
1961
+ 3. Agent/Skill 작업 수행
1962
+ 4. 실행 결과 반환
1812
1963
  \`\`\`
1813
1964
 
1814
1965
  ### Orchestrator 참조
@@ -1846,14 +1997,6 @@ npm run build # 3. 빌드 검증 (Next.js/TypeScript 프로젝트)
1846
1997
  - Quality Gate 우회 시도 거부
1847
1998
  - "그냥 커밋해줘", "빌드 생략해줘" 등 거부
1848
1999
 
1849
- ### 3. SEMO Message Format
1850
-
1851
- 모든 SEMO 동작은 시스템 메시지로 시작:
1852
-
1853
- \`\`\`
1854
- [SEMO] {Component}: {Action} → {Result}
1855
- \`\`\`
1856
-
1857
2000
  ---
1858
2001
 
1859
2002
  ## 설치된 구성
@@ -1891,10 +2034,10 @@ ${extensionsList}
1891
2034
  | 커맨드 | 설명 |
1892
2035
  |--------|------|
1893
2036
  | \`/SEMO:help\` | 도움말 |
1894
- | \`/SEMO:slack\` | Slack 메시지 전송 |
1895
2037
  | \`/SEMO:feedback\` | 피드백 제출 |
1896
- | \`/SEMO:health\` | 환경 검증 |
1897
2038
  | \`/SEMO:update\` | SEMO 업데이트 |
2039
+ | \`/SEMO:onboarding\` | 온보딩 가이드 |
2040
+ | \`/SEMO:dry-run {프롬프트}\` | 명령 검증 (라우팅 시뮬레이션) |
1898
2041
 
1899
2042
  ## Context Mesh 사용
1900
2043
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@team-semicolon/semo-cli",
3
- "version": "3.0.17",
3
+ "version": "3.0.19",
4
4
  "description": "SEMO CLI - AI Agent Orchestration Framework Installer",
5
5
  "main": "dist/index.js",
6
6
  "bin": {