@team-semicolon/semo-cli 3.0.0 โ†’ 3.0.2

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 +46 -9
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -408,6 +408,11 @@ async function setupExtensionSymlinks(cwd, packages) {
408
408
  console.log(chalk_1.default.cyan("\n๐Ÿ”— Extensions ์—ฐ๊ฒฐ"));
409
409
  const claudeDir = path.join(cwd, ".claude");
410
410
  const semoSystemDir = path.join(cwd, "semo-system");
411
+ // .claude/agents, .claude/skills ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ (์—†์œผ๋ฉด)
412
+ const claudeAgentsDir = path.join(claudeDir, "agents");
413
+ const claudeSkillsDir = path.join(claudeDir, "skills");
414
+ fs.mkdirSync(claudeAgentsDir, { recursive: true });
415
+ fs.mkdirSync(claudeSkillsDir, { recursive: true });
411
416
  for (const pkg of packages) {
412
417
  const pkgPath = path.join(semoSystemDir, pkg);
413
418
  if (!fs.existsSync(pkgPath))
@@ -416,7 +421,6 @@ async function setupExtensionSymlinks(cwd, packages) {
416
421
  // Extension์˜ agents/skills๋งŒ ๊ฐœ๋ณ„ ๋งํฌํ•˜์—ฌ ๋ณ‘ํ•ฉ
417
422
  // 1. Extension์˜ agents๋ฅผ .claude/agents/์— ๊ฐœ๋ณ„ ๋งํฌ
418
423
  const extAgentsDir = path.join(pkgPath, "agents");
419
- const claudeAgentsDir = path.join(claudeDir, "agents");
420
424
  if (fs.existsSync(extAgentsDir)) {
421
425
  const agents = fs.readdirSync(extAgentsDir).filter(f => fs.statSync(path.join(extAgentsDir, f)).isDirectory());
422
426
  for (const agent of agents) {
@@ -428,9 +432,8 @@ async function setupExtensionSymlinks(cwd, packages) {
428
432
  }
429
433
  }
430
434
  }
431
- // 3. Extension์˜ skills๋ฅผ .claude/skills/์— ๊ฐœ๋ณ„ ๋งํฌ
435
+ // 2. Extension์˜ skills๋ฅผ .claude/skills/์— ๊ฐœ๋ณ„ ๋งํฌ
432
436
  const extSkillsDir = path.join(pkgPath, "skills");
433
- const claudeSkillsDir = path.join(claudeDir, "skills");
434
437
  if (fs.existsSync(extSkillsDir)) {
435
438
  const skills = fs.readdirSync(extSkillsDir).filter(f => fs.statSync(path.join(extSkillsDir, f)).isDirectory());
436
439
  for (const skill of skills) {
@@ -467,9 +470,23 @@ const BASE_MCP_SERVERS = [
467
470
  args: ["-y", "@modelcontextprotocol/server-sequential-thinking"],
468
471
  },
469
472
  ];
473
+ // === Claude MCP ์„œ๋ฒ„ ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ ===
474
+ function isMCPServerRegistered(serverName) {
475
+ try {
476
+ const result = (0, child_process_1.execSync)("claude mcp list", { stdio: "pipe", encoding: "utf-8" });
477
+ return result.includes(serverName);
478
+ }
479
+ catch {
480
+ return false;
481
+ }
482
+ }
470
483
  // === Claude MCP ๋“ฑ๋ก ํ•จ์ˆ˜ ===
471
484
  function registerMCPServer(server) {
472
485
  try {
486
+ // ์ด๋ฏธ ๋“ฑ๋ก๋œ ์„œ๋ฒ„์ธ์ง€ ํ™•์ธ
487
+ if (isMCPServerRegistered(server.name)) {
488
+ return { success: true, skipped: true };
489
+ }
473
490
  // claude mcp add ๋ช…๋ น์–ด ๊ตฌ์„ฑ
474
491
  // ํ˜•์‹: claude mcp add <name> [-e KEY=value...] -- <command> [args...]
475
492
  const args = ["mcp", "add", server.name];
@@ -567,13 +584,20 @@ async function setupMCP(cwd, extensions, force) {
567
584
  // Claude Code์— MCP ์„œ๋ฒ„ ๋“ฑ๋ก ์‹œ๋„
568
585
  console.log(chalk_1.default.cyan("\n๐Ÿ”Œ Claude Code์— MCP ์„œ๋ฒ„ ๋“ฑ๋ก ์ค‘..."));
569
586
  const successServers = [];
587
+ const skippedServers = [];
570
588
  const failedServers = [];
571
589
  for (const server of allServers) {
572
590
  const spinner = (0, ora_1.default)(` ${server.name} ๋“ฑ๋ก ์ค‘...`).start();
573
591
  const result = registerMCPServer(server);
574
592
  if (result.success) {
575
- spinner.succeed(` ${server.name} ๋“ฑ๋ก ์™„๋ฃŒ`);
576
- successServers.push(server.name);
593
+ if (result.skipped) {
594
+ spinner.info(` ${server.name} ์ด๋ฏธ ๋“ฑ๋ก๋จ (๊ฑด๋„ˆ๋œ€)`);
595
+ skippedServers.push(server.name);
596
+ }
597
+ else {
598
+ spinner.succeed(` ${server.name} ๋“ฑ๋ก ์™„๋ฃŒ`);
599
+ successServers.push(server.name);
600
+ }
577
601
  }
578
602
  else {
579
603
  spinner.fail(` ${server.name} ๋“ฑ๋ก ์‹คํŒจ`);
@@ -582,7 +606,10 @@ async function setupMCP(cwd, extensions, force) {
582
606
  }
583
607
  // ๊ฒฐ๊ณผ ์š”์•ฝ
584
608
  if (successServers.length > 0) {
585
- console.log(chalk_1.default.green(`\nโœ“ ${successServers.length}๊ฐœ MCP ์„œ๋ฒ„ ์ž๋™ ๋“ฑ๋ก ์™„๋ฃŒ`));
609
+ console.log(chalk_1.default.green(`\nโœ“ ${successServers.length}๊ฐœ MCP ์„œ๋ฒ„ ์ƒˆ๋กœ ๋“ฑ๋ก ์™„๋ฃŒ`));
610
+ }
611
+ if (skippedServers.length > 0) {
612
+ console.log(chalk_1.default.gray(` (${skippedServers.length}๊ฐœ ์ด๋ฏธ ๋“ฑ๋ก๋จ)`));
586
613
  }
587
614
  // ์‹คํŒจํ•œ ์„œ๋ฒ„๊ฐ€ ์žˆ์œผ๋ฉด ์ˆ˜๋™ ๋“ฑ๋ก ์•ˆ๋‚ด
588
615
  if (failedServers.length > 0) {
@@ -657,13 +684,20 @@ async function mergeExtensionSettings(cwd, packages) {
657
684
  if (newServers.length > 0) {
658
685
  console.log(chalk_1.default.cyan("\n๐Ÿ”Œ Claude Code์— MCP ์„œ๋ฒ„ ๋“ฑ๋ก ์ค‘..."));
659
686
  const successServers = [];
687
+ const skippedServers = [];
660
688
  const failedServers = [];
661
689
  for (const server of newServers) {
662
690
  const spinner = (0, ora_1.default)(` ${server.name} ๋“ฑ๋ก ์ค‘...`).start();
663
691
  const result = registerMCPServer(server);
664
692
  if (result.success) {
665
- spinner.succeed(` ${server.name} ๋“ฑ๋ก ์™„๋ฃŒ`);
666
- successServers.push(server.name);
693
+ if (result.skipped) {
694
+ spinner.info(` ${server.name} ์ด๋ฏธ ๋“ฑ๋ก๋จ (๊ฑด๋„ˆ๋œ€)`);
695
+ skippedServers.push(server.name);
696
+ }
697
+ else {
698
+ spinner.succeed(` ${server.name} ๋“ฑ๋ก ์™„๋ฃŒ`);
699
+ successServers.push(server.name);
700
+ }
667
701
  }
668
702
  else {
669
703
  spinner.fail(` ${server.name} ๋“ฑ๋ก ์‹คํŒจ`);
@@ -671,7 +705,10 @@ async function mergeExtensionSettings(cwd, packages) {
671
705
  }
672
706
  }
673
707
  if (successServers.length > 0) {
674
- console.log(chalk_1.default.green(`\nโœ“ ${successServers.length}๊ฐœ MCP ์„œ๋ฒ„ ์ž๋™ ๋“ฑ๋ก ์™„๋ฃŒ`));
708
+ console.log(chalk_1.default.green(`\nโœ“ ${successServers.length}๊ฐœ MCP ์„œ๋ฒ„ ์ƒˆ๋กœ ๋“ฑ๋ก ์™„๋ฃŒ`));
709
+ }
710
+ if (skippedServers.length > 0) {
711
+ console.log(chalk_1.default.gray(` (${skippedServers.length}๊ฐœ ์ด๋ฏธ ๋“ฑ๋ก๋จ)`));
675
712
  }
676
713
  if (failedServers.length > 0) {
677
714
  console.log(chalk_1.default.yellow(`\nโš  ${failedServers.length}๊ฐœ MCP ์„œ๋ฒ„ ์ž๋™ ๋“ฑ๋ก ์‹คํŒจ`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@team-semicolon/semo-cli",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "SEMO CLI - AI Agent Orchestration Framework Installer",
5
5
  "main": "dist/index.js",
6
6
  "bin": {