connectbase-client 2.0.0 → 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/CHANGELOG.md CHANGED
@@ -3,6 +3,70 @@
3
3
  본 SDK 의 모든 주요 변경사항을 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/) 형식으로 기록합니다.
4
4
  버전은 [Semantic Versioning](https://semver.org/lang/ko/) 을 따릅니다.
5
5
 
6
+ ## [3.0.1] - 2026-04-28
7
+
8
+ ### Fixed
9
+
10
+ - `npx connectbase docs` 가 인증 없이 곧장 문서를 받도록 수정. 백엔드 `/v1/storages/webs/claude-md`
11
+ 는 public 라우트인데 CLI 가 불필요하게 브라우저 인증 → 앱 선택 → Public Key 발급을 강제하던
12
+ 흐름을 제거. 캐시된 publicKey 가 있으면 문서에 박아주고, 없으면 백엔드가 placeholder
13
+ (`YOUR_PUBLIC_KEY_HERE`) 로 대체해 그대로 다운로드.
14
+
15
+ ## [3.0.0] - 2026-04-28 — BREAKING
16
+
17
+ 게임 서버 mechanism-only 재설계. ConnectBase 가 박아두던 게임 룰 (파티/로비/랭킹/매치메이킹/
18
+ killcam/highlight) 을 모두 제거하고, primitive (`cb.game.matchqueue`, `cb.game.leaderboard`,
19
+ `cb.game.scripts`) + 사용자 Lua 로 대체. 1:1 마이그레이션은 [MIGRATION_v3.md](../../../docs/sdk/MIGRATION_v3.md).
20
+
21
+ ### Removed (BREAKING)
22
+
23
+ - **Lobby**: `listLobbies`, `createLobby`, `getLobby`, `joinLobby`, `leaveLobby`, `toggleReady`,
24
+ `startGame`, `kickPlayer`, `updateLobby`, `sendLobbyChat`, `invitePlayer`, `acceptInvite`,
25
+ `declineInvite`, `getPlayerInvites` 메서드 + 관련 타입 (`LobbyInfo`, `CreateLobbyRequest`,
26
+ `UpdateLobbyRequest`, `LobbyInvite`)
27
+ - **Party**: `createParty`, `joinParty`, `acceptPartyInvite`, `declinePartyInvite`,
28
+ `leaveParty`, `kickFromParty`, `inviteToParty`, `getParty`, `getMyParties`, `setReady`,
29
+ `setPartyMetadata`, `getPartyInvites`, `sendPartyChat` + `PartyInfo`, `PartyInvite`
30
+ - **Matchmaking**: `joinQueue`, `leaveQueue`, `getMatchStatus` + `JoinQueueRequest`,
31
+ `MatchmakingTicket`
32
+ - **Ranking**: `getLeaderboard`, `getPlayerStats`, `getPlayerRank` + `LeaderboardEntry` (구
33
+ player_id/rating/tier/wins/losses 시그니처. 신규 `LeaderboardScoreEntry` 가 대체).
34
+ - **Killcam/Highlight**: `cb.game.replay.killcam(...)`, `cb.game.replay.highlights(...)`
35
+ 관련 endpoint 가 백엔드에서 제거되어 SDK 호출 시 404. 사용자가 `cb.game.replay.download`
36
+ 로 raw frame 받아 클라/Lua 에서 직접 처리.
37
+
38
+ ### Added — v3 primitive
39
+
40
+ - **Matchqueue** (`cb.game.matchqueue.*` → `enqueueMatch / listMatchqueue / cancelMatch`):
41
+ rating/region 등 attributes 는 free-form. 매칭 알고리즘은 사용자 Lua 가 list → notify.
42
+ - **Leaderboard** (`submitScore / getTopScores / getMemberRank / getRankAround / resetLeaderboard / removeFromLeaderboard`):
43
+ ELO/티어/시즌 박지 않음. 시즌은 key suffix (`ranks:2026q2`) 로 분리, 점수 공식은 Lua.
44
+ - **Scripts** (`uploadScript / listScripts / getScript / listScriptVersions /
45
+ activateScript / rollbackScript / disableScript`): Lua 스크립트 영속 메타 + 버전 + hot reload.
46
+ - 신규 타입: `MatchqueueTicket`, `MatchqueueListResponse`, `LeaderboardScoreEntry`,
47
+ `LeaderboardListResponse`, `ScriptMeta`, `ScriptVersion`, `ScriptListResponse`,
48
+ `ScriptVersionListResponse`, `ScriptDetailResponse`.
49
+
50
+ ### Backend 영향
51
+
52
+ - game-server v3 부터 `/v1/game/:appID/matchqueue/:key/*`, `/leaderboards/:key/*`,
53
+ `/scripts/*` 라우트가 유일한 게임 메커니즘 endpoint. lobby/party/ranking/matchmaking
54
+ 엔드포인트는 모두 404.
55
+ - 자세한 변경: [`docs/sdk/MIGRATION_v3.md`](../../../docs/sdk/MIGRATION_v3.md),
56
+ [`docs/game-server/RECIPES.md`](../../../docs/game-server/RECIPES.md).
57
+
58
+ ### Migration 요약
59
+
60
+ ```ts
61
+ // Before (v2.x)
62
+ await cb.game.matchmaking.join({ mode: "ranked", rating: 1500 })
63
+ await cb.game.ranking.submit({ leaderboard: "elo", score: 2150 })
64
+
65
+ // After (v3.0)
66
+ await cb.game.enqueueMatch(appId, "ranked", userId, { rating: 1500 })
67
+ await cb.game.submitScore(appId, "elo", userId, 32, "incr")
68
+ ```
69
+
6
70
  ## [2.0.0] - 2026-04-27 — BREAKING
7
71
 
8
72
  Realtime presence/typing 단일화의 최종 단계. 1.13 deprecation 단계를 건너뛰고 즉시
package/dist/cli.js CHANGED
@@ -952,70 +952,6 @@ function detectMonorepo(gitRoot) {
952
952
  }
953
953
  return result;
954
954
  }
955
- async function ensureDocsPublicKey(config) {
956
- if (config.publicKey) return config.publicKey;
957
- const rcPath = path2.join(process.cwd(), ".connectbaserc");
958
- const baseUrl = config.baseUrl || DEFAULT_BASE_URL;
959
- const readRc = () => {
960
- if (!fs2.existsSync(rcPath)) return {};
961
- try {
962
- return JSON.parse(fs2.readFileSync(rcPath, "utf-8"));
963
- } catch {
964
- return {};
965
- }
966
- };
967
- const writeRc = (data) => {
968
- fs2.writeFileSync(rcPath, JSON.stringify(data, null, 2) + "\n");
969
- addToGitignore(".connectbaserc");
970
- };
971
- let secretKey = config.secretKey;
972
- if (!secretKey) {
973
- info("Public Key \uBC1C\uAE09\uC744 \uC704\uD574 \uBE0C\uB77C\uC6B0\uC800 \uC778\uC99D\uC744 \uC2DC\uC791\uD569\uB2C8\uB2E4...");
974
- secretKey = await browserAuthFlow();
975
- const rc2 = readRc();
976
- rc2.secretKey = secretKey;
977
- writeRc(rc2);
978
- config.secretKey = secretKey;
979
- }
980
- const savedAppId = readRc().tunnelAppId || "";
981
- const resolved = await resolveApp(secretKey, baseUrl, savedAppId);
982
- let publicKey = resolved.publicKey;
983
- if (!publicKey) {
984
- info("Public Key \uBC1C\uAE09 \uC911...");
985
- const res = await makeRequest(
986
- `${baseUrl}/v1/public/cli/apps/${resolved.appId}/public-keys`,
987
- "POST",
988
- { "X-Public-Key": secretKey },
989
- JSON.stringify({ name: "CLI Docs Key" })
990
- );
991
- if (res.status !== 201) {
992
- const data2 = res.data;
993
- const detail = data2?.error || data2?.message || `HTTP ${res.status}`;
994
- error(`Public Key \uBC1C\uAE09 \uC2E4\uD328: ${detail}`);
995
- process.exit(1);
996
- }
997
- const data = res.data;
998
- if (!data.key) {
999
- error("Public Key \uBC1C\uAE09 \uC751\uB2F5\uC774 \uBE44\uC5B4 \uC788\uC2B5\uB2C8\uB2E4");
1000
- process.exit(1);
1001
- }
1002
- publicKey = data.key;
1003
- success("Public Key \uBC1C\uAE09 \uC644\uB8CC");
1004
- }
1005
- const rc = readRc();
1006
- let changed = false;
1007
- if (rc.publicKey !== publicKey) {
1008
- rc.publicKey = publicKey;
1009
- changed = true;
1010
- }
1011
- if (rc.tunnelAppId !== resolved.appId) {
1012
- rc.tunnelAppId = resolved.appId;
1013
- changed = true;
1014
- }
1015
- if (changed) writeRc(rc);
1016
- config.publicKey = publicKey;
1017
- return publicKey;
1018
- }
1019
955
  async function downloadDocs(publicKey, templates, baseDir) {
1020
956
  if (!baseDir) {
1021
957
  baseDir = getProjectRoot();
@@ -2165,8 +2101,7 @@ async function main() {
2165
2101
  setupRoot: parsed.options.setupRoot === "true"
2166
2102
  });
2167
2103
  } else if (parsed.command === "docs") {
2168
- const docsPublicKey = await ensureDocsPublicKey(config);
2169
- await downloadDocs(docsPublicKey);
2104
+ await downloadDocs(config.publicKey || "");
2170
2105
  } else if (parsed.command === "mcp") {
2171
2106
  await setupMcp();
2172
2107
  } else if (parsed.command === "deploy") {