@swttch/extend-kit 0.7.2 → 0.8.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/README.ko.md +65 -0
- package/README.md +65 -0
- package/dist/battery/api/http.d.ts +22 -0
- package/dist/battery/api/http.js +24 -3
- package/dist/battery/api/http.js.map +1 -1
- package/dist/cli/index.js +5 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/ext/index.d.ts +2 -0
- package/dist/ext/index.js +116 -0
- package/dist/ext/index.js.map +1 -0
- package/dist/ext/operations.d.ts +54 -0
- package/dist/ext/operations.js +103 -0
- package/dist/ext/operations.js.map +1 -0
- package/dist/ext/run.d.ts +35 -0
- package/dist/ext/run.js +161 -0
- package/dist/ext/run.js.map +1 -0
- package/package.json +3 -2
package/README.ko.md
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
| --- | --- |
|
|
9
9
|
| **battery** | *사용자 본인의* 머신에 저장된 Claude Code 로그인 정보(keychain 또는 자격증명 파일)를 읽어야 합니다 |
|
|
10
10
|
| **stt** | 받아쓰기는 OAuth 토큰을 전송하는데, JetBrains 플러그인은 자격증명을 다룰 수 없습니다 |
|
|
11
|
+
| **swttch-ext** | 저장된 로그인으로 내 계정에 대해 호출합니다(아티팩트: 목록, 이름 변경, 고정, 삭제) |
|
|
11
12
|
|
|
12
13
|
## battery
|
|
13
14
|
|
|
@@ -15,6 +16,70 @@ Claude Code의 내부 API를 래핑한 TypeScript SDK 및 CLI입니다. Claude C
|
|
|
15
16
|
|
|
16
17
|
> **`claude-code-battery`에서 옮겨오시나요?** import만 `@swttch/extend-kit`으로 바꾸면 나머지는 그대로입니다 — export 목록과 `ccb` 명령은 변경되지 않았습니다. 기존 패키지도 계속 동작하며, 이제 이 패키지를 재노출합니다.
|
|
17
18
|
|
|
19
|
+
## swttch-ext
|
|
20
|
+
|
|
21
|
+
내 머신에서 내 Claude 계정에 대해 하는 호출을 위한 명령입니다. 저장된 Claude Code 로그인을 쓰며, 따로 묻는 것은 없습니다.
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
swttch-ext api <서비스> <호출> [--옵션 값 ...] [--yes]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
모든 호출은 **JSON 객체 하나**를 출력하고, 성공하면 종료 코드 `0`입니다.
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{ "ok": true, "data": { "...": "..." } }
|
|
31
|
+
{ "ok": false, "error": { "code": "not_found", "message": "...", "status": 404 } }
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 아티팩트 (`frame`)
|
|
35
|
+
|
|
36
|
+
Claude가 게시한 [아티팩트](https://code.claude.com/docs/en/artifacts)를 관리합니다. 아티팩트는 `slug`(UUID)로 가리키며, `list`가 알려 줍니다.
|
|
37
|
+
|
|
38
|
+
| 호출 | 하는 일 | 파라미터 |
|
|
39
|
+
| --- | --- | --- |
|
|
40
|
+
| `frame list` | 내 아티팩트 목록: 이름, 소유자, 마지막 수정, 고정 여부, 각각에 할 수 있는 일 | `--limit` (1–200, 기본 50) |
|
|
41
|
+
| `frame retitle` | 이름 바꾸기. 페이지의 `<title>`이 고쳐지고, 새 버전으로 저장됩니다 | `--slug`, `--title` |
|
|
42
|
+
| `frame pin` | 고정 | `--slug` |
|
|
43
|
+
| `frame unpin` | 고정 해제 | `--slug` |
|
|
44
|
+
| `frame delete` | 완전히 삭제. 링크가 모두에게 열리지 않게 되고 되돌릴 수 없습니다 | `--slug`, `--yes` |
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
swttch-ext api frame list --limit 10
|
|
48
|
+
swttch-ext api frame retitle --slug 3627498c-4893-4ce8-bfaf-524f7b041c1d --title "분기 보고서"
|
|
49
|
+
swttch-ext api frame pin --slug 3627498c-4893-4ce8-bfaf-524f7b041c1d
|
|
50
|
+
swttch-ext api frame delete --slug 3627498c-4893-4ce8-bfaf-524f7b041c1d --yes
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- **`delete`는 `--yes` 없이는 아무것도 하지 않고** `confirmation_required`로 답합니다.
|
|
54
|
+
- **`<title>`이 없는 페이지는 이름을 바꿀 수 없습니다**(`rejected`). 페이지에 `<title>`을 넣고 다시 게시한 뒤에 바꾸세요.
|
|
55
|
+
- 이름 변경·고정·삭제는 내가 소유한 아티팩트에만 됩니다. 남의 것은 `not_found`로 답합니다.
|
|
56
|
+
|
|
57
|
+
### 이 버전이 할 수 있는 일 알아보기
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
swttch-ext api --list # 모든 호출과 파라미터(JSON)
|
|
61
|
+
swttch-ext --capabilities # {"capabilities":["api.frame.list", ...]}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`swttch-ext`를 부르는 프로그램은 먼저 `--capabilities`를 확인해, 오래된 설치와 실패한 호출을 구분할 수 있습니다.
|
|
65
|
+
|
|
66
|
+
### 오류 코드
|
|
67
|
+
|
|
68
|
+
| `error.code` | 뜻 |
|
|
69
|
+
| --- | --- |
|
|
70
|
+
| `confirmation_required` | 되돌릴 수 없는 호출을 `--yes` 없이 실행했습니다 |
|
|
71
|
+
| `invalid_argument` | 파라미터가 없거나, 비었거나, 너무 길거나, 허용되지 않습니다 |
|
|
72
|
+
| `unknown_operation` | 그런 호출이 없습니다. `--list`를 보세요 |
|
|
73
|
+
| `not_found` | 아티팩트가 없거나 내 것이 아닙니다 |
|
|
74
|
+
| `rejected` / `conflict` | 서버가 변경을 거절했거나(이유는 `message`), 그 사이 아티팩트가 바뀌었습니다 |
|
|
75
|
+
| `token_expired` | 저장된 로그인이 더는 받아들여지지 않습니다. `claude`를 한 번 실행해 갱신하세요 |
|
|
76
|
+
| `forbidden` / `rate_limited` | 이 계정이 할 수 없는 일입니다 / 요청이 너무 많습니다(`hint`에 기다릴 시간) |
|
|
77
|
+
| `network_error` / `timeout` | 서버에 닿지 못했습니다. 위의 프록시 설정이 여기에도 적용됩니다 |
|
|
78
|
+
|
|
79
|
+
프록시 환경변수, `--env=NAME=VALUE`, Claude Code 설정파일은 `ccb`와 같은 방식으로 읽습니다.
|
|
80
|
+
|
|
81
|
+
> **비공식 API**: `ccb`와 마찬가지로 Anthropic이 문서화하지 않은 엔드포인트를 쓰므로 바뀔 수 있습니다.
|
|
82
|
+
|
|
18
83
|
## 주의사항
|
|
19
84
|
|
|
20
85
|
- **비공식 API**: 이 패키지는 Claude Code 클라이언트의 비공식 내부 API를 사용합니다. Anthropic에서 공식으로 지원하지 않으므로 향후 변경될 수 있습니다.
|
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@ The companion tools [Swttch](https://github.com/Swttch/swttch) needs but cannot
|
|
|
8
8
|
| --- | --- |
|
|
9
9
|
| **battery** | Reads the Claude Code login stored on *your* machine (keychain, or a credentials file) |
|
|
10
10
|
| **stt** | Dictation sends your OAuth token, and a JetBrains plugin may not handle credentials |
|
|
11
|
+
| **swttch-ext** | Acts on your account with the saved login (artifacts: list, rename, pin, delete) |
|
|
11
12
|
|
|
12
13
|
## battery
|
|
13
14
|
|
|
@@ -15,6 +16,70 @@ A TypeScript SDK and CLI that wraps the internal API of Claude Code. This allows
|
|
|
15
16
|
|
|
16
17
|
> **Moving from `claude-code-battery`?** Change the import to `@swttch/extend-kit` and everything else stays the same — the exports and the `ccb` command are unchanged. The old package still works; it now re-exports this one.
|
|
17
18
|
|
|
19
|
+
## swttch-ext
|
|
20
|
+
|
|
21
|
+
A command for calls that act on your Claude account from your own machine — the saved Claude Code login is used, and nothing is asked of you.
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
swttch-ext api <service> <call> [--param value ...] [--yes]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Every call prints **one JSON object** and exits `0` on success:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{ "ok": true, "data": { "...": "..." } }
|
|
31
|
+
{ "ok": false, "error": { "code": "not_found", "message": "...", "status": 404 } }
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Artifacts (`frame`)
|
|
35
|
+
|
|
36
|
+
Manage the pages Claude published as [Artifacts](https://code.claude.com/docs/en/artifacts). An artifact is named by its `slug` (a UUID), which `list` returns.
|
|
37
|
+
|
|
38
|
+
| Call | What it does | Parameters |
|
|
39
|
+
| --- | --- | --- |
|
|
40
|
+
| `frame list` | Lists your artifacts: name, owner, last update, whether it is pinned, and what you may do to each | `--limit` (1–200, default 50) |
|
|
41
|
+
| `frame retitle` | Renames an artifact. The page's `<title>` is rewritten, and the change is saved as a new version | `--slug`, `--title` |
|
|
42
|
+
| `frame pin` | Pins an artifact | `--slug` |
|
|
43
|
+
| `frame unpin` | Removes the pin | `--slug` |
|
|
44
|
+
| `frame delete` | Deletes an artifact for good. Its link stops working for everyone and it cannot be restored | `--slug`, `--yes` |
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
swttch-ext api frame list --limit 10
|
|
48
|
+
swttch-ext api frame retitle --slug 3627498c-4893-4ce8-bfaf-524f7b041c1d --title "Quarterly report"
|
|
49
|
+
swttch-ext api frame pin --slug 3627498c-4893-4ce8-bfaf-524f7b041c1d
|
|
50
|
+
swttch-ext api frame delete --slug 3627498c-4893-4ce8-bfaf-524f7b041c1d --yes
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- **`delete` does nothing without `--yes`.** It answers `confirmation_required` instead.
|
|
54
|
+
- **A page with no `<title>` cannot be renamed** (`rejected`): add a `<title>` to the page and publish it again first.
|
|
55
|
+
- Only artifacts you own can be renamed, pinned or deleted; for anyone else's the answer is `not_found`.
|
|
56
|
+
|
|
57
|
+
### Finding out what this version can do
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
swttch-ext api --list # every call, with its parameters, as JSON
|
|
61
|
+
swttch-ext --capabilities # {"capabilities":["api.frame.list", ...]}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
A program that calls `swttch-ext` can check `--capabilities` first, so an older install is told apart from a failed call.
|
|
65
|
+
|
|
66
|
+
### Error codes
|
|
67
|
+
|
|
68
|
+
| `error.code` | Meaning |
|
|
69
|
+
| --- | --- |
|
|
70
|
+
| `confirmation_required` | A call that cannot be undone was run without `--yes` |
|
|
71
|
+
| `invalid_argument` | A parameter is missing, empty, too long, or not allowed |
|
|
72
|
+
| `unknown_operation` | There is no such call; see `--list` |
|
|
73
|
+
| `not_found` | The artifact does not exist, or is not yours |
|
|
74
|
+
| `rejected` / `conflict` | The server refused the change (the reason is in `message`), or the artifact changed meanwhile |
|
|
75
|
+
| `token_expired` | The saved login is no longer accepted; run `claude` once to refresh it |
|
|
76
|
+
| `forbidden` / `rate_limited` | The account may not do that / too many requests (`hint` says how long to wait) |
|
|
77
|
+
| `network_error` / `timeout` | The server could not be reached; the proxy settings above apply here too |
|
|
78
|
+
|
|
79
|
+
Proxy variables, `--env=NAME=VALUE` and Claude Code's settings files are read the same way as for `ccb`.
|
|
80
|
+
|
|
81
|
+
> **Unofficial API**: like `ccb`, these calls use endpoints Anthropic does not document, so they may change.
|
|
82
|
+
|
|
18
83
|
## Important Notes
|
|
19
84
|
|
|
20
85
|
- **Unofficial API**: This package uses the unofficial internal API of the Claude Code client. Anthropic does not officially support it, so it may change in the future.
|
|
@@ -13,6 +13,19 @@ export interface JsonResponse<T> {
|
|
|
13
13
|
* Absent when the header was missing or was an HTTP-date rather than a count.
|
|
14
14
|
*/
|
|
15
15
|
retryAfterSec?: number;
|
|
16
|
+
/**
|
|
17
|
+
* The start of the body the destination answered a non-2xx with, as text.
|
|
18
|
+
*
|
|
19
|
+
* The write calls need it: a refusal to rename says WHY in its body ("title too long"), and a
|
|
20
|
+
* caller that only got the status could say nothing more useful than the status. Capped, since
|
|
21
|
+
* it is a diagnostic and not a document, and absent on success.
|
|
22
|
+
*/
|
|
23
|
+
errorText?: string;
|
|
24
|
+
}
|
|
25
|
+
/** {@link GetJsonOptions} plus the one thing only a write has. */
|
|
26
|
+
export interface RequestJsonOptions extends GetJsonOptions {
|
|
27
|
+
/** A JSON body to send. Sets the content type and length. */
|
|
28
|
+
body?: unknown;
|
|
16
29
|
}
|
|
17
30
|
/** Options that change how a request is made, rather than what is requested. */
|
|
18
31
|
export interface GetJsonOptions {
|
|
@@ -30,6 +43,15 @@ export interface GetJsonOptions {
|
|
|
30
43
|
* for, the error says so explicitly.
|
|
31
44
|
*/
|
|
32
45
|
export declare function getJson<T>(url: string, headers: Record<string, string>, options?: GetJsonOptions): Promise<JsonResponse<T>>;
|
|
46
|
+
/**
|
|
47
|
+
* Send a request with any method and read the answer as JSON, through a proxy when one is
|
|
48
|
+
* configured. {@link getJson} is this with `GET`; everything said there about proxies and
|
|
49
|
+
* timeouts holds here, because it is the same code.
|
|
50
|
+
*
|
|
51
|
+
* An empty body on a 2xx is a valid answer (a DELETE that says "done" by saying nothing), and
|
|
52
|
+
* comes back as `body: undefined` rather than as a parse failure.
|
|
53
|
+
*/
|
|
54
|
+
export declare function requestJson<T>(method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', url: string, headers: Record<string, string>, options?: RequestJsonOptions): Promise<JsonResponse<T>>;
|
|
33
55
|
/**
|
|
34
56
|
* The proxy in play for `url`, safe to print, so a caller can name it in its own
|
|
35
57
|
* errors. Credentials are stripped here rather than at each call site, because a
|
package/dist/battery/api/http.js
CHANGED
|
@@ -59,7 +59,22 @@ function defaultDeadlineMs() {
|
|
|
59
59
|
* for, the error says so explicitly.
|
|
60
60
|
*/
|
|
61
61
|
export async function getJson(url, headers, options = {}) {
|
|
62
|
+
return requestJson('GET', url, headers, options);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Send a request with any method and read the answer as JSON, through a proxy when one is
|
|
66
|
+
* configured. {@link getJson} is this with `GET`; everything said there about proxies and
|
|
67
|
+
* timeouts holds here, because it is the same code.
|
|
68
|
+
*
|
|
69
|
+
* An empty body on a 2xx is a valid answer (a DELETE that says "done" by saying nothing), and
|
|
70
|
+
* comes back as `body: undefined` rather than as a parse failure.
|
|
71
|
+
*/
|
|
72
|
+
export async function requestJson(method, url, headers, options = {}) {
|
|
62
73
|
const { agent: agentOverride, deadlineMs = defaultDeadlineMs() } = options;
|
|
74
|
+
const payload = options.body === undefined ? undefined : JSON.stringify(options.body);
|
|
75
|
+
const sentHeaders = payload === undefined
|
|
76
|
+
? headers
|
|
77
|
+
: { ...headers, 'content-type': 'application/json', 'content-length': String(Buffer.byteLength(payload)) };
|
|
63
78
|
// Built before the agent, because the agent needs it: see the note in
|
|
64
79
|
// proxyAgentFor on why a signal given only to the request cannot end a wait
|
|
65
80
|
// that has not produced a socket yet.
|
|
@@ -95,7 +110,7 @@ export async function getJson(url, headers, options = {}) {
|
|
|
95
110
|
let result;
|
|
96
111
|
try {
|
|
97
112
|
result = await new Promise((resolve, reject) => {
|
|
98
|
-
const req = request(url, { method
|
|
113
|
+
const req = request(url, { method, headers: sentHeaders, agent, signal: abort.signal }, (res) => {
|
|
99
114
|
const chunks = [];
|
|
100
115
|
res.on('data', (chunk) => chunks.push(chunk));
|
|
101
116
|
res.on('end', () => resolve({
|
|
@@ -130,7 +145,7 @@ export async function getJson(url, headers, options = {}) {
|
|
|
130
145
|
? 'This connection went through the proxy from HTTP_PROXY/HTTPS_PROXY/ALL_PROXY. Check that the proxy is running and reachable.'
|
|
131
146
|
: undefined, { ...(proxyUrl && { proxyUrl }), reachedDestination: false }));
|
|
132
147
|
});
|
|
133
|
-
req.end();
|
|
148
|
+
req.end(payload);
|
|
134
149
|
});
|
|
135
150
|
}
|
|
136
151
|
finally {
|
|
@@ -158,8 +173,14 @@ export async function getJson(url, headers, options = {}) {
|
|
|
158
173
|
}
|
|
159
174
|
const { status, statusText, text, retryAfterSec } = result;
|
|
160
175
|
if (status < 200 || status >= 300) {
|
|
161
|
-
return {
|
|
176
|
+
return {
|
|
177
|
+
ok: false, status, statusText, body: undefined,
|
|
178
|
+
...(retryAfterSec !== undefined && { retryAfterSec }),
|
|
179
|
+
...(text.trim() !== '' && { errorText: text.trim().slice(0, 500) }),
|
|
180
|
+
};
|
|
162
181
|
}
|
|
182
|
+
if (text.trim() === '')
|
|
183
|
+
return { ok: true, status, statusText, body: undefined };
|
|
163
184
|
try {
|
|
164
185
|
return { ok: true, status, statusText, body: JSON.parse(text) };
|
|
165
186
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/battery/api/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAkC,MAAM,WAAW,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/battery/api/http.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -66,7 +66,11 @@ async function run() {
|
|
|
66
66
|
// A caller checks this before using a command: the plugin has to know
|
|
67
67
|
// whether the kit on this machine is new enough to stream dictation, since
|
|
68
68
|
// the only alternative it once had (importing the module) is gone.
|
|
69
|
-
|
|
69
|
+
// `settings.env` says this build reads Claude Code's settings files and applies their
|
|
70
|
+
// `env` block. The caller needs to know: the plugin stopped copying that block into the
|
|
71
|
+
// child's environment once this existed, so a kit without it silently loses every
|
|
72
|
+
// variable configured there — a proxy, a CLAUDE_CODE_OAUTH_TOKEN — with no error to show.
|
|
73
|
+
console.log(JSON.stringify({ capabilities: ['oauth.usage.account-file', 'stt.stream', 'settings.env'] }));
|
|
70
74
|
return;
|
|
71
75
|
}
|
|
72
76
|
if (args.some(arg => arg.startsWith('--account-file')) && (!accountFile || module !== 'oauth' || subcommand[0] !== 'usage')) {
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE7C,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,oBAAoB,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AACxF,MAAM,OAAO,GAAW,GAAG,CAAC,OAAO,CAAC;AAEpC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACrE,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACvC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAEzG;;;;;;;;GAQG;AACH,SAAS,SAAS;IAChB,OAAO,IAAI;SACR,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;SACvC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;SACtC,GAAG,CAAC,CAAC,UAAU,EAA2B,EAAE;QAC3C,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,qFAAqF;QACrF,gEAAgE;QAChE,IAAI,EAAE,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACzB,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,IAAI,EAA4B,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAC/D,CAAC;AAED,KAAK,UAAU,YAAY;IACzB,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,cAAc,EAAE,CAAC;IACpG,MAAM,KAAK,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IAC1C,OAAO,IAAI,gBAAgB,CAAC,KAAK,CAAC,CAAC;AACrC,CAAC;AAED,KAAK,UAAU,GAAG;IAChB,0FAA0F;IAC1F,0FAA0F;IAC1F,sEAAsE;IACtE,EAAE;IACF,0FAA0F;IAC1F,4EAA4E;IAC5E,EAAE;IACF,yFAAyF;IACzF,yFAAyF;IACzF,0FAA0F;IAC1F,8CAA8C;IAC9C,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM;QAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IAC9D,MAAM,gBAAgB,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE7E,MAAM,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,OAAO,CAAC;IAExC,IAAI,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAChC,sEAAsE;QACtE,2EAA2E;QAC3E,mEAAmE;QACnE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,YAAY,EAAE,CAAC,0BAA0B,EAAE,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { dirname, resolve } from 'node:path';
|
|
5
|
+
import { applySettingsEnv } from '../settings-env.js';
|
|
6
|
+
import { OPERATIONS, operationCapabilities } from './operations.js';
|
|
7
|
+
import { describeError, runOperation } from './run.js';
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const VERSION = JSON.parse(readFileSync(resolve(__dirname, '../../package.json'), 'utf-8')).version;
|
|
10
|
+
const args = process.argv.slice(2);
|
|
11
|
+
/** `--name value` or `--name=value`, for every name that is not one of this command's own flags. */
|
|
12
|
+
const OWN_FLAGS = new Set(['json', 'yes', 'list', 'capabilities', 'help', 'version', 'env']);
|
|
13
|
+
function parseOptions(rest) {
|
|
14
|
+
const positionals = [];
|
|
15
|
+
const values = {};
|
|
16
|
+
const flags = new Set();
|
|
17
|
+
const env = [];
|
|
18
|
+
for (let i = 0; i < rest.length; i++) {
|
|
19
|
+
const arg = rest[i];
|
|
20
|
+
if (arg === '-h') {
|
|
21
|
+
flags.add('help');
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (arg === '-v') {
|
|
25
|
+
flags.add('version');
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (!arg.startsWith('--')) {
|
|
29
|
+
positionals.push(arg);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const eq = arg.indexOf('=');
|
|
33
|
+
const name = eq === -1 ? arg.slice(2) : arg.slice(2, eq);
|
|
34
|
+
if (name === 'env' && eq !== -1) {
|
|
35
|
+
const assignment = arg.slice(eq + 1);
|
|
36
|
+
const at = assignment.indexOf('=');
|
|
37
|
+
if (at > 0)
|
|
38
|
+
env.push([assignment.slice(0, at), assignment.slice(at + 1)]);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (OWN_FLAGS.has(name)) {
|
|
42
|
+
flags.add(name);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (eq !== -1) {
|
|
46
|
+
values[name] = arg.slice(eq + 1);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const next = rest[i + 1];
|
|
50
|
+
if (next === undefined || next.startsWith('--')) {
|
|
51
|
+
values[name] = '';
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
values[name] = next;
|
|
55
|
+
i++;
|
|
56
|
+
}
|
|
57
|
+
return { positionals, values, flags, env };
|
|
58
|
+
}
|
|
59
|
+
function print(result) {
|
|
60
|
+
console.log(JSON.stringify(result));
|
|
61
|
+
}
|
|
62
|
+
const HELP = `swttch-ext v${VERSION} — calls to services Swttch uses, from @swttch/extend-kit
|
|
63
|
+
|
|
64
|
+
Usage: swttch-ext api <service> <call> [--param value ...] [--yes] [--json]
|
|
65
|
+
|
|
66
|
+
swttch-ext api --list List the calls this version can make
|
|
67
|
+
swttch-ext --capabilities List what this version can do, as JSON
|
|
68
|
+
swttch-ext api frame retitle --slug <id> --title "New name"
|
|
69
|
+
swttch-ext api frame pin --slug <id>
|
|
70
|
+
swttch-ext api frame delete --slug <id> --yes
|
|
71
|
+
|
|
72
|
+
Every call prints one JSON object: {"ok":true,"data":...} or {"ok":false,"error":{...}}.
|
|
73
|
+
A call that cannot be undone refuses to run without --yes.`;
|
|
74
|
+
async function main() {
|
|
75
|
+
const { positionals, values, flags, env } = parseOptions(args);
|
|
76
|
+
if (flags.has('version')) {
|
|
77
|
+
console.log(VERSION);
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
if (flags.has('capabilities')) {
|
|
81
|
+
console.log(JSON.stringify({ capabilities: operationCapabilities() }));
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
84
|
+
if (flags.has('help') || positionals.length === 0) {
|
|
85
|
+
console.log(HELP);
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
88
|
+
const [command, service, call] = positionals;
|
|
89
|
+
if (command !== 'api') {
|
|
90
|
+
console.error(`Unknown command: ${command}\n\n${HELP}`);
|
|
91
|
+
return 1;
|
|
92
|
+
}
|
|
93
|
+
if (flags.has('list')) {
|
|
94
|
+
console.log(JSON.stringify({
|
|
95
|
+
calls: OPERATIONS.map(({ service: s, name, method, path, params, capability, destructive, about }) => ({
|
|
96
|
+
service: s, name, method, path, capability, destructive, about,
|
|
97
|
+
params: params.map(({ name: n, required, about: a }) => ({ name: n, required, about: a })),
|
|
98
|
+
})),
|
|
99
|
+
}));
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
if (!service || !call) {
|
|
103
|
+
print({ ok: false, error: { code: 'invalid_argument', message: 'Say which call: swttch-ext api <service> <call>.' } });
|
|
104
|
+
return 2;
|
|
105
|
+
}
|
|
106
|
+
// The same environment `claude` would see, as `ccb` sets it up: the proxy and the login both depend on it.
|
|
107
|
+
for (const [name, value] of env)
|
|
108
|
+
process.env[name] = value;
|
|
109
|
+
await applySettingsEnv(process.cwd(), new Set(env.map(([name]) => name)));
|
|
110
|
+
const result = await runOperation(service, call, values, { yes: flags.has('yes'), version: VERSION });
|
|
111
|
+
print(result);
|
|
112
|
+
return result.ok ? 0 : 1;
|
|
113
|
+
}
|
|
114
|
+
main().then((code) => { if (code !== 0)
|
|
115
|
+
process.exit(code); }, (err) => { print(describeError(err)); process.exit(1); });
|
|
116
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ext/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The API calls `swttch-ext api` can make, as data.
|
|
3
|
+
*
|
|
4
|
+
* One entry is one call: its method, its path, the parameters it takes, and what each answer
|
|
5
|
+
* means. Adding a call is adding an entry; there is deliberately NO way to name a path that is
|
|
6
|
+
* not in this table. The command carries the user's login to a server, and a command that
|
|
7
|
+
* would send it to any path it was given is a general-purpose client for that login. The
|
|
8
|
+
* table is what makes "this tool can rename an artifact" a statement that can be checked, and
|
|
9
|
+
* what the plugin reads (`api --list`) to decide which menu items to offer.
|
|
10
|
+
*
|
|
11
|
+
* The calls here are the ones Claude Code's own artifact client makes (read from the CLI,
|
|
12
|
+
* 2.1.308): same host, same login, same paths. They are not documented by Anthropic.
|
|
13
|
+
*/
|
|
14
|
+
export type ParamKind = 'string' | 'digits';
|
|
15
|
+
export interface ParamSpec {
|
|
16
|
+
name: string;
|
|
17
|
+
kind: ParamKind;
|
|
18
|
+
required: boolean;
|
|
19
|
+
/** What the value is, for `--list` and the help text. */
|
|
20
|
+
about: string;
|
|
21
|
+
/** Longest value accepted, so a runaway argument is refused here and not by the server. */
|
|
22
|
+
maxLength: number;
|
|
23
|
+
/** The path segment this value fills, the body field it becomes, or the query parameter it is. */
|
|
24
|
+
in: 'path' | 'body' | 'query';
|
|
25
|
+
/** For a `digits` value: the largest number accepted. */
|
|
26
|
+
max?: number;
|
|
27
|
+
}
|
|
28
|
+
/** What a call's answer means, as a code the caller can branch on and a sentence a person can read. */
|
|
29
|
+
export interface ErrorRule {
|
|
30
|
+
status: number;
|
|
31
|
+
code: string;
|
|
32
|
+
message: string;
|
|
33
|
+
}
|
|
34
|
+
export interface Operation {
|
|
35
|
+
service: string;
|
|
36
|
+
name: string;
|
|
37
|
+
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
38
|
+
/** `{slug}` marks where a path parameter goes. */
|
|
39
|
+
path: string;
|
|
40
|
+
params: ParamSpec[];
|
|
41
|
+
/** The capability name a caller can look for in `--capabilities`. */
|
|
42
|
+
capability: string;
|
|
43
|
+
/** Changes or removes something that cannot be put back; refuses to run without `--yes`. */
|
|
44
|
+
destructive: boolean;
|
|
45
|
+
/** Answers to a status that say more than the status does. */
|
|
46
|
+
errors: ErrorRule[];
|
|
47
|
+
/** Statuses worth one more try after the server's own Retry-After (capped), as the CLI does for delete. */
|
|
48
|
+
retryOn?: number[];
|
|
49
|
+
about: string;
|
|
50
|
+
}
|
|
51
|
+
export declare const OPERATIONS: Operation[];
|
|
52
|
+
export declare function findOperation(service: string, name: string): Operation | undefined;
|
|
53
|
+
/** Every capability name the table provides, for `--capabilities`. */
|
|
54
|
+
export declare function operationCapabilities(): string[];
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The API calls `swttch-ext api` can make, as data.
|
|
3
|
+
*
|
|
4
|
+
* One entry is one call: its method, its path, the parameters it takes, and what each answer
|
|
5
|
+
* means. Adding a call is adding an entry; there is deliberately NO way to name a path that is
|
|
6
|
+
* not in this table. The command carries the user's login to a server, and a command that
|
|
7
|
+
* would send it to any path it was given is a general-purpose client for that login. The
|
|
8
|
+
* table is what makes "this tool can rename an artifact" a statement that can be checked, and
|
|
9
|
+
* what the plugin reads (`api --list`) to decide which menu items to offer.
|
|
10
|
+
*
|
|
11
|
+
* The calls here are the ones Claude Code's own artifact client makes (read from the CLI,
|
|
12
|
+
* 2.1.308): same host, same login, same paths. They are not documented by Anthropic.
|
|
13
|
+
*/
|
|
14
|
+
const SLUG = {
|
|
15
|
+
name: 'slug',
|
|
16
|
+
kind: 'string',
|
|
17
|
+
required: true,
|
|
18
|
+
about: 'The artifact id: the last part of its address, https://claude.ai/artifact/<slug>',
|
|
19
|
+
maxLength: 128,
|
|
20
|
+
in: 'path',
|
|
21
|
+
};
|
|
22
|
+
const NOT_OWNER_OR_GONE = {
|
|
23
|
+
status: 404,
|
|
24
|
+
code: 'not_found',
|
|
25
|
+
message: 'Artifact not found. It may have been deleted, or you are not its owner.',
|
|
26
|
+
};
|
|
27
|
+
export const OPERATIONS = [
|
|
28
|
+
{
|
|
29
|
+
service: 'frame',
|
|
30
|
+
name: 'list',
|
|
31
|
+
method: 'GET',
|
|
32
|
+
path: '/api/frame/frames',
|
|
33
|
+
params: [
|
|
34
|
+
{ name: 'limit', kind: 'digits', required: false, about: 'How many to list (default 50, at most 200)', maxLength: 3, in: 'query', max: 200 },
|
|
35
|
+
],
|
|
36
|
+
capability: 'api.frame.list',
|
|
37
|
+
destructive: false,
|
|
38
|
+
errors: [],
|
|
39
|
+
about: 'List your artifacts: name, owner, when it was updated, whether it is pinned, and what you may do to it',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
service: 'frame',
|
|
43
|
+
name: 'retitle',
|
|
44
|
+
method: 'POST',
|
|
45
|
+
path: '/api/frame/retitle/{slug}',
|
|
46
|
+
params: [
|
|
47
|
+
SLUG,
|
|
48
|
+
{ name: 'title', kind: 'string', required: true, about: 'The new name', maxLength: 300, in: 'body' },
|
|
49
|
+
],
|
|
50
|
+
capability: 'api.frame.retitle',
|
|
51
|
+
destructive: false,
|
|
52
|
+
errors: [
|
|
53
|
+
NOT_OWNER_OR_GONE,
|
|
54
|
+
{ status: 409, code: 'conflict', message: 'The name was refused because the artifact changed meanwhile.' },
|
|
55
|
+
{ status: 400, code: 'rejected', message: 'The name was refused.' },
|
|
56
|
+
// A page with no <title> has nothing to rename: the server rewrites the title inside the stored page.
|
|
57
|
+
{ status: 422, code: 'rejected', message: 'The page could not be renamed. A page needs a <title> in its <head> to be renamed.' },
|
|
58
|
+
],
|
|
59
|
+
about: 'Rename an artifact you own',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
service: 'frame',
|
|
63
|
+
name: 'pin',
|
|
64
|
+
method: 'POST',
|
|
65
|
+
path: '/api/frame/favorite/{slug}',
|
|
66
|
+
params: [SLUG],
|
|
67
|
+
capability: 'api.frame.pin',
|
|
68
|
+
destructive: false,
|
|
69
|
+
errors: [NOT_OWNER_OR_GONE],
|
|
70
|
+
about: 'Pin an artifact (it stays at the top of the list)',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
service: 'frame',
|
|
74
|
+
name: 'unpin',
|
|
75
|
+
method: 'DELETE',
|
|
76
|
+
path: '/api/frame/favorite/{slug}',
|
|
77
|
+
params: [SLUG],
|
|
78
|
+
capability: 'api.frame.unpin',
|
|
79
|
+
destructive: false,
|
|
80
|
+
errors: [NOT_OWNER_OR_GONE],
|
|
81
|
+
about: 'Unpin an artifact',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
service: 'frame',
|
|
85
|
+
name: 'delete',
|
|
86
|
+
method: 'DELETE',
|
|
87
|
+
path: '/api/frame/{slug}',
|
|
88
|
+
params: [SLUG],
|
|
89
|
+
capability: 'api.frame.delete',
|
|
90
|
+
destructive: true,
|
|
91
|
+
errors: [NOT_OWNER_OR_GONE],
|
|
92
|
+
retryOn: [409, 429, 503],
|
|
93
|
+
about: 'Delete an artifact for good: its link stops working for everyone and it cannot be restored',
|
|
94
|
+
},
|
|
95
|
+
];
|
|
96
|
+
export function findOperation(service, name) {
|
|
97
|
+
return OPERATIONS.find((op) => op.service === service && op.name === name);
|
|
98
|
+
}
|
|
99
|
+
/** Every capability name the table provides, for `--capabilities`. */
|
|
100
|
+
export function operationCapabilities() {
|
|
101
|
+
return OPERATIONS.map((op) => op.capability);
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=operations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../../src/ext/operations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type Operation } from './operations.js';
|
|
2
|
+
/** What `swttch-ext api` prints: one object on stdout, whatever happened. */
|
|
3
|
+
export type ApiResult = {
|
|
4
|
+
ok: true;
|
|
5
|
+
data: unknown;
|
|
6
|
+
} | {
|
|
7
|
+
ok: false;
|
|
8
|
+
error: {
|
|
9
|
+
code: string;
|
|
10
|
+
message: string;
|
|
11
|
+
status?: number;
|
|
12
|
+
hint?: string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export interface RunOptions {
|
|
16
|
+
/** Confirms a destructive call. */
|
|
17
|
+
yes?: boolean;
|
|
18
|
+
/** Where to send it; defaults to ANTHROPIC_BASE_URL, then the real API. Tests point it at a local server. */
|
|
19
|
+
baseUrl?: string;
|
|
20
|
+
/** A token to use instead of the saved login. Tests only; a caller never passes the user's. */
|
|
21
|
+
token?: string;
|
|
22
|
+
/** This tool's version, sent so the service can tell its callers apart. */
|
|
23
|
+
version?: string;
|
|
24
|
+
}
|
|
25
|
+
/** Check the values against the call's parameters, and say what is wrong in a way a caller can show. */
|
|
26
|
+
export declare function checkParams(op: Operation, values: Record<string, string>): ApiResult | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Make one call from the table. Never throws for an answer the server gave: a refusal is an
|
|
29
|
+
* `ok: false` result with a code. It throws only {@link CcbError}s for things outside the call
|
|
30
|
+
* (no login, no network), which the entry point turns into the same shape.
|
|
31
|
+
*/
|
|
32
|
+
export declare function runOperation(service: string, name: string, values: Record<string, string>, options?: RunOptions): Promise<ApiResult>;
|
|
33
|
+
/** The server's own sentence from an error body shaped `{"error":"..."}` or `{"error":{"message":"..."}}`, else the text itself. */
|
|
34
|
+
export declare function readableReason(errorText: string): string;
|
|
35
|
+
export declare function describeError(err: unknown): ApiResult;
|
package/dist/ext/run.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { getCredentials, getAccessToken } from '../battery/auth/index.js';
|
|
2
|
+
import { requestJson, proxyInUseFor } from '../battery/api/http.js';
|
|
3
|
+
import { CcbError } from '../battery/errors.js';
|
|
4
|
+
import { findOperation } from './operations.js';
|
|
5
|
+
const BASE_URL = 'https://api.anthropic.com';
|
|
6
|
+
/**
|
|
7
|
+
* Headers the artifact service asks of its callers. Without them its answers are 404 for every
|
|
8
|
+
* path, including ones the account plainly has (measured: the same login lists its artifacts with
|
|
9
|
+
* them and gets "not found" without). They say which kind of client is asking, and Claude Code's
|
|
10
|
+
* own client sends the same set. The version names this tool, not Claude Code: the service has
|
|
11
|
+
* accepted that, and a caller should not claim to be a client it is not.
|
|
12
|
+
*/
|
|
13
|
+
function frameHeaders(version) {
|
|
14
|
+
return {
|
|
15
|
+
Accept: 'application/json',
|
|
16
|
+
'X-Frame-CP': 'go',
|
|
17
|
+
'X-Frame-Surface': 'code',
|
|
18
|
+
'X-Frame-Platform': 'cli',
|
|
19
|
+
'X-Frame-Client-Version': `swttch-ext/${version}`,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/** The same beta flag `ccb oauth` sends; the login is a Claude.ai OAuth token. */
|
|
23
|
+
const OAUTH_BETA = 'oauth-2025-04-20';
|
|
24
|
+
/** The longest a retry will wait on the server's own Retry-After, as the CLI caps it. */
|
|
25
|
+
const MAX_RETRY_WAIT_MS = 10_000;
|
|
26
|
+
const DEFAULT_RETRY_WAIT_MS = 1_000;
|
|
27
|
+
function resolveBaseUrl(explicit) {
|
|
28
|
+
const chosen = explicit ?? process.env.ANTHROPIC_BASE_URL?.trim() ?? '';
|
|
29
|
+
return (chosen || BASE_URL).replace(/\/+$/, '');
|
|
30
|
+
}
|
|
31
|
+
function fail(code, message, extra = {}) {
|
|
32
|
+
return { ok: false, error: { code, message, ...extra } };
|
|
33
|
+
}
|
|
34
|
+
/** Check the values against the call's parameters, and say what is wrong in a way a caller can show. */
|
|
35
|
+
export function checkParams(op, values) {
|
|
36
|
+
const known = new Set(op.params.map((p) => p.name));
|
|
37
|
+
for (const name of Object.keys(values)) {
|
|
38
|
+
if (!known.has(name))
|
|
39
|
+
return fail('invalid_argument', `--${name} is not a parameter of ${op.service} ${op.name}.`);
|
|
40
|
+
}
|
|
41
|
+
for (const param of op.params) {
|
|
42
|
+
const value = values[param.name];
|
|
43
|
+
if (value === undefined) {
|
|
44
|
+
if (param.required)
|
|
45
|
+
return fail('invalid_argument', `--${param.name} is required for ${op.service} ${op.name}.`);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (value.trim() === '')
|
|
49
|
+
return fail('invalid_argument', `--${param.name} must not be empty.`);
|
|
50
|
+
if (value.length > param.maxLength) {
|
|
51
|
+
return fail('invalid_argument', `--${param.name} is longer than ${param.maxLength} characters.`);
|
|
52
|
+
}
|
|
53
|
+
if (param.kind === 'digits' && (!/^\d+$/.test(value) || Number(value) < 1 || Number(value) > (param.max ?? 1000))) {
|
|
54
|
+
return fail('invalid_argument', `--${param.name} must be a whole number from 1 to ${param.max ?? 1000}.`);
|
|
55
|
+
}
|
|
56
|
+
// A path parameter is one segment: letting a slash through would let a value name another path.
|
|
57
|
+
if (param.in === 'path' && !/^[A-Za-z0-9_-]+$/.test(value)) {
|
|
58
|
+
return fail('invalid_argument', `--${param.name} may hold only letters, digits, "-" and "_".`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
function buildRequest(op, values) {
|
|
64
|
+
let path = op.path;
|
|
65
|
+
const body = {};
|
|
66
|
+
const query = [];
|
|
67
|
+
for (const param of op.params) {
|
|
68
|
+
const value = values[param.name];
|
|
69
|
+
if (value === undefined)
|
|
70
|
+
continue;
|
|
71
|
+
if (param.in === 'path')
|
|
72
|
+
path = path.replace(`{${param.name}}`, encodeURIComponent(value));
|
|
73
|
+
else if (param.in === 'query')
|
|
74
|
+
query.push(`${encodeURIComponent(param.name)}=${encodeURIComponent(value)}`);
|
|
75
|
+
else
|
|
76
|
+
body[param.name] = value;
|
|
77
|
+
}
|
|
78
|
+
if (query.length > 0)
|
|
79
|
+
path += `?${query.join('&')}`;
|
|
80
|
+
return Object.keys(body).length > 0 ? { path, body } : { path };
|
|
81
|
+
}
|
|
82
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
83
|
+
/**
|
|
84
|
+
* Make one call from the table. Never throws for an answer the server gave: a refusal is an
|
|
85
|
+
* `ok: false` result with a code. It throws only {@link CcbError}s for things outside the call
|
|
86
|
+
* (no login, no network), which the entry point turns into the same shape.
|
|
87
|
+
*/
|
|
88
|
+
export async function runOperation(service, name, values, options = {}) {
|
|
89
|
+
const op = findOperation(service, name);
|
|
90
|
+
if (!op)
|
|
91
|
+
return fail('unknown_operation', `There is no call named "${service} ${name}". Run \`swttch-ext api --list\`.`);
|
|
92
|
+
const bad = checkParams(op, values);
|
|
93
|
+
if (bad)
|
|
94
|
+
return bad;
|
|
95
|
+
if (op.destructive && !options.yes) {
|
|
96
|
+
return fail('confirmation_required', `${op.service} ${op.name} cannot be undone. Run it again with --yes to go ahead.`);
|
|
97
|
+
}
|
|
98
|
+
const token = options.token ?? getAccessToken(await getCredentials());
|
|
99
|
+
const request = buildRequest(op, values);
|
|
100
|
+
const url = `${resolveBaseUrl(options.baseUrl)}${request.path}`;
|
|
101
|
+
const headers = {
|
|
102
|
+
Authorization: `Bearer ${token}`,
|
|
103
|
+
'anthropic-beta': OAUTH_BETA,
|
|
104
|
+
...(op.service === 'frame' ? frameHeaders(options.version ?? 'dev') : {}),
|
|
105
|
+
};
|
|
106
|
+
let response = await requestJson(op.method, url, headers, { body: request.body });
|
|
107
|
+
if (!response.ok && op.retryOn?.includes(response.status)) {
|
|
108
|
+
// The server said "not now": wait as long as it asked (capped), then ask once more.
|
|
109
|
+
const waitMs = Math.min(MAX_RETRY_WAIT_MS, (response.retryAfterSec ?? DEFAULT_RETRY_WAIT_MS / 1000) * 1000);
|
|
110
|
+
await sleep(waitMs);
|
|
111
|
+
response = await requestJson(op.method, url, headers, { body: request.body });
|
|
112
|
+
}
|
|
113
|
+
if (response.ok)
|
|
114
|
+
return { ok: true, data: response.body ?? null };
|
|
115
|
+
const rule = op.errors.find((e) => e.status === response.status);
|
|
116
|
+
const proxy = proxyInUseFor(url);
|
|
117
|
+
if (rule) {
|
|
118
|
+
const detail = response.errorText && rule.status !== 404 ? ` (${readableReason(response.errorText)})` : '';
|
|
119
|
+
return fail(rule.code, `${rule.message}${detail}`, { status: response.status });
|
|
120
|
+
}
|
|
121
|
+
if (response.status === 401) {
|
|
122
|
+
return fail('token_expired', 'The saved login is no longer accepted.', {
|
|
123
|
+
status: 401, hint: 'Run `claude` once to refresh it.',
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
if (response.status === 403) {
|
|
127
|
+
return fail('forbidden', 'This account may not do that.', {
|
|
128
|
+
status: 403,
|
|
129
|
+
hint: proxy ? `The request went through the proxy at ${proxy}; a refusal can come from the network.` : undefined,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
if (response.status === 429) {
|
|
133
|
+
return fail('rate_limited', 'Too many requests. Try again shortly.', {
|
|
134
|
+
status: 429,
|
|
135
|
+
hint: response.retryAfterSec !== undefined ? `Retry after ${response.retryAfterSec}s.` : undefined,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return fail('api_error', `The server answered ${response.status} ${response.statusText}.`, { status: response.status, ...(response.errorText && { hint: readableReason(response.errorText) }) });
|
|
139
|
+
}
|
|
140
|
+
/** The server's own sentence from an error body shaped `{"error":"..."}` or `{"error":{"message":"..."}}`, else the text itself. */
|
|
141
|
+
export function readableReason(errorText) {
|
|
142
|
+
try {
|
|
143
|
+
const parsed = JSON.parse(errorText);
|
|
144
|
+
if (typeof parsed.error === 'string')
|
|
145
|
+
return parsed.error;
|
|
146
|
+
if (parsed.error && typeof parsed.error === 'object' && typeof parsed.error.message === 'string') {
|
|
147
|
+
return parsed.error.message;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
// Not JSON: the text is the reason.
|
|
152
|
+
}
|
|
153
|
+
return errorText;
|
|
154
|
+
}
|
|
155
|
+
export function describeError(err) {
|
|
156
|
+
if (err instanceof CcbError) {
|
|
157
|
+
return fail(err.code, err.message, { ...(err.hint && { hint: err.hint }), ...(err.details?.status && { status: err.details.status }) });
|
|
158
|
+
}
|
|
159
|
+
return fail('unknown_error', err instanceof Error ? err.message : String(err));
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/ext/run.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swttch/extend-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Companion tools for Swttch that live outside the plugin bundle: Claude Code account/usage SDK, the ccb CLI, and speech-to-text.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"./cli": "./dist/cli/index.js"
|
|
22
22
|
},
|
|
23
23
|
"bin": {
|
|
24
|
-
"ccb": "dist/cli/index.js"
|
|
24
|
+
"ccb": "dist/cli/index.js",
|
|
25
|
+
"swttch-ext": "dist/ext/index.js"
|
|
25
26
|
},
|
|
26
27
|
"scripts": {
|
|
27
28
|
"build": "tsc",
|