@team-semicolon/semo-cli 2.0.5 โ 3.0.1
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 +91 -37
- 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
|
-
//
|
|
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,28 +470,34 @@ 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 {
|
|
473
|
-
//
|
|
474
|
-
|
|
486
|
+
// ์ด๋ฏธ ๋ฑ๋ก๋ ์๋ฒ์ธ์ง ํ์ธ
|
|
487
|
+
if (isMCPServerRegistered(server.name)) {
|
|
488
|
+
return { success: true, skipped: true };
|
|
489
|
+
}
|
|
490
|
+
// claude mcp add ๋ช
๋ น์ด ๊ตฌ์ฑ
|
|
491
|
+
// ํ์: claude mcp add <name> [-e KEY=value...] -- <command> [args...]
|
|
492
|
+
const args = ["mcp", "add", server.name];
|
|
493
|
+
// ํ๊ฒฝ๋ณ์๊ฐ ์๋ ๊ฒฝ์ฐ -e ์ต์
์ถ๊ฐ
|
|
475
494
|
if (server.env) {
|
|
476
495
|
for (const [key, value] of Object.entries(server.env)) {
|
|
477
|
-
|
|
496
|
+
args.push("-e", `${key}=${value}`);
|
|
478
497
|
}
|
|
479
498
|
}
|
|
480
|
-
//
|
|
481
|
-
|
|
482
|
-
"mcp", "add",
|
|
483
|
-
server.name,
|
|
484
|
-
"--",
|
|
485
|
-
server.command,
|
|
486
|
-
...server.args,
|
|
487
|
-
];
|
|
488
|
-
// ํ๊ฒฝ๋ณ์๊ฐ ์์ผ๋ฉด ๋ช
๋ น์ด ์์ ์ถ๊ฐ
|
|
489
|
-
if (envArgs.length > 0) {
|
|
490
|
-
args.splice(2, 0, ...envArgs);
|
|
491
|
-
}
|
|
499
|
+
// -- ๊ตฌ๋ถ์ ํ ๋ช
๋ น์ด์ ์ธ์ ์ถ๊ฐ
|
|
500
|
+
args.push("--", server.command, ...server.args);
|
|
492
501
|
(0, child_process_1.execSync)(`claude ${args.join(" ")}`, { stdio: "pipe" });
|
|
493
502
|
return { success: true };
|
|
494
503
|
}
|
|
@@ -575,13 +584,20 @@ async function setupMCP(cwd, extensions, force) {
|
|
|
575
584
|
// Claude Code์ MCP ์๋ฒ ๋ฑ๋ก ์๋
|
|
576
585
|
console.log(chalk_1.default.cyan("\n๐ Claude Code์ MCP ์๋ฒ ๋ฑ๋ก ์ค..."));
|
|
577
586
|
const successServers = [];
|
|
587
|
+
const skippedServers = [];
|
|
578
588
|
const failedServers = [];
|
|
579
589
|
for (const server of allServers) {
|
|
580
590
|
const spinner = (0, ora_1.default)(` ${server.name} ๋ฑ๋ก ์ค...`).start();
|
|
581
591
|
const result = registerMCPServer(server);
|
|
582
592
|
if (result.success) {
|
|
583
|
-
|
|
584
|
-
|
|
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
|
+
}
|
|
585
601
|
}
|
|
586
602
|
else {
|
|
587
603
|
spinner.fail(` ${server.name} ๋ฑ๋ก ์คํจ`);
|
|
@@ -590,7 +606,10 @@ async function setupMCP(cwd, extensions, force) {
|
|
|
590
606
|
}
|
|
591
607
|
// ๊ฒฐ๊ณผ ์์ฝ
|
|
592
608
|
if (successServers.length > 0) {
|
|
593
|
-
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}๊ฐ ์ด๋ฏธ ๋ฑ๋ก๋จ)`));
|
|
594
613
|
}
|
|
595
614
|
// ์คํจํ ์๋ฒ๊ฐ ์์ผ๋ฉด ์๋ ๋ฑ๋ก ์๋ด
|
|
596
615
|
if (failedServers.length > 0) {
|
|
@@ -665,13 +684,20 @@ async function mergeExtensionSettings(cwd, packages) {
|
|
|
665
684
|
if (newServers.length > 0) {
|
|
666
685
|
console.log(chalk_1.default.cyan("\n๐ Claude Code์ MCP ์๋ฒ ๋ฑ๋ก ์ค..."));
|
|
667
686
|
const successServers = [];
|
|
687
|
+
const skippedServers = [];
|
|
668
688
|
const failedServers = [];
|
|
669
689
|
for (const server of newServers) {
|
|
670
690
|
const spinner = (0, ora_1.default)(` ${server.name} ๋ฑ๋ก ์ค...`).start();
|
|
671
691
|
const result = registerMCPServer(server);
|
|
672
692
|
if (result.success) {
|
|
673
|
-
|
|
674
|
-
|
|
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
|
+
}
|
|
675
701
|
}
|
|
676
702
|
else {
|
|
677
703
|
spinner.fail(` ${server.name} ๋ฑ๋ก ์คํจ`);
|
|
@@ -679,7 +705,10 @@ async function mergeExtensionSettings(cwd, packages) {
|
|
|
679
705
|
}
|
|
680
706
|
}
|
|
681
707
|
if (successServers.length > 0) {
|
|
682
|
-
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}๊ฐ ์ด๋ฏธ ๋ฑ๋ก๋จ)`));
|
|
683
712
|
}
|
|
684
713
|
if (failedServers.length > 0) {
|
|
685
714
|
console.log(chalk_1.default.yellow(`\nโ ${failedServers.length}๊ฐ MCP ์๋ฒ ์๋ ๋ฑ๋ก ์คํจ`));
|
|
@@ -978,11 +1007,19 @@ program
|
|
|
978
1007
|
console.log(chalk_1.default.red("\nSEMO๊ฐ ์ค์น๋์ด ์์ง ์์ต๋๋ค. 'semo init'์ ๋จผ์ ์คํํ์ธ์.\n"));
|
|
979
1008
|
process.exit(1);
|
|
980
1009
|
}
|
|
981
|
-
|
|
1010
|
+
// ๋ ๊ฑฐ์ ํจํค์ง ์ด๋ฆ โ ์ ์ด๋ฆ ๋ณํ
|
|
1011
|
+
let resolvedPackage = packageName;
|
|
1012
|
+
if (packageName in LEGACY_MAPPING) {
|
|
1013
|
+
resolvedPackage = LEGACY_MAPPING[packageName];
|
|
1014
|
+
console.log(chalk_1.default.yellow(`\n๐ก '${packageName}' โ '${resolvedPackage}' (v3.0 ๊ตฌ์กฐ)`));
|
|
1015
|
+
}
|
|
1016
|
+
if (!(resolvedPackage in EXTENSION_PACKAGES)) {
|
|
982
1017
|
console.log(chalk_1.default.red(`\n์ ์ ์๋ ํจํค์ง: ${packageName}`));
|
|
983
|
-
console.log(chalk_1.default.gray(`์ฌ์ฉ ๊ฐ๋ฅํ ํจํค์ง: ${Object.keys(EXTENSION_PACKAGES).join(", ")}
|
|
1018
|
+
console.log(chalk_1.default.gray(`์ฌ์ฉ ๊ฐ๋ฅํ ํจํค์ง: ${Object.keys(EXTENSION_PACKAGES).join(", ")}`));
|
|
1019
|
+
console.log(chalk_1.default.gray(`๋ ๊ฑฐ์ ๋ณ์นญ: ${Object.keys(LEGACY_MAPPING).join(", ")}\n`));
|
|
984
1020
|
process.exit(1);
|
|
985
1021
|
}
|
|
1022
|
+
packageName = resolvedPackage;
|
|
986
1023
|
const pkgPath = path.join(semoSystemDir, packageName);
|
|
987
1024
|
if (fs.existsSync(pkgPath) && !options.force) {
|
|
988
1025
|
console.log(chalk_1.default.yellow(`\n${EXTENSION_PACKAGES[packageName].name} ํจํค์ง๊ฐ ์ด๋ฏธ ์ค์น๋์ด ์์ต๋๋ค.`));
|
|
@@ -1006,24 +1043,41 @@ program
|
|
|
1006
1043
|
.action(() => {
|
|
1007
1044
|
const cwd = process.cwd();
|
|
1008
1045
|
const semoSystemDir = path.join(cwd, "semo-system");
|
|
1009
|
-
console.log(chalk_1.default.cyan.bold("\n๐ฆ SEMO ํจํค์ง
|
|
1046
|
+
console.log(chalk_1.default.cyan.bold("\n๐ฆ SEMO ํจํค์ง ๋ชฉ๋ก (v3.0)\n"));
|
|
1010
1047
|
// Standard
|
|
1011
1048
|
console.log(chalk_1.default.white.bold("Standard (ํ์)"));
|
|
1012
1049
|
const coreInstalled = fs.existsSync(path.join(semoSystemDir, "semo-core"));
|
|
1013
1050
|
const skillsInstalled = fs.existsSync(path.join(semoSystemDir, "semo-skills"));
|
|
1014
1051
|
console.log(` ${coreInstalled ? chalk_1.default.green("โ") : chalk_1.default.gray("โ")} semo-core - ์์น, ์ค์ผ์คํธ๋ ์ดํฐ`);
|
|
1015
|
-
console.log(` ${skillsInstalled ? chalk_1.default.green("โ") : chalk_1.default.gray("โ")} semo-skills -
|
|
1052
|
+
console.log(` ${skillsInstalled ? chalk_1.default.green("โ") : chalk_1.default.gray("โ")} semo-skills - ํตํฉ ์คํฌ`);
|
|
1016
1053
|
console.log();
|
|
1017
|
-
// Extensions
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1054
|
+
// Extensions - ๋ ์ด์ด๋ณ ๊ทธ๋ฃนํ
|
|
1055
|
+
const layers = {
|
|
1056
|
+
biz: { title: "Business Layer", emoji: "๐ผ" },
|
|
1057
|
+
eng: { title: "Engineering Layer", emoji: "โ๏ธ" },
|
|
1058
|
+
ops: { title: "Operations Layer", emoji: "๐" },
|
|
1059
|
+
meta: { title: "Meta", emoji: "๐ง" },
|
|
1060
|
+
};
|
|
1061
|
+
for (const [layerKey, layerInfo] of Object.entries(layers)) {
|
|
1062
|
+
const layerPackages = Object.entries(EXTENSION_PACKAGES).filter(([, pkg]) => pkg.layer === layerKey);
|
|
1063
|
+
if (layerPackages.length === 0)
|
|
1064
|
+
continue;
|
|
1065
|
+
console.log(chalk_1.default.white.bold(`${layerInfo.emoji} ${layerInfo.title}`));
|
|
1066
|
+
for (const [key, pkg] of layerPackages) {
|
|
1067
|
+
const isInstalled = fs.existsSync(path.join(semoSystemDir, key));
|
|
1068
|
+
const status = isInstalled ? chalk_1.default.green("โ") : chalk_1.default.gray("โ");
|
|
1069
|
+
const displayKey = key.includes("/") ? key.split("/")[1] : key;
|
|
1070
|
+
console.log(` ${status} ${chalk_1.default.cyan(displayKey)} - ${pkg.desc}`);
|
|
1071
|
+
console.log(chalk_1.default.gray(` semo add ${key}`));
|
|
1072
|
+
}
|
|
1073
|
+
console.log();
|
|
1023
1074
|
}
|
|
1024
|
-
|
|
1025
|
-
console.log(chalk_1.default.gray("
|
|
1026
|
-
console.log(chalk_1.default.gray("
|
|
1075
|
+
// ๋ ๊ฑฐ์ ํธํ์ฑ ์๋ด
|
|
1076
|
+
console.log(chalk_1.default.gray("โ".repeat(50)));
|
|
1077
|
+
console.log(chalk_1.default.gray("๋ ๊ฑฐ์ ๋ช
๋ น์ด๋ ์ง์๋ฉ๋๋ค:"));
|
|
1078
|
+
console.log(chalk_1.default.gray(" semo add next โ eng/nextjs"));
|
|
1079
|
+
console.log(chalk_1.default.gray(" semo add backend โ eng/spring"));
|
|
1080
|
+
console.log(chalk_1.default.gray(" semo add mvp โ biz/poc\n"));
|
|
1027
1081
|
});
|
|
1028
1082
|
// === status ๋ช
๋ น์ด ===
|
|
1029
1083
|
program
|