connectbase-client 6.2.0 → 6.3.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/CHANGELOG.md +87 -5
- package/README.md +24 -19
- package/dist/cli.js +189 -158
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,88 @@
|
|
|
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
|
+
## [6.3.0] - 2026-09-07
|
|
7
|
+
|
|
8
|
+
### Fixed — Secret Key 가 만료되면 `init` 을 다시 돌릴 수 없던 문제
|
|
9
|
+
|
|
10
|
+
`init` 은 `.connectbaserc` 에 저장된 Secret Key 를 그대로 집어 씁니다. 그 키가 만료되거나
|
|
11
|
+
취소되면 앱 목록 조회가 401 을 받고 **그대로 종료**했는데, 다시 실행해도 같은 죽은 키를
|
|
12
|
+
다시 집어 오므로 같은 자리에서 또 죽었습니다. `.connectbaserc` 를 손으로 지우는 것 말고는
|
|
13
|
+
빠져나올 길이 없었습니다.
|
|
14
|
+
|
|
15
|
+
이제 401 을 받으면 **그 자리에서 재인증**합니다 (브라우저 로그인 또는 직접 입력). 새 키는
|
|
16
|
+
즉시 `.connectbaserc` 에 저장되고 `.mcp.json` 에도 반영되므로, 파일을 지우는 절차가
|
|
17
|
+
사라졌습니다. 비대화형(`--yes`)에서는 프롬프트 대신 새 키를 넘기라고 명확히 안내합니다.
|
|
18
|
+
|
|
19
|
+
`connectbase mcp` 도 같습니다 — 넘겨받은 키가 살아 있는지 **먼저 확인**한 뒤 `.mcp.json`
|
|
20
|
+
에 씁니다. 종전에는 만료된 키를 그대로 적고 "설정 완료" 라고 말해서, 실패가 Claude Code 의
|
|
21
|
+
401 로만 드러났습니다. (네트워크 오류로는 막지 않습니다 — 오프라인에서도 설정은 써집니다.)
|
|
22
|
+
|
|
23
|
+
재초기화 확인 프롬프트의 기본값도 "계속" 으로 바꿨습니다. 같은 앱을 고르면 Public Key 를
|
|
24
|
+
재사용하므로 재실행은 안전한 동작입니다.
|
|
25
|
+
|
|
26
|
+
### Fixed — `npm run deploy` 가 `command not found` 로 죽던 문제
|
|
27
|
+
|
|
28
|
+
`init` 이 `package.json` 에 deploy 스크립트만 넣고 CLI 를 의존성으로 선언하지 않아서,
|
|
29
|
+
SDK 가 설치되지 않은 프로젝트에서 마지막 안내대로 `npm run deploy` 를 치면
|
|
30
|
+
`connectbase: command not found` 가 났습니다. 이제 `devDependencies` 에
|
|
31
|
+
`connectbase-client` 를 함께 선언하고, 설치가 필요하면 마지막 안내에 `npm install` 을
|
|
32
|
+
포함합니다. (`npx --yes` 를 스크립트에 박는 우회는 쓰지 않았습니다 — 빌드마다
|
|
33
|
+
레지스트리에서 최신본을 끌어오면 재현 가능한 빌드가 아닙니다.)
|
|
34
|
+
|
|
35
|
+
빌드 스크립트가 있으면 deploy 스크립트는 이제 build 명령을 **복사하지 않고**
|
|
36
|
+
`npm run build && connectbase deploy <dir>` 로 위임합니다. 복사본은 build 가 바뀌어도
|
|
37
|
+
갱신되지 않아 조용히 낡습니다.
|
|
38
|
+
|
|
39
|
+
### Fixed — `--base-url` / `CONNECTBASE_BASE_URL` 이 `init` 에서 무시되던 문제
|
|
40
|
+
|
|
41
|
+
`init` 과 브라우저 로그인, SDK 문서 다운로드, MCP 설정이 상수를 직접 참조해, 로컬이나
|
|
42
|
+
스테이징 스택을 지정해도 프로덕션 API 로 갔습니다. 브라우저 로그인 URL 도 같은 환경을
|
|
43
|
+
가리키도록 API URL 에서 파생시킵니다.
|
|
44
|
+
|
|
45
|
+
### Fixed — CLI 버전을 빌드 시점에 주입
|
|
46
|
+
|
|
47
|
+
종전에는 런타임에 `package.json` 을 찾아 읽고, 실패하면 하드코딩된 옛 버전(`3.25.1`)으로
|
|
48
|
+
폴백했습니다. 그 폴백은 조용히 낡았고, 단순히 `--version` 이 틀리는 데서 끝나지 않았습니다 —
|
|
49
|
+
`init` 이 사용자의 `package.json` 에 적는 의존성 범위에까지 그 값이 들어갑니다.
|
|
50
|
+
|
|
51
|
+
### Fixed — git 저장소가 아닌 폴더에서 `fatal:` 오류가 출력되던 문제
|
|
52
|
+
|
|
53
|
+
`init` 이 프로젝트 루트를 찾을 때 쓰는 `git rev-parse` 의 stderr 가 그대로 새어 나와,
|
|
54
|
+
정상 경로인데도 화면에 `fatal: … 깃 저장소가 아닙니다` 가 세 번 찍혔습니다.
|
|
55
|
+
|
|
56
|
+
### Changed — 문서의 `npx` 예제가 패키지 이름을 쓰도록 통일
|
|
57
|
+
|
|
58
|
+
`connectbase` 는 이 패키지가 설치하는 **bin 이름**이지 npm 패키지 이름이 아닙니다. npx 는
|
|
59
|
+
로컬 `node_modules/.bin` 을 먼저 보고, 없으면 그 이름의 **패키지**를 레지스트리에서 받으려
|
|
60
|
+
합니다. 그래서 `npx connectbase init` 은 이 패키지가 이미 설치된 프로젝트에서만 동작하고,
|
|
61
|
+
아무것도 없는 새 폴더 — 즉 `init` 을 처음 실행하는 바로 그 상황 — 에서는 npm 404 가 났습니다.
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
$ npx connectbase init
|
|
65
|
+
npm error 404 Not Found - GET https://registry.npmjs.org/connectbase
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
전역 설치(`npm i -g connectbase-client`)로 PATH 에 `connectbase` 가 있어도 마찬가지입니다.
|
|
69
|
+
npx 는 PATH 를 보지 않습니다.
|
|
70
|
+
|
|
71
|
+
규칙을 하나로 정리했습니다:
|
|
72
|
+
|
|
73
|
+
| 형태 | 이름 | 왜 |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| `npx …` | `connectbase-client` | npx 인자는 **패키지** 이름이다. 설치 여부와 무관하게 항상 동작 |
|
|
76
|
+
| 전역 설치 후 / `npm run` 스크립트 / `node_modules/.bin` | `connectbase` | 짧은 bin 이름. 0.16.1 에서 정한 용도 그대로 |
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npx connectbase-client init # 설치 전 — 패키지 이름
|
|
80
|
+
npm install # init 이 devDependencies 에 넣어 둔 것을 설치
|
|
81
|
+
npm run deploy # 내부적으로 `connectbase deploy ./dist` — 짧은 이름 그대로
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
`connectbase` 를 실제 패키지로도 발행하려 했으나, npm 이 2013 년의 `connect-base` 와
|
|
85
|
+
이름이 유사하다는 이유로 거절했습니다 (`@connectbase` 스코프도 타인이 사용 중). 이름을
|
|
86
|
+
확보하면 `npx connectbase` 도 함께 동작하게 할 예정입니다.
|
|
87
|
+
|
|
6
88
|
## [6.2.0] - 2026-09-06
|
|
7
89
|
|
|
8
90
|
### Added — 웹 스토리지 관리 API 에 Secret Key 전송
|
|
@@ -23,7 +105,7 @@ production 승격이 가능했습니다 — 공개된 사이트에서 키를 뽑
|
|
|
23
105
|
|
|
24
106
|
**이 버전은 아무것도 깨뜨리지 않습니다.** Secret Key 가 없으면 경고만 하고 그대로 진행합니다.
|
|
25
107
|
CLI 가 서버보다 먼저 조이면, 우리가 생성해 드리는 GitHub Actions 워크플로처럼 버전을 고정하지
|
|
26
|
-
않는(`npx --yes connectbase deploy`) 환경이 서버 변경 전에 깨지기 때문입니다.
|
|
108
|
+
않는(`npx --yes connectbase-client deploy`) 환경이 서버 변경 전에 깨지기 때문입니다.
|
|
27
109
|
|
|
28
110
|
**지금 해두실 것.** CI 를 쓰신다면 저장소 시크릿에 `CONNECTBASE_SECRET_KEY` 를 추가하고
|
|
29
111
|
워크플로 env 에 넣으세요. 워크플로 파일에 값을 직접 적으면 저장소에 커밋됩니다.
|
|
@@ -554,7 +636,7 @@ await ctx.cbAdmin.appMembers.remove(ctx.appId, memberId)
|
|
|
554
636
|
```bash
|
|
555
637
|
# 이제 dist 에 두기만 하면 함께 올라간다
|
|
556
638
|
echo "/blog /blog.html 200" > dist/_redirects
|
|
557
|
-
npx connectbase deploy ./dist
|
|
639
|
+
npx connectbase-client deploy ./dist
|
|
558
640
|
```
|
|
559
641
|
|
|
560
642
|
- `_redirects`, `_headers` 만 이름 완전일치로 허용한다. `Dockerfile`·`Makefile`·`LICENSE`
|
|
@@ -1152,7 +1234,7 @@ AI 에이전트(Claude Code 등)가 `init` 을 직접 실행할 수 있도록
|
|
|
1152
1234
|
자동 정리(레거시 fullstack 파일 포함), `deploy` 성공 후 변경이 있을 때만 조용히 자동 갱신
|
|
1153
1235
|
(`--skip-docs` 로 생략 가능).
|
|
1154
1236
|
- **CLAUDE.md @import**: 참조 블록이 `@.claude/docs/project-rules.md` import 로 규칙을 매
|
|
1155
|
-
세션 자동 로드. MCP 미연결 시 `npx connectbase mcp` 안내 지시 포함. `mcp` 명령도 비대화형
|
|
1237
|
+
세션 자동 로드. MCP 미연결 시 `npx connectbase-client mcp` 안내 지시 포함. `mcp` 명령도 비대화형
|
|
1156
1238
|
지원(`--secret-key`/env/.connectbaserc 자동 사용).
|
|
1157
1239
|
|
|
1158
1240
|
### Changed / Security
|
|
@@ -2793,7 +2875,7 @@ ComfyUI × 웹스토리지 같은 e2e 통합 패턴 (작업 제출 → 폴링
|
|
|
2793
2875
|
|
|
2794
2876
|
### Fixed
|
|
2795
2877
|
|
|
2796
|
-
- `npx connectbase docs` 가 인증 없이 곧장 문서를 받도록 수정. 백엔드 `/v1/storages/webs/claude-md`
|
|
2878
|
+
- `npx connectbase-client docs` 가 인증 없이 곧장 문서를 받도록 수정. 백엔드 `/v1/storages/webs/claude-md`
|
|
2797
2879
|
는 public 라우트인데 CLI 가 불필요하게 브라우저 인증 → 앱 선택 → Public Key 발급을 강제하던
|
|
2798
2880
|
흐름을 제거. 캐시된 publicKey 가 있으면 문서에 박아주고, 없으면 백엔드가 placeholder
|
|
2799
2881
|
(`YOUR_PUBLIC_KEY_HERE`) 로 대체해 그대로 다운로드.
|
|
@@ -3225,7 +3307,7 @@ sisun 팀(`019d85c7-...`) 의 운영 피드백 3건이 시작점이며, 백엔
|
|
|
3225
3307
|
|
|
3226
3308
|
## [1.4.2] - 2026-04-18
|
|
3227
3309
|
|
|
3228
|
-
`npx connectbase docs` 명령이 init/deploy/tunnel 과 달리 brower auth 흐름을 거치지 않아, Public Key 가 없는 사용자가 키 발급 경로를 모른 채 prompt 만 보던 UX 문제 해결.
|
|
3310
|
+
`npx connectbase-client docs` 명령이 init/deploy/tunnel 과 달리 brower auth 흐름을 거치지 않아, Public Key 가 없는 사용자가 키 발급 경로를 모른 채 prompt 만 보던 UX 문제 해결.
|
|
3229
3311
|
|
|
3230
3312
|
### Fixed
|
|
3231
3313
|
|
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ Connect Base provides **two types** of Keys. Use the right key for your use case
|
|
|
27
27
|
|---------|----------|---------|
|
|
28
28
|
| Frontend SDK (`new ConnectBase()`) | **Public Key** (`cb_pk_`) | Web/app: DB queries, auth, file uploads |
|
|
29
29
|
| `.env` file (`VITE_CONNECTBASE_PUBLIC_KEY`) | **Public Key** (`cb_pk_`) | React, Vue, etc. |
|
|
30
|
-
| CLI deploy (`.connectbaserc`) | **Public Key + Secret Key** (`cb_pk_` + `cb_sk_`) | `npx connectbase deploy` |
|
|
30
|
+
| CLI deploy (`.connectbaserc`) | **Public Key + Secret Key** (`cb_pk_` + `cb_sk_`) | `npx connectbase-client deploy` |
|
|
31
31
|
| MCP server (AI tools) | **Secret Key** (`cb_sk_`) | Claude, Cursor, Windsurf |
|
|
32
32
|
| Server-side admin tasks | **Secret Key** (`cb_sk_`) | Backend full data access |
|
|
33
33
|
|
|
@@ -131,22 +131,27 @@ try {
|
|
|
131
131
|
|
|
132
132
|
Deploy your web application to Connect Base Web Storage with a single command.
|
|
133
133
|
|
|
134
|
-
>
|
|
135
|
-
>
|
|
136
|
-
>
|
|
137
|
-
>
|
|
138
|
-
>
|
|
139
|
-
>
|
|
140
|
-
> **401 `SECRET_KEY_REQUIRED`**.
|
|
134
|
+
> **After `npx`, always use the package name `connectbase-client`.** This package installs two
|
|
135
|
+
> bins — `connectbase` and `connectbase-client` — but `connectbase` is a *bin* name, not a
|
|
136
|
+
> package name. npx checks the local `node_modules/.bin` first and otherwise fetches a
|
|
137
|
+
> **package** by that name, so `npx connectbase init` only works in a project that already has
|
|
138
|
+
> this package installed; in an empty folder it fails with npm 404. A global install does not
|
|
139
|
+
> help — npx does not look at `PATH`.
|
|
141
140
|
>
|
|
142
|
-
>
|
|
143
|
-
>
|
|
141
|
+
> Use the short `connectbase` **after** installing: globally, inside `npm run` scripts, or via
|
|
142
|
+
> `node_modules/.bin`.
|
|
143
|
+
>
|
|
144
|
+
> ```bash
|
|
145
|
+
> npx connectbase-client init # nothing installed yet — package name
|
|
146
|
+
> npm install # installs what init added to devDependencies
|
|
147
|
+
> npm run deploy # runs `connectbase deploy ./dist` — short name is fine here
|
|
148
|
+
> ```
|
|
144
149
|
|
|
145
150
|
### Quick Start
|
|
146
151
|
|
|
147
152
|
```bash
|
|
148
153
|
# 1. Initialize (one-time setup)
|
|
149
|
-
npx connectbase init
|
|
154
|
+
npx connectbase-client init
|
|
150
155
|
|
|
151
156
|
# 2. Deploy
|
|
152
157
|
npm run deploy
|
|
@@ -173,14 +178,14 @@ The `init` command will:
|
|
|
173
178
|
If you prefer not to use `init`, you can pass options directly:
|
|
174
179
|
|
|
175
180
|
```bash
|
|
176
|
-
npx connectbase deploy ./dist -s <storage-id> -k <public-key> --secret-key <secret-key>
|
|
181
|
+
npx connectbase-client deploy ./dist -s <storage-id> -k <public-key> --secret-key <secret-key>
|
|
177
182
|
```
|
|
178
183
|
|
|
179
184
|
The Secret Key can also come from `CONNECTBASE_SECRET_KEY` — preferred in CI, so it never
|
|
180
185
|
appears in shell history or CI logs:
|
|
181
186
|
|
|
182
187
|
```bash
|
|
183
|
-
CONNECTBASE_SECRET_KEY=cb_sk_... npx connectbase deploy ./dist -s <storage-id> -k <public-key>
|
|
188
|
+
CONNECTBASE_SECRET_KEY=cb_sk_... npx connectbase-client deploy ./dist -s <storage-id> -k <public-key>
|
|
184
189
|
```
|
|
185
190
|
|
|
186
191
|
### Options
|
|
@@ -204,14 +209,14 @@ Expose a local server to the internet through a secure WebSocket tunnel. Useful
|
|
|
204
209
|
|
|
205
210
|
```bash
|
|
206
211
|
# Expose local port 8084 to the internet
|
|
207
|
-
npx connectbase tunnel 8084 -k <public-key>
|
|
212
|
+
npx connectbase-client tunnel 8084 -k <public-key>
|
|
208
213
|
|
|
209
214
|
# With environment variable
|
|
210
215
|
export CONNECTBASE_PUBLIC_KEY=your-public-key
|
|
211
|
-
npx connectbase tunnel 8084
|
|
216
|
+
npx connectbase-client tunnel 8084
|
|
212
217
|
|
|
213
218
|
# For GPU servers or long-running tasks (e.g., image generation)
|
|
214
|
-
npx connectbase tunnel 7860 --timeout 300 --max-body 50
|
|
219
|
+
npx connectbase-client tunnel 7860 --timeout 300 --max-body 50
|
|
215
220
|
```
|
|
216
221
|
|
|
217
222
|
The tunnel creates a public URL like `https://tunnel.connectbase.world/<tunnel-id>/` that proxies all HTTP requests to your local service.
|
|
@@ -241,7 +246,7 @@ on the server, so your SDK only needs the Public Key.
|
|
|
241
246
|
|
|
242
247
|
```bash
|
|
243
248
|
# Start ComfyUI on port 8188, expose it as endpoint label "comfyui-main"
|
|
244
|
-
npx connectbase tunnel 8188 --label comfyui-main --description "ComfyUI on my desktop"
|
|
249
|
+
npx connectbase-client tunnel 8188 --label comfyui-main --description "ComfyUI on my desktop"
|
|
245
250
|
```
|
|
246
251
|
|
|
247
252
|
Authentication uses your User Secret Key (`cb_sk_*`); the CLI calls the dual-auth
|
|
@@ -272,14 +277,14 @@ The `init` command creates `.connectbaserc` automatically. You can also create i
|
|
|
272
277
|
export CONNECTBASE_PUBLIC_KEY=cb_pk_your-public-key
|
|
273
278
|
export CONNECTBASE_SECRET_KEY=cb_sk_your-secret-key # required by deploy / promote
|
|
274
279
|
export CONNECTBASE_STORAGE_ID=your-storage-id
|
|
275
|
-
npx connectbase deploy ./dist
|
|
280
|
+
npx connectbase-client deploy ./dist
|
|
276
281
|
```
|
|
277
282
|
|
|
278
283
|
In CI, read the Secret Key from a repository secret:
|
|
279
284
|
|
|
280
285
|
```yaml
|
|
281
286
|
# GitHub Actions
|
|
282
|
-
- run: npx connectbase deploy ./dist
|
|
287
|
+
- run: npx connectbase-client deploy ./dist
|
|
283
288
|
env:
|
|
284
289
|
CONNECTBASE_PUBLIC_KEY: ${{ vars.CONNECTBASE_PUBLIC_KEY }}
|
|
285
290
|
CONNECTBASE_SECRET_KEY: ${{ secrets.CONNECTBASE_SECRET_KEY }}
|
package/dist/cli.js
CHANGED
|
@@ -147,18 +147,7 @@ function handleTunnelError(msg, appId, localPort) {
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
// src/cli.ts
|
|
150
|
-
|
|
151
|
-
try {
|
|
152
|
-
const pkgPath = path2.join(__dirname, "..", "package.json");
|
|
153
|
-
if (fs2.existsSync(pkgPath)) {
|
|
154
|
-
const pkg = JSON.parse(fs2.readFileSync(pkgPath, "utf-8"));
|
|
155
|
-
return pkg.version || "0.0.0";
|
|
156
|
-
}
|
|
157
|
-
} catch {
|
|
158
|
-
}
|
|
159
|
-
return "3.25.1";
|
|
160
|
-
}
|
|
161
|
-
var VERSION = getPackageVersion();
|
|
150
|
+
var VERSION = "6.3.0" ? "6.3.0" : getPackageVersion();
|
|
162
151
|
var DEFAULT_BASE_URL = "https://api.connectbase.world";
|
|
163
152
|
var colors = {
|
|
164
153
|
reset: "\x1B[0m",
|
|
@@ -311,7 +300,7 @@ function storageAdminHeaders(config) {
|
|
|
311
300
|
);
|
|
312
301
|
log(" \uACE7 \uC11C\uBC84\uAC00 Secret Key \uB97C \uC694\uAD6C\uD569\uB2C8\uB2E4. \uC9C0\uAE08 \uC124\uC815\uD574 \uB450\uC138\uC694.");
|
|
313
302
|
log(
|
|
314
|
-
` ${colors.cyan}npx connectbase init${colors.reset} \uC774 \uBC1C\uAE09\uD574 .connectbaserc \uC5D0 \uC800\uC7A5\uD569\uB2C8\uB2E4.`
|
|
303
|
+
` ${colors.cyan}npx connectbase-client init${colors.reset} \uC774 \uBC1C\uAE09\uD574 .connectbaserc \uC5D0 \uC800\uC7A5\uD569\uB2C8\uB2E4.`
|
|
315
304
|
);
|
|
316
305
|
log(
|
|
317
306
|
` \uC774\uBBF8 \uD0A4\uAC00 \uC788\uB2E4\uBA74 ${colors.cyan}CONNECTBASE_SECRET_KEY${colors.reset} \uD658\uACBD\uBCC0\uC218\uB85C \uC9C0\uC815\uD558\uC138\uC694.`
|
|
@@ -667,10 +656,10 @@ async function deploy(directory, config, isDev = false, deployOpts = {}) {
|
|
|
667
656
|
const pkg = JSON.parse(fs2.readFileSync(pkgPath, "utf-8"));
|
|
668
657
|
if (pkg.scripts?.build) {
|
|
669
658
|
warn(
|
|
670
|
-
`\uBC30\uD3EC \uC804 \uBE4C\uB4DC\uB97C \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694: ${colors.cyan}npm run build && npx connectbase deploy${colors.reset}`
|
|
659
|
+
`\uBC30\uD3EC \uC804 \uBE4C\uB4DC\uB97C \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694: ${colors.cyan}npm run build && npx connectbase-client deploy${colors.reset}`
|
|
671
660
|
);
|
|
672
661
|
warn(
|
|
673
|
-
`\uB610\uB294 package.json\uC5D0 deploy \uC2A4\uD06C\uB9BD\uD2B8\uB97C \uB4F1\uB85D\uD558\uC138\uC694: ${colors.cyan}npx connectbase init${colors.reset}`
|
|
662
|
+
`\uB610\uB294 package.json\uC5D0 deploy \uC2A4\uD06C\uB9BD\uD2B8\uB97C \uB4F1\uB85D\uD558\uC138\uC694: ${colors.cyan}npx connectbase-client init${colors.reset}`
|
|
674
663
|
);
|
|
675
664
|
}
|
|
676
665
|
} catch {
|
|
@@ -702,7 +691,7 @@ async function deploy(directory, config, isDev = false, deployOpts = {}) {
|
|
|
702
691
|
const envLabel = isDev ? "QA" : "Prod";
|
|
703
692
|
if (isDev) {
|
|
704
693
|
warn(
|
|
705
|
-
`${colors.yellow}--dev \uB294 deprecated${colors.reset} \uC785\uB2C8\uB2E4 \u2014 QA \uCC44\uB110\uB85C \uBC30\uD3EC\uD569\uB2C8\uB2E4(production \uBBF8\uBC18\uC601). \uC774\uD6C4 ${colors.cyan}npx connectbase promote${colors.reset} \uB85C production \uC5D0 \uBC18\uC601\uD558\uC138\uC694. promote_mode=manual \uC774\uBA74 \uC77C\uBC18 ${colors.cyan}deploy${colors.reset} \uB3C4 \uB3D9\uC77C\uD558\uAC8C QA \uB85C \uBC30\uD3EC\uB429\uB2C8\uB2E4.`
|
|
694
|
+
`${colors.yellow}--dev \uB294 deprecated${colors.reset} \uC785\uB2C8\uB2E4 \u2014 QA \uCC44\uB110\uB85C \uBC30\uD3EC\uD569\uB2C8\uB2E4(production \uBBF8\uBC18\uC601). \uC774\uD6C4 ${colors.cyan}npx connectbase-client promote${colors.reset} \uB85C production \uC5D0 \uBC18\uC601\uD558\uC138\uC694. promote_mode=manual \uC774\uBA74 \uC77C\uBC18 ${colors.cyan}deploy${colors.reset} \uB3C4 \uB3D9\uC77C\uD558\uAC8C QA \uB85C \uBC30\uD3EC\uB429\uB2C8\uB2E4.`
|
|
706
695
|
);
|
|
707
696
|
}
|
|
708
697
|
const baseStorageUrl = `${config.baseUrl}/v1/public/storages/webs/${config.storageId}`;
|
|
@@ -918,7 +907,7 @@ ${colors.cyan}Production: ${dep.production_url}${colors.reset}`
|
|
|
918
907
|
log(`
|
|
919
908
|
${colors.yellow}QA URL: ${dep.qa_url}${colors.reset}`);
|
|
920
909
|
log(
|
|
921
|
-
`${colors.dim}\uAC80\uC99D \uD6C4 \uBC18\uC601: ${colors.cyan}npx connectbase promote${colors.reset}
|
|
910
|
+
`${colors.dim}\uAC80\uC99D \uD6C4 \uBC18\uC601: ${colors.cyan}npx connectbase-client promote${colors.reset}
|
|
922
911
|
`
|
|
923
912
|
);
|
|
924
913
|
}
|
|
@@ -1019,7 +1008,7 @@ ${colors.cyan}\uBC30\uD3EC \uC774\uB825${colors.reset} (promote_mode: ${data.pro
|
|
|
1019
1008
|
if (data.qa_url)
|
|
1020
1009
|
log(`${colors.yellow}QA: ${data.qa_url}${colors.reset}`);
|
|
1021
1010
|
log(
|
|
1022
|
-
`${colors.dim}\uB864\uBC31: npx connectbase promote <deployment_id>${colors.reset}
|
|
1011
|
+
`${colors.dim}\uB864\uBC31: npx connectbase-client promote <deployment_id>${colors.reset}
|
|
1023
1012
|
`
|
|
1024
1013
|
);
|
|
1025
1014
|
}
|
|
@@ -1086,7 +1075,9 @@ function getProjectRoot() {
|
|
|
1086
1075
|
const gitRoot = getGitRoot();
|
|
1087
1076
|
return gitRoot || process.cwd();
|
|
1088
1077
|
}
|
|
1089
|
-
|
|
1078
|
+
function consoleUrlFor(baseUrl) {
|
|
1079
|
+
return baseUrl.replace("api.", "");
|
|
1080
|
+
}
|
|
1090
1081
|
function openBrowser(url) {
|
|
1091
1082
|
const { exec } = require("child_process");
|
|
1092
1083
|
const platform2 = process.platform;
|
|
@@ -1101,10 +1092,10 @@ function openBrowser(url) {
|
|
|
1101
1092
|
exec(command, () => {
|
|
1102
1093
|
});
|
|
1103
1094
|
}
|
|
1104
|
-
async function browserAuthFlow() {
|
|
1095
|
+
async function browserAuthFlow(baseUrl = DEFAULT_BASE_URL) {
|
|
1105
1096
|
info("\uBE0C\uB77C\uC6B0\uC800 \uC778\uC99D \uC138\uC158\uC744 \uC2DC\uC791\uD569\uB2C8\uB2E4...");
|
|
1106
1097
|
const startRes = await makeRequest(
|
|
1107
|
-
`${
|
|
1098
|
+
`${baseUrl}/v1/public/cli-auth/start`,
|
|
1108
1099
|
"POST",
|
|
1109
1100
|
{}
|
|
1110
1101
|
);
|
|
@@ -1115,7 +1106,7 @@ async function browserAuthFlow() {
|
|
|
1115
1106
|
process.exit(1);
|
|
1116
1107
|
}
|
|
1117
1108
|
const { session_id } = startRes.data;
|
|
1118
|
-
const authUrl = `${
|
|
1109
|
+
const authUrl = `${consoleUrlFor(baseUrl)}/auth/cli-auth?session=${session_id}`;
|
|
1119
1110
|
log(`
|
|
1120
1111
|
${colors.cyan}\uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uB85C\uADF8\uC778\uD558\uC138\uC694:${colors.reset}`);
|
|
1121
1112
|
log(`${colors.dim}${authUrl}${colors.reset}
|
|
@@ -1135,7 +1126,7 @@ ${colors.cyan}\uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uB85C\uADF8\uC778\uD558\uC13
|
|
|
1135
1126
|
await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
|
|
1136
1127
|
try {
|
|
1137
1128
|
const pollRes = await makeRequest(
|
|
1138
|
-
`${
|
|
1129
|
+
`${baseUrl}/v1/public/cli-auth/poll/${session_id}`,
|
|
1139
1130
|
"GET",
|
|
1140
1131
|
{}
|
|
1141
1132
|
);
|
|
@@ -1182,10 +1173,73 @@ ${colors.cyan}\uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uB85C\uADF8\uC778\uD558\uC13
|
|
|
1182
1173
|
error("\uC778\uC99D \uC2DC\uAC04\uC774 \uCD08\uACFC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.");
|
|
1183
1174
|
process.exit(1);
|
|
1184
1175
|
}
|
|
1176
|
+
async function promptForSecretKey(baseUrl = DEFAULT_BASE_URL) {
|
|
1177
|
+
log(`
|
|
1178
|
+
${colors.dim}\uC778\uC99D \uBC29\uC2DD\uC744 \uC120\uD0DD\uD558\uC138\uC694:${colors.reset}`);
|
|
1179
|
+
log(` ${colors.cyan}1${colors.reset}) Secret Key \uC9C1\uC811 \uC785\uB825 (cb_sk_...)`);
|
|
1180
|
+
log(` ${colors.cyan}2${colors.reset}) \uBE0C\uB77C\uC6B0\uC800 \uB85C\uADF8\uC778\uC73C\uB85C \uC790\uB3D9 \uBC1C\uAE09
|
|
1181
|
+
`);
|
|
1182
|
+
const authChoice = await prompt(
|
|
1183
|
+
`${colors.blue}?${colors.reset} \uC120\uD0DD (1/2): `
|
|
1184
|
+
);
|
|
1185
|
+
if (authChoice === "2") {
|
|
1186
|
+
try {
|
|
1187
|
+
return await browserAuthFlow(baseUrl);
|
|
1188
|
+
} catch (err) {
|
|
1189
|
+
error(`\uB124\uD2B8\uC6CC\uD06C \uC624\uB958: ${err instanceof Error ? err.message : err}`);
|
|
1190
|
+
info(
|
|
1191
|
+
"\uC778\uD130\uB137 \uC5F0\uACB0\uC744 \uD655\uC778\uD558\uAC70\uB098, Secret Key \uC9C1\uC811 \uC785\uB825(\uC635\uC158 1)\uC744 \uC2DC\uB3C4\uD558\uC138\uC694"
|
|
1192
|
+
);
|
|
1193
|
+
process.exit(1);
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
log(
|
|
1197
|
+
`${colors.dim}Secret Key (cb_sk_): \uCF58\uC194 > \uD504\uB85C\uD544 > \uC2DC\uD06C\uB9BF \uD0A4 \uD0ED\uC5D0\uC11C \uBC1C\uAE09${colors.reset}
|
|
1198
|
+
`
|
|
1199
|
+
);
|
|
1200
|
+
const entered = await promptSecret(
|
|
1201
|
+
`${colors.blue}?${colors.reset} Secret Key: `
|
|
1202
|
+
);
|
|
1203
|
+
if (!entered) {
|
|
1204
|
+
error("Secret Key\uB294 \uD544\uC218\uC785\uB2C8\uB2E4");
|
|
1205
|
+
process.exit(1);
|
|
1206
|
+
}
|
|
1207
|
+
if (entered.startsWith("cb_pk_")) {
|
|
1208
|
+
error("Public Key\uAC00 \uC544\uB2CC Secret Key(cb_sk_)\uB97C \uC785\uB825\uD558\uC138\uC694");
|
|
1209
|
+
info("Secret Key\uB294 \uCF58\uC194 > \uD504\uB85C\uD544 > \uC2DC\uD06C\uB9BF \uD0A4 \uD0ED\uC5D0\uC11C \uC0DD\uC131\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4");
|
|
1210
|
+
process.exit(1);
|
|
1211
|
+
}
|
|
1212
|
+
if (!entered.startsWith("cb_sk_")) {
|
|
1213
|
+
error(
|
|
1214
|
+
"\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD0A4 \uD615\uC2DD\uC785\uB2C8\uB2E4. cb_sk_\uB85C \uC2DC\uC791\uD558\uB294 Secret Key\uB97C \uC785\uB825\uD558\uC138\uC694"
|
|
1215
|
+
);
|
|
1216
|
+
process.exit(1);
|
|
1217
|
+
}
|
|
1218
|
+
return entered;
|
|
1219
|
+
}
|
|
1220
|
+
function saveSecretKeyToRc(secretKey, dir = process.cwd()) {
|
|
1221
|
+
const rcPath = path2.join(dir, ".connectbaserc");
|
|
1222
|
+
let rcData = {};
|
|
1223
|
+
if (fs2.existsSync(rcPath)) {
|
|
1224
|
+
try {
|
|
1225
|
+
rcData = JSON.parse(fs2.readFileSync(rcPath, "utf-8"));
|
|
1226
|
+
} catch {
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
rcData.secretKey = secretKey;
|
|
1230
|
+
fs2.writeFileSync(rcPath, `${JSON.stringify(rcData, null, 2)}
|
|
1231
|
+
`);
|
|
1232
|
+
}
|
|
1233
|
+
async function fetchAppsWithSecretKey(baseUrl, secretKey) {
|
|
1234
|
+
return makeRequest(`${baseUrl}/v1/public/cli/apps`, "GET", {
|
|
1235
|
+
"X-Public-Key": secretKey
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1185
1238
|
async function init(config = {}, opts = {}) {
|
|
1186
1239
|
log(`
|
|
1187
1240
|
${colors.cyan}Connect Base \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654${colors.reset}
|
|
1188
1241
|
`);
|
|
1242
|
+
const baseUrl = config.baseUrl || DEFAULT_BASE_URL;
|
|
1189
1243
|
const cwd = process.cwd();
|
|
1190
1244
|
const projectRoot = getProjectRoot();
|
|
1191
1245
|
if (cwd !== projectRoot) {
|
|
@@ -1199,7 +1253,7 @@ ${colors.cyan}Connect Base \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654${colors.r
|
|
|
1199
1253
|
if (!process.stdin.isTTY && !nonInteractive) {
|
|
1200
1254
|
error("\uBE44\uB300\uD654\uD615 \uD658\uACBD\uC785\uB2C8\uB2E4. --yes \uD50C\uB798\uADF8\uC640 \uD568\uAED8 \uD544\uC694\uD55C \uAC12\uC744 \uC9C0\uC815\uD558\uC138\uC694");
|
|
1201
1255
|
log(
|
|
1202
|
-
`${colors.dim}\uC608: npx connectbase init --yes --secret-key cb_sk_... [--app <\uC571ID>] [--storage <\uC2A4\uD1A0\uB9AC\uC9C0ID>] [--deploy-dir ./dist]${colors.reset}`
|
|
1256
|
+
`${colors.dim}\uC608: npx connectbase-client init --yes --secret-key cb_sk_... [--app <\uC571ID>] [--storage <\uC2A4\uD1A0\uB9AC\uC9C0ID>] [--deploy-dir ./dist]${colors.reset}`
|
|
1203
1257
|
);
|
|
1204
1258
|
log(
|
|
1205
1259
|
`${colors.dim}Secret Key\uB294 CONNECTBASE_SECRET_KEY \uD658\uACBD\uBCC0\uC218\uB85C\uB3C4 \uC804\uB2EC\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4${colors.reset}`
|
|
@@ -1221,10 +1275,14 @@ ${colors.cyan}Connect Base \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654${colors.r
|
|
|
1221
1275
|
process.exit(1);
|
|
1222
1276
|
}
|
|
1223
1277
|
} else {
|
|
1278
|
+
info(
|
|
1279
|
+
".connectbaserc\uAC00 \uC774\uBBF8 \uC788\uC2B5\uB2C8\uB2E4 \u2014 \uAE30\uC874 \uC571/\uD0A4 \uC124\uC815\uC744 \uC7AC\uC0AC\uC6A9\uD574 \uB2E4\uC2DC \uAD6C\uC131\uD569\uB2C8\uB2E4"
|
|
1280
|
+
);
|
|
1224
1281
|
const overwrite = await prompt(
|
|
1225
|
-
`${colors.
|
|
1282
|
+
`${colors.blue}?${colors.reset} \uACC4\uC18D\uD560\uAE4C\uC694? (Y/n): `
|
|
1226
1283
|
);
|
|
1227
|
-
|
|
1284
|
+
const answer = overwrite.toLowerCase();
|
|
1285
|
+
if (answer === "n" || answer === "no") {
|
|
1228
1286
|
info("\uCD08\uAE30\uD654\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4");
|
|
1229
1287
|
return;
|
|
1230
1288
|
}
|
|
@@ -1238,57 +1296,14 @@ ${colors.cyan}Connect Base \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654${colors.r
|
|
|
1238
1296
|
);
|
|
1239
1297
|
process.exit(1);
|
|
1240
1298
|
}
|
|
1241
|
-
info("Secret Key \
|
|
1299
|
+
info("\uC800\uC7A5\uB41C Secret Key \uC0AC\uC6A9 (\uD50C\uB798\uADF8/\uD658\uACBD\uBCC0\uC218/.connectbaserc)");
|
|
1242
1300
|
} else if (nonInteractive) {
|
|
1243
1301
|
error(
|
|
1244
1302
|
"Secret Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4: --secret-key cb_sk_... \uB610\uB294 CONNECTBASE_SECRET_KEY \uD658\uACBD\uBCC0\uC218"
|
|
1245
1303
|
);
|
|
1246
1304
|
process.exit(1);
|
|
1247
1305
|
} else {
|
|
1248
|
-
|
|
1249
|
-
${colors.dim}\uC778\uC99D \uBC29\uC2DD\uC744 \uC120\uD0DD\uD558\uC138\uC694:${colors.reset}`);
|
|
1250
|
-
log(` ${colors.cyan}1${colors.reset}) Secret Key \uC9C1\uC811 \uC785\uB825 (cb_sk_...)`);
|
|
1251
|
-
log(` ${colors.cyan}2${colors.reset}) \uBE0C\uB77C\uC6B0\uC800 \uB85C\uADF8\uC778\uC73C\uB85C \uC790\uB3D9 \uBC1C\uAE09
|
|
1252
|
-
`);
|
|
1253
|
-
const authChoice = await prompt(
|
|
1254
|
-
`${colors.blue}?${colors.reset} \uC120\uD0DD (1/2): `
|
|
1255
|
-
);
|
|
1256
|
-
if (authChoice === "2") {
|
|
1257
|
-
try {
|
|
1258
|
-
secretKey = await browserAuthFlow();
|
|
1259
|
-
} catch (err) {
|
|
1260
|
-
error(`\uB124\uD2B8\uC6CC\uD06C \uC624\uB958: ${err instanceof Error ? err.message : err}`);
|
|
1261
|
-
info(
|
|
1262
|
-
"\uC778\uD130\uB137 \uC5F0\uACB0\uC744 \uD655\uC778\uD558\uAC70\uB098, Secret Key \uC9C1\uC811 \uC785\uB825(\uC635\uC158 1)\uC744 \uC2DC\uB3C4\uD558\uC138\uC694"
|
|
1263
|
-
);
|
|
1264
|
-
process.exit(1);
|
|
1265
|
-
}
|
|
1266
|
-
} else {
|
|
1267
|
-
log(
|
|
1268
|
-
`${colors.dim}Secret Key (cb_sk_): \uCF58\uC194 > \uD504\uB85C\uD544 > \uC2DC\uD06C\uB9BF \uD0A4 \uD0ED\uC5D0\uC11C \uBC1C\uAE09${colors.reset}
|
|
1269
|
-
`
|
|
1270
|
-
);
|
|
1271
|
-
secretKey = await promptSecret(
|
|
1272
|
-
`${colors.blue}?${colors.reset} Secret Key: `
|
|
1273
|
-
);
|
|
1274
|
-
if (!secretKey) {
|
|
1275
|
-
error("Secret Key\uB294 \uD544\uC218\uC785\uB2C8\uB2E4");
|
|
1276
|
-
process.exit(1);
|
|
1277
|
-
}
|
|
1278
|
-
if (secretKey.startsWith("cb_pk_")) {
|
|
1279
|
-
error("Public Key\uAC00 \uC544\uB2CC Secret Key(cb_sk_)\uB97C \uC785\uB825\uD558\uC138\uC694");
|
|
1280
|
-
info(
|
|
1281
|
-
"Secret Key\uB294 \uCF58\uC194 > \uD504\uB85C\uD544 > \uC2DC\uD06C\uB9BF \uD0A4 \uD0ED\uC5D0\uC11C \uC0DD\uC131\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4"
|
|
1282
|
-
);
|
|
1283
|
-
process.exit(1);
|
|
1284
|
-
}
|
|
1285
|
-
if (!secretKey.startsWith("cb_sk_")) {
|
|
1286
|
-
error(
|
|
1287
|
-
"\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD0A4 \uD615\uC2DD\uC785\uB2C8\uB2E4. cb_sk_\uB85C \uC2DC\uC791\uD558\uB294 Secret Key\uB97C \uC785\uB825\uD558\uC138\uC694"
|
|
1288
|
-
);
|
|
1289
|
-
process.exit(1);
|
|
1290
|
-
}
|
|
1291
|
-
}
|
|
1306
|
+
secretKey = await promptForSecretKey(baseUrl);
|
|
1292
1307
|
}
|
|
1293
1308
|
let appId = "";
|
|
1294
1309
|
let publicKey = "";
|
|
@@ -1304,7 +1319,7 @@ ${colors.dim}\uC778\uC99D \uBC29\uC2DD\uC744 \uC120\uD0DD\uD558\uC138\uC694:${co
|
|
|
1304
1319
|
const issuePublicKey = async (targetAppId) => {
|
|
1305
1320
|
info("Public Key \uC0DD\uC131 \uC911...");
|
|
1306
1321
|
const newKeyRes = await makeRequest(
|
|
1307
|
-
`${
|
|
1322
|
+
`${baseUrl}/v1/public/cli/apps/${targetAppId}/public-keys`,
|
|
1308
1323
|
"POST",
|
|
1309
1324
|
{ "X-Public-Key": secretKey },
|
|
1310
1325
|
JSON.stringify({})
|
|
@@ -1319,14 +1334,26 @@ ${colors.dim}\uC778\uC99D \uBC29\uC2DD\uC744 \uC120\uD0DD\uD558\uC138\uC694:${co
|
|
|
1319
1334
|
};
|
|
1320
1335
|
try {
|
|
1321
1336
|
info("\uC571 \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
1322
|
-
|
|
1323
|
-
`${DEFAULT_BASE_URL}/v1/public/cli/apps`,
|
|
1324
|
-
"GET",
|
|
1325
|
-
{ "X-Public-Key": secretKey }
|
|
1326
|
-
);
|
|
1337
|
+
let appsRes = await fetchAppsWithSecretKey(baseUrl, secretKey);
|
|
1327
1338
|
if (appsRes.status === 401) {
|
|
1328
|
-
|
|
1329
|
-
|
|
1339
|
+
warn("\uC800\uC7A5\uB41C Secret Key\uAC00 \uB354 \uC774\uC0C1 \uC720\uD6A8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 (\uB9CC\uB8CC \uB610\uB294 \uCDE8\uC18C)");
|
|
1340
|
+
if (nonInteractive) {
|
|
1341
|
+
error(
|
|
1342
|
+
"\uC0C8 Secret Key\uB97C --secret-key cb_sk_... \uB610\uB294 CONNECTBASE_SECRET_KEY \uB85C \uC804\uB2EC\uD558\uC138\uC694"
|
|
1343
|
+
);
|
|
1344
|
+
process.exit(1);
|
|
1345
|
+
}
|
|
1346
|
+
info("\uC0C8 Secret Key\uB85C \uB2E4\uC2DC \uC778\uC99D\uD569\uB2C8\uB2E4");
|
|
1347
|
+
secretKey = await promptForSecretKey(baseUrl);
|
|
1348
|
+
appsRes = await fetchAppsWithSecretKey(baseUrl, secretKey);
|
|
1349
|
+
if (appsRes.status === 401) {
|
|
1350
|
+
error(
|
|
1351
|
+
"\uC0C8\uB85C \uBC1B\uC740 Secret Key\uB3C4 \uC720\uD6A8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uCF58\uC194 > \uD504\uB85C\uD544 > \uC2DC\uD06C\uB9BF \uD0A4 \uD0ED\uC5D0\uC11C \uD0A4 \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uC138\uC694"
|
|
1352
|
+
);
|
|
1353
|
+
process.exit(1);
|
|
1354
|
+
}
|
|
1355
|
+
saveSecretKeyToRc(secretKey, cwd);
|
|
1356
|
+
success("\uC0C8 Secret Key\uB97C .connectbaserc\uC5D0 \uC800\uC7A5\uD588\uC2B5\uB2C8\uB2E4");
|
|
1330
1357
|
}
|
|
1331
1358
|
if (appsRes.status !== 200) {
|
|
1332
1359
|
throw new Error(`HTTP ${appsRes.status}`);
|
|
@@ -1376,7 +1403,7 @@ ${colors.blue}?${colors.reset} \uC120\uD0DD (\uBC88\uD638): `
|
|
|
1376
1403
|
) || projectName;
|
|
1377
1404
|
info("\uC571 \uC0DD\uC131 \uC911...");
|
|
1378
1405
|
const createRes = await makeRequest(
|
|
1379
|
-
`${
|
|
1406
|
+
`${baseUrl}/v1/public/cli/apps`,
|
|
1380
1407
|
"POST",
|
|
1381
1408
|
{ "X-Public-Key": secretKey },
|
|
1382
1409
|
JSON.stringify({ name: appName })
|
|
@@ -1431,7 +1458,7 @@ ${colors.blue}?${colors.reset} \uC120\uD0DD (\uBC88\uD638): `
|
|
|
1431
1458
|
try {
|
|
1432
1459
|
info("\uC6F9 \uC2A4\uD1A0\uB9AC\uC9C0 \uC870\uD68C \uC911...");
|
|
1433
1460
|
const listRes = await makeRequest(
|
|
1434
|
-
`${
|
|
1461
|
+
`${baseUrl}/v1/public/storages/webs`,
|
|
1435
1462
|
"GET",
|
|
1436
1463
|
{
|
|
1437
1464
|
"X-Public-Key": publicKeyForSdk,
|
|
@@ -1473,7 +1500,7 @@ ${colors.blue}?${colors.reset} \uC120\uD0DD (\uBC88\uD638): `
|
|
|
1473
1500
|
) || projectName;
|
|
1474
1501
|
info("\uC6F9 \uC2A4\uD1A0\uB9AC\uC9C0 \uC0DD\uC131 \uC911...");
|
|
1475
1502
|
const createRes = await makeRequest(
|
|
1476
|
-
`${
|
|
1503
|
+
`${baseUrl}/v1/public/storages/webs`,
|
|
1477
1504
|
"POST",
|
|
1478
1505
|
{
|
|
1479
1506
|
"X-Public-Key": publicKeyForSdk,
|
|
@@ -1529,12 +1556,17 @@ ${colors.blue}?${colors.reset} \uC120\uD0DD (\uBC88\uD638): `
|
|
|
1529
1556
|
`);
|
|
1530
1557
|
success(".connectbaserc \uC0DD\uC131 \uC644\uB8CC");
|
|
1531
1558
|
addToGitignore(".connectbaserc");
|
|
1532
|
-
addDeployScript(deployDir);
|
|
1533
|
-
await setupClaudeCode(secretKey, projectRoot);
|
|
1559
|
+
const { needsInstall } = addDeployScript(deployDir);
|
|
1560
|
+
await setupClaudeCode(secretKey, projectRoot, baseUrl);
|
|
1534
1561
|
log(`
|
|
1535
1562
|
${colors.green}\uCD08\uAE30\uD654 \uC644\uB8CC!${colors.reset}
|
|
1536
1563
|
`);
|
|
1537
1564
|
log(`${colors.dim}\uBC30\uD3EC\uD558\uB824\uBA74:${colors.reset}`);
|
|
1565
|
+
if (needsInstall) {
|
|
1566
|
+
log(
|
|
1567
|
+
` ${colors.cyan}npm install${colors.reset} ${colors.dim}# connectbase-client (CLI \uD3EC\uD568) \uC124\uCE58${colors.reset}`
|
|
1568
|
+
);
|
|
1569
|
+
}
|
|
1538
1570
|
log(` ${colors.cyan}npm run deploy${colors.reset}`);
|
|
1539
1571
|
log(`
|
|
1540
1572
|
${colors.dim}Claude Code\uC5D0\uC11C MCP\uAC00 \uC790\uB3D9 \uC5F0\uACB0\uB429\uB2C8\uB2E4${colors.reset}
|
|
@@ -1589,31 +1621,46 @@ function addDeployScript(deployDir) {
|
|
|
1589
1621
|
const pkgPath = path2.join(process.cwd(), "package.json");
|
|
1590
1622
|
if (!fs2.existsSync(pkgPath)) {
|
|
1591
1623
|
warn("package.json\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4 deploy \uC2A4\uD06C\uB9BD\uD2B8\uB97C \uCD94\uAC00\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4");
|
|
1592
|
-
return;
|
|
1624
|
+
return { needsInstall: false };
|
|
1593
1625
|
}
|
|
1594
1626
|
try {
|
|
1595
1627
|
const pkg = JSON.parse(fs2.readFileSync(pkgPath, "utf-8"));
|
|
1596
1628
|
if (!pkg.scripts) pkg.scripts = {};
|
|
1629
|
+
const declared = (name) => Boolean(pkg.dependencies?.[name] || pkg.devDependencies?.[name]);
|
|
1630
|
+
let needsInstall = false;
|
|
1631
|
+
if (!declared("connectbase-client")) {
|
|
1632
|
+
if (!pkg.devDependencies) pkg.devDependencies = {};
|
|
1633
|
+
pkg.devDependencies["connectbase-client"] = VERSION === "0.0.0" ? "latest" : `^${VERSION}`;
|
|
1634
|
+
needsInstall = true;
|
|
1635
|
+
}
|
|
1597
1636
|
if (pkg.scripts.deploy) {
|
|
1598
1637
|
info(
|
|
1599
1638
|
`package.json\uC5D0 \uC774\uBBF8 deploy \uC2A4\uD06C\uB9BD\uD2B8\uAC00 \uC788\uC2B5\uB2C8\uB2E4: "${pkg.scripts.deploy}"`
|
|
1600
1639
|
);
|
|
1601
|
-
|
|
1640
|
+
} else {
|
|
1641
|
+
const deployCmd = `connectbase deploy ${deployDir}`;
|
|
1642
|
+
pkg.scripts.deploy = pkg.scripts.build ? `npm run build && ${deployCmd}` : deployCmd;
|
|
1643
|
+
success("package.json\uC5D0 deploy \uC2A4\uD06C\uB9BD\uD2B8 \uCD94\uAC00 \uC644\uB8CC");
|
|
1602
1644
|
}
|
|
1603
|
-
const deployCmd = `connectbase deploy ${deployDir}`;
|
|
1604
|
-
pkg.scripts.deploy = pkg.scripts.build ? `${pkg.scripts.build} && ${deployCmd}` : deployCmd;
|
|
1605
1645
|
fs2.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}
|
|
1606
1646
|
`);
|
|
1607
|
-
|
|
1647
|
+
if (needsInstall) {
|
|
1648
|
+
success(
|
|
1649
|
+
`package.json devDependencies\uC5D0 connectbase-client@${pkg.devDependencies["connectbase-client"]} \uCD94\uAC00 \uC644\uB8CC`
|
|
1650
|
+
);
|
|
1651
|
+
}
|
|
1652
|
+
return { needsInstall };
|
|
1608
1653
|
} catch {
|
|
1609
1654
|
warn("package.json \uC218\uC815\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4");
|
|
1655
|
+
return { needsInstall: false };
|
|
1610
1656
|
}
|
|
1611
1657
|
}
|
|
1612
1658
|
function getGitRoot() {
|
|
1613
1659
|
try {
|
|
1614
1660
|
const { execSync } = require("child_process");
|
|
1615
1661
|
return execSync("git rev-parse --show-toplevel", {
|
|
1616
|
-
encoding: "utf-8"
|
|
1662
|
+
encoding: "utf-8",
|
|
1663
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1617
1664
|
}).trim();
|
|
1618
1665
|
} catch {
|
|
1619
1666
|
return null;
|
|
@@ -1715,6 +1762,7 @@ var LEGACY_DOC_FILES = [
|
|
|
1715
1762
|
];
|
|
1716
1763
|
async function downloadDocs(baseDir, opts = {}) {
|
|
1717
1764
|
const quiet = opts.quiet === true;
|
|
1765
|
+
const baseUrl = opts.baseUrl || DEFAULT_BASE_URL;
|
|
1718
1766
|
if (!baseDir) {
|
|
1719
1767
|
baseDir = getProjectRoot();
|
|
1720
1768
|
}
|
|
@@ -1736,7 +1784,7 @@ async function downloadDocs(baseDir, opts = {}) {
|
|
|
1736
1784
|
if (!quiet) info("SDK \uAC1C\uBC1C \uAC00\uC774\uB4DC \uB2E4\uC6B4\uB85C\uB4DC \uC911...");
|
|
1737
1785
|
try {
|
|
1738
1786
|
const res = await makeRequest(
|
|
1739
|
-
`${
|
|
1787
|
+
`${baseUrl}/v1/storages/webs/claude-md?template=rules&format=sections`,
|
|
1740
1788
|
"GET",
|
|
1741
1789
|
{}
|
|
1742
1790
|
);
|
|
@@ -1769,7 +1817,7 @@ async function downloadDocs(baseDir, opts = {}) {
|
|
|
1769
1817
|
}
|
|
1770
1818
|
return "unchanged";
|
|
1771
1819
|
}
|
|
1772
|
-
const stamp = `<!-- generated by connectbase-cli v${VERSION} (${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}) \u2014 \uC790\uB3D9 \uC0DD\uC131 \uD30C\uC77C\uC785\uB2C8\uB2E4. \uC9C1\uC811 \uC218\uC815\uD558\uC9C0 \uB9D0\uACE0 'npx connectbase update'\uB85C \uAC31\uC2E0\uD558\uC138\uC694 -->
|
|
1820
|
+
const stamp = `<!-- generated by connectbase-cli v${VERSION} (${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}) \u2014 \uC790\uB3D9 \uC0DD\uC131 \uD30C\uC77C\uC785\uB2C8\uB2E4. \uC9C1\uC811 \uC218\uC815\uD558\uC9C0 \uB9D0\uACE0 'npx connectbase-client update'\uB85C \uAC31\uC2E0\uD558\uC138\uC694 -->
|
|
1773
1821
|
|
|
1774
1822
|
`;
|
|
1775
1823
|
for (const section of sections) {
|
|
@@ -1849,7 +1897,7 @@ function updateRootClaudeMd(claudeMdPath, quiet = false) {
|
|
|
1849
1897
|
|
|
1850
1898
|
1. \uC704\uC5D0 import\uB41C project-rules.md\uC758 \uAE30\uB2A5 \uB9E4\uD551\uD45C\xB7\uBCF4\uC548 \uADDC\uCE59\uC744 \uB530\uB974\uC138\uC694
|
|
1851
1899
|
2. \uCF54\uB4DC\uB97C \uC791\uC131\uD558\uAE30 \uC804 \`search_sdk_docs("\uD0A4\uC6CC\uB4DC")\`\uB85C SDK \uAD6C\uD604 \uBC29\uBC95\uC744 \uAC80\uC0C9\uD558\uACE0, \uAC80\uC0C9 \uACB0\uACFC\uC758 \uCF54\uB4DC \uD328\uD134\uC744 \uADF8\uB300\uB85C \uB530\uB974\uC138\uC694
|
|
1852
|
-
3. \`search_sdk_docs\` \uB3C4\uAD6C\uAC00 \uBCF4\uC774\uC9C0 \uC54A\uC73C\uBA74 MCP\uAC00 \uC5F0\uACB0\uB418\uC9C0 \uC54A\uC740 \uC0C1\uD0DC\uC785\uB2C8\uB2E4 \u2014 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \`npx connectbase mcp\` \uC2E4\uD589\uC744 \uC548\uB0B4\uD558\uC138\uC694 (Secret Key \uD544\uC694)
|
|
1900
|
+
3. \`search_sdk_docs\` \uB3C4\uAD6C\uAC00 \uBCF4\uC774\uC9C0 \uC54A\uC73C\uBA74 MCP\uAC00 \uC5F0\uACB0\uB418\uC9C0 \uC54A\uC740 \uC0C1\uD0DC\uC785\uB2C8\uB2E4 \u2014 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \`npx connectbase-client mcp\` \uC2E4\uD589\uC744 \uC548\uB0B4\uD558\uC138\uC694 (Secret Key \uD544\uC694)
|
|
1853
1901
|
${endMarker}`;
|
|
1854
1902
|
if (fs2.existsSync(claudeMdPath)) {
|
|
1855
1903
|
let content = fs2.readFileSync(claudeMdPath, "utf-8");
|
|
@@ -1885,7 +1933,7 @@ function createSubPackageClaudeMd(subClaudeMdPath, gitRoot, quiet = false) {
|
|
|
1885
1933
|
|
|
1886
1934
|
1. \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC758 \`${relPath}/.claude/docs/project-rules.md\`\uC758 \uAE30\uB2A5 \uB9E4\uD551\uD45C\xB7\uBCF4\uC548 \uADDC\uCE59\uC744 \uB530\uB974\uC138\uC694
|
|
1887
1935
|
2. \uCF54\uB4DC\uB97C \uC791\uC131\uD558\uAE30 \uC804 \`search_sdk_docs("\uD0A4\uC6CC\uB4DC")\`\uB85C SDK \uAD6C\uD604 \uBC29\uBC95\uC744 \uAC80\uC0C9\uD558\uC138\uC694
|
|
1888
|
-
3. \`search_sdk_docs\` \uB3C4\uAD6C\uAC00 \uBCF4\uC774\uC9C0 \uC54A\uC73C\uBA74 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \`npx connectbase mcp\` \uC2E4\uD589\uC744 \uC548\uB0B4\uD558\uC138\uC694
|
|
1936
|
+
3. \`search_sdk_docs\` \uB3C4\uAD6C\uAC00 \uBCF4\uC774\uC9C0 \uC54A\uC73C\uBA74 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \`npx connectbase-client mcp\` \uC2E4\uD589\uC744 \uC548\uB0B4\uD558\uC138\uC694
|
|
1889
1937
|
${endMarker}`;
|
|
1890
1938
|
if (fs2.existsSync(subClaudeMdPath)) {
|
|
1891
1939
|
let content = fs2.readFileSync(subClaudeMdPath, "utf-8");
|
|
@@ -1913,7 +1961,7 @@ ${subBlock}
|
|
|
1913
1961
|
}
|
|
1914
1962
|
if (!quiet) success(`\uC11C\uBE0C \uD328\uD0A4\uC9C0 CLAUDE.md \uC0DD\uC131 \uC644\uB8CC: ${subClaudeMdPath}`);
|
|
1915
1963
|
}
|
|
1916
|
-
async function setupMcp(secretKey) {
|
|
1964
|
+
async function setupMcp(secretKey, baseUrl = DEFAULT_BASE_URL) {
|
|
1917
1965
|
const gitRoot = getGitRoot();
|
|
1918
1966
|
const root = gitRoot || process.cwd();
|
|
1919
1967
|
const monorepo = detectMonorepo(root);
|
|
@@ -1924,51 +1972,31 @@ async function setupMcp(secretKey) {
|
|
|
1924
1972
|
}
|
|
1925
1973
|
}
|
|
1926
1974
|
const mcpConfigPath = path2.join(root, ".mcp.json");
|
|
1975
|
+
if (secretKey) {
|
|
1976
|
+
const check = await fetchAppsWithSecretKey(baseUrl, secretKey).catch(
|
|
1977
|
+
() => null
|
|
1978
|
+
);
|
|
1979
|
+
if (check?.status === 401) {
|
|
1980
|
+
warn("\uC800\uC7A5\uB41C Secret Key\uAC00 \uB354 \uC774\uC0C1 \uC720\uD6A8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 (\uB9CC\uB8CC \uB610\uB294 \uCDE8\uC18C)");
|
|
1981
|
+
secretKey = "";
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1927
1984
|
if (!secretKey) {
|
|
1928
1985
|
if (!process.stdin.isTTY) {
|
|
1929
|
-
error("Secret Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4 (\uBE44\uB300\uD654\uD615 \uD658\uACBD)");
|
|
1986
|
+
error("\uC720\uD6A8\uD55C Secret Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4 (\uBE44\uB300\uD654\uD615 \uD658\uACBD)");
|
|
1930
1987
|
log(`${colors.dim}\uB2E4\uC74C \uC911 \uD558\uB098\uB85C \uD0A4\uB97C \uC804\uB2EC\uD558\uC138\uC694:${colors.reset}`);
|
|
1931
1988
|
log(
|
|
1932
|
-
` ${colors.cyan}npx connectbase mcp --secret-key cb_sk_...${colors.reset}`
|
|
1989
|
+
` ${colors.cyan}npx connectbase-client mcp --secret-key cb_sk_...${colors.reset}`
|
|
1933
1990
|
);
|
|
1934
1991
|
log(
|
|
1935
|
-
` ${colors.cyan}CONNECTBASE_SECRET_KEY=cb_sk_... npx connectbase mcp${colors.reset}`
|
|
1992
|
+
` ${colors.cyan}CONNECTBASE_SECRET_KEY=cb_sk_... npx connectbase-client mcp${colors.reset}`
|
|
1936
1993
|
);
|
|
1937
1994
|
process.exit(1);
|
|
1938
1995
|
}
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
`);
|
|
1944
|
-
const authChoice = await prompt(
|
|
1945
|
-
`${colors.blue}?${colors.reset} \uC120\uD0DD (1/2): `
|
|
1946
|
-
);
|
|
1947
|
-
if (authChoice === "2") {
|
|
1948
|
-
try {
|
|
1949
|
-
secretKey = await browserAuthFlow();
|
|
1950
|
-
const skRcPath = path2.join(process.cwd(), ".connectbaserc");
|
|
1951
|
-
let rcData = {};
|
|
1952
|
-
if (fs2.existsSync(skRcPath)) {
|
|
1953
|
-
try {
|
|
1954
|
-
rcData = JSON.parse(fs2.readFileSync(skRcPath, "utf-8"));
|
|
1955
|
-
} catch {
|
|
1956
|
-
}
|
|
1957
|
-
}
|
|
1958
|
-
rcData.secretKey = secretKey;
|
|
1959
|
-
fs2.writeFileSync(skRcPath, `${JSON.stringify(rcData, null, 2)}
|
|
1960
|
-
`);
|
|
1961
|
-
addToGitignore(".connectbaserc", root);
|
|
1962
|
-
success("Secret Key \uBC1C\uAE09 \uBC0F \uC800\uC7A5 \uC644\uB8CC");
|
|
1963
|
-
} catch (err) {
|
|
1964
|
-
error(`\uC778\uC99D \uC2E4\uD328: ${err instanceof Error ? err.message : err}`);
|
|
1965
|
-
process.exit(1);
|
|
1966
|
-
}
|
|
1967
|
-
} else {
|
|
1968
|
-
secretKey = await promptSecret(
|
|
1969
|
-
`${colors.blue}?${colors.reset} Secret Key: `
|
|
1970
|
-
);
|
|
1971
|
-
}
|
|
1996
|
+
secretKey = await promptForSecretKey(baseUrl);
|
|
1997
|
+
saveSecretKeyToRc(secretKey);
|
|
1998
|
+
addToGitignore(".connectbaserc", root);
|
|
1999
|
+
success("Secret Key\uB97C .connectbaserc\uC5D0 \uC800\uC7A5\uD588\uC2B5\uB2C8\uB2E4");
|
|
1972
2000
|
}
|
|
1973
2001
|
const mcpEntry = {
|
|
1974
2002
|
type: "http",
|
|
@@ -2007,10 +2035,10 @@ ${colors.dim}\uC778\uC99D \uBC29\uC2DD\uC744 \uC120\uD0DD\uD558\uC138\uC694:${co
|
|
|
2007
2035
|
${colors.dim}Claude Code\uC5D0\uC11C ConnectBase MCP \uB3C4\uAD6C\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.${colors.reset}`
|
|
2008
2036
|
);
|
|
2009
2037
|
}
|
|
2010
|
-
async function setupClaudeCode(secretKey, projectRoot) {
|
|
2038
|
+
async function setupClaudeCode(secretKey, projectRoot, baseUrl = DEFAULT_BASE_URL) {
|
|
2011
2039
|
const root = projectRoot || getProjectRoot();
|
|
2012
|
-
await downloadDocs(root);
|
|
2013
|
-
await setupMcp(secretKey);
|
|
2040
|
+
await downloadDocs(root, { baseUrl });
|
|
2041
|
+
await setupMcp(secretKey, baseUrl);
|
|
2014
2042
|
}
|
|
2015
2043
|
async function fetchLatestVersion(packageName) {
|
|
2016
2044
|
try {
|
|
@@ -2118,7 +2146,7 @@ ${colors.cyan}ConnectBase Update${colors.reset}
|
|
|
2118
2146
|
if (!opts.skipDocs) {
|
|
2119
2147
|
log("");
|
|
2120
2148
|
info("SDK \uBB38\uC11C \uC5C5\uB370\uC774\uD2B8 \uC911...");
|
|
2121
|
-
await downloadDocs(projectRoot);
|
|
2149
|
+
await downloadDocs(projectRoot, { baseUrl: config.baseUrl });
|
|
2122
2150
|
}
|
|
2123
2151
|
if (!opts.skipMcp) {
|
|
2124
2152
|
log("");
|
|
@@ -2203,15 +2231,15 @@ function setupMonorepoRoot(projectRoot, monorepo) {
|
|
|
2203
2231
|
if (!pkg.scripts) pkg.scripts = {};
|
|
2204
2232
|
let changed = false;
|
|
2205
2233
|
if (!pkg.scripts["cb:update"]) {
|
|
2206
|
-
pkg.scripts["cb:update"] = "npx connectbase update";
|
|
2234
|
+
pkg.scripts["cb:update"] = "npx connectbase-client update";
|
|
2207
2235
|
changed = true;
|
|
2208
2236
|
}
|
|
2209
2237
|
if (!pkg.scripts["cb:docs"]) {
|
|
2210
|
-
pkg.scripts["cb:docs"] = "npx connectbase docs";
|
|
2238
|
+
pkg.scripts["cb:docs"] = "npx connectbase-client docs";
|
|
2211
2239
|
changed = true;
|
|
2212
2240
|
}
|
|
2213
2241
|
if (!pkg.scripts["cb:mcp"]) {
|
|
2214
|
-
pkg.scripts["cb:mcp"] = "npx connectbase mcp";
|
|
2242
|
+
pkg.scripts["cb:mcp"] = "npx connectbase-client mcp";
|
|
2215
2243
|
changed = true;
|
|
2216
2244
|
}
|
|
2217
2245
|
if (changed) {
|
|
@@ -3403,7 +3431,7 @@ function showHelp() {
|
|
|
3403
3431
|
${colors.cyan}connectbase${colors.reset} - Connect Base SDK & CLI
|
|
3404
3432
|
|
|
3405
3433
|
${colors.yellow}\uC0AC\uC6A9\uBC95:${colors.reset}
|
|
3406
|
-
npx connectbase <command> [options]
|
|
3434
|
+
npx connectbase-client <command> [options]
|
|
3407
3435
|
|
|
3408
3436
|
${colors.yellow}\uBA85\uB839\uC5B4:${colors.reset}
|
|
3409
3437
|
init \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654 (\uC571 \uC0DD\uC131, MCP \uC124\uC815, SDK \uBB38\uC11C \uB2E4\uC6B4\uB85C\uB4DC)
|
|
@@ -3451,36 +3479,36 @@ ${colors.yellow}\uC635\uC158:${colors.reset}
|
|
|
3451
3479
|
|
|
3452
3480
|
${colors.yellow}\uBE60\uB978 \uC2DC\uC791:${colors.reset}
|
|
3453
3481
|
${colors.dim}# 1. \uCD08\uAE30\uD654 (\uCD5C\uCD08 1\uD68C)${colors.reset}
|
|
3454
|
-
npx connectbase init
|
|
3482
|
+
npx connectbase-client init
|
|
3455
3483
|
|
|
3456
3484
|
${colors.dim}# 1-1. \uBE44\uB300\uD654\uD615 \uCD08\uAE30\uD654 (CI/AI \uC5D0\uC774\uC804\uD2B8)${colors.reset}
|
|
3457
|
-
npx connectbase init --yes --secret-key cb_sk_...
|
|
3485
|
+
npx connectbase-client init --yes --secret-key cb_sk_...
|
|
3458
3486
|
|
|
3459
3487
|
${colors.dim}# 2. SDK \uC804\uCCB4 \uC5C5\uB370\uC774\uD2B8 (\uBC84\uC804 \uCCB4\uD06C + \uBB38\uC11C + MCP)${colors.reset}
|
|
3460
|
-
npx connectbase update
|
|
3488
|
+
npx connectbase-client update
|
|
3461
3489
|
|
|
3462
3490
|
${colors.dim}# 2-1. \uBAA8\uB178\uB808\uD3EC \uB8E8\uD2B8\uC5D0 \uD3B8\uC758 \uC2A4\uD06C\uB9BD\uD2B8 \uC124\uCE58${colors.reset}
|
|
3463
|
-
npx connectbase update --setup-root
|
|
3491
|
+
npx connectbase-client update --setup-root
|
|
3464
3492
|
|
|
3465
3493
|
${colors.dim}# 3. SDK \uBB38\uC11C\uB9CC \uC5C5\uB370\uC774\uD2B8${colors.reset}
|
|
3466
|
-
npx connectbase docs
|
|
3494
|
+
npx connectbase-client docs
|
|
3467
3495
|
|
|
3468
3496
|
${colors.dim}# 4. MCP \uC11C\uBC84 \uC124\uC815${colors.reset}
|
|
3469
|
-
npx connectbase mcp
|
|
3497
|
+
npx connectbase-client mcp
|
|
3470
3498
|
|
|
3471
3499
|
${colors.dim}# 4. Prod \uBC30\uD3EC${colors.reset}
|
|
3472
3500
|
npm run deploy
|
|
3473
3501
|
|
|
3474
3502
|
${colors.dim}# 4-1. QA \uC6CC\uD06C\uD50C\uB85C\uC6B0 (\uC2E0\uADDC \uC2A4\uD1A0\uB9AC\uC9C0 \uAE30\uBCF8 promote_mode=manual)${colors.reset}
|
|
3475
|
-
npx connectbase deploy ./dist ${colors.dim}# QA \uD658\uACBD\uC5D0\uB9CC \uBC30\uD3EC${colors.reset}
|
|
3476
|
-
npx connectbase releases ${colors.dim}# \uBC30\uD3EC \uC774\uB825 \uD655\uC778${colors.reset}
|
|
3477
|
-
npx connectbase promote ${colors.dim}# QA \uAC80\uC99D \uD6C4 production \uBC18\uC601${colors.reset}
|
|
3503
|
+
npx connectbase-client deploy ./dist ${colors.dim}# QA \uD658\uACBD\uC5D0\uB9CC \uBC30\uD3EC${colors.reset}
|
|
3504
|
+
npx connectbase-client releases ${colors.dim}# \uBC30\uD3EC \uC774\uB825 \uD655\uC778${colors.reset}
|
|
3505
|
+
npx connectbase-client promote ${colors.dim}# QA \uAC80\uC99D \uD6C4 production \uBC18\uC601${colors.reset}
|
|
3478
3506
|
|
|
3479
3507
|
${colors.dim}# 5. \uD130\uB110 (\uAE30\uBCF8)${colors.reset}
|
|
3480
|
-
npx connectbase tunnel 3000
|
|
3508
|
+
npx connectbase-client tunnel 3000
|
|
3481
3509
|
|
|
3482
3510
|
${colors.dim}# 6. \uD130\uB110 (GPU \uC11C\uBC84 \uB4F1 \uAE34 \uC751\uB2F5 \uC2DC)${colors.reset}
|
|
3483
|
-
npx connectbase tunnel 7860 --timeout 300 --max-body 50
|
|
3511
|
+
npx connectbase-client tunnel 7860 --timeout 300 --max-body 50
|
|
3484
3512
|
|
|
3485
3513
|
${colors.yellow}\uD658\uACBD\uBCC0\uC218:${colors.reset}
|
|
3486
3514
|
CONNECTBASE_PUBLIC_KEY Public Key (cb_pk_*)
|
|
@@ -3594,20 +3622,20 @@ async function main() {
|
|
|
3594
3622
|
setupRoot: parsed.options.setupRoot === "true"
|
|
3595
3623
|
});
|
|
3596
3624
|
} else if (parsed.command === "docs") {
|
|
3597
|
-
await downloadDocs();
|
|
3625
|
+
await downloadDocs(void 0, { baseUrl: config.baseUrl });
|
|
3598
3626
|
} else if (parsed.command === "mcp") {
|
|
3599
|
-
await setupMcp(config.secretKey);
|
|
3627
|
+
await setupMcp(config.secretKey, config.baseUrl);
|
|
3600
3628
|
} else if (parsed.command === "deploy") {
|
|
3601
3629
|
const directory = parsed.args[0] || fileConfig.deployDir || ".";
|
|
3602
3630
|
if (!config.publicKey) {
|
|
3603
3631
|
error(
|
|
3604
|
-
'Public Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. "npx connectbase init"\uC73C\uB85C \uC124\uC815\uD558\uAC70\uB098 -k \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694'
|
|
3632
|
+
'Public Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. "npx connectbase-client init"\uC73C\uB85C \uC124\uC815\uD558\uAC70\uB098 -k \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694'
|
|
3605
3633
|
);
|
|
3606
3634
|
process.exit(1);
|
|
3607
3635
|
}
|
|
3608
3636
|
if (!config.storageId) {
|
|
3609
3637
|
error(
|
|
3610
|
-
'\uC2A4\uD1A0\uB9AC\uC9C0 ID\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. "npx connectbase init"\uC73C\uB85C \uC124\uC815\uD558\uAC70\uB098 -s \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694'
|
|
3638
|
+
'\uC2A4\uD1A0\uB9AC\uC9C0 ID\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. "npx connectbase-client init"\uC73C\uB85C \uC124\uC815\uD558\uAC70\uB098 -s \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694'
|
|
3611
3639
|
);
|
|
3612
3640
|
process.exit(1);
|
|
3613
3641
|
}
|
|
@@ -3628,7 +3656,10 @@ async function main() {
|
|
|
3628
3656
|
if (fs2.existsSync(
|
|
3629
3657
|
path2.join(docsRoot, ".claude", "docs", DOCS_MANIFEST_FILE)
|
|
3630
3658
|
)) {
|
|
3631
|
-
const refreshed = await downloadDocs(docsRoot, {
|
|
3659
|
+
const refreshed = await downloadDocs(docsRoot, {
|
|
3660
|
+
quiet: true,
|
|
3661
|
+
baseUrl: config.baseUrl
|
|
3662
|
+
});
|
|
3632
3663
|
if (refreshed === "updated") {
|
|
3633
3664
|
info("SDK \uBB38\uC11C\uAC00 \uC0C8 \uBC84\uC804\uC73C\uB85C \uAC31\uC2E0\uB418\uC5C8\uC2B5\uB2C8\uB2E4 (.claude/docs/)");
|
|
3634
3665
|
}
|
|
@@ -3639,13 +3670,13 @@ async function main() {
|
|
|
3639
3670
|
} else if (parsed.command === "promote" || parsed.command === "releases") {
|
|
3640
3671
|
if (!config.publicKey) {
|
|
3641
3672
|
error(
|
|
3642
|
-
'Public Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. "npx connectbase init"\uC73C\uB85C \uC124\uC815\uD558\uAC70\uB098 -k \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694'
|
|
3673
|
+
'Public Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. "npx connectbase-client init"\uC73C\uB85C \uC124\uC815\uD558\uAC70\uB098 -k \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694'
|
|
3643
3674
|
);
|
|
3644
3675
|
process.exit(1);
|
|
3645
3676
|
}
|
|
3646
3677
|
if (!config.storageId) {
|
|
3647
3678
|
error(
|
|
3648
|
-
'\uC2A4\uD1A0\uB9AC\uC9C0 ID\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. "npx connectbase init"\uC73C\uB85C \uC124\uC815\uD558\uAC70\uB098 -s \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694'
|
|
3679
|
+
'\uC2A4\uD1A0\uB9AC\uC9C0 ID\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. "npx connectbase-client init"\uC73C\uB85C \uC124\uC815\uD558\uAC70\uB098 -s \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694'
|
|
3649
3680
|
);
|
|
3650
3681
|
process.exit(1);
|
|
3651
3682
|
}
|
|
@@ -3657,7 +3688,7 @@ async function main() {
|
|
|
3657
3688
|
} else if (parsed.command === "tunnel") {
|
|
3658
3689
|
const portStr = parsed.args[0];
|
|
3659
3690
|
if (!portStr) {
|
|
3660
|
-
error("\uD3EC\uD2B8 \uBC88\uD638\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. \uC608: npx connectbase tunnel 8084");
|
|
3691
|
+
error("\uD3EC\uD2B8 \uBC88\uD638\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. \uC608: npx connectbase-client tunnel 8084");
|
|
3661
3692
|
process.exit(1);
|
|
3662
3693
|
}
|
|
3663
3694
|
const port = parseInt(portStr, 10);
|