connectbase-client 0.15.0 → 0.16.0

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 CHANGED
@@ -108,7 +108,18 @@ function handleTunnelError(msg, appId, localPort) {
108
108
  }
109
109
 
110
110
  // src/cli.ts
111
- var VERSION = "0.10.6";
111
+ function getPackageVersion() {
112
+ try {
113
+ const pkgPath = path2.join(__dirname, "..", "package.json");
114
+ if (fs2.existsSync(pkgPath)) {
115
+ const pkg = JSON.parse(fs2.readFileSync(pkgPath, "utf-8"));
116
+ return pkg.version || "0.0.0";
117
+ }
118
+ } catch {
119
+ }
120
+ return "0.15.1";
121
+ }
122
+ var VERSION = getPackageVersion();
112
123
  var DEFAULT_BASE_URL = "https://api.connectbase.world";
113
124
  var colors = {
114
125
  reset: "\x1B[0m",
@@ -1043,6 +1054,229 @@ async function setupClaudeCode(publicKey, secretKey, projectRoot) {
1043
1054
  await downloadDocs(publicKey, void 0, root);
1044
1055
  await setupMcp(secretKey);
1045
1056
  }
1057
+ async function fetchLatestVersion(packageName) {
1058
+ try {
1059
+ const res = await makeRequest(
1060
+ `https://registry.npmjs.org/${packageName}/latest`,
1061
+ "GET",
1062
+ {}
1063
+ );
1064
+ if (res.status === 200) {
1065
+ const data = res.data;
1066
+ return data.version || null;
1067
+ }
1068
+ } catch {
1069
+ }
1070
+ return null;
1071
+ }
1072
+ function compareVersions(a, b) {
1073
+ const pa = a.split(".").map(Number);
1074
+ const pb = b.split(".").map(Number);
1075
+ for (let i = 0; i < 3; i++) {
1076
+ const diff = (pa[i] || 0) - (pb[i] || 0);
1077
+ if (diff !== 0) return diff > 0 ? 1 : -1;
1078
+ }
1079
+ return 0;
1080
+ }
1081
+ function findSubPackagesWithConfig(gitRoot) {
1082
+ const results = [];
1083
+ const candidates = ["apps", "packages", "projects", "services", "libs"];
1084
+ for (const candidate of candidates) {
1085
+ const dir = path2.join(gitRoot, candidate);
1086
+ if (!fs2.existsSync(dir)) continue;
1087
+ try {
1088
+ const entries = fs2.readdirSync(dir, { withFileTypes: true });
1089
+ for (const entry of entries) {
1090
+ if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
1091
+ const subDir = path2.join(dir, entry.name);
1092
+ if (fs2.existsSync(path2.join(subDir, ".connectbaserc"))) {
1093
+ results.push(subDir);
1094
+ }
1095
+ }
1096
+ } catch {
1097
+ }
1098
+ }
1099
+ try {
1100
+ const entries = fs2.readdirSync(gitRoot, { withFileTypes: true });
1101
+ for (const entry of entries) {
1102
+ if (!entry.isDirectory() || entry.name.startsWith(".") || candidates.includes(entry.name)) continue;
1103
+ if (entry.name === "node_modules") continue;
1104
+ const subDir = path2.join(gitRoot, entry.name);
1105
+ if (fs2.existsSync(path2.join(subDir, ".connectbaserc")) && !results.includes(subDir)) {
1106
+ results.push(subDir);
1107
+ }
1108
+ }
1109
+ } catch {
1110
+ }
1111
+ return results;
1112
+ }
1113
+ async function update(config, opts) {
1114
+ log(`
1115
+ ${colors.cyan}ConnectBase Update${colors.reset}
1116
+ `);
1117
+ const gitRoot = getGitRoot();
1118
+ const projectRoot = gitRoot || process.cwd();
1119
+ const monorepo = detectMonorepo(projectRoot);
1120
+ info("\uCD5C\uC2E0 \uBC84\uC804 \uD655\uC778 \uC911...");
1121
+ const latestVersion = await fetchLatestVersion("connectbase-client");
1122
+ if (latestVersion) {
1123
+ const cmp = compareVersions(VERSION, latestVersion);
1124
+ if (cmp >= 0) {
1125
+ success(`\uCD5C\uC2E0 \uBC84\uC804\uC785\uB2C8\uB2E4 (v${VERSION})`);
1126
+ } else {
1127
+ warn(`\uC0C8 \uBC84\uC804\uC774 \uC788\uC2B5\uB2C8\uB2E4: v${VERSION} \u2192 v${colors.green}${latestVersion}${colors.reset}`);
1128
+ log(` ${colors.cyan}npm install connectbase-client@latest${colors.reset}`);
1129
+ log(` ${colors.cyan}pnpm add connectbase-client@latest${colors.reset}`);
1130
+ log("");
1131
+ }
1132
+ } else {
1133
+ warn("npm \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0\uC11C \uBC84\uC804 \uC815\uBCF4\uB97C \uAC00\uC838\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
1134
+ }
1135
+ if (opts.checkOnly) {
1136
+ return;
1137
+ }
1138
+ if (monorepo.type !== "none") {
1139
+ info(`\uBAA8\uB178\uB808\uD3EC \uAC10\uC9C0: ${monorepo.type} (\uB8E8\uD2B8: ${projectRoot})`);
1140
+ const subPackages = findSubPackagesWithConfig(projectRoot);
1141
+ if (subPackages.length > 0) {
1142
+ info(`ConnectBase\uB97C \uC0AC\uC6A9\uD558\uB294 \uC11C\uBE0C \uD328\uD0A4\uC9C0 ${subPackages.length}\uAC1C \uBC1C\uACAC:`);
1143
+ for (const sp of subPackages) {
1144
+ log(` ${colors.dim}\u2022 ${path2.relative(projectRoot, sp)}${colors.reset}`);
1145
+ }
1146
+ }
1147
+ }
1148
+ if (!opts.skipDocs) {
1149
+ log("");
1150
+ info("SDK \uBB38\uC11C \uC5C5\uB370\uC774\uD2B8 \uC911...");
1151
+ let docsKey = config.publicKey || config.secretKey;
1152
+ if (!docsKey) {
1153
+ const rootRcPath = path2.join(projectRoot, ".connectbaserc");
1154
+ if (fs2.existsSync(rootRcPath)) {
1155
+ try {
1156
+ const rc = JSON.parse(fs2.readFileSync(rootRcPath, "utf-8"));
1157
+ docsKey = rc.publicKey || rc.secretKey;
1158
+ } catch {
1159
+ }
1160
+ }
1161
+ }
1162
+ if (!docsKey && monorepo.type !== "none") {
1163
+ const subPackages = findSubPackagesWithConfig(projectRoot);
1164
+ for (const sp of subPackages) {
1165
+ try {
1166
+ const rc = JSON.parse(fs2.readFileSync(path2.join(sp, ".connectbaserc"), "utf-8"));
1167
+ if (rc.publicKey || rc.secretKey) {
1168
+ docsKey = rc.publicKey || rc.secretKey;
1169
+ break;
1170
+ }
1171
+ } catch {
1172
+ }
1173
+ }
1174
+ }
1175
+ if (docsKey) {
1176
+ await downloadDocs(docsKey, void 0, projectRoot);
1177
+ } else {
1178
+ warn("Public Key\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4 \uBB38\uC11C \uC5C5\uB370\uC774\uD2B8\uB97C \uAC74\uB108\uB701\uB2C8\uB2E4");
1179
+ info(".connectbaserc \uD30C\uC77C\uC774\uB098 --public-key \uC635\uC158\uC73C\uB85C \uD0A4\uB97C \uC9C0\uC815\uD558\uC138\uC694");
1180
+ }
1181
+ }
1182
+ if (!opts.skipMcp) {
1183
+ log("");
1184
+ const mcpConfigPath = path2.join(projectRoot, ".mcp.json");
1185
+ if (fs2.existsSync(mcpConfigPath)) {
1186
+ let secretKey = config.secretKey;
1187
+ if (!secretKey) {
1188
+ const rootRcPath = path2.join(projectRoot, ".connectbaserc");
1189
+ if (fs2.existsSync(rootRcPath)) {
1190
+ try {
1191
+ const rc = JSON.parse(fs2.readFileSync(rootRcPath, "utf-8"));
1192
+ secretKey = rc.secretKey;
1193
+ } catch {
1194
+ }
1195
+ }
1196
+ }
1197
+ if (!secretKey && monorepo.type !== "none") {
1198
+ const subPackages = findSubPackagesWithConfig(projectRoot);
1199
+ for (const sp of subPackages) {
1200
+ try {
1201
+ const rc = JSON.parse(fs2.readFileSync(path2.join(sp, ".connectbaserc"), "utf-8"));
1202
+ if (rc.secretKey) {
1203
+ secretKey = rc.secretKey;
1204
+ break;
1205
+ }
1206
+ } catch {
1207
+ }
1208
+ }
1209
+ }
1210
+ if (secretKey) {
1211
+ try {
1212
+ const mcpConfig = JSON.parse(fs2.readFileSync(mcpConfigPath, "utf-8"));
1213
+ const servers = mcpConfig.mcpServers || {};
1214
+ if (servers["connect-base"]) {
1215
+ servers["connect-base"] = {
1216
+ type: "http",
1217
+ url: "https://mcp.connectbase.world/mcp",
1218
+ headers: { Authorization: `Bearer ${secretKey}` }
1219
+ };
1220
+ mcpConfig.mcpServers = servers;
1221
+ fs2.writeFileSync(mcpConfigPath, JSON.stringify(mcpConfig, null, 2) + "\n");
1222
+ success("MCP \uC124\uC815 \uC5C5\uB370\uC774\uD2B8 \uC644\uB8CC");
1223
+ } else {
1224
+ info('.mcp.json\uC5D0 connect-base \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. "connectbase mcp"\uB85C \uC124\uC815\uD558\uC138\uC694');
1225
+ }
1226
+ } catch {
1227
+ warn(".mcp.json \uC5C5\uB370\uC774\uD2B8 \uC2E4\uD328");
1228
+ }
1229
+ } else {
1230
+ info("Secret Key\uAC00 \uC5C6\uC5B4 MCP \uC124\uC815 \uC5C5\uB370\uC774\uD2B8\uB97C \uAC74\uB108\uB701\uB2C8\uB2E4");
1231
+ }
1232
+ } else {
1233
+ info('.mcp.json\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. "connectbase mcp"\uB85C \uCD5C\uCD08 \uC124\uC815\uD558\uC138\uC694');
1234
+ }
1235
+ }
1236
+ if (opts.setupRoot || monorepo.type !== "none" && monorepo.isSubPackage) {
1237
+ log("");
1238
+ setupMonorepoRoot(projectRoot, monorepo);
1239
+ }
1240
+ log(`
1241
+ ${colors.green}\uC5C5\uB370\uC774\uD2B8 \uC644\uB8CC!${colors.reset}
1242
+ `);
1243
+ }
1244
+ function setupMonorepoRoot(projectRoot, monorepo) {
1245
+ const rootPkgPath = path2.join(projectRoot, "package.json");
1246
+ if (!fs2.existsSync(rootPkgPath)) {
1247
+ warn("\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0 package.json\uC774 \uC5C6\uC5B4 \uD3B8\uC758 \uC2A4\uD06C\uB9BD\uD2B8\uB97C \uCD94\uAC00\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
1248
+ return;
1249
+ }
1250
+ try {
1251
+ const pkg = JSON.parse(fs2.readFileSync(rootPkgPath, "utf-8"));
1252
+ if (!pkg.scripts) pkg.scripts = {};
1253
+ let changed = false;
1254
+ if (!pkg.scripts["cb:update"]) {
1255
+ pkg.scripts["cb:update"] = "npx connectbase-client update";
1256
+ changed = true;
1257
+ }
1258
+ if (!pkg.scripts["cb:docs"]) {
1259
+ pkg.scripts["cb:docs"] = "npx connectbase-client docs";
1260
+ changed = true;
1261
+ }
1262
+ if (!pkg.scripts["cb:mcp"]) {
1263
+ pkg.scripts["cb:mcp"] = "npx connectbase-client mcp";
1264
+ changed = true;
1265
+ }
1266
+ if (changed) {
1267
+ fs2.writeFileSync(rootPkgPath, JSON.stringify(pkg, null, 2) + "\n");
1268
+ success("\uBAA8\uB178\uB808\uD3EC \uB8E8\uD2B8\uC5D0 \uD3B8\uC758 \uC2A4\uD06C\uB9BD\uD2B8 \uCD94\uAC00 \uC644\uB8CC");
1269
+ log(` ${colors.dim}\uC0AC\uC6A9\uBC95:${colors.reset}`);
1270
+ log(` ${colors.cyan}${monorepo.type === "pnpm" ? "pnpm" : monorepo.type === "yarn" ? "yarn" : "npm run"} cb:update${colors.reset} \u2014 SDK \uC5C5\uB370\uC774\uD2B8 + \uBB38\uC11C \uAC31\uC2E0`);
1271
+ log(` ${colors.cyan}${monorepo.type === "pnpm" ? "pnpm" : monorepo.type === "yarn" ? "yarn" : "npm run"} cb:docs${colors.reset} \u2014 \uBB38\uC11C\uB9CC \uAC31\uC2E0`);
1272
+ log(` ${colors.cyan}${monorepo.type === "pnpm" ? "pnpm" : monorepo.type === "yarn" ? "yarn" : "npm run"} cb:mcp${colors.reset} \u2014 MCP \uC124\uC815`);
1273
+ } else {
1274
+ info("\uBAA8\uB178\uB808\uD3EC \uB8E8\uD2B8\uC5D0 \uC774\uBBF8 \uD3B8\uC758 \uC2A4\uD06C\uB9BD\uD2B8\uAC00 \uC124\uC815\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4");
1275
+ }
1276
+ } catch {
1277
+ warn("\uB8E8\uD2B8 package.json \uC218\uC815\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4");
1278
+ }
1279
+ }
1046
1280
  function createWsTextFrame(payload) {
1047
1281
  const data = Buffer.from(payload, "utf-8");
1048
1282
  const len = data.length;
@@ -1583,6 +1817,7 @@ ${colors.yellow}\uC0AC\uC6A9\uBC95:${colors.reset}
1583
1817
 
1584
1818
  ${colors.yellow}\uBA85\uB839\uC5B4:${colors.reset}
1585
1819
  init \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654 (\uC571 \uC0DD\uC131, MCP \uC124\uC815, SDK \uBB38\uC11C \uB2E4\uC6B4\uB85C\uB4DC)
1820
+ update SDK \uBC84\uC804 \uCCB4\uD06C + \uBB38\uC11C/MCP \uC77C\uAD04 \uC5C5\uB370\uC774\uD2B8 (\uBAA8\uB178\uB808\uD3EC \uB8E8\uD2B8 \uC9C0\uC6D0)
1586
1821
  docs SDK \uBB38\uC11C \uB2E4\uC6B4\uB85C\uB4DC/\uC5C5\uB370\uC774\uD2B8 (\uBAA8\uB178\uB808\uD3EC \uC790\uB3D9 \uAC10\uC9C0)
1587
1822
  mcp MCP \uC11C\uBC84 \uC124\uC815 (.mcp.json \uC0DD\uC131/\uC5C5\uB370\uC774\uD2B8, \uBAA8\uB178\uB808\uD3EC \uC790\uB3D9 \uAC10\uC9C0)
1588
1823
  deploy <directory> \uC6F9 \uC2A4\uD1A0\uB9AC\uC9C0\uC5D0 \uD30C\uC77C \uBC30\uD3EC (--dev: Dev \uD658\uACBD)
@@ -1603,7 +1838,11 @@ ${colors.yellow}\uC635\uC158:${colors.reset}
1603
1838
  --max-body <MB> \uD130\uB110 \uCD5C\uB300 \uBC14\uB514 \uD06C\uAE30 (MB, tunnel \uC804\uC6A9)
1604
1839
  --force \uD130\uB110 lockfile \uBB34\uC2DC (\uC911\uBCF5 \uC2E4\uD589 \uAC15\uC81C, tunnel \uC804\uC6A9)
1605
1840
  -d, --dev Dev \uD658\uACBD\uC5D0 \uBC30\uD3EC (deploy \uC804\uC6A9)
1606
- (docs, mcp\uB294 \uBAA8\uB178\uB808\uD3EC\uB97C \uC790\uB3D9 \uAC10\uC9C0\uD558\uC5EC \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0 \uC0DD\uC131)
1841
+ --check \uBC84\uC804\uB9CC \uD655\uC778 (update \uC804\uC6A9)
1842
+ --skip-docs \uBB38\uC11C \uC5C5\uB370\uC774\uD2B8 \uAC74\uB108\uB6F0\uAE30 (update \uC804\uC6A9)
1843
+ --skip-mcp MCP \uC5C5\uB370\uC774\uD2B8 \uAC74\uB108\uB6F0\uAE30 (update \uC804\uC6A9)
1844
+ --setup-root \uBAA8\uB178\uB808\uD3EC \uB8E8\uD2B8\uC5D0 \uD3B8\uC758 \uC2A4\uD06C\uB9BD\uD2B8 \uCD94\uAC00 (update \uC804\uC6A9)
1845
+ (docs, mcp, update\uB294 \uBAA8\uB178\uB808\uD3EC\uB97C \uC790\uB3D9 \uAC10\uC9C0\uD558\uC5EC \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0 \uC0DD\uC131)
1607
1846
  -h, --help \uB3C4\uC6C0\uB9D0 \uD45C\uC2DC
1608
1847
  -v, --version \uBC84\uC804 \uD45C\uC2DC
1609
1848
 
@@ -1611,10 +1850,16 @@ ${colors.yellow}\uBE60\uB978 \uC2DC\uC791:${colors.reset}
1611
1850
  ${colors.dim}# 1. \uCD08\uAE30\uD654 (\uCD5C\uCD08 1\uD68C)${colors.reset}
1612
1851
  npx connectbase-client init
1613
1852
 
1614
- ${colors.dim}# 2. SDK \uBB38\uC11C \uC5C5\uB370\uC774\uD2B8${colors.reset}
1853
+ ${colors.dim}# 2. SDK \uC804\uCCB4 \uC5C5\uB370\uC774\uD2B8 (\uBC84\uC804 \uCCB4\uD06C + \uBB38\uC11C + MCP)${colors.reset}
1854
+ npx connectbase update
1855
+
1856
+ ${colors.dim}# 2-1. \uBAA8\uB178\uB808\uD3EC \uB8E8\uD2B8\uC5D0 \uD3B8\uC758 \uC2A4\uD06C\uB9BD\uD2B8 \uC124\uCE58${colors.reset}
1857
+ npx connectbase update --setup-root
1858
+
1859
+ ${colors.dim}# 3. SDK \uBB38\uC11C\uB9CC \uC5C5\uB370\uC774\uD2B8${colors.reset}
1615
1860
  npx connectbase docs
1616
1861
 
1617
- ${colors.dim}# 3. MCP \uC11C\uBC84 \uC124\uC815${colors.reset}
1862
+ ${colors.dim}# 4. MCP \uC11C\uBC84 \uC124\uC815${colors.reset}
1618
1863
  npx connectbase mcp
1619
1864
 
1620
1865
  ${colors.dim}# 4. Prod \uBC30\uD3EC${colors.reset}
@@ -1671,6 +1916,14 @@ function parseArgs(args) {
1671
1916
  result.options.force = "true";
1672
1917
  } else if (arg === "-d" || arg === "--dev") {
1673
1918
  result.options.dev = "true";
1919
+ } else if (arg === "--check") {
1920
+ result.options.check = "true";
1921
+ } else if (arg === "--skip-docs") {
1922
+ result.options.skipDocs = "true";
1923
+ } else if (arg === "--skip-mcp") {
1924
+ result.options.skipMcp = "true";
1925
+ } else if (arg === "--setup-root") {
1926
+ result.options.setupRoot = "true";
1674
1927
  } else if (arg === "-h" || arg === "--help") {
1675
1928
  result.options.help = "true";
1676
1929
  } else if (arg === "-v" || arg === "--version") {
@@ -1705,6 +1958,13 @@ async function main() {
1705
1958
  };
1706
1959
  if (parsed.command === "init") {
1707
1960
  await init();
1961
+ } else if (parsed.command === "update") {
1962
+ await update(config, {
1963
+ checkOnly: parsed.options.check === "true",
1964
+ skipDocs: parsed.options.skipDocs === "true",
1965
+ skipMcp: parsed.options.skipMcp === "true",
1966
+ setupRoot: parsed.options.setupRoot === "true"
1967
+ });
1708
1968
  } else if (parsed.command === "docs") {
1709
1969
  let docsPublicKey = config.publicKey ?? config.publicKey;
1710
1970
  if (!docsPublicKey) {