connectbase-client 0.10.1 → 0.10.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/cli.js +122 -12
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -608,12 +608,56 @@ function getGitRoot() {
|
|
|
608
608
|
return null;
|
|
609
609
|
}
|
|
610
610
|
}
|
|
611
|
+
function detectMonorepo(gitRoot) {
|
|
612
|
+
const cwd = process.cwd();
|
|
613
|
+
const result = { type: "none", root: gitRoot, isSubPackage: false };
|
|
614
|
+
if (fs.existsSync(path.join(gitRoot, "pnpm-workspace.yaml"))) {
|
|
615
|
+
result.type = "pnpm";
|
|
616
|
+
} else if (fs.existsSync(path.join(gitRoot, "turbo.json"))) {
|
|
617
|
+
result.type = "turborepo";
|
|
618
|
+
} else if (fs.existsSync(path.join(gitRoot, "nx.json"))) {
|
|
619
|
+
result.type = "nx";
|
|
620
|
+
} else if (fs.existsSync(path.join(gitRoot, "lerna.json"))) {
|
|
621
|
+
result.type = "lerna";
|
|
622
|
+
} else {
|
|
623
|
+
const rootPkgPath = path.join(gitRoot, "package.json");
|
|
624
|
+
if (fs.existsSync(rootPkgPath)) {
|
|
625
|
+
try {
|
|
626
|
+
const pkg = JSON.parse(fs.readFileSync(rootPkgPath, "utf-8"));
|
|
627
|
+
if (pkg.workspaces) {
|
|
628
|
+
result.type = fs.existsSync(path.join(gitRoot, "yarn.lock")) ? "yarn" : "npm";
|
|
629
|
+
}
|
|
630
|
+
} catch {
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
if (result.type !== "none" && cwd !== gitRoot) {
|
|
635
|
+
const cwdPkgPath = path.join(cwd, "package.json");
|
|
636
|
+
if (fs.existsSync(cwdPkgPath)) {
|
|
637
|
+
result.isSubPackage = true;
|
|
638
|
+
try {
|
|
639
|
+
const pkg = JSON.parse(fs.readFileSync(cwdPkgPath, "utf-8"));
|
|
640
|
+
result.subPackageName = pkg.name;
|
|
641
|
+
} catch {
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
return result;
|
|
646
|
+
}
|
|
611
647
|
async function downloadDocs(apiKey, templates, baseDir) {
|
|
612
648
|
if (!baseDir) {
|
|
613
649
|
baseDir = getProjectRoot();
|
|
614
650
|
}
|
|
615
|
-
const
|
|
616
|
-
const
|
|
651
|
+
const gitRoot = getGitRoot() || baseDir;
|
|
652
|
+
const monorepo = detectMonorepo(gitRoot);
|
|
653
|
+
if (monorepo.type !== "none") {
|
|
654
|
+
info(`\uBAA8\uB178\uB808\uD3EC \uAC10\uC9C0: ${monorepo.type} (\uB8E8\uD2B8: ${gitRoot})`);
|
|
655
|
+
if (monorepo.isSubPackage) {
|
|
656
|
+
info(`\uD604\uC7AC \uC11C\uBE0C \uD328\uD0A4\uC9C0: ${monorepo.subPackageName || path.basename(process.cwd())}`);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
const docsDir = path.join(gitRoot, ".claude", "docs");
|
|
660
|
+
const rootClaudeMd = path.join(gitRoot, "CLAUDE.md");
|
|
617
661
|
if (!fs.existsSync(docsDir)) {
|
|
618
662
|
fs.mkdirSync(docsDir, { recursive: true });
|
|
619
663
|
}
|
|
@@ -637,8 +681,12 @@ async function downloadDocs(apiKey, templates, baseDir) {
|
|
|
637
681
|
const filePath = path.join(docsDir, section.filename);
|
|
638
682
|
fs.writeFileSync(filePath, section.content);
|
|
639
683
|
}
|
|
640
|
-
success(
|
|
684
|
+
success(`${gitRoot}/.claude/docs/ \uC5D0 ${sections.length}\uAC1C \uBB38\uC11C \uC800\uC7A5 \uC644\uB8CC`);
|
|
641
685
|
updateRootClaudeMd(rootClaudeMd);
|
|
686
|
+
if (monorepo.isSubPackage) {
|
|
687
|
+
const subClaudeMd = path.join(process.cwd(), "CLAUDE.md");
|
|
688
|
+
createSubPackageClaudeMd(subClaudeMd, gitRoot);
|
|
689
|
+
}
|
|
642
690
|
log(`${colors.dim}\u203B SDK \uBB38\uC11C\uB294 MCP search_sdk_docs\uB85C \uAC80\uC0C9\uD558\uC138\uC694${colors.reset}`);
|
|
643
691
|
} catch {
|
|
644
692
|
warn("SDK \uAC00\uC774\uB4DC \uB2E4\uC6B4\uB85C\uB4DC \uC2E4\uD328, \uAE30\uBCF8 \uBB38\uC11C\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4");
|
|
@@ -650,6 +698,10 @@ async function downloadDocs(apiKey, templates, baseDir) {
|
|
|
650
698
|
`;
|
|
651
699
|
fs.writeFileSync(path.join(docsDir, "project-rules.md"), fallbackContent);
|
|
652
700
|
updateRootClaudeMd(rootClaudeMd);
|
|
701
|
+
if (monorepo.isSubPackage) {
|
|
702
|
+
const subClaudeMd = path.join(process.cwd(), "CLAUDE.md");
|
|
703
|
+
createSubPackageClaudeMd(subClaudeMd, gitRoot);
|
|
704
|
+
}
|
|
653
705
|
success(`.claude/docs/ \uC0DD\uC131 \uC644\uB8CC (\uAE30\uBCF8)`);
|
|
654
706
|
}
|
|
655
707
|
}
|
|
@@ -695,10 +747,55 @@ ${sdkBlock}
|
|
|
695
747
|
success("CLAUDE.md \uC0DD\uC131 \uC644\uB8CC");
|
|
696
748
|
}
|
|
697
749
|
}
|
|
698
|
-
|
|
699
|
-
const
|
|
750
|
+
function createSubPackageClaudeMd(subClaudeMdPath, gitRoot) {
|
|
751
|
+
const startMarker = "<!-- CONNECTBASE_SUB_START -->";
|
|
752
|
+
const endMarker = "<!-- CONNECTBASE_SUB_END -->";
|
|
753
|
+
const relPath = path.relative(path.dirname(subClaudeMdPath), gitRoot);
|
|
754
|
+
const subBlock = `${startMarker}
|
|
755
|
+
## ConnectBase SDK
|
|
756
|
+
|
|
757
|
+
\uC774 \uD328\uD0A4\uC9C0\uB294 **ConnectBase**\uB97C \uBC31\uC5D4\uB4DC\uB85C \uC0AC\uC6A9\uD569\uB2C8\uB2E4.
|
|
758
|
+
|
|
759
|
+
### AI \uD544\uB3C5
|
|
760
|
+
|
|
761
|
+
1. \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC758 \`${relPath}/.claude/docs/project-rules.md\`\uB97C **Read tool\uB85C \uC77D\uC73C\uC138\uC694**
|
|
762
|
+
2. \`search_sdk_docs("\uD0A4\uC6CC\uB4DC")\`\uB85C SDK \uAD6C\uD604 \uBC29\uBC95\uC744 \uAC80\uC0C9\uD558\uC138\uC694
|
|
763
|
+
3. \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC758 \`${relPath}/CLAUDE.md\`\uB3C4 \uCC38\uACE0\uD558\uC138\uC694
|
|
764
|
+
${endMarker}`;
|
|
765
|
+
if (fs.existsSync(subClaudeMdPath)) {
|
|
766
|
+
let content = fs.readFileSync(subClaudeMdPath, "utf-8");
|
|
767
|
+
const startIdx = content.indexOf(startMarker);
|
|
768
|
+
const endIdx = content.indexOf(endMarker);
|
|
769
|
+
if (startIdx !== -1 && endIdx !== -1) {
|
|
770
|
+
content = content.substring(0, startIdx) + subBlock + content.substring(endIdx + endMarker.length);
|
|
771
|
+
} else if (content.indexOf("<!-- CONNECTBASE_START -->") === -1) {
|
|
772
|
+
content = content.trimEnd() + "\n\n" + subBlock + "\n";
|
|
773
|
+
} else {
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
776
|
+
fs.writeFileSync(subClaudeMdPath, content);
|
|
777
|
+
} else {
|
|
778
|
+
fs.writeFileSync(subClaudeMdPath, `# ${path.basename(path.dirname(subClaudeMdPath))}
|
|
779
|
+
|
|
780
|
+
${subBlock}
|
|
781
|
+
`);
|
|
782
|
+
}
|
|
783
|
+
success(`\uC11C\uBE0C \uD328\uD0A4\uC9C0 CLAUDE.md \uC0DD\uC131 \uC644\uB8CC: ${subClaudeMdPath}`);
|
|
784
|
+
}
|
|
785
|
+
async function setupMcp(secretKey) {
|
|
786
|
+
const gitRoot = getGitRoot();
|
|
787
|
+
const root = gitRoot || process.cwd();
|
|
788
|
+
const monorepo = detectMonorepo(root);
|
|
789
|
+
if (monorepo.type !== "none") {
|
|
790
|
+
info(`\uBAA8\uB178\uB808\uD3EC \uAC10\uC9C0: ${monorepo.type} (\uB8E8\uD2B8: ${root})`);
|
|
791
|
+
if (monorepo.isSubPackage) {
|
|
792
|
+
info(`MCP \uC124\uC815\uC740 \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8(${root})\uC5D0 \uC0DD\uC131\uB429\uB2C8\uB2E4`);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
700
795
|
const mcpConfigPath = path.join(root, ".mcp.json");
|
|
701
|
-
|
|
796
|
+
if (!secretKey) {
|
|
797
|
+
secretKey = await prompt(`${colors.blue}?${colors.reset} Secret Key (cb_sk_...): `);
|
|
798
|
+
}
|
|
702
799
|
const mcpEntry = {
|
|
703
800
|
type: "http",
|
|
704
801
|
url: "https://mcp.connectbase.world/mcp",
|
|
@@ -722,14 +819,21 @@ async function setupClaudeCode(apiKey, secretKey, projectRoot) {
|
|
|
722
819
|
}
|
|
723
820
|
mcpConfig.mcpServers["connect-base"] = mcpEntry;
|
|
724
821
|
fs.writeFileSync(mcpConfigPath, JSON.stringify(mcpConfig, null, 2) + "\n");
|
|
725
|
-
success(
|
|
822
|
+
success(`${mcpConfigPath} \uC0DD\uC131 \uC644\uB8CC`);
|
|
726
823
|
addToGitignore(".mcp.json", root);
|
|
727
|
-
if (secretKey) {
|
|
728
|
-
success("MCP \uC11C\uBC84 \
|
|
824
|
+
if (secretKey && secretKey !== "YOUR_SECRET_KEY_HERE") {
|
|
825
|
+
success("MCP \uC11C\uBC84 \uC124\uC815 \uC644\uB8CC (Secret Key \uC801\uC6A9\uB428)");
|
|
729
826
|
} else {
|
|
730
827
|
warn("MCP \uC11C\uBC84\uB294 Secret Key (cb_sk_)\uB9CC \uD5C8\uC6A9\uD569\uB2C8\uB2E4.");
|
|
731
828
|
info(".mcp.json \uD30C\uC77C\uC758 YOUR_SECRET_KEY_HERE\uB97C Secret Key\uB85C \uAD50\uCCB4\uD558\uC138\uC694.");
|
|
732
829
|
}
|
|
830
|
+
log(`
|
|
831
|
+
${colors.dim}Claude Code\uC5D0\uC11C ConnectBase MCP \uB3C4\uAD6C\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.${colors.reset}`);
|
|
832
|
+
}
|
|
833
|
+
async function setupClaudeCode(apiKey, secretKey, projectRoot) {
|
|
834
|
+
const root = projectRoot || getProjectRoot();
|
|
835
|
+
await downloadDocs(apiKey, void 0, root);
|
|
836
|
+
await setupMcp(secretKey);
|
|
733
837
|
}
|
|
734
838
|
function createWsTextFrame(payload) {
|
|
735
839
|
const data = Buffer.from(payload, "utf-8");
|
|
@@ -1081,7 +1185,8 @@ ${colors.yellow}\uC0AC\uC6A9\uBC95:${colors.reset}
|
|
|
1081
1185
|
|
|
1082
1186
|
${colors.yellow}\uBA85\uB839\uC5B4:${colors.reset}
|
|
1083
1187
|
init \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654 (\uC571 \uC0DD\uC131, MCP \uC124\uC815, SDK \uBB38\uC11C \uB2E4\uC6B4\uB85C\uB4DC)
|
|
1084
|
-
docs SDK \uBB38\uC11C \uB2E4\uC6B4\uB85C\uB4DC/\uC5C5\uB370\uC774\uD2B8 (\
|
|
1188
|
+
docs SDK \uBB38\uC11C \uB2E4\uC6B4\uB85C\uB4DC/\uC5C5\uB370\uC774\uD2B8 (\uBAA8\uB178\uB808\uD3EC \uC790\uB3D9 \uAC10\uC9C0)
|
|
1189
|
+
mcp MCP \uC11C\uBC84 \uC124\uC815 (.mcp.json \uC0DD\uC131/\uC5C5\uB370\uC774\uD2B8, \uBAA8\uB178\uB808\uD3EC \uC790\uB3D9 \uAC10\uC9C0)
|
|
1085
1190
|
deploy <directory> \uC6F9 \uC2A4\uD1A0\uB9AC\uC9C0\uC5D0 \uD30C\uC77C \uBC30\uD3EC (--dev: Dev \uD658\uACBD)
|
|
1086
1191
|
tunnel <port> \uB85C\uCEEC \uC11C\uBE44\uC2A4\uB97C \uC778\uD130\uB137\uC5D0 \uB178\uCD9C
|
|
1087
1192
|
|
|
@@ -1099,7 +1204,7 @@ ${colors.yellow}\uC635\uC158:${colors.reset}
|
|
|
1099
1204
|
-t, --timeout <sec> \uD130\uB110 \uC694\uCCAD \uD0C0\uC784\uC544\uC6C3 (\uCD08, tunnel \uC804\uC6A9)
|
|
1100
1205
|
--max-body <MB> \uD130\uB110 \uCD5C\uB300 \uBC14\uB514 \uD06C\uAE30 (MB, tunnel \uC804\uC6A9)
|
|
1101
1206
|
-d, --dev Dev \uD658\uACBD\uC5D0 \uBC30\uD3EC (deploy \uC804\uC6A9)
|
|
1102
|
-
(docs\uB294 \
|
|
1207
|
+
(docs, mcp\uB294 \uBAA8\uB178\uB808\uD3EC\uB97C \uC790\uB3D9 \uAC10\uC9C0\uD558\uC5EC \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0 \uC0DD\uC131)
|
|
1103
1208
|
-h, --help \uB3C4\uC6C0\uB9D0 \uD45C\uC2DC
|
|
1104
1209
|
-v, --version \uBC84\uC804 \uD45C\uC2DC
|
|
1105
1210
|
|
|
@@ -1110,7 +1215,10 @@ ${colors.yellow}\uBE60\uB978 \uC2DC\uC791:${colors.reset}
|
|
|
1110
1215
|
${colors.dim}# 2. SDK \uBB38\uC11C \uC5C5\uB370\uC774\uD2B8${colors.reset}
|
|
1111
1216
|
npx connectbase docs
|
|
1112
1217
|
|
|
1113
|
-
${colors.dim}# 3.
|
|
1218
|
+
${colors.dim}# 3. MCP \uC11C\uBC84 \uC124\uC815${colors.reset}
|
|
1219
|
+
npx connectbase mcp
|
|
1220
|
+
|
|
1221
|
+
${colors.dim}# 4. Prod \uBC30\uD3EC${colors.reset}
|
|
1114
1222
|
npm run deploy
|
|
1115
1223
|
|
|
1116
1224
|
${colors.dim}# 4. Dev \uD658\uACBD \uBC30\uD3EC (\uB0B4\uBD80 QA\uC6A9)${colors.reset}
|
|
@@ -1198,6 +1306,8 @@ async function main() {
|
|
|
1198
1306
|
}
|
|
1199
1307
|
}
|
|
1200
1308
|
await downloadDocs(docsApiKey);
|
|
1309
|
+
} else if (parsed.command === "mcp") {
|
|
1310
|
+
await setupMcp();
|
|
1201
1311
|
} else if (parsed.command === "deploy") {
|
|
1202
1312
|
const directory = parsed.args[0] || fileConfig.deployDir || ".";
|
|
1203
1313
|
if (!config.apiKey) {
|