connectbase-client 0.10.2 → 0.10.4
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 +190 -47
- package/dist/connect-base.umd.js +3 -3
- package/dist/index.d.mts +105 -66
- package/dist/index.d.ts +105 -66
- package/dist/index.js +31 -47
- package/dist/index.mjs +30 -47
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -369,7 +369,7 @@ ${colors.cyan}Connect Base \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654${colors.r
|
|
|
369
369
|
return;
|
|
370
370
|
}
|
|
371
371
|
}
|
|
372
|
-
log(`${colors.dim}Secret Key (cb_sk_): \uCF58\uC194 > \uD504\uB85C\uD544 >
|
|
372
|
+
log(`${colors.dim}Secret Key (cb_sk_): \uCF58\uC194 > \uD504\uB85C\uD544 > \uC2DC\uD06C\uB9BF \uD0A4 \uD0ED\uC5D0\uC11C \uBC1C\uAE09${colors.reset}
|
|
373
373
|
`);
|
|
374
374
|
const secretKey = await promptSecret(`${colors.blue}?${colors.reset} Secret Key: `);
|
|
375
375
|
if (!secretKey) {
|
|
@@ -378,7 +378,7 @@ ${colors.cyan}Connect Base \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654${colors.r
|
|
|
378
378
|
}
|
|
379
379
|
if (secretKey.startsWith("cb_pk_")) {
|
|
380
380
|
error("Public Key\uAC00 \uC544\uB2CC Secret Key(cb_sk_)\uB97C \uC785\uB825\uD558\uC138\uC694");
|
|
381
|
-
info("Secret Key\uB294 \uCF58\uC194 > \uD504\uB85C\uD544 >
|
|
381
|
+
info("Secret Key\uB294 \uCF58\uC194 > \uD504\uB85C\uD544 > \uC2DC\uD06C\uB9BF \uD0A4 \uD0ED\uC5D0\uC11C \uC0DD\uC131\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4");
|
|
382
382
|
process.exit(1);
|
|
383
383
|
}
|
|
384
384
|
if (!secretKey.startsWith("cb_sk_")) {
|
|
@@ -712,21 +712,12 @@ function updateRootClaudeMd(claudeMdPath) {
|
|
|
712
712
|
## ConnectBase SDK
|
|
713
713
|
|
|
714
714
|
\uC774 \uD504\uB85C\uC81D\uD2B8\uB294 **ConnectBase**\uB97C \uBC31\uC5D4\uB4DC\uB85C \uC0AC\uC6A9\uD569\uB2C8\uB2E4.
|
|
715
|
-
\uC0AC\uC6A9\uC790\uB294 **\uBE44\uAC1C\uBC1C\uC790**\uC785\uB2C8\uB2E4. \uC26C\uC6B4 \uB9D0\uB85C \uC124\uBA85\uD558\uACE0, \uBC14\uB85C \uC2E4\uD589 \uAC00\uB2A5\uD55C \uC644\uC131\uB41C \uCF54\uB4DC\uB97C \uC81C\uACF5\uD558\uC138\uC694.
|
|
716
715
|
|
|
717
716
|
### AI \uD544\uB3C5 \u2014 \uCF54\uB529 \uC804 \uBC18\uB4DC\uC2DC \uC218\uD589
|
|
718
717
|
|
|
719
|
-
1. \`.claude/docs/project-rules.md
|
|
720
|
-
2. \
|
|
721
|
-
3.
|
|
722
|
-
4. \uC644\uC131\uB41C \uCF54\uB4DC\uB97C \uC791\uC131\uD558\uC138\uC694 (\uC2A4\uB2C8\uD3AB X, \uBC14\uB85C \uC2E4\uD589 \uAC00\uB2A5\uD55C \uC804\uCCB4 \uCF54\uB4DC)
|
|
723
|
-
|
|
724
|
-
### \uBE44\uAC1C\uBC1C\uC790 \uC751\uB300 \uC6D0\uCE59
|
|
725
|
-
|
|
726
|
-
- \uC804\uBB38 \uC6A9\uC5B4 \uB300\uC2E0 \uC26C\uC6B4 \uB9D0 \uC0AC\uC6A9 ("API" \u2192 "\uAE30\uB2A5", "DB" \u2192 "\uC800\uC7A5\uC18C")
|
|
727
|
-
- \uC5D0\uB7EC \uBC1C\uC0DD \uC2DC \uC6D0\uC778\uACFC \uD574\uACB0\uCC45\uC744 \uD55C \uC904\uB85C \uC124\uBA85
|
|
728
|
-
- \uCF54\uB4DC \uC791\uC131 \uC804 "\uC774\uB807\uAC8C \uB9CC\uB4E4\uAC8C\uC694~" \uD55C \uC904 \uC694\uC57D \uBA3C\uC800
|
|
729
|
-
- \uBAA8\uB974\uB294 \uAC8C \uC788\uC73C\uBA74 \uB9CC\uB4E4\uAE30 \uC804\uC5D0 \uBA3C\uC800 \uC9C8\uBB38
|
|
718
|
+
1. \`.claude/docs/project-rules.md\`\uB97C **Read tool\uB85C \uC77D\uC73C\uC138\uC694** (\uAE30\uB2A5 \uB9E4\uD551\uD45C, \uBCF4\uC548 \uADDC\uCE59, \uC5D0\uB7EC \uAC00\uC774\uB4DC)
|
|
719
|
+
2. \`search_sdk_docs("\uD0A4\uC6CC\uB4DC")\`\uB85C \uAD6C\uD604 \uBC29\uBC95\uC744 \uAC80\uC0C9\uD558\uC138\uC694
|
|
720
|
+
3. \uAC80\uC0C9 \uACB0\uACFC\uC758 \uCF54\uB4DC \uD328\uD134\uC744 \uB530\uB77C \uAD6C\uD604\uD558\uC138\uC694
|
|
730
721
|
${endMarker}`;
|
|
731
722
|
if (fs.existsSync(claudeMdPath)) {
|
|
732
723
|
let content = fs.readFileSync(claudeMdPath, "utf-8");
|
|
@@ -735,7 +726,7 @@ ${endMarker}`;
|
|
|
735
726
|
if (startIdx !== -1 && endIdx !== -1) {
|
|
736
727
|
content = content.substring(0, startIdx) + sdkBlock + content.substring(endIdx + endMarker.length);
|
|
737
728
|
} else {
|
|
738
|
-
content =
|
|
729
|
+
content = sdkBlock + "\n\n" + content.trimStart();
|
|
739
730
|
}
|
|
740
731
|
fs.writeFileSync(claudeMdPath, content);
|
|
741
732
|
info("CLAUDE.md\uC5D0 ConnectBase \uCC38\uC870 \uC5C5\uB370\uC774\uD2B8 \uC644\uB8CC");
|
|
@@ -782,10 +773,20 @@ ${subBlock}
|
|
|
782
773
|
}
|
|
783
774
|
success(`\uC11C\uBE0C \uD328\uD0A4\uC9C0 CLAUDE.md \uC0DD\uC131 \uC644\uB8CC: ${subClaudeMdPath}`);
|
|
784
775
|
}
|
|
785
|
-
async function
|
|
786
|
-
const
|
|
776
|
+
async function setupMcp(secretKey) {
|
|
777
|
+
const gitRoot = getGitRoot();
|
|
778
|
+
const root = gitRoot || process.cwd();
|
|
779
|
+
const monorepo = detectMonorepo(root);
|
|
780
|
+
if (monorepo.type !== "none") {
|
|
781
|
+
info(`\uBAA8\uB178\uB808\uD3EC \uAC10\uC9C0: ${monorepo.type} (\uB8E8\uD2B8: ${root})`);
|
|
782
|
+
if (monorepo.isSubPackage) {
|
|
783
|
+
info(`MCP \uC124\uC815\uC740 \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8(${root})\uC5D0 \uC0DD\uC131\uB429\uB2C8\uB2E4`);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
787
786
|
const mcpConfigPath = path.join(root, ".mcp.json");
|
|
788
|
-
|
|
787
|
+
if (!secretKey) {
|
|
788
|
+
secretKey = await prompt(`${colors.blue}?${colors.reset} Secret Key (cb_sk_...): `);
|
|
789
|
+
}
|
|
789
790
|
const mcpEntry = {
|
|
790
791
|
type: "http",
|
|
791
792
|
url: "https://mcp.connectbase.world/mcp",
|
|
@@ -809,14 +810,21 @@ async function setupClaudeCode(apiKey, secretKey, projectRoot) {
|
|
|
809
810
|
}
|
|
810
811
|
mcpConfig.mcpServers["connect-base"] = mcpEntry;
|
|
811
812
|
fs.writeFileSync(mcpConfigPath, JSON.stringify(mcpConfig, null, 2) + "\n");
|
|
812
|
-
success(
|
|
813
|
+
success(`${mcpConfigPath} \uC0DD\uC131 \uC644\uB8CC`);
|
|
813
814
|
addToGitignore(".mcp.json", root);
|
|
814
|
-
if (secretKey) {
|
|
815
|
-
success("MCP \uC11C\uBC84 \
|
|
815
|
+
if (secretKey && secretKey !== "YOUR_SECRET_KEY_HERE") {
|
|
816
|
+
success("MCP \uC11C\uBC84 \uC124\uC815 \uC644\uB8CC (Secret Key \uC801\uC6A9\uB428)");
|
|
816
817
|
} else {
|
|
817
818
|
warn("MCP \uC11C\uBC84\uB294 Secret Key (cb_sk_)\uB9CC \uD5C8\uC6A9\uD569\uB2C8\uB2E4.");
|
|
818
819
|
info(".mcp.json \uD30C\uC77C\uC758 YOUR_SECRET_KEY_HERE\uB97C Secret Key\uB85C \uAD50\uCCB4\uD558\uC138\uC694.");
|
|
819
820
|
}
|
|
821
|
+
log(`
|
|
822
|
+
${colors.dim}Claude Code\uC5D0\uC11C ConnectBase MCP \uB3C4\uAD6C\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.${colors.reset}`);
|
|
823
|
+
}
|
|
824
|
+
async function setupClaudeCode(apiKey, secretKey, projectRoot) {
|
|
825
|
+
const root = projectRoot || getProjectRoot();
|
|
826
|
+
await downloadDocs(apiKey, void 0, root);
|
|
827
|
+
await setupMcp(secretKey);
|
|
820
828
|
}
|
|
821
829
|
function createWsTextFrame(payload) {
|
|
822
830
|
const data = Buffer.from(payload, "utf-8");
|
|
@@ -932,15 +940,89 @@ function getTunnelServerUrl(baseUrl) {
|
|
|
932
940
|
}
|
|
933
941
|
return baseUrl.replace(/:\d+/, ":8090");
|
|
934
942
|
}
|
|
943
|
+
async function resolveAppForTunnel(apiKey, baseUrl, appIdOption) {
|
|
944
|
+
if (appIdOption) {
|
|
945
|
+
return appIdOption;
|
|
946
|
+
}
|
|
947
|
+
let apps = [];
|
|
948
|
+
try {
|
|
949
|
+
info("\uC571 \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
950
|
+
const appsRes = await makeRequest(
|
|
951
|
+
`${baseUrl}/v1/public/cli/apps`,
|
|
952
|
+
"GET",
|
|
953
|
+
{ "X-API-Key": apiKey }
|
|
954
|
+
);
|
|
955
|
+
if (appsRes.status === 401) {
|
|
956
|
+
error("Secret Key\uAC00 \uC720\uD6A8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uCF58\uC194\uC5D0\uC11C \uD0A4\uB97C \uD655\uC778\uD558\uC138\uC694");
|
|
957
|
+
process.exit(1);
|
|
958
|
+
}
|
|
959
|
+
if (appsRes.status !== 200) {
|
|
960
|
+
throw new Error(`HTTP ${appsRes.status}`);
|
|
961
|
+
}
|
|
962
|
+
const appsData = appsRes.data;
|
|
963
|
+
apps = appsData.apps || [];
|
|
964
|
+
} catch (err) {
|
|
965
|
+
error(`\uC571 \uBAA9\uB85D \uC870\uD68C \uC2E4\uD328: ${err instanceof Error ? err.message : err}`);
|
|
966
|
+
process.exit(1);
|
|
967
|
+
}
|
|
968
|
+
if (apps.length === 1) {
|
|
969
|
+
success(`\uC571 \uC790\uB3D9 \uC120\uD0DD: ${apps[0].name}`);
|
|
970
|
+
return apps[0].id;
|
|
971
|
+
}
|
|
972
|
+
if (apps.length > 0) {
|
|
973
|
+
log(`
|
|
974
|
+
${colors.dim}\uB0B4 \uC571 \uBAA9\uB85D:${colors.reset}`);
|
|
975
|
+
apps.forEach((a, i) => {
|
|
976
|
+
const date = a.created_at ? a.created_at.substring(0, 10) : "";
|
|
977
|
+
log(` ${colors.cyan}${i + 1}${colors.reset}) ${a.name} ${colors.dim}(${date})${colors.reset}`);
|
|
978
|
+
});
|
|
979
|
+
}
|
|
980
|
+
log(` ${colors.cyan}0${colors.reset}) \uC0C8 \uC571 \uB9CC\uB4E4\uAE30`);
|
|
981
|
+
const choice = await prompt(`
|
|
982
|
+
${colors.blue}?${colors.reset} \uC571 \uC120\uD0DD (\uBC88\uD638): `);
|
|
983
|
+
const num = parseInt(choice, 10);
|
|
984
|
+
if (num > 0 && num <= apps.length) {
|
|
985
|
+
success(`\uC120\uD0DD\uB428: ${apps[num - 1].name}`);
|
|
986
|
+
return apps[num - 1].id;
|
|
987
|
+
}
|
|
988
|
+
const projectName = path.basename(process.cwd());
|
|
989
|
+
const appName = await prompt(`${colors.blue}?${colors.reset} \uC571 \uC774\uB984 (${projectName}): `) || projectName;
|
|
990
|
+
info("\uC571 \uC0DD\uC131 \uC911...");
|
|
991
|
+
const createRes = await makeRequest(
|
|
992
|
+
`${baseUrl}/v1/public/cli/apps`,
|
|
993
|
+
"POST",
|
|
994
|
+
{ "X-API-Key": apiKey },
|
|
995
|
+
JSON.stringify({ name: appName })
|
|
996
|
+
);
|
|
997
|
+
if (createRes.status === 402) {
|
|
998
|
+
error("\uC571 \uC0DD\uC131 \uD55C\uB3C4 \uCD08\uACFC. \uD50C\uB79C \uC5C5\uADF8\uB808\uC774\uB4DC\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4");
|
|
999
|
+
process.exit(1);
|
|
1000
|
+
}
|
|
1001
|
+
if (createRes.status !== 201) {
|
|
1002
|
+
const data = createRes.data;
|
|
1003
|
+
error(`\uC571 \uC0DD\uC131 \uC2E4\uD328: ${data?.error || `HTTP ${createRes.status}`}`);
|
|
1004
|
+
process.exit(1);
|
|
1005
|
+
}
|
|
1006
|
+
const createData = createRes.data;
|
|
1007
|
+
success(`\uC571 \uC0DD\uC131 \uC644\uB8CC: ${createData.app_name}`);
|
|
1008
|
+
return createData.app_id;
|
|
1009
|
+
}
|
|
935
1010
|
async function startTunnel(port, config, tunnelOpts) {
|
|
936
1011
|
if (!config.apiKey) {
|
|
937
|
-
error("
|
|
1012
|
+
error("Secret Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. -k \uC635\uC158 \uB610\uB294 CONNECTBASE_API_KEY \uD658\uACBD\uBCC0\uC218\uB97C \uC124\uC815\uD558\uC138\uC694");
|
|
1013
|
+
info("Secret Key\uB294 \uCF58\uC194 > \uD504\uB85C\uD544 > \uC2DC\uD06C\uB9BF \uD0A4 \uD0ED\uC5D0\uC11C \uC0DD\uC131\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4");
|
|
1014
|
+
process.exit(1);
|
|
1015
|
+
}
|
|
1016
|
+
if (!config.apiKey.startsWith("cb_sk_")) {
|
|
1017
|
+
error("\uD130\uB110\uC740 \uC720\uC800 Secret Key(cb_sk_)\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. Public Key(cb_pk_)\uB294 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
|
|
1018
|
+
info("Secret Key\uB294 \uCF58\uC194 > \uD504\uB85C\uD544 > \uC2DC\uD06C\uB9BF \uD0A4 \uD0ED\uC5D0\uC11C \uC0DD\uC131\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4");
|
|
938
1019
|
process.exit(1);
|
|
939
1020
|
}
|
|
1021
|
+
const appId = await resolveAppForTunnel(config.apiKey, config.baseUrl, tunnelOpts?.appId);
|
|
940
1022
|
const tunnelServerUrl = getTunnelServerUrl(config.baseUrl);
|
|
941
1023
|
const parsedUrl = new URL(tunnelServerUrl);
|
|
942
1024
|
const isHttps = parsedUrl.protocol === "https:";
|
|
943
|
-
let wsPath = `/v1/tunnel/connect?
|
|
1025
|
+
let wsPath = `/v1/tunnel/connect?app_id=${encodeURIComponent(appId)}`;
|
|
944
1026
|
if (tunnelOpts?.timeout) {
|
|
945
1027
|
wsPath += `&timeout=${tunnelOpts.timeout}`;
|
|
946
1028
|
}
|
|
@@ -986,7 +1068,8 @@ ${colors.cyan}ConnectBase Tunnel${colors.reset}`);
|
|
|
986
1068
|
"Upgrade": "websocket",
|
|
987
1069
|
"Connection": "Upgrade",
|
|
988
1070
|
"Sec-WebSocket-Key": wsKey,
|
|
989
|
-
"Sec-WebSocket-Version": "13"
|
|
1071
|
+
"Sec-WebSocket-Version": "13",
|
|
1072
|
+
"Authorization": `Bearer ${config.apiKey}`
|
|
990
1073
|
}
|
|
991
1074
|
};
|
|
992
1075
|
const req = lib.request(reqOptions);
|
|
@@ -1112,29 +1195,78 @@ ${colors.dim}Ctrl+C\uB85C \uC885\uB8CC${colors.reset}
|
|
|
1112
1195
|
headers: localHeaders
|
|
1113
1196
|
};
|
|
1114
1197
|
const localReq = http.request(reqOptions, (res) => {
|
|
1115
|
-
const
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
const response = {
|
|
1124
|
-
type: "http_response",
|
|
1125
|
-
request_id: requestId,
|
|
1126
|
-
status: res.statusCode || 200,
|
|
1127
|
-
headers: responseHeaders,
|
|
1128
|
-
body: body.length > 0 ? body.toString("base64") : ""
|
|
1129
|
-
};
|
|
1198
|
+
const responseHeaders = {};
|
|
1199
|
+
for (const [key, value] of Object.entries(res.headers)) {
|
|
1200
|
+
if (value) responseHeaders[key] = Array.isArray(value) ? value.join(", ") : value;
|
|
1201
|
+
}
|
|
1202
|
+
const contentType = (responseHeaders["content-type"] || "").toLowerCase();
|
|
1203
|
+
const transferEncoding = (responseHeaders["transfer-encoding"] || "").toLowerCase();
|
|
1204
|
+
const isStreaming = contentType.includes("text/event-stream") || transferEncoding.includes("chunked");
|
|
1205
|
+
if (isStreaming) {
|
|
1130
1206
|
try {
|
|
1131
|
-
sock.write(createWsTextFrame(JSON.stringify(
|
|
1132
|
-
|
|
1133
|
-
|
|
1207
|
+
sock.write(createWsTextFrame(JSON.stringify({
|
|
1208
|
+
type: "http_response_start",
|
|
1209
|
+
request_id: requestId,
|
|
1210
|
+
status: res.statusCode || 200,
|
|
1211
|
+
headers: responseHeaders
|
|
1212
|
+
})));
|
|
1134
1213
|
} catch {
|
|
1135
|
-
warn(`\
|
|
1214
|
+
warn(`\uC2A4\uD2B8\uB9AC\uBC0D \uC2DC\uC791 \uC804\uC1A1 \uC2E4\uD328: ${requestId}`);
|
|
1215
|
+
return;
|
|
1136
1216
|
}
|
|
1137
|
-
|
|
1217
|
+
const methodColor = method === "GET" ? colors.green : method === "POST" ? colors.blue : colors.yellow;
|
|
1218
|
+
log(`${colors.dim}${(/* @__PURE__ */ new Date()).toLocaleTimeString()}${colors.reset} ${methodColor}${method}${colors.reset} ${reqPath} \u2192 ${res.statusCode} ${colors.cyan}[stream]${colors.reset}`);
|
|
1219
|
+
res.on("data", (chunk) => {
|
|
1220
|
+
try {
|
|
1221
|
+
sock.write(createWsTextFrame(JSON.stringify({
|
|
1222
|
+
type: "http_response_chunk",
|
|
1223
|
+
request_id: requestId,
|
|
1224
|
+
data: chunk.toString("base64")
|
|
1225
|
+
})));
|
|
1226
|
+
} catch {
|
|
1227
|
+
warn(`\uC2A4\uD2B8\uB9AC\uBC0D \uCCAD\uD06C \uC804\uC1A1 \uC2E4\uD328: ${requestId}`);
|
|
1228
|
+
}
|
|
1229
|
+
});
|
|
1230
|
+
res.on("end", () => {
|
|
1231
|
+
try {
|
|
1232
|
+
sock.write(createWsTextFrame(JSON.stringify({
|
|
1233
|
+
type: "http_response_end",
|
|
1234
|
+
request_id: requestId
|
|
1235
|
+
})));
|
|
1236
|
+
} catch {
|
|
1237
|
+
}
|
|
1238
|
+
});
|
|
1239
|
+
res.on("error", (err) => {
|
|
1240
|
+
try {
|
|
1241
|
+
sock.write(createWsTextFrame(JSON.stringify({
|
|
1242
|
+
type: "http_response_error",
|
|
1243
|
+
request_id: requestId,
|
|
1244
|
+
error: err.message
|
|
1245
|
+
})));
|
|
1246
|
+
} catch {
|
|
1247
|
+
}
|
|
1248
|
+
});
|
|
1249
|
+
} else {
|
|
1250
|
+
const chunks = [];
|
|
1251
|
+
res.on("data", (chunk) => chunks.push(chunk));
|
|
1252
|
+
res.on("end", () => {
|
|
1253
|
+
const body = Buffer.concat(chunks);
|
|
1254
|
+
const response = {
|
|
1255
|
+
type: "http_response",
|
|
1256
|
+
request_id: requestId,
|
|
1257
|
+
status: res.statusCode || 200,
|
|
1258
|
+
headers: responseHeaders,
|
|
1259
|
+
body: body.length > 0 ? body.toString("base64") : ""
|
|
1260
|
+
};
|
|
1261
|
+
try {
|
|
1262
|
+
sock.write(createWsTextFrame(JSON.stringify(response)));
|
|
1263
|
+
const methodColor = method === "GET" ? colors.green : method === "POST" ? colors.blue : colors.yellow;
|
|
1264
|
+
log(`${colors.dim}${(/* @__PURE__ */ new Date()).toLocaleTimeString()}${colors.reset} ${methodColor}${method}${colors.reset} ${reqPath} \u2192 ${res.statusCode}`);
|
|
1265
|
+
} catch {
|
|
1266
|
+
warn(`\uC751\uB2F5 \uC804\uC1A1 \uC2E4\uD328: ${requestId}`);
|
|
1267
|
+
}
|
|
1268
|
+
});
|
|
1269
|
+
}
|
|
1138
1270
|
});
|
|
1139
1271
|
localReq.on("error", (err) => {
|
|
1140
1272
|
const response = {
|
|
@@ -1168,7 +1300,8 @@ ${colors.yellow}\uC0AC\uC6A9\uBC95:${colors.reset}
|
|
|
1168
1300
|
|
|
1169
1301
|
${colors.yellow}\uBA85\uB839\uC5B4:${colors.reset}
|
|
1170
1302
|
init \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654 (\uC571 \uC0DD\uC131, MCP \uC124\uC815, SDK \uBB38\uC11C \uB2E4\uC6B4\uB85C\uB4DC)
|
|
1171
|
-
docs SDK \uBB38\uC11C \uB2E4\uC6B4\uB85C\uB4DC/\uC5C5\uB370\uC774\uD2B8 (\
|
|
1303
|
+
docs SDK \uBB38\uC11C \uB2E4\uC6B4\uB85C\uB4DC/\uC5C5\uB370\uC774\uD2B8 (\uBAA8\uB178\uB808\uD3EC \uC790\uB3D9 \uAC10\uC9C0)
|
|
1304
|
+
mcp MCP \uC11C\uBC84 \uC124\uC815 (.mcp.json \uC0DD\uC131/\uC5C5\uB370\uC774\uD2B8, \uBAA8\uB178\uB808\uD3EC \uC790\uB3D9 \uAC10\uC9C0)
|
|
1172
1305
|
deploy <directory> \uC6F9 \uC2A4\uD1A0\uB9AC\uC9C0\uC5D0 \uD30C\uC77C \uBC30\uD3EC (--dev: Dev \uD658\uACBD)
|
|
1173
1306
|
tunnel <port> \uB85C\uCEEC \uC11C\uBE44\uC2A4\uB97C \uC778\uD130\uB137\uC5D0 \uB178\uCD9C
|
|
1174
1307
|
|
|
@@ -1186,7 +1319,7 @@ ${colors.yellow}\uC635\uC158:${colors.reset}
|
|
|
1186
1319
|
-t, --timeout <sec> \uD130\uB110 \uC694\uCCAD \uD0C0\uC784\uC544\uC6C3 (\uCD08, tunnel \uC804\uC6A9)
|
|
1187
1320
|
--max-body <MB> \uD130\uB110 \uCD5C\uB300 \uBC14\uB514 \uD06C\uAE30 (MB, tunnel \uC804\uC6A9)
|
|
1188
1321
|
-d, --dev Dev \uD658\uACBD\uC5D0 \uBC30\uD3EC (deploy \uC804\uC6A9)
|
|
1189
|
-
(docs\uB294 \
|
|
1322
|
+
(docs, mcp\uB294 \uBAA8\uB178\uB808\uD3EC\uB97C \uC790\uB3D9 \uAC10\uC9C0\uD558\uC5EC \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0 \uC0DD\uC131)
|
|
1190
1323
|
-h, --help \uB3C4\uC6C0\uB9D0 \uD45C\uC2DC
|
|
1191
1324
|
-v, --version \uBC84\uC804 \uD45C\uC2DC
|
|
1192
1325
|
|
|
@@ -1197,7 +1330,10 @@ ${colors.yellow}\uBE60\uB978 \uC2DC\uC791:${colors.reset}
|
|
|
1197
1330
|
${colors.dim}# 2. SDK \uBB38\uC11C \uC5C5\uB370\uC774\uD2B8${colors.reset}
|
|
1198
1331
|
npx connectbase docs
|
|
1199
1332
|
|
|
1200
|
-
${colors.dim}# 3.
|
|
1333
|
+
${colors.dim}# 3. MCP \uC11C\uBC84 \uC124\uC815${colors.reset}
|
|
1334
|
+
npx connectbase mcp
|
|
1335
|
+
|
|
1336
|
+
${colors.dim}# 4. Prod \uBC30\uD3EC${colors.reset}
|
|
1201
1337
|
npm run deploy
|
|
1202
1338
|
|
|
1203
1339
|
${colors.dim}# 4. Dev \uD658\uACBD \uBC30\uD3EC (\uB0B4\uBD80 QA\uC6A9)${colors.reset}
|
|
@@ -1240,6 +1376,8 @@ function parseArgs(args) {
|
|
|
1240
1376
|
result.options.timeout = args[++i];
|
|
1241
1377
|
} else if (arg === "--max-body") {
|
|
1242
1378
|
result.options.maxBody = args[++i];
|
|
1379
|
+
} else if (arg === "-a" || arg === "--app") {
|
|
1380
|
+
result.options.appId = args[++i];
|
|
1243
1381
|
} else if (arg === "-d" || arg === "--dev") {
|
|
1244
1382
|
result.options.dev = "true";
|
|
1245
1383
|
} else if (arg === "-h" || arg === "--help") {
|
|
@@ -1285,6 +1423,8 @@ async function main() {
|
|
|
1285
1423
|
}
|
|
1286
1424
|
}
|
|
1287
1425
|
await downloadDocs(docsApiKey);
|
|
1426
|
+
} else if (parsed.command === "mcp") {
|
|
1427
|
+
await setupMcp();
|
|
1288
1428
|
} else if (parsed.command === "deploy") {
|
|
1289
1429
|
const directory = parsed.args[0] || fileConfig.deployDir || ".";
|
|
1290
1430
|
if (!config.apiKey) {
|
|
@@ -1317,6 +1457,9 @@ async function main() {
|
|
|
1317
1457
|
const m = parseInt(parsed.options.maxBody, 10);
|
|
1318
1458
|
if (!isNaN(m) && m > 0) tunnelOpts.maxBody = m;
|
|
1319
1459
|
}
|
|
1460
|
+
if (parsed.options.appId) {
|
|
1461
|
+
tunnelOpts.appId = parsed.options.appId;
|
|
1462
|
+
}
|
|
1320
1463
|
await startTunnel(port, config, tunnelOpts);
|
|
1321
1464
|
} else {
|
|
1322
1465
|
error(`\uC54C \uC218 \uC5C6\uB294 \uBA85\uB839\uC5B4: ${parsed.command}`);
|