@cortexkit/opencode-anthropic-auth 1.22.0 → 1.23.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.md +37 -20
- package/dist/billing-lineage.d.ts +51 -0
- package/dist/claustrum-enrollment-registry.d.ts +4 -0
- package/dist/cli.d.ts +2 -1
- package/dist/cli.js +89 -6
- package/dist/custody-dimensions.d.ts +36 -0
- package/dist/custody-enrollment.d.ts +14 -0
- package/dist/custody-live.d.ts +111 -0
- package/dist/custody-manifest-watcher.d.ts +16 -0
- package/dist/custody-mode.d.ts +186 -0
- package/dist/effort-history.d.ts +5 -1
- package/dist/fable-fallback.d.ts +1 -1
- package/dist/{index-926t2bzc.js → index-0jfsxyn9.js} +1 -1
- package/dist/index-1fq7h6yd.js +430 -0
- package/dist/{index-7f57ewkp.js → index-1gr8v4fn.js} +1 -1
- package/dist/index-797pmamn.js +2 -0
- package/dist/{index-bx5hsgf8.js → index-8y2t4mwz.js} +2 -2
- package/dist/index-a5d6v3ba.js +5 -0
- package/dist/index-n96q8pks.js +2 -0
- package/dist/index-xxhyhp98.js +2 -0
- package/dist/index-xzbhzz0a.js +2 -0
- package/dist/index-z7gfdyv3.js +1 -0
- package/dist/index.js +27 -22
- package/dist/local-login.d.ts +64 -0
- package/dist/{logger-jrkranbz.js → logger-kk9vyem9.js} +1 -1
- package/dist/prime-manager-registry.d.ts +5 -1
- package/dist/rpc/notifications.d.ts +3 -3
- package/dist/rpc/port-file.js +1 -1
- package/dist/rpc/protocol.d.ts +9 -2
- package/dist/rpc/protocol.js +1 -1
- package/dist/rpc/rpc-client.d.ts +1 -1
- package/dist/rpc/rpc-client.js +1 -1
- package/dist/rpc/rpc-dir.js +1 -1
- package/dist/rpc/server-registry.d.ts +10 -0
- package/dist/setup/activation.d.ts +7 -0
- package/dist/setup/claustrum.d.ts +26 -0
- package/dist/setup/command-runner.d.ts +2 -0
- package/dist/setup/command.d.ts +8 -0
- package/dist/setup/detect.d.ts +5 -0
- package/dist/setup/jsonc.d.ts +9 -0
- package/dist/setup/opencode-config.d.ts +18 -0
- package/dist/setup/paths.d.ts +15 -0
- package/dist/setup/pi.d.ts +8 -0
- package/dist/setup/process-fence.d.ts +14 -0
- package/dist/setup/types.d.ts +37 -0
- package/dist/sidebar-state.d.ts +3 -1
- package/dist/sidebar-state.js +1 -1
- package/dist/transform.d.ts +5 -1
- package/dist/tui/command-dialogs.d.ts +27 -2
- package/dist/tui-preferences.js +2 -2
- package/package.json +10 -5
- package/src/rpc/notifications.ts +28 -24
- package/src/rpc/protocol.ts +18 -2
- package/src/rpc/rpc-client.ts +1 -1
- package/src/rpc/rpc-server.ts +18 -5
- package/src/rpc/server-registry.ts +61 -0
- package/src/sidebar-state.ts +26 -2
- package/src/tui/command-dialogs.tsx +273 -68
- package/src/tui-compiled/rpc/protocol.ts +18 -2
- package/src/tui-compiled/rpc/rpc-client.ts +1 -1
- package/src/tui-compiled/sidebar-state.ts +26 -2
- package/src/tui-compiled/tui/command-dialogs.tsx +215 -61
- package/src/tui-compiled/tui.tsx +1 -0
- package/src/tui.tsx +1 -0
- package/dist/index-8aga2zwv.js +0 -4
- package/dist/index-cgez4m0h.js +0 -2
- package/dist/index-d3f8g6ve.js +0 -428
- package/dist/index-sh51yqxs.js +0 -2
package/README.md
CHANGED
|
@@ -32,27 +32,39 @@ This repo is a Bun workspace monorepo with two user-facing integrations and one
|
|
|
32
32
|
- **Cache keepalive**: use `/claude-cachekeep always` or `/claude-cachekeep HH-HH` to pre-warm hybrid cache anchors for active sessions before the 1-hour TTL expires.
|
|
33
33
|
- **Quota window priming**: opt in with `/claude-prime on` to start each 5-hour quota window about one minute after it resets instead of waiting for the next normal prompt.
|
|
34
34
|
- **Lane start (OpenCode only)**: use `/claude-start` to fire one synthetic, one-token turn through the current session's normal model, agent, variant, quota, routing, cache, and request pipeline.
|
|
35
|
-
- **Fast mode toggle**: use `/claude-fast on|off` to request Anthropic fast mode for supported Opus models.
|
|
36
|
-
- **Adaptive reasoning visibility**: request summarized adaptive thinking for Claude Fable 5/5.1, Mythos 5/5.1, and Opus 5. OpenCode exposes native `low`, `medium`, `high`, `xhigh`, and `max` effort variants for Fable 5.1 and Opus 5. OAuth Fable 5.1 sessions can change effort between turns without rewriting the cached prefix.
|
|
37
|
-
- **Fable/Opus 5 safety fallback**: eligible OAuth requests try Anthropic's server-side safety fallback first. The plugin preserves Anthropic's fallback conversation boundary across OpenCode history and automatically starts its deterministic 10-response Opus 4.8 recovery if the response still ends in refusal. The TUI sidebar and OpenCode Desktop report the active target model and restoration. Set `OPENCODE_ANTHROPIC_AUTH_FALLBACK_MODE=legacy` to bypass the server policy and use client-side recovery exclusively.
|
|
35
|
+
- **Fast mode toggle**: use `/claude-fast on|off` to request Anthropic fast mode for supported Opus models (`claude-opus-4-6`, `claude-opus-4-7`, `claude-opus-4-8`, `claude-opus-5`, and `claude-opus-5-5`).
|
|
36
|
+
- **Adaptive reasoning visibility**: request summarized adaptive thinking for Claude Fable 5/5.1, Mythos 5/5.1, Opus 5, and Opus 5.5. OpenCode exposes native `low`, `medium`, `high`, `xhigh`, and `max` effort variants for Fable 5.1, Opus 5, and Opus 5.5. On Opus 5.5, thinking is always on (adaptive summarized) per the model specification. OAuth Fable 5.1 sessions can change effort between turns without rewriting the cached prefix.
|
|
37
|
+
- **Fable/Opus 5 and 5.5 safety fallback**: eligible OAuth requests try Anthropic's server-side safety fallback first. The plugin preserves Anthropic's fallback conversation boundary across OpenCode history and automatically starts its deterministic 10-response Opus 4.8 recovery if the response still ends in refusal. The TUI sidebar and OpenCode Desktop report the active target model and restoration. Set `OPENCODE_ANTHROPIC_AUTH_FALLBACK_MODE=legacy` to bypass the server policy and use client-side recovery exclusively.
|
|
38
38
|
- **Live quota visibility**: use `/claude-quota` to see main and fallback quota state, reset times, and refresh errors.
|
|
39
39
|
- **Host-local quota feed**: optionally publish sanitized response-header quota observations so another local CortexKit process can reuse fresh account state without polling Anthropic's rate-limited usage endpoint.
|
|
40
40
|
- **Killswitch**: per-account hard-block thresholds that stop requests before hitting Anthropic's rate limits, with synthetic 429 retry-after when all accounts are exhausted.
|
|
41
41
|
- **User-owned Cloudflare relay**: optionally provision your own Worker relay to reduce repeated client upload bytes for large OpenCode or Pi requests.
|
|
42
|
-
- **Claude-compatible request hardening**: Claude Code 2.1.258 identity and final-body billing signing, live-session-stable billing suffixes, Fable 5.1 thinking-prefix recovery, safer token refresh persistence, replay-safe fallback retries, and subagent cache isolation.
|
|
42
|
+
- **Claude-compatible request hardening**: Claude Code 2.1.258 identity and final-body billing signing, user-turn prompt and request lineage across tool loops, live-session-stable billing suffixes, Fable 5.1 thinking-prefix recovery, safer token refresh persistence, replay-safe fallback retries, and subagent cache isolation.
|
|
43
43
|
|
|
44
44
|
## What these integrations do
|
|
45
45
|
|
|
46
46
|
- Let OpenCode and Pi use Claude Pro/Max OAuth credentials instead of an Anthropic API key.
|
|
47
47
|
- In OpenCode, intercept the final Anthropic request and rewrite it into the Claude-compatible shape expected by Anthropic OAuth access.
|
|
48
48
|
- In Pi, replace Pi's built-in Anthropic provider with a CortexKit provider override that uses the same Claude-compatible request path.
|
|
49
|
-
- Add Claude billing headers with stable `cc_version` and body-derived `cch` signing.
|
|
49
|
+
- Add Claude billing headers with stable `cc_version`, user-turn `cc_prompt_id`/`cc_prev_req` lineage, and body-derived `cch` signing.
|
|
50
50
|
- Support fallback Claude accounts stored in a local per-agent sidecar file.
|
|
51
51
|
- Keep fallback OAuth tokens fresh in the background.
|
|
52
52
|
- Apply quota thresholds before routing to main or fallback accounts.
|
|
53
53
|
- Add `/claude-cache`, `/claude-cachekeep`, `/claude-prime`, `/claude-start`, `/claude-fast`, `/claude-quota`, and `/claude-dump` commands.
|
|
54
54
|
- Optionally relay large requests through a Cloudflare Worker owned by the user.
|
|
55
55
|
|
|
56
|
+
## Setup wizard (recommended)
|
|
57
|
+
|
|
58
|
+
Run the interactive setup wizard:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
bunx @cortexkit/opencode-anthropic-auth setup
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The wizard detects OpenCode, Pi, and Claustrum, configures plugin entries, and optionally activates Claustrum custody.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
56
68
|
## Install
|
|
57
69
|
|
|
58
70
|
### OpenCode
|
|
@@ -231,7 +243,7 @@ The `routing` block controls `/claude-routing`, `claudeCache` controls `/claude-
|
|
|
231
243
|
|
|
232
244
|
`quotaHeaderFeed.enabled` is an OpenCode-only, restart-required opt-in. It publishes only allowlisted quota-window values, an opaque account reference, an observation timestamp, and the configured OAuth-account count; it never publishes tokens, raw headers, request bodies, model IDs, or refresh errors. Per-process lease files use owner-only permissions under `$TMPDIR/opencode-anthropic-auth/quota-header-feed`, expire after three minutes, and can be redirected with `OPENCODE_ANTHROPIC_AUTH_QUOTA_FEED_DIR`.
|
|
233
245
|
|
|
234
|
-
`claustrum.accounts
|
|
246
|
+
`claustrum.accounts` remains loadable only so configurations can safely downgrade to older releases; it does not gate custody per account. Capability handles are bearer credentials and must not be copied into the public config file.
|
|
235
247
|
|
|
236
248
|
Runtime data is stored separately in `anthropic-auth-state.json`: fallback OAuth tokens, API-route keys, token refresh backoff, quota snapshots, and quota API backoff. Sticky session assignments use `anthropic-auth-routing-state.json` and store only SHA-256 hashes of session IDs. Background refresh and quota checks write only runtime state, so editing `anthropic-auth.json` does not get overwritten by another running plugin instance.
|
|
237
249
|
|
|
@@ -244,7 +256,7 @@ Fallback accounts are separate Claude OAuth accounts or Anthropic-compatible API
|
|
|
244
256
|
|
|
245
257
|
Use `/claude-routing fallback-first` to prefer usable fallback accounts before the main account, `/claude-routing main-first` to restore the default, or `/claude-routing sticky-balanced` to allocate each new session according to spendable 5-hour, 7-day, and matching model-scoped OAuth quota headroom. The command persists `routing.mode` and takes effect on the next request without restarting. `/claude-routing reset` clears only the current session's assignment so its next request is allocated again.
|
|
246
258
|
|
|
247
|
-
`sticky-balanced` normalizes quota headroom by time until reset and tracks weighted initial-prompt deficit until the next quota refresh. Assignments are persisted by hashed session ID in `anthropic-auth-routing-state.json`, shared safely across OpenCode plugin instances and restarts. Active hybrid CacheKeep sessions seed their current route when the mode is first enabled.
|
|
259
|
+
`sticky-balanced` normalizes quota headroom by time until reset and tracks weighted initial-prompt deficit until the next quota refresh. Assignments are persisted by hashed session ID in `anthropic-auth-routing-state.json`, shared safely across OpenCode plugin instances and restarts. Active hybrid CacheKeep sessions seed their current route when the mode is first enabled. Changing the user-selected model discards the old assignment and its model-specific CacheKeep preference before quota-based reselection; transparent safety-recovery model changes retain the original account.
|
|
248
260
|
|
|
249
261
|
Affinity survives network/relay failures, 5xx responses, unconfirmed 429s, quota-probe failures, and relative quota changes. Confirmed 7-day or matching model-scoped exhaustion migrates a session. Confirmed 5-hour exhaustion migrates only when more than 15 minutes remain; otherwise the plugin retains the route and returns `Retry-After`. Fable content-filter recovery keeps Fable, Opus 4.8, and Fable prewarms on the same sticky account. Direct Opus sessions first prefer an otherwise usable account whose Fable quota is exhausted.
|
|
250
262
|
|
|
@@ -283,23 +295,17 @@ Fallback OAuth tokens refresh in the background so idle accounts do not expire b
|
|
|
283
295
|
|
|
284
296
|
If Anthropic reports `invalid_grant`, that account must be logged in again. `/claude-account reset-backoff` manually clears the main account's refresh backoff and its matching quota backoff.
|
|
285
297
|
|
|
286
|
-
###
|
|
298
|
+
### Claustrum manifest service
|
|
287
299
|
|
|
288
|
-
|
|
300
|
+
In global Claustrum mode, `/claude-account claustrum` serves OAuth routes that have a binding present in the Claustrum handle manifest; `/claude-account local` returns authority to local OAuth refresh. The vault serves credentials, and the plugin discovers only its own provider block.
|
|
289
301
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
"accounts": {
|
|
294
|
-
"personal-alt": { "enabled": true }
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
```
|
|
302
|
+
The request path reads only a resident in-memory credential. Startup warming and periodic reconciliation perform vault I/O and keep idle credentials refreshed. In Claustrum mode, a cold or unavailable vault must return a typed provider-unavailable response; it does not fall back to the sidecar credential path. That cold-route behavior lands with the dedicated cold-route task. Vault-served 401 reports carry the exact record version and response provenance, including relay-stream 401s, so a sidecar-served failure cannot invalidate a healthy vault credential. `/claude-account` and the account modal show manifest-binding presence, current vault service, and vault reauthentication state without exposing capability handles.
|
|
303
|
+
|
|
304
|
+
After a new Anthropic credential is explicitly bound to `anthropic-auth`, a running plugin watches the manifest and automatically creates its secret-free routing row; the same reconciliation runs during startup. Enrollment requires an exact live `credential.get` match for both the manifest credential ID and provider account UUID, persists only a custody tombstone plus identity metadata, and immediately refreshes the new route's quota so sticky-balanced routing does not wait for the next background interval. Existing disabled rows remain disabled. To stop routing without changing the manifest, disable the account; removing a manifest-bound row is refused until its binding is removed.
|
|
299
305
|
|
|
300
|
-
The request
|
|
306
|
+
Claustrum mode also starts the future scoped-discovery enrollment ceremony under the host identity `anthropic-auth-opencode`. The plugin writes the request secret before proposing, shares one locked ceremony across every OpenCode project process, and displays the pending request ID and exact approval command in `/claude-account`. Approval is persisted atomically as an owner-only token at `$XDG_STATE_HOME/cortexkit/anthropic-auth/opencode-enrollment.json` (default `~/.local/state/cortexkit/anthropic-auth/opencode-enrollment.json`). Grant that identity only `category:anthropic-native`; never grant the broader `llm-provider` category. This release does not spend the enrollment token yet: model requests continue through the existing capability-handle manifest until the scoped-discovery cutover lands. `/claude-account enrollment-reset` retries only a denied or locally blocked ceremony and refuses to discard pending or approved authority.
|
|
301
307
|
|
|
302
|
-
|
|
308
|
+
If Claustrum has replaced the main host credential with its provider-bound tombstone, the plugin rejects refresh locally without contacting Anthropic or persisting a permanent `invalid_grant` state. API-key routes are unaffected.
|
|
303
309
|
|
|
304
310
|
## Quota-aware routing
|
|
305
311
|
|
|
@@ -676,14 +682,25 @@ Dump state is persisted in the active sidecar config as `dump.enabled` (`~/.conf
|
|
|
676
682
|
| Variable | Description |
|
|
677
683
|
| --- | --- |
|
|
678
684
|
| `ANTHROPIC_BASE_URL` | Override the Anthropic API endpoint. Must be HTTP(S). |
|
|
685
|
+
| `ANTHROPIC_CUSTOM_HEADERS` | Add proxy-specific headers on API-key and proxy routes. Authentication, protocol, framing, and internal correlation headers cannot be overridden. Ignored for OAuth requests. |
|
|
686
|
+
| `ANTHROPIC_MODEL` | Default proxy alias for any `claude-*` model. Ignored for OAuth requests. |
|
|
687
|
+
| `ANTHROPIC_DEFAULT_SONNET_MODEL` | Proxy alias for `claude-sonnet-*` models. |
|
|
688
|
+
| `ANTHROPIC_DEFAULT_OPUS_MODEL` | Proxy alias for `claude-opus-*` models. |
|
|
689
|
+
| `ANTHROPIC_DEFAULT_HAIKU_MODEL` | Proxy alias for `claude-haiku-*` models. |
|
|
690
|
+
| `ANTHROPIC_DEFAULT_FABLE_MODEL` | Proxy alias for `claude-fable-*` and `claude-mythos-*` models. |
|
|
679
691
|
| `ANTHROPIC_INSECURE` | Set to `1` or `true` to skip TLS verification when `ANTHROPIC_BASE_URL` is set. |
|
|
680
692
|
| `OPENCODE_ANTHROPIC_AUTH_FILE` | Override the OpenCode sidecar config path. |
|
|
693
|
+
| `OPENCODE_ANTHROPIC_AUTH_CLAUSTRUM_ENROLLMENT_FILE` | Override the owner-only OpenCode Claustrum enrollment-token path. |
|
|
681
694
|
| `OPENCODE_ANTHROPIC_AUTH_FALLBACK_MODE` | Set to `legacy` to bypass Anthropic's server policy and use deterministic 10-response client recovery exclusively. The default tries server-side safety fallback first and uses client recovery as a backstop. |
|
|
682
695
|
| `PI_ANTHROPIC_AUTH_FILE` | Override the Pi sidecar config path. |
|
|
683
696
|
| `PI_AGENT_DIR` | Override Pi's agent directory when deriving the default sidecar path. |
|
|
684
697
|
| `CLOUDFLARE_API_TOKEN` | Cloudflare token used by `bunx @cortexkit/opencode-anthropic-auth relay setup`. Not stored. |
|
|
685
698
|
| `CLOUDFLARE_ACCOUNT_ID` | Cloudflare account ID used by relay setup. |
|
|
686
699
|
|
|
700
|
+
`ANTHROPIC_CUSTOM_HEADERS` and the model-alias variables apply only to API-key and proxy routes. OAuth requests keep the Claude Code header and model identity unchanged. Custom headers accept either a JSON object or comma/newline-separated `name: value` entries. A configuration containing an invalid or protected header is ignored as a whole with one redacted warning; it cannot replace route authentication, Anthropic protocol headers, body framing, or plugin-internal correlation headers.
|
|
701
|
+
|
|
702
|
+
An `ANTHROPIC_BASE_URL` path is preserved. For example, `https://proxy.example/anthropic` sends requests to `/anthropic/v1/messages`, while a versioned base such as `https://proxy.example/anthropic/v2` sends to `/anthropic/v2/messages`. Existing version segments are not duplicated, and unrelated paths ending in `/messages` are not rewritten.
|
|
703
|
+
|
|
687
704
|
## Request rewriting
|
|
688
705
|
|
|
689
706
|
For Claude Pro/Max OAuth requests, the plugin works at the final Anthropic wire-request layer:
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export declare const BILLING_LINEAGE_REQUEST_HEADER = "x-cortexkit-billing-lineage";
|
|
2
|
+
interface MessageLike {
|
|
3
|
+
info?: {
|
|
4
|
+
id?: unknown;
|
|
5
|
+
sessionID?: unknown;
|
|
6
|
+
sessionId?: unknown;
|
|
7
|
+
role?: unknown;
|
|
8
|
+
agent?: unknown;
|
|
9
|
+
synthetic?: unknown;
|
|
10
|
+
ignored?: unknown;
|
|
11
|
+
};
|
|
12
|
+
parts?: Array<{
|
|
13
|
+
type?: unknown;
|
|
14
|
+
text?: unknown;
|
|
15
|
+
synthetic?: unknown;
|
|
16
|
+
ignored?: unknown;
|
|
17
|
+
metadata?: Record<string, unknown>;
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
20
|
+
export interface BillingLineageContext {
|
|
21
|
+
sessionId: string;
|
|
22
|
+
messageId: string;
|
|
23
|
+
promptId: string;
|
|
24
|
+
previousRequestId?: string;
|
|
25
|
+
requestToken: string;
|
|
26
|
+
generation: number;
|
|
27
|
+
sequence: number;
|
|
28
|
+
}
|
|
29
|
+
export interface BillingLineageTrackerOptions {
|
|
30
|
+
createPromptId?: () => string;
|
|
31
|
+
createRequestToken?: () => string;
|
|
32
|
+
maxPrompts?: number;
|
|
33
|
+
maxRequests?: number;
|
|
34
|
+
maxSessions?: number;
|
|
35
|
+
}
|
|
36
|
+
export declare function extractAnthropicRequestId(headers: Headers): string | undefined;
|
|
37
|
+
export declare class BillingLineageTracker {
|
|
38
|
+
#private;
|
|
39
|
+
constructor(options?: BillingLineageTrackerOptions);
|
|
40
|
+
observeMessages(messages: MessageLike[]): void;
|
|
41
|
+
markHeaders(input: {
|
|
42
|
+
sessionId: string;
|
|
43
|
+
messageId: string;
|
|
44
|
+
agent?: string;
|
|
45
|
+
headers: Record<string, string>;
|
|
46
|
+
}): boolean;
|
|
47
|
+
resolveHeader(value: string | null | undefined): BillingLineageContext | undefined;
|
|
48
|
+
commit(context: BillingLineageContext | undefined, requestId: string | undefined): boolean;
|
|
49
|
+
clearSession(sessionId: string): void;
|
|
50
|
+
}
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { adoptClaustrumEnrollment as adoptSharedEnrollment } from '@cortexkit/anthropic-auth-core';
|
|
2
|
+
export type { ClaustrumEnrollmentAdoption } from '@cortexkit/anthropic-auth-core';
|
|
3
|
+
export declare function getOpenCodeClaustrumEnrollmentPaths(env?: NodeJS.ProcessEnv, cwd?: string): import("@cortexkit/anthropic-auth-core").ClaustrumEnrollmentPaths;
|
|
4
|
+
export declare function adoptClaustrumEnrollment(options: Omit<Parameters<typeof adoptSharedEnrollment>[0], 'proposedName'>): import("@cortexkit/anthropic-auth-core").ClaustrumEnrollmentAdoption;
|
package/dist/cli.d.ts
CHANGED
|
@@ -40,4 +40,5 @@ export interface ApiAddDeps {
|
|
|
40
40
|
prompt?: (message: string) => Promise<string>;
|
|
41
41
|
}
|
|
42
42
|
export declare function addApiRoute(labelArg?: string, deps?: ApiAddDeps): Promise<void>;
|
|
43
|
-
|
|
43
|
+
import { runSetupCommand } from './setup/command.ts';
|
|
44
|
+
export { runSetupCommand };
|
package/dist/cli.js
CHANGED
|
@@ -1,14 +1,97 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{$ as
|
|
2
|
+
import{a as NF,d as PF,g as IF}from"./index-797pmamn.js";import{$d as e1,Aa as LF,Ba as UF,G as YF,H as KF,Ia as kF,Ka as DF,Ld as w0,Na as e,Nd as o1,Oa as HF,Pd as l0,Rd as s1,Sa as q0,U as MF,Vd as t1,Wa as VF,Wf as wF,Ya as n1,_a as bF,_f as hF,dc as F1}from"./index-1fq7h6yd.js";import"./index-a5d6v3ba.js";import{nh as _3}from"./index-xxhyhp98.js";import{th as u0,uh as xF,vh as z0}from"./index-n96q8pks.js";var A0=xF((Df,L1)=>{var C0={to(F,f){if(!f)return`\x1B[${F+1}G`;return`\x1B[${f+1};${F+1}H`},move(F,f){let $="";if(F<0)$+=`\x1B[${-F}D`;else if(F>0)$+=`\x1B[${F}C`;if(f<0)$+=`\x1B[${-f}A`;else if(f>0)$+=`\x1B[${f}B`;return $},up:(F=1)=>`\x1B[${F}A`,down:(F=1)=>`\x1B[${F}B`,forward:(F=1)=>`\x1B[${F}C`,backward:(F=1)=>`\x1B[${F}D`,nextLine:(F=1)=>"\x1B[E".repeat(F),prevLine:(F=1)=>"\x1B[F".repeat(F),left:"\x1B[G",hide:"\x1B[?25l",show:"\x1B[?25h",save:"\x1B7",restore:"\x1B8"},yF={up:(F=1)=>"\x1B[S".repeat(F),down:(F=1)=>"\x1B[T".repeat(F)},aF={screen:"\x1B[2J",up:(F=1)=>"\x1B[1J".repeat(F),down:(F=1)=>"\x1B[J".repeat(F),line:"\x1B[2K",lineEnd:"\x1B[K",lineStart:"\x1B[1K",lines(F){let f="";for(let $=0;$<F;$++)f+=this.line+($<F-1?C0.up():"");if(F)f+=C0.left;return f}};L1.exports={cursor:C0,scroll:yF,erase:aF,beep:"\x07"}});import{stdin as s3,stdout as t3}from"node:process";import{createInterface as e3}from"node:readline/promises";import{styleText as m0}from"node:util";import{stdout as p0,stdin as H1}from"node:process";import*as a from"node:readline";import TF from"node:readline";var f1=(()=>{let F=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g;return(f)=>{let $=0;F.lastIndex=0;while(F.test(f))$+=1;return f.length-$}})(),$1=(F)=>{return F===12288||F>=65281&&F<=65376||F>=65504&&F<=65510},J1=(F)=>{return F===8987||F===9001||F>=12272&&F<=12287||F>=12289&&F<=12350||F>=12441&&F<=12543||F>=12549&&F<=12591||F>=12593&&F<=12686||F>=12688&&F<=12771||F>=12783&&F<=12830||F>=12832&&F<=12871||F>=12880&&F<=19903||F>=65040&&F<=65049||F>=65072&&F<=65106||F>=65108&&F<=65126||F>=65128&&F<=65131||F>=127488&&F<=127490||F>=127504&&F<=127547||F>=127552&&F<=127560||F>=131072&&F<=196605||F>=196608&&F<=262141};var OF=/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y,BF=/[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y,j1=/(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu,gF=/\t{1,1000}/y,W1=/[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[\u{E0061}-\u{E007A}]{2}[\u{E0030}-\u{E0039}\u{E0061}-\u{E007A}]{1,3}\u{E007F}|(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})(?:\u200D(?:\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F\u20E3?))*/yu,CF=/(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y,AF=/\p{M}+/gu,RF={limit:1/0,ellipsis:""},Z1=(F,f={},$={})=>{let J=f.limit??1/0,j=f.ellipsis??"",W=f?.ellipsisWidth??(j?Z1(j,RF,$).width:0),Q=0,Z=$.controlWidth??0,z=$.tabWidth??8,Y=$.emojiWidth??2,X=2,G=$.regularWidth??1,K=$.wideWidth??2,L=[[CF,G],[OF,0],[BF,Z],[gF,z],[W1,Y],[j1,K]],M=0,k=0,h=F.length,E=0,B=!1,O=h,U=Math.max(0,J-W),D=0,v=0,P=0,H=0;F:while(!0){if(v>D||k>=h&&k>M){let V=F.slice(D,v)||F.slice(M,k);E=0;for(let m of V.replaceAll(AF,"")){let C=m.codePointAt(0)||0;if($1(C))H=2;else if(J1(C))H=K;else H=G;if(P+H>U)O=Math.min(O,Math.max(D,M)+E);if(P+H>J){B=!0;break F}E+=m.length,P+=H}D=v=0}if(k>=h)break F;for(let V=0,m=L.length;V<m;V++){let[C,G0]=L[V];if(C.lastIndex=k,C.test(F)){if(E=C===j1?f1(F.slice(k,C.lastIndex)):C===W1?1:C.lastIndex-k,H=E*G0,P+H>U)O=Math.min(O,k+Math.floor((U-P)/G0));if(P+H>J){B=!0;break F}P+=H,D=M,v=k,k=M=C.lastIndex;continue F}}k+=1}return{width:B?U:P,index:B?O:h,truncated:B,ellipsed:B&&J>=W}},Q1=Z1;var mF={limit:1/0,ellipsis:"",ellipsisWidth:0},SF=(F,f={})=>{return Q1(F,mF,f).width},R=SF;var K0="\x1B",X1="",uF=39,B0="\x07",K1="[",pF="]",M1="m",g0=`${pF}8;;`,z1=new RegExp(`(?:\\${K1}(?<code>\\d+)m|\\${g0}(?<uri>.*)${B0})`,"y"),Y1=(F)=>{if(F>=30&&F<=37)return 39;if(F>=90&&F<=97)return 39;if(F>=40&&F<=47)return 49;if(F>=100&&F<=107)return 49;if(F===1||F===2)return 22;if(F===3)return 23;if(F===4)return 24;if(F===7)return 27;if(F===8)return 28;if(F===9)return 29;if(F===0)return 0;return},q1=(F)=>`${K0}${K1}${F}${M1}`,G1=(F)=>`${K0}${g0}${F}${B0}`,O0=(F,f,$)=>{let J=f[Symbol.iterator](),j=!1,W=!1,Q=F.at(-1),Z=Q===void 0?0:R(Q),z=J.next(),Y=J.next(),X=0;while(!z.done){let G=z.value,K=R(G);if(Z+K<=$)F[F.length-1]+=G;else F.push(G),Z=0;if(G===K0||G===X1)j=!0,W=f.startsWith(g0,X+1);if(j){if(W){if(G===B0)j=!1,W=!1}else if(G===M1)j=!1}else if(Z+=K,Z===$&&!Y.done)F.push(""),Z=0;z=Y,Y=J.next(),X+=G.length}if(Q=F.at(-1),!Z&&Q!==void 0&&Q.length&&F.length>1)F[F.length-2]+=F.pop()},dF=(F)=>{let f=F.split(" "),$=f.length;while($){if(R(f[$-1]))break;$--}if($===f.length)return F;return f.slice(0,$).join(" ")+f.slice($).join("")},cF=(F,f,$={})=>{if($.trim!==!1&&F.trim()==="")return"";let J="",j,W,Q=F.split(" "),Z=[""],z=0;for(let G=0;G<Q.length;G++){let K=Q[G];if($.trim!==!1){let M=Z.at(-1)??"",k=M.trimStart();if(M.length!==k.length)Z[Z.length-1]=k,z=R(k)}if(G!==0){if(z>=f&&($.wordWrap===!1||$.trim===!1))Z.push(""),z=0;if(z||$.trim===!1)Z[Z.length-1]+=" ",z++}let L=R(K);if($.hard&&L>f){let M=f-z,k=1+Math.floor((L-M-1)/f);if(Math.floor((L-1)/f)<k)Z.push("");O0(Z,K,f),z=R(Z.at(-1)??"");continue}if(z+L>f&&z&&L){if($.wordWrap===!1&&z<f){O0(Z,K,f),z=R(Z.at(-1)??"");continue}Z.push(""),z=0}if(z+L>f&&$.wordWrap===!1){O0(Z,K,f),z=R(Z.at(-1)??"");continue}Z[Z.length-1]+=K,z+=L}if($.trim!==!1)Z=Z.map((G)=>dF(G));let Y=Z.join(`
|
|
3
|
+
`),X=!1;for(let G=0;G<Y.length;G++){let K=Y[G];if(J+=K,!X){if(X=K>="\uD800"&&K<="\uDBFF",X)continue}else X=!1;if(K===K0||K===X1){z1.lastIndex=G+1;let M=z1.exec(Y)?.groups;if(M?.code!==void 0){let k=Number.parseFloat(M.code);j=k===uF?void 0:k}else if(M?.uri!==void 0)W=M.uri.length===0?void 0:M.uri}if(Y[G+1]===`
|
|
4
|
+
`){if(W)J+=G1("");let L=j?Y1(j):void 0;if(j&&L)J+=q1(L)}else if(K===`
|
|
5
|
+
`){if(j&&Y1(j))J+=q1(j);if(W)J+=G1(W)}}return J},_F=/\r?\n/;function c(F,f,$){return String(F).normalize().split(_F).map((J)=>cF(J,f,$)).join(`
|
|
6
|
+
`)}var A=u0(A0(),1);import{ReadStream as U1}from"node:tty";function o(F,f,$){if(!$.some((Q)=>!Q.disabled))return F;let J=F+f,j=Math.max($.length-1,0),W=J<0?j:J>j?0:J;return $[W]?.disabled?o(W,f<0?-1:1,$):W}function M0(F,f,$,J){let j=J.split(`
|
|
7
|
+
`),W=0,Q=F;for(let z of j){if(Q<=z.length)break;Q-=z.length+1,W++}for(W=Math.max(0,Math.min(j.length-1,W+$)),Q=Math.min(Q,j[W].length)+f;Q<0&&W>0;)W--,Q+=j[W].length+1;for(;Q>j[W].length&&W<j.length-1;)Q-=j[W].length+1,W++;Q=Math.max(0,Math.min(j[W].length,Q));let Z=0;for(let z=0;z<W;z++)Z+=j[z].length+1;return Z+Q}var iF=["up","down","left","right","space","enter","cancel"],lF=["January","February","March","April","May","June","July","August","September","October","November","December"],g={actions:new Set(iF),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["\x03","cancel"],["escape","cancel"]]),messages:{cancel:"Canceled",error:"Something went wrong"},withGuide:!0,accessible:void 0,date:{monthNames:[...lF],messages:{required:"Please enter a valid date",invalidMonth:"There are only 12 months in a year",invalidDay:(F,f)=>`There are only ${F} days in ${f}`,afterMin:(F)=>`Date must be on or after ${F.toISOString().slice(0,10)}`,beforeMax:(F)=>`Date must be on or before ${F.toISOString().slice(0,10)}`}}};function rF(F){if(F!==void 0)return F;if(g.accessible!==void 0)return g.accessible;let f=process.env.ACCESSIBLE;return f!==void 0&&f!==""&&f!=="0"&&f!=="false"}function d0(F,f){if(typeof F=="string")return g.aliases.get(F)===f;for(let $ of F)if($!==void 0&&d0($,f))return!0;return!1}function nF(F,f){if(F===f)return;let $=F.split(`
|
|
8
|
+
`),J=f.split(`
|
|
9
|
+
`),j=Math.max($.length,J.length),W=[];for(let Q=0;Q<j;Q++)$[Q]!==J[Q]&&W.push(Q);return{lines:W,numLinesBefore:$.length,numLinesAfter:J.length,numLines:j}}var oF=globalThis.process.platform.startsWith("win"),k0=Symbol("clack:cancel");function s(F){return F===k0}function L0(F,f){let $=F;$.isTTY&&$.setRawMode(f)}function V1({input:F=H1,output:f=p0,overwrite:$=!0,hideCursor:J=!0}={}){let j=a.createInterface({input:F,output:f,prompt:"",tabSize:1});a.emitKeypressEvents(F,j),F instanceof U1&&F.isTTY&&F.setRawMode(!0);let W=(Q,{name:Z,sequence:z})=>{let Y=String(Q);if(d0([Y,Z,z],"cancel")){J&&f.write(A.cursor.show),process.exit(0);return}if(!$)return;a.moveCursor(f,Z==="return"?0:-1,Z==="return"?-1:0,()=>{a.clearLine(f,1,()=>{F.once("keypress",W)})})};return J&&f.write(A.cursor.hide),F.once("keypress",W),()=>{F.off("keypress",W),J&&f.write(A.cursor.show),F instanceof U1&&F.isTTY&&!oF&&F.setRawMode(!1),j.terminal=!1,j.close()}}var f0=(F)=>("columns"in F)&&typeof F.columns=="number"?F.columns:80,c0=(F)=>("rows"in F)&&typeof F.rows=="number"?F.rows:20;function $0(F,f,$,J=$,j=$,W){let Q=f0(F??p0);return c(f,Q-$.length,{hard:!0,trim:!1}).split(`
|
|
10
|
+
`).map((Z,z,Y)=>{let X=W?W(Z,z):Z;return z===0?`${J}${X}`:z===Y.length-1?`${j}${X}`:`${$}${X}`}).join(`
|
|
11
|
+
`)}function b1(F,f){if("~standard"in F){let $=F["~standard"].validate(f);return $ instanceof Promise?$.then((J)=>J.issues?.at(0)?.message):$.issues?.at(0)?.message}return F(f)}class l{input;output;_abortSignal;rl;opts;_render;_track=!1;_prevFrame="";_subscribers=new Map;_cursor=0;state="initial";error="";value;userInput="";get accessible(){return rF(this.opts.accessible)}constructor(F,f=!0){let{input:$=H1,output:J=p0,render:j,signal:W,...Q}=F;this.opts=Q,this.onKeypress=this.onKeypress.bind(this),this.close=this.close.bind(this),this.render=this.render.bind(this),this._render=j.bind(this),this._track=f,this._abortSignal=W,this.input=$,this.output=J}unsubscribe(){this._subscribers.clear()}setSubscriber(F,f){let $=this._subscribers.get(F)??[];$.push(f),this._subscribers.set(F,$)}on(F,f){this.setSubscriber(F,{cb:f})}once(F,f){this.setSubscriber(F,{cb:f,once:!0})}emit(F,...f){let $=this._subscribers.get(F)??[],J=[];for(let j of $)j.cb(...f),j.once&&J.push(()=>$.splice($.indexOf(j),1));for(let j of J)j()}prompt(){return new Promise((F)=>{if(this._abortSignal){if(this._abortSignal.aborted)return this.state="cancel",this.close(),F(k0);this._abortSignal.addEventListener("abort",()=>{this.state="cancel",this.close()},{once:!0})}this.rl=TF.createInterface({input:this.input,tabSize:2,prompt:"",escapeCodeTimeout:50,terminal:!0}),this.rl.prompt(),this.opts.initialUserInput!==void 0&&this._setUserInput(this.opts.initialUserInput,!0),this.input.on("keypress",this.onKeypress),L0(this.input,!0),this.output.on("resize",this.render),this.render(),this.once("submit",()=>{this.output.write(A.cursor.show),this.output.off("resize",this.render),L0(this.input,!1),F(this.value)}),this.once("cancel",()=>{this.output.write(A.cursor.show),this.output.off("resize",this.render),L0(this.input,!1),F(k0)})})}_isActionKey(F,f){return F==="\t"}_shouldSubmit(F,f){return!0}_setValue(F){this.value=F,this.emit("value",this.value)}_setUserInput(F,f){this.userInput=F??"",this.emit("userInput",this.userInput),f&&this._track&&this.rl&&(this.rl.write(this.userInput),this._cursor=this.rl.cursor)}_clearUserInput(){this.rl?.write(null,{ctrl:!0,name:"u"}),this._setUserInput("")}async onKeypress(F,f){if(this.state!=="validating"){if(this._track&&f.name!=="return"&&(f.name&&this._isActionKey(F,f)&&this.rl?.write(null,{ctrl:!0,name:"h"}),this._cursor=this.rl?.cursor??0,this._setUserInput(this.rl?.line)),this.state==="error"&&(this.state="active"),f?.name&&(!this._track&&g.aliases.has(f.name)&&this.emit("cursor",g.aliases.get(f.name)),g.actions.has(f.name)&&this.emit("cursor",f.name)),F&&(F.toLowerCase()==="y"||F.toLowerCase()==="n")&&this.emit("confirm",F.toLowerCase()==="y"),this.emit("key",F,f),f?.name==="return"&&this._shouldSubmit(F,f)){if(this.opts.validate){let $=b1(this.opts.validate,this.value),J;$ instanceof Promise?(this.state="validating",this.render(),J=await $):J=$,J&&(this.error=J instanceof Error?J.message:J,this.state="error",this.rl?.write(this.userInput))}this.state!=="error"&&(this.state="submit")}d0([F,f?.name,f?.sequence],"cancel")&&(this.state="cancel"),(this.state==="submit"||this.state==="cancel")&&this.emit("finalize"),this.render(),(this.state==="submit"||this.state==="cancel")&&this.close()}}close(){this.input.unpipe(),this.input.removeListener("keypress",this.onKeypress),this.output.write(`
|
|
12
|
+
`),L0(this.input,!1),this.rl?.close(),this.rl=void 0,this.emit(`${this.state}`,this.value),this.unsubscribe()}restoreCursor(){let F=c(this._prevFrame,process.stdout.columns,{hard:!0,trim:!1}).split(`
|
|
13
|
+
`).length-1;this.output.write(A.cursor.move(-999,F*-1))}render(){let F=c(this._render(this)??"",process.stdout.columns,{hard:!0,trim:!1});if(F!==this._prevFrame){if(this.state==="initial")this.output.write(A.cursor.hide);else{let f=nF(this._prevFrame,F),$=c0(this.output);if(this.restoreCursor(),f){let J=Math.max(0,f.numLinesAfter-$),j=Math.max(0,f.numLinesBefore-$),W=f.lines.find((Q)=>Q>=J);if(W===void 0){this._prevFrame=F;return}if(f.lines.length===1){this.output.write(A.cursor.move(0,W-j)),this.output.write(A.erase.lines(1));let Q=F.split(`
|
|
14
|
+
`);this.output.write(Q[W]),this._prevFrame=F,this.output.write(A.cursor.move(0,Q.length-W-1));return}else if(f.lines.length>1){if(J<j)W=J;else{let Z=W-j;Z>0&&this.output.write(A.cursor.move(0,Z))}this.output.write(A.erase.down());let Q=F.split(`
|
|
15
|
+
`).slice(W);this.output.write(Q.join(`
|
|
16
|
+
`)),this._prevFrame=F;return}}this.output.write(A.erase.down())}this.output.write(F),this.state==="initial"&&(this.state="active"),this._prevFrame=F}}}function sF(F,f){if(F===void 0||f.length===0)return 0;let $=f.findIndex((J)=>J.value===F);return $!==-1?$:0}function tF(F,f){return(f.label??String(f.value)).toLowerCase().includes(F.toLowerCase())}function eF(F,f){if(f)return F?f:f[0]}var F3=class extends l{filteredOptions;multiple;isNavigating=!1;selectedValues=[];focusedValue;#f=0;#j="";#F;#Z;#Q;#$;get cursor(){return this.#f}get userInputWithCursor(){if(!this.userInput)return m0(["inverse","hidden"],"_");if(this._cursor>=this.userInput.length)return`${this.userInput}█`;let f=this.userInput.slice(0,this.cursor),$=this.userInput.slice(this.cursor,this.cursor+1),J=this.userInput.slice(this.cursor+1);return`${f}${m0("inverse",$)}${J}`}get options(){return typeof this.#Z=="function"?this.#Z():this.#Z}constructor(f){super(f),this.#Z=f.options,this.#Q=f.placeholder,this.#$=f.completeOnTab===!0;let $=this.options;this.filteredOptions=[...$],this.multiple=f.multiple===!0,this.#F=typeof f.options=="function"?f.filter:f.filter??tF;let J;if(f.initialValue&&Array.isArray(f.initialValue)?this.multiple?J=f.initialValue:J=f.initialValue.slice(0,1):!this.multiple&&this.options.length>0&&(J=[this.options[0]?.value]),J)for(let j of J){let W=$.findIndex((Q)=>Q.value===j);W!==-1&&(this.toggleSelected(j),this.#f=W)}this.focusedValue=this.options[this.#f]?.value,this.on("key",(j,W)=>this.#J(j,W)),this.on("userInput",(j)=>this.#W(j))}_isActionKey(f,$){return f==="\t"||this.multiple&&this.isNavigating&&$.name==="space"&&f!==void 0&&f!==""}#J(f,$){let J=$.name==="up",j=$.name==="down",W=$.name==="return",Q=this.userInput===""||this.userInput==="\t",Z=this.#Q,z=this.options,Y=Z!==void 0&&Z!==""&&z.some((X)=>!X.disabled&&(this.#F?this.#F(Z,X):!0));if($.name==="tab"&&Q&&Y){this.userInput==="\t"&&this._clearUserInput(),this._setUserInput(Z,!0),this.isNavigating=!1;return}if($.name==="tab"&&this.#$&&!this.multiple&&this.focusedValue!==void 0){let X=String(this.focusedValue);this._clearUserInput(),this._setUserInput(X,!0),this.isNavigating=!1;return}J||j?(this.#f=o(this.#f,J?-1:1,this.filteredOptions),this.focusedValue=this.filteredOptions[this.#f]?.value,this.multiple||(this.selectedValues=[this.focusedValue]),this.isNavigating=!0):W?this.value=eF(this.multiple,this.selectedValues):this.multiple?this.focusedValue!==void 0&&($.name==="tab"||this.isNavigating&&$.name==="space")?this.toggleSelected(this.focusedValue):this.isNavigating=!1:(this.focusedValue&&(this.selectedValues=[this.focusedValue]),this.isNavigating=!1)}deselectAll(){this.selectedValues=[]}toggleSelected(f){this.filteredOptions.length!==0&&(this.multiple?this.selectedValues.includes(f)?this.selectedValues=this.selectedValues.filter(($)=>$!==f):this.selectedValues=[...this.selectedValues,f]:this.selectedValues=[f])}#W(f){if(f!==this.#j){this.#j=f;let $=this.options;f&&this.#F?this.filteredOptions=$.filter((W)=>this.#F?.(f,W)):this.filteredOptions=[...$];let J=sF(this.focusedValue,this.filteredOptions);this.#f=o(J,0,this.filteredOptions);let j=this.filteredOptions[this.#f];j&&!j.disabled?this.focusedValue=j.value:this.focusedValue=void 0,this.multiple||(this.focusedValue!==void 0?this.toggleSelected(this.focusedValue):this.deselectAll())}}};class _0 extends l{get cursor(){return this.value?0:1}get _value(){return this.cursor===0}constructor(F){super(F,!1),this.value=!!F.initialValue,this.on("userInput",()=>{this.value=this._value}),this.on("confirm",(f)=>{this.output.write(A.cursor.move(0,-1)),this.value=f,this.state="submit",this.close()}),this.on("cursor",()=>{this.value=!this.value})}}var f3={Y:{type:"year",len:4},M:{type:"month",len:2},D:{type:"day",len:2}};function k1(F){return[...F].map((f)=>f3[f])}function $3(F){let f=new Intl.DateTimeFormat(F,{year:"numeric",month:"2-digit",day:"2-digit"}).formatToParts(new Date(2000,0,15)),$=[],J="/";for(let j of f)j.type==="literal"?J=j.value.trim()||j.value:(j.type==="year"||j.type==="month"||j.type==="day")&&$.push({type:j.type,len:j.type==="year"?4:2});return{segments:$,separator:J}}function R0(F){return Number.parseInt((F||"0").replace(/_/g,"0"),10)||0}function U0(F){return{year:R0(F.year),month:R0(F.month),day:R0(F.day)}}function S0(F,f){return new Date(F||2001,f||1,0).getDate()}function w1(F){let{year:f,month:$,day:J}=U0(F);if(!f||f<0||f>9999||!$||$<1||$>12||!J||J<1)return;let j=new Date(Date.UTC(f,$-1,J));if(!(j.getUTCFullYear()!==f||j.getUTCMonth()!==$-1||j.getUTCDate()!==J))return{year:f,month:$,day:J}}function D1(F){let f=w1(F);return f?new Date(Date.UTC(f.year,f.month-1,f.day)):void 0}function J3(F,f,$,J){let j=$?{year:$.getUTCFullYear(),month:$.getUTCMonth()+1,day:$.getUTCDate()}:null,W=J?{year:J.getUTCFullYear(),month:J.getUTCMonth()+1,day:J.getUTCDate()}:null;return F==="year"?{min:j?.year??1,max:W?.year??9999}:F==="month"?{min:j&&f.year===j.year?j.month:1,max:W&&f.year===W.year?W.month:12}:{min:j&&f.year===j.year&&f.month===j.month?j.day:1,max:W&&f.year===W.year&&f.month===W.month?W.day:S0(f.year,f.month)}}class h1 extends l{#f;#j;#F;#Z;#Q;#$={segmentIndex:0,positionInSegment:0};#J=!0;#W=null;inlineError="";get segmentCursor(){return{...this.#$}}get segmentValues(){return{...this.#F}}get segments(){return this.#f}get separator(){return this.#j}get formattedValue(){return this.#G(this.#F)}#G(F){return this.#f.map((f)=>F[f.type]).join(this.#j)}#z(){this._setUserInput(this.#G(this.#F)),this._setValue(D1(this.#F)??void 0)}constructor(F){let f=F.format?{segments:k1(F.format),separator:F.separator??"/"}:$3(F.locale),$=F.separator??f.separator,J=F.format?k1(F.format):f.segments,j=F.initialValue??F.defaultValue,W=j?{year:String(j.getUTCFullYear()).padStart(4,"0"),month:String(j.getUTCMonth()+1).padStart(2,"0"),day:String(j.getUTCDate()).padStart(2,"0")}:{year:"____",month:"__",day:"__"},Q=J.map((Z)=>W[Z.type]).join($);super({...F,initialUserInput:Q},!1),this.#f=J,this.#j=$,this.#F=W,this.#Z=F.minDate,this.#Q=F.maxDate,this.#z(),this.on("cursor",(Z)=>this.#M(Z)),this.on("key",(Z,z)=>this.#L(Z,z)),this.on("finalize",()=>this.#U(F))}#Y(){let F=Math.max(0,Math.min(this.#$.segmentIndex,this.#f.length-1)),f=this.#f[F];if(f)return this.#$.positionInSegment=Math.max(0,Math.min(this.#$.positionInSegment,f.len-1)),{segment:f,index:F}}#q(F){this.inlineError="",this.#W=null;let f=this.#Y();f&&(this.#$.segmentIndex=Math.max(0,Math.min(this.#f.length-1,f.index+F)),this.#$.positionInSegment=0,this.#J=!0)}#X(F){let f=this.#Y();if(!f)return;let{segment:$}=f,J=this.#F[$.type],j=!J||J.replace(/_/g,"")==="",W=Number.parseInt((J||"0").replace(/_/g,"0"),10)||0,Q=J3($.type,U0(this.#F),this.#Z,this.#Q),Z;j?Z=F===1?Q.min:Q.max:Z=Math.max(Math.min(Q.max,W+F),Q.min),this.#F={...this.#F,[$.type]:Z.toString().padStart($.len,"0")},this.#J=!0,this.#W=null,this.#z()}#M(F){if(F)switch(F){case"right":return this.#q(1);case"left":return this.#q(-1);case"up":return this.#X(1);case"down":return this.#X(-1)}}#L(F,f){if(f?.name==="backspace"||f?.sequence===""||f?.sequence==="\b"||F===""||F==="\b"){this.inlineError="";let $=this.#Y();if(!$)return;if(!this.#F[$.segment.type].replace(/_/g,"")){this.#q(-1);return}this.#F[$.segment.type]="_".repeat($.segment.len),this.#J=!0,this.#$.positionInSegment=0,this.#z();return}if(f?.name==="tab"){this.inlineError="";let $=this.#Y();if(!$)return;let J=f.shift?-1:1,j=$.index+J;j>=0&&j<this.#f.length&&(this.#$.segmentIndex=j,this.#$.positionInSegment=0,this.#J=!0);return}if(F&&/^[0-9]$/.test(F)){let $=this.#Y();if(!$)return;let{segment:J}=$,j=!this.#F[J.type].replace(/_/g,"");if(this.#J&&this.#W!==null&&!j){let K=this.#W+F,L={...this.#F,[J.type]:K},M=this.#K(L,J);if(M){this.inlineError=M,this.#W=null,this.#J=!1;return}this.inlineError="",this.#F[J.type]=K,this.#W=null,this.#J=!1,this.#z(),$.index<this.#f.length-1&&(this.#$.segmentIndex=$.index+1,this.#$.positionInSegment=0,this.#J=!0);return}this.#J&&!j&&(this.#F[J.type]="_".repeat(J.len),this.#$.positionInSegment=0),this.#J=!1,this.#W=null;let W=this.#F[J.type],Q=W.indexOf("_"),Z=Q>=0?Q:Math.min(this.#$.positionInSegment,J.len-1);if(Z<0||Z>=J.len)return;let z=W.slice(0,Z)+F+W.slice(Z+1),Y=!1;if(Z===0&&W==="__"&&(J.type==="month"||J.type==="day")){let K=Number.parseInt(F,10);z=`0${F}`,Y=K<=(J.type==="month"?1:2)}if(J.type==="year"&&(z=(W.replace(/_/g,"")+F).padStart(J.len,"_")),!z.includes("_")){let K={...this.#F,[J.type]:z},L=this.#K(K,J);if(L){this.inlineError=L;return}}this.inlineError="",this.#F[J.type]=z;let X=z.includes("_")?void 0:w1(this.#F);if(X){let{year:K,month:L}=X,M=S0(K,L);this.#F={year:String(Math.max(0,Math.min(9999,K))).padStart(4,"0"),month:String(Math.max(1,Math.min(12,L))).padStart(2,"0"),day:String(Math.max(1,Math.min(M,X.day))).padStart(2,"0")}}this.#z();let G=z.indexOf("_");Y?(this.#J=!0,this.#W=F):G>=0?this.#$.positionInSegment=G:Q>=0&&$.index<this.#f.length-1?(this.#$.segmentIndex=$.index+1,this.#$.positionInSegment=0,this.#J=!0):this.#$.positionInSegment=Math.min(Z+1,J.len-1)}}#K(F,f){let{month:$,day:J}=U0(F);if(f.type==="month"&&($<0||$>12))return g.date.messages.invalidMonth;if(f.type==="day"&&(J<0||J>31))return g.date.messages.invalidDay(31,"any month")}#U(F){let{year:f,month:$,day:J}=U0(this.#F);if(f&&$&&J){let j=S0(f,$);this.#F={...this.#F,day:String(Math.min(J,j)).padStart(2,"0")}}this.value=D1(this.#F)??F.defaultValue??void 0}}var j3=class extends l{options;cursor=0;#f;getGroupItems(f){return this.options.filter(($)=>$.group===f)}isGroupSelected(f){let $=this.getGroupItems(f),J=this.value;return J===void 0?!1:$.every((j)=>J.includes(j.value))}toggleValue(){let f=this.options[this.cursor];if(f!==void 0)if(this.value===void 0&&(this.value=[]),f.group===!0){let $=f.value,J=this.getGroupItems($);this.isGroupSelected($)?this.value=this.value.filter((j)=>J.findIndex((W)=>W.value===j)===-1):this.value=[...this.value,...J.map((j)=>j.value)],this.value=Array.from(new Set(this.value))}else{let $=this.value.includes(f.value);this.value=$?this.value.filter((J)=>J!==f.value):[...this.value,f.value]}}constructor(f){super(f,!1);let{options:$}=f;this.#f=f.selectableGroups!==!1,this.options=Object.entries($).flatMap(([J,j])=>[{value:J,group:!0,label:J},...j.map((W)=>({...W,group:J}))]),this.value=[...f.initialValues??[]],this.cursor=Math.max(this.options.findIndex(({value:J})=>J===f.cursorAt),this.#f?0:1),this.on("cursor",(J)=>{switch(J){case"left":case"up":{this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;let j=this.options[this.cursor]?.group===!0;!this.#f&&j&&(this.cursor=this.cursor===0?this.options.length-1:this.cursor-1);break}case"down":case"right":{this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;let j=this.options[this.cursor]?.group===!0;!this.#f&&j&&(this.cursor=this.cursor===this.options.length-1?0:this.cursor+1);break}case"space":this.toggleValue();break}})}},W3=new Set(["up","down","left","right"]);class N1 extends l{#f=!1;#j;focused="editor";get userInputWithCursor(){if(this.state==="submit")return this.userInput;let F=this.userInput;if(this.cursor>=F.length)return`${F}█`;let f=F.slice(0,this.cursor),$=F.slice(this.cursor,this.cursor+1),J=F.slice(this.cursor+1);return $===`
|
|
17
|
+
`?`${f}█
|
|
18
|
+
${J}`:`${f}${m0("inverse",$)}${J}`}get cursor(){return this._cursor}#F(F){if(this.userInput.length===0){this._setUserInput(F);return}this._setUserInput(this.userInput.slice(0,this.cursor)+F+this.userInput.slice(this.cursor))}#Z(F){let f=this.value??"";switch(F){case"up":this._cursor=M0(this._cursor,0,-1,f);return;case"down":this._cursor=M0(this._cursor,0,1,f);return;case"left":this._cursor=M0(this._cursor,-1,0,f);return;case"right":this._cursor=M0(this._cursor,1,0,f);return}}_shouldSubmit(F,f){if(this.#j)return this.focused==="submit"?!0:(this.#F(`
|
|
19
|
+
`),this._cursor++,!1);let $=this.#f;return this.#f=!0,$&&this.cursor===this.userInput.length?(this.userInput[this.cursor-1]===`
|
|
20
|
+
`&&(this._setUserInput(this.userInput.slice(0,this.cursor-1)+this.userInput.slice(this.cursor)),this._cursor--),!0):(this.#F(`
|
|
21
|
+
`),this._cursor++,!1)}constructor(F){let f=F.initialUserInput??F.initialValue;super({...F,initialUserInput:f},!1),f!==void 0&&(this._cursor=f.length),this.#j=F.showSubmit??!1,this.on("key",($,J)=>{if(J?.name&&W3.has(J.name)){this.#f=!1,this.#Z(J.name);return}if($==="\t"&&this.#j){this.focused=this.focused==="editor"?"submit":"editor";return}if(J?.name!=="return"){if(this.#f=!1,J?.name==="backspace"&&this.cursor>0){this._setUserInput(this.userInput.slice(0,this.cursor-1)+this.userInput.slice(this.cursor)),this._cursor--;return}if(J?.name==="delete"&&this.cursor<this.userInput.length){this._setUserInput(this.userInput.slice(0,this.cursor)+this.userInput.slice(this.cursor+1));return}$&&(this.#j&&this.focused==="submit"&&(this.focused="editor"),this.#F($??""),this._cursor++)}}),this.on("userInput",($)=>{this._setValue($)}),this.on("finalize",()=>{this.value||(this.value=F.defaultValue),this.value===void 0&&(this.value="")})}}class x0 extends l{options;cursor=0;get _value(){return this.options[this.cursor]?.value}get _enabledOptions(){return this.options.filter((F)=>F.disabled!==!0)}toggleAll(){let F=this._enabledOptions,f=this.value!==void 0&&this.value.length===F.length;this.value=f?[]:F.map(($)=>$.value)}toggleInvert(){let F=this.value;if(!F)return;let f=this._enabledOptions.filter(($)=>!F.includes($.value));this.value=f.map(($)=>$.value)}toggleValue(){this.value===void 0&&(this.value=[]);let F=this.value.includes(this._value);this.value=F?this.value.filter((f)=>f!==this._value):[...this.value,this._value]}constructor(F){super(F,!1),this.options=F.options,this.value=[...F.initialValues??[]];let f=Math.max(this.options.findIndex(({value:$})=>$===F.cursorAt),0);this.cursor=this.options[f]?.disabled?o(f,1,this.options):f,this.on("key",($,J)=>{J.name==="a"&&this.toggleAll(),J.name==="i"&&this.toggleInvert()}),this.on("cursor",($)=>{switch($){case"left":case"up":this.cursor=o(this.cursor,-1,this.options);break;case"down":case"right":this.cursor=o(this.cursor,1,this.options);break;case"space":this.toggleValue();break}})}}import{styleText as q,stripVTControlCharacters as Cf}from"node:util";import p from"node:process";var j0=u0(A0(),1);function Z3(){if(p.platform!=="win32")return p.env.TERM!=="linux";return Boolean(p.env.CI)||Boolean(p.env.WT_SESSION)||Boolean(p.env.TERMINUS_SUBLIME)||p.env.ConEmuTask==="{cmd::Cmder}"||p.env.TERM_PROGRAM==="Terminus-Sublime"||p.env.TERM_PROGRAM==="vscode"||p.env.TERM==="xterm-256color"||p.env.TERM==="alacritty"||p.env.TERMINAL_EMULATOR==="JetBrains-JediTerm"}var y0=Z3(),Q3=()=>process.env.CI==="true";var b=(F,f)=>y0?F:f,P1=b("◆","*"),A1=b("■","x"),R1=b("▲","x"),D0=b("◇","o"),z3=b("┌","T"),w=b("│","|"),W0=b("└","—"),Sf=b("┐","T"),uf=b("┘","—"),I1=b("●",">"),E1=b("○"," "),Y3=b("◻","[•]"),v1=b("◼","[+]"),O1=b("◻","[ ]"),pf=b("▪","•"),B1=b("─","-"),q3=b("╮","+"),G3=b("├","+"),X3=b("╯","+"),K3=b("╰","+"),df=b("╭","+"),M3=b("●","•"),L3=b("◆","*"),U3=b("▲","!"),k3=b("■","x"),m1=(F)=>{switch(F){case"initial":case"active":return q("cyan",P1);case"cancel":return q("red",A1);case"error":return q("yellow",R1);case"submit":return q("green",D0);case"validating":return q("dim",P1)}},D3=(F)=>{switch(F){case"initial":case"active":return q("cyan",w);case"cancel":return q("red",w);case"error":return q("yellow",w);case"submit":return q("green",w)}};function H3(F,f){let $=[`${f?`${q("cyan",w)} `:""}${F.join(" • ")}`];return f&&$.push(q("cyan",W0)),$}var g1=(F,f,$,J,j,W=!1)=>{let Q=f,Z=0;if(W)for(let z=J-1;z>=$;z--){let Y=F[z];if(Y&&(Q-=Y.length),Z++,Q<=j)break}else for(let z=$;z<J;z++){let Y=F[z];if(Y&&(Q-=Y.length),Z++,Q<=j)break}return{lineCount:Q,removals:Z}},C1=({cursor:F,options:f,style:$,output:J=process.stdout,maxItems:j=Number.POSITIVE_INFINITY,columnPadding:W=0,rowPadding:Q=4})=>{let Z=f0(J)-W,z=c0(J),Y=q("dim","..."),X=Math.max(z-Q,0),G=Math.max(Math.min(j,X),5),K=0;F>=G-3&&(K=Math.max(Math.min(F-G+3,f.length-G),0));let L=G<f.length&&K>0,M=G<f.length&&K+G<f.length,k=Math.min(K+G,f.length),h=[],E=0;L&&E++,M&&E++;let B=K+(L?1:0),O=k-(M?1:0);for(let D=B;D<O;D++){let v=f[D],P=v?$(v,D===F):"",H=c(P,Z,{hard:!0,trim:!1}).split(`
|
|
22
|
+
`);h.push(H),E+=H.length}if(E>X){let D=0,v=0,P=E,H=F-B,V=X,m=()=>g1(h,P,0,H,V),C=()=>g1(h,P,H+1,h.length,V,!0);L?({lineCount:P,removals:D}=m(),P>V&&(M||(V-=1),{lineCount:P,removals:v}=C())):(M||(V-=1),{lineCount:P,removals:v}=C(),P>V&&(V-=1,{lineCount:P,removals:D}=m())),D>0&&(L=!0,h.splice(0,D)),v>0&&(M=!0,h.splice(h.length-v,v))}let U=[];L&&U.push(Y);for(let D of h)for(let v of D)U.push(v);return M&&U.push(Y),U};var a0=(F)=>{let f=F.active??"Yes",$=F.inactive??"No";return new _0({active:f,inactive:$,signal:F.signal,input:F.input,output:F.output,initialValue:F.initialValue??!0,render(){let J=F.withGuide??g.withGuide,j=`${m1(this.state)} `,W=J?`${q("gray",w)} `:"",Q=$0(F.output,F.message,W,j),Z=`${J?`${q("gray",w)}
|
|
23
|
+
`:""}${Q}
|
|
24
|
+
`,z=this.value?f:$;switch(this.state){case"submit":{let Y=J?`${q("gray",w)} `:"";return`${Z}${Y}${q("dim",z)}`}case"cancel":{let Y=J?`${q("gray",w)} `:"";return`${Z}${Y}${q(["strikethrough","dim"],z)}${J?`
|
|
25
|
+
${q("gray",w)}`:""}`}default:{let Y=J?`${q("cyan",w)} `:"",X=J?q("cyan",W0):"";return`${Z}${Y}${this.value?`${q("green",I1)} ${f}`:`${q("dim",E1)} ${q("dim",f)}`}${F.vertical?J?`
|
|
26
|
+
${q("cyan",w)} `:`
|
|
27
|
+
`:` ${q("dim","/")} `}${this.value?`${q("dim",E1)} ${q("dim",$)}`:`${q("green",I1)} ${$}`}
|
|
28
|
+
${X}
|
|
29
|
+
`}}}}).prompt()};var V3=[`${q("dim","↑/↓")} to navigate`,`${q("dim","Space:")} select`,`${q("dim","Enter:")} confirm`],J0=(F,f)=>F.split(`
|
|
30
|
+
`).map(($)=>f($)).join(`
|
|
31
|
+
`),S1=(F)=>{let f=(j,W)=>{let Q=j.label??String(j.value);return W==="disabled"?`${q("gray",O1)} ${J0(Q,(Z)=>q(["strikethrough","gray"],Z))}${j.hint?` ${q("dim",`(${j.hint??"disabled"})`)}`:""}`:W==="active"?`${q("cyan",Y3)} ${Q}${j.hint?` ${q("dim",`(${j.hint})`)}`:""}`:W==="selected"?`${q("green",v1)} ${J0(Q,(Z)=>q("dim",Z))}${j.hint?` ${q("dim",`(${j.hint})`)}`:""}`:W==="cancelled"?`${J0(Q,(Z)=>q(["strikethrough","dim"],Z))}`:W==="active-selected"?`${q("green",v1)} ${Q}${j.hint?` ${q("dim",`(${j.hint})`)}`:""}`:W==="submitted"?`${J0(Q,(Z)=>q("dim",Z))}`:`${q("dim",O1)} ${J0(Q,(Z)=>q("dim",Z))}`},$=F.required??!0,J=F.showInstructions??!0;return new x0({options:F.options,signal:F.signal,input:F.input,output:F.output,initialValues:F.initialValues,required:$,cursorAt:F.cursorAt,validate(j){if($&&(j===void 0||j.length===0))return`Please select at least one option.
|
|
32
|
+
${q("reset",q("dim",`Press ${q(["gray","bgWhite","inverse"]," space ")} to select, ${q("gray",q("bgWhite",q("inverse"," enter ")))} to submit`))}`},render(){let j=F.withGuide??g.withGuide,W=$0(F.output,F.message,j?`${D3(this.state)} `:"",`${m1(this.state)} `),Q=`${j?`${q("gray",w)}
|
|
33
|
+
`:""}${W}
|
|
34
|
+
`,Z=this.value??[],z=(Y,X)=>{if(Y.disabled)return f(Y,"disabled");let G=Z.includes(Y.value);return X&&G?f(Y,"active-selected"):G?f(Y,"selected"):f(Y,X?"active":"inactive")};switch(this.state){case"submit":{let Y=this.options.filter(({value:G})=>Z.includes(G)).map((G)=>f(G,"submitted")).join(q("dim",", "))||q("dim","none"),X=$0(F.output,Y,j?`${q("gray",w)} `:"");return`${Q}${X}`}case"cancel":{let Y=this.options.filter(({value:G})=>Z.includes(G)).map((G)=>f(G,"cancelled")).join(q("dim",", "));if(Y.trim()==="")return`${Q}${q("gray",w)}`;let X=$0(F.output,Y,j?`${q("gray",w)} `:"");return`${Q}${X}${j?`
|
|
35
|
+
${q("gray",w)}`:""}`}case"error":{let Y=j?`${q("yellow",w)} `:"",X=this.error.split(`
|
|
36
|
+
`).map((L,M)=>M===0?`${j?`${q("yellow",W0)} `:""}${q("yellow",L)}`:` ${L}`).join(`
|
|
37
|
+
`),G=Q.split(`
|
|
38
|
+
`).length,K=X.split(`
|
|
39
|
+
`).length+1;return`${Q}${Y}${C1({output:F.output,options:this.options,cursor:this.cursor,maxItems:F.maxItems,columnPadding:Y.length,rowPadding:G+K,style:z}).join(`
|
|
40
|
+
${Y}`)}
|
|
41
|
+
${X}
|
|
42
|
+
`}default:{let Y=j?`${q("cyan",w)} `:"",X=Q.split(`
|
|
43
|
+
`).length,G=J?H3(V3,j):j?[q("cyan",W0)]:[],K=G.join(`
|
|
44
|
+
`),L=G.length+1;return`${Q}${Y}${C1({output:F.output,options:this.options,cursor:this.cursor,maxItems:F.maxItems,columnPadding:Y.length,rowPadding:X+L,style:z}).join(`
|
|
45
|
+
${Y}`)}
|
|
46
|
+
${K}
|
|
47
|
+
`}}}}).prompt()};var N={message:(F=[],{symbol:f=q("gray",w),secondarySymbol:$=q("gray",w),output:J=process.stdout,spacing:j=1,withGuide:W}={})=>{let Q=[],Z=W??g.withGuide,z=Z?$:"",Y=Z?`${f} `:"",X=Z?`${$} `:"";for(let K=0;K<j;K++)Q.push(z);let G=Array.isArray(F)?F:F.split(`
|
|
48
|
+
`);if(G.length>0){let[K,...L]=G;K.length>0?Q.push(`${Y}${K}`):Q.push(Z?f:"");for(let M of L)M.length>0?Q.push(`${X}${M}`):Q.push(Z?$:"")}J.write(`${Q.join(`
|
|
49
|
+
`)}
|
|
50
|
+
`)},info:(F,f)=>{N.message(F,{...f,symbol:q("blue",M3)})},success:(F,f)=>{N.message(F,{...f,symbol:q("green",L3)})},step:(F,f)=>{N.message(F,{...f,symbol:q("green",D0)})},warn:(F,f)=>{N.message(F,{...f,symbol:q("yellow",U3)})},warning:(F,f)=>{N.warn(F,f)},error:(F,f)=>{N.message(F,{...f,symbol:q("red",k3)})}};var u1=(F="",f)=>{let $=f?.output??process.stdout,J=f?.withGuide??g.withGuide?`${q("gray",z3)} `:"";$.write(`${J}${F}
|
|
51
|
+
`)},y=(F="",f)=>{let $=f?.output??process.stdout,J=f?.withGuide??g.withGuide?`${q("gray",w)}
|
|
52
|
+
${q("gray",W0)} `:"";$.write(`${J}${F}
|
|
53
|
+
|
|
54
|
+
`)};var b3=(F)=>F,w3=(F,f,$)=>{let J={hard:!0,trim:!1},j=c(F,f,J).split(`
|
|
55
|
+
`),W=j.reduce((z,Y)=>Math.max(R(Y),z),0),Q=j.map($).reduce((z,Y)=>Math.max(R(Y),z),0),Z=f-(Q-W);return c(F,Z,J)},p1=(F="",f="",$)=>{let J=$?.output??p.stdout,j=$?.withGuide??g.withGuide,W=$?.format??b3,Q=["",...w3(F,f0(J)-6,W).split(`
|
|
56
|
+
`).map(W),""],Z=R(f),z=Math.max(Q.reduce((K,L)=>{let M=R(L);return M>K?M:K},0),Z)+2,Y=Q.map((K)=>`${q("gray",w)} ${K}${" ".repeat(z-R(K))}${q("gray",w)}`).join(`
|
|
57
|
+
`),X=j?`${q("gray",w)}
|
|
58
|
+
`:"",G=j?G3:K3;J.write(`${X}${q("green",D0)} ${q("reset",f)} ${q("gray",B1.repeat(Math.max(z-Z-1,1))+q3)}
|
|
59
|
+
${Y}
|
|
60
|
+
${q("gray",G+B1.repeat(z+2)+X3)}
|
|
61
|
+
`)};var h3=(F)=>q("magenta",F),d1=({indicator:F="dots",onCancel:f,output:$=process.stdout,cancelMessage:J,errorMessage:j,frames:W=y0?["◒","◐","◓","◑"]:["•","o","O","0"],delay:Q=y0?80:120,signal:Z,...z}={})=>{let Y=Q3(),X,G,K=!1,L=!1,M="",k,h=performance.now(),E=f0($),B=z?.styleFrame??h3,O=(I)=>{let u=I>1?j??g.messages.error:J??g.messages.cancel;L=I===1,K&&(F0(u,I),L&&typeof f=="function"&&f())},U=()=>O(2),D=()=>O(1),v=()=>{process.on("uncaughtExceptionMonitor",U),process.on("unhandledRejection",U),process.on("SIGINT",D),process.on("SIGTERM",D),process.on("exit",O),Z&&Z.addEventListener("abort",D)},P=()=>{process.removeListener("uncaughtExceptionMonitor",U),process.removeListener("unhandledRejection",U),process.removeListener("SIGINT",D),process.removeListener("SIGTERM",D),process.removeListener("exit",O),Z&&Z.removeEventListener("abort",D)},H=()=>{if(k===void 0)return;Y&&$.write(`
|
|
62
|
+
`);let I=c(k,E,{hard:!0,trim:!1}).split(`
|
|
63
|
+
`);I.length>1&&$.write(j0.cursor.up(I.length-1)),$.write(j0.cursor.to(0)),$.write(j0.erase.down())},V=(I)=>I.replace(/\.+$/,""),m=(I)=>{let u=(performance.now()-I)/1000,_=Math.floor(u/60),x=Math.floor(u%60);return _>0?`[${_}m ${x}s]`:`[${x}s]`},C=z.withGuide??g.withGuide,G0=(I="")=>{K=!0,X=V1({output:$}),M=V(I),h=performance.now(),C&&$.write(`${q("gray",w)}
|
|
64
|
+
`);let u=0,_=0;v(),G=setInterval(()=>{if(Y&&M===k)return;H(),k=M;let x=B(W[u]),X0;if(Y)X0=`${x} ${M}...`;else if(F==="timer")X0=`${x} ${M} ${m(h)}`;else{let vF=".".repeat(Math.floor(_)).slice(0,3);X0=`${x} ${M}${vF}`}let EF=c(X0,E,{hard:!0,trim:!1});$.write(EF),u=u+1<W.length?u+1:0,_=_<4?_+0.125:0},Q)},F0=(I="",u=0,_=!1)=>{if(!K)return;K=!1,clearInterval(G),H();let x=u===0?q("green",D0):u===1?q("red",A1):q("red",R1);M=I??M,_||(F==="timer"?$.write(`${x} ${M} ${m(h)}
|
|
65
|
+
`):$.write(`${x} ${M}
|
|
66
|
+
`)),P(),X()};return{start:G0,stop:(I="")=>F0(I,0),message:(I="")=>{M=V(I??M)},cancel:(I="")=>F0(I,1),error:(I="")=>F0(I,2),clear:()=>F0("",0,!0),get isCancelled(){return L}}},cf={light:b("─","-"),heavy:b("━","="),block:b("█","#")};var _f=[`${q("dim","↑/↓")} to navigate`,`${q("dim","Enter:")} confirm`];var xf=`${q("gray",w)} `;import{existsSync as c1}from"node:fs";import{mkdir as O3,readFile as _1,rename as B3,unlink as g3,writeFile as C3}from"node:fs/promises";import{dirname as A3,join as R3}from"node:path";import{execFile as N3}from"node:child_process";import{promisify as P3}from"node:util";var I3=P3(N3),S={async run(F,f,$={}){try{let J=$.env?{...process.env,...$.env}:process.env,{stdout:j,stderr:W}=await I3(F,f,{env:J,timeout:$.timeoutMs??15000,maxBuffer:10485760});return{exitCode:0,stdout:typeof j==="string"?j:String(j),stderr:typeof W==="string"?W:String(W)}}catch(J){let j=J;return{exitCode:typeof j?.code==="number"?j.code:1,stdout:typeof j?.stdout==="string"?j.stdout:j?.stdout!=null?String(j.stdout):"",stderr:typeof j?.stderr==="string"?j.stderr:j?.stderr!=null?String(j.stderr):String(j?.message??J)}}}};var E3=/(?:^|\/)(opencode|litecode|opencode2|pi)(?:$|\s)/i;class H0 extends Error{activeHosts;constructor(F){let f=F.map(($)=>` - PID ${$.pid}: ${$.command.slice(0,80)}`).join(`
|
|
67
|
+
`);super(`OpenCode or Pi processes are currently running:
|
|
68
|
+
${f}
|
|
69
|
+
|
|
70
|
+
Please quit all OpenCode, LiteCode, and Pi processes before running setup.`);this.activeHosts=F;this.name="ProcessFenceViolationError"}}function v3(F=S){return{async listRunningHosts(f){let $=process.platform==="win32",J=$?"tasklist":"ps",j=$?["/fo","csv","/nh"]:["-eo","pid,command"],W=await F.run(J,j,{env:f});if(W.exitCode!==0)throw Error(`Process inspection failed (${W.stderr.trim()||`exit ${W.exitCode}`})`);let Q=W.stdout.split(/\r?\n/),Z=[],z=process.pid;for(let Y of Q){let X=Y.trim();if(!X)continue;let G,K;if($){let L=X.split(",").map((M)=>M.replace(/^"|"$/g,""));if(L.length<2)continue;K=L[0]??"",G=Number(L[1])}else{let L=/^(\d+)\s+(.+)$/.exec(X);if(!L)continue;G=Number(L[1]),K=L[2]??""}if(!Number.isInteger(G)||G===z)continue;if(E3.test(K))Z.push({pid:G,command:K})}return Z}}}var Z0=v3(S);async function Q0(F=Z0){let f=await F.listRunningHosts();if(f.length>0)throw new H0(f)}var m3={type:"oauth",access:"",refresh:"claustrum-tombstone:v1:anthropic",expires:0};async function x1(F){let f=F.fence??Z0;await Q0(f);let $={},J=null;if(c1(F.authPath)){J=await _1(F.authPath,"utf8");try{if($=JSON.parse(J),typeof $!=="object"||$===null||Array.isArray($))$={}}catch{$={}}}$.anthropic=m3;let j=`${JSON.stringify($,null,2)}
|
|
71
|
+
`,W=A3(F.authPath);await O3(W,{recursive:!0,mode:448});let Q=R3(W,`.auth.${process.pid}.${Date.now()}.tmp`);await C3(Q,j,{mode:384});try{if(await Q0(f),J!==null&&c1(F.authPath)){if(await _1(F.authPath,"utf8")!==J)throw Error("OpenCode auth.json was modified concurrently during setup")}if(F.beforeRename)await F.beforeRename();await B3(Q,F.authPath)}catch(Z){throw await g3(Q).catch(()=>{}),Z}}import{join as c3}from"node:path";import{existsSync as S3,readFileSync as u3}from"node:fs";import{homedir as T0}from"node:os";import{dirname as y1,join as T,resolve as V0}from"node:path";import{fileURLToPath as p3}from"node:url";var i="@cortexkit/opencode-anthropic-auth",t="@cortexkit/pi-anthropic-auth";function r(F=process.env){let f=F.OPENCODE_CONFIG_DIR?.trim();if(f)return V0(f);let $=F.XDG_CONFIG_HOME?.trim();if($)return T(V0($),"opencode");return T(T0(),".config","opencode")}function d3(F=process.env){let f=F.XDG_DATA_HOME?.trim();if(f)return T(V0(f),"opencode");return T(T0(),".local","share","opencode")}function b0(F=process.env){return T(d3(F),"auth.json")}function n(F=process.env){let f=F.PI_CODING_AGENT_DIR?.trim()||F.PI_AGENT_DIR?.trim();if(f)return V0(f);return T(T0(),".pi","agent")}function i0(F=process.env){return T(n(F),"auth.json")}function a1(F){return`${i}@${F}`}function T1(F){return`${i}@${F}`}function i1(F){return`npm:${t}@${F}`}async function l1(){let F=y1(p3(import.meta.url));for(let f=0;f<5;f++){let $=T(F,"package.json");if(S3($))try{let j=JSON.parse(u3($,"utf8"));if(typeof j.version==="string"&&j.version.trim())return j.version.trim()}catch{}let J=y1(F);if(J===F)break;F=J}return"1.22.0"}var r1=300000;async function r0(F,f={}){let $=f.runner??S,J=f.ckBinary??"ck",j=f.env??process.env,W=`anthropic-auth-${F}`,Q=f.paths??s1(F,j),Z=await o1(Q,W),z=f.enrollmentClient,Y=!1,X=async()=>{if(!z)z=await w0(),Y=!0;return z};try{if(Z.state==="idle")Z=await new l0({client:await X(),paths:Q,proposedName:W}).reconcile();if(Z.state==="pending"&&Z.requestId){let k=await $.run(J,["auth","enroll","approve","--request-id",Z.requestId,"--name",W],{env:j});if(k.exitCode!==0)return{ok:!1,message:`Failed to approve enrollment via ck: ${k.stderr.trim()||`exit ${k.exitCode}`}`,discoveredAccounts:[]};Z=await new l0({client:await X(),paths:Q,proposedName:W}).reconcile()}if(Z.state!=="approved")return{ok:!1,message:`Enrollment did not complete (state: ${Z.state})`,discoveredAccounts:[]};let G=await $.run(J,["auth","grant","--principal",`enrolled:${W}`,"--selector-kind","category","--selector","anthropic-native","--operation","read"],{env:j});if(G.exitCode!==0)return{ok:!1,message:`Failed to grant anthropic-native access: ${G.stderr.trim()||`exit ${G.exitCode}`}`,discoveredAccounts:[]};let{readClaustrumEnrollmentToken:K}=await import("./index-z7gfdyv3.js"),L=await K(Q.tokenPath),M=f.scopedClient??await e1();try{let h=(await M.listScoped(L.token)).rows.filter((H)=>H.refreshAdapter==="anthropic"&&H.categories?.includes("anthropic-native")&&H.operations?.includes("read")&&H.state==="active");if(h.length===0)return{ok:!1,message:"No active Anthropic accounts found in Claustrum vault",discoveredAccounts:[]};let E=Date.now(),B=[];for(let H of h){let V;try{V=await M.getScoped({credentialId:H.id,enrollmentToken:L.token,minTtlMs:r1})}catch(m){let C=m instanceof Error?m.message:String(m);return{ok:!1,message:`Scoped retrieval failed for ${H.id}: ${C}`,discoveredAccounts:[]}}if(!V||typeof V.credentialId!=="string"||V.credentialId!==H.id||typeof V.accountId!=="string"||V.accountId!==H.accountId||typeof V.expiresAtMs!=="number"||!Number.isFinite(V.expiresAtMs)||V.expiresAtMs<E+r1||typeof V.material!=="string"||!V.material.trim())return{ok:!1,message:`Invalid or incomplete credential served for ${H.id}`,discoveredAccounts:[]};B.push({credentialId:H.id,accountId:V.accountId})}let O=F==="opencode"?r(j):n(j),U=c3(O,"anthropic-auth.json");await n1("claustrum",U);let{ClaustrumScopedCustody:D}=await import("./index-z7gfdyv3.js"),v=new D({client:M,readToken:async()=>L});if(!await t1({path:U,custody:v}))return{ok:!1,message:`Failed to commit scoped roster for ${F}`,discoveredAccounts:[]};return{ok:!0,message:`Configured Claustrum custody with ${B.length} Anthropic account(s)`,discoveredAccounts:B}}finally{if(!f.scopedClient)M.close?.()}}finally{if(Y)z?.close?.()}}import{existsSync as t0}from"node:fs";var d=u0(_3(),1);import{existsSync as x3,readFileSync as y3}from"node:fs";function Y0(F){if(!x3(F))return{value:null,text:"",exists:!1};let f=y3(F,"utf8"),$=[],J=d.parse(f,$,{allowTrailingComma:!0});return{value:$.length===0?J:null,text:f,exists:!0}}function n0(F,f,$,J){let W=d.parse(F,[],{allowTrailingComma:!0})??{};for(let G of f)if(typeof W==="object"&&W!==null)W=W[G];else{W=void 0;break}let Q=Array.isArray(W)?W:[],Z=Q.findIndex((G)=>typeof G==="string"&&J(G));if(Z!==-1&&Q[Z]===$)return{text:F,changed:!1};let z;if(Z!==-1)z=d.modify(F,[...f,Z],$,{formattingOptions:{insertSpaces:!0,tabSize:2}});else if(!Array.isArray(W))z=d.modify(F,f,[$],{formattingOptions:{insertSpaces:!0,tabSize:2}});else z=d.modify(F,[...f,Q.length],$,{formattingOptions:{insertSpaces:!0,tabSize:2}});let Y=d.applyEdits(F,z);return{text:d.applyEdits(Y,d.format(Y,void 0,{insertSpaces:!0,tabSize:2})),changed:!0}}import{existsSync as h0}from"node:fs";import{mkdir as FF,writeFile as N0}from"node:fs/promises";import{join as P0}from"node:path";function fF(F){return F===i||F.startsWith(`${i}@`)}function o0(F){let f=P0(F,"opencode.jsonc");if(h0(f))return{path:f,exists:!0};let $=P0(F,"opencode.json");if(h0($))return{path:$,exists:!0};return{path:f,exists:!1}}function a3(F){let f=P0(F,"tui.jsonc");if(h0(f))return{path:f,exists:!0};let $=P0(F,"tui.json");if(h0($))return{path:$,exists:!0};return{path:f,exists:!1}}async function $F(F,f=process.env){let $=r(f);await FF($,{recursive:!0});let{path:J,exists:j}=o0($),W=a1(F);if(!j){let Y=`{
|
|
72
|
+
"$schema": "https://opencode.ai/config.json",
|
|
73
|
+
"plugin": [
|
|
74
|
+
"${W}"
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
`;return await N0(J,Y,"utf8"),{configPath:J,changed:!0,created:!0}}let{text:Q}=Y0(J),{text:Z,changed:z}=n0(Q,["plugin"],W,fF);if(z)await N0(J,Z,"utf8");return{configPath:J,changed:z,created:!1}}async function JF(F,f=process.env){let $=r(f);await FF($,{recursive:!0});let{path:J,exists:j}=a3($),W=T1(F);if(!j){let Y=`{
|
|
78
|
+
"plugin": [
|
|
79
|
+
"${W}"
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
`;return await N0(J,Y,"utf8"),{configPath:J,changed:!0,created:!0}}let{text:Q}=Y0(J),{text:Z,changed:z}=n0(Q,["plugin"],W,fF);if(z)await N0(J,Z,"utf8");return{configPath:J,changed:z,created:!1}}import{existsSync as s0}from"node:fs";import{readFile as jF,writeFile as T3}from"node:fs/promises";import{join as i3}from"node:path";function WF(F=process.env){let f=i3(n(F),"settings.json");if(!s0(f))return!1;try{let J=JSON.parse(l3(f))?.packages;if(!Array.isArray(J))return!1;return J.some((j)=>{let W=typeof j==="string"?j:typeof j==="object"&&j!==null?j.source:"";if(typeof W!=="string")return!1;return W===t||W.startsWith(`${t}@`)||W===`npm:${t}`||W.startsWith(`npm:${t}@`)})}catch{return!1}}function l3(F){return z0("node:fs").readFileSync(F,"utf8")}async function ZF(F=process.env){let f=i0(F);if(!s0(f))return!1;try{let $=await jF(f,"utf8"),J=JSON.parse($);return Boolean(J?.anthropic&&typeof J.anthropic==="object")}catch{return!1}}async function QF(F=process.env){let f=i0(F);if(!s0(f))return!1;try{let $=await jF(f,"utf8"),J=JSON.parse($);if(J?.anthropic)return delete J.anthropic,await T3(f,`${JSON.stringify(J,null,2)}
|
|
83
|
+
`,{mode:384}),!0;return!1}catch{return!1}}async function zF(F,f=S,$=process.env){let J=i1(F),j=await f.run("pi",["install",J],{env:$});if(j.exitCode!==0)return{ok:!1,message:`Failed to install Pi package: ${j.stderr.trim()||`exit ${j.exitCode}`}`};return{ok:!0,message:`Installed ${J}`}}async function r3(F=process.env,f=S){let $=await f.run("opencode",["--version"],{env:F}),J=$.exitCode===0,j=J?$.stdout.trim()||null:null,W=r(F),{path:Q,exists:Z}=o0(W),z=!1;if(Z){let{value:X}=Y0(Q);if(Array.isArray(X?.plugin))z=X.plugin.some((G)=>typeof G==="string"&&(G===i||G.startsWith(`${i}@`)))}return{kind:"opencode",installed:J||Z||t0(b0(F)),version:j,configPath:Q,pluginInstalled:z}}async function n3(F=process.env,f=S){let $=await f.run("pi",["--version"],{env:F}),J=$.exitCode===0,j=null;if(J){let Y=$.stdout.trim()||$.stderr.trim();j=Y.split(/\r?\n/).find((G)=>/^\d+\.\d+\.\d+/.test(G.trim()))?.trim()??Y??null}let W=n(F),Q=J||t0(W),Z=WF(F),z=await ZF(F);return{kind:"pi",installed:Q,version:j,configPath:W,pluginInstalled:Z,hasLocalAuth:z}}async function o3(F=process.env,f=S){let $=await f.run("ck",["--version"],{env:F}),J=$.exitCode===0,j=J?$.stdout.trim()||null:null,W=null,Q=!1;try{if(W=YF(),W&&t0(W)){let Z=await w0({connectionFile:W,handshakeTimeoutMs:2000});Q=!0,Z.close()}}catch{Q=!1}return{ckInstalled:J,ckVersion:j,daemonRunning:Q,connectionPath:W}}async function qF(F=process.env,f=S){let[$,J,j]=await Promise.all([r3(F,f),n3(F,f),o3(F,f)]);return{opencode:$,pi:J,claustrum:j}}async function GF(F=[],f={}){let $=f.env??process.env,J=f.runner??S,j=f.fence??Z0,W=F.includes("--yes")||F.includes("-y"),Q=F.includes("--dry-run"),Z=F.includes("--no-claustrum"),z=F.includes("--claustrum");u1("CortexKit Anthropic Auth Setup");let Y=d1();Y.start("Detecting installed environments…");let X=await qF($,J);Y.stop("Environment detection complete.");let G=X.opencode.installed?`detected (${X.opencode.version??"version unknown"}, ${X.opencode.pluginInstalled?"plugin already configured":"plugin not configured"})`:"not found",K=X.pi.installed?`detected (${X.pi.version??"version unknown"}, ${X.pi.pluginInstalled?"extension already installed":"extension not installed"})`:"not found",L=X.claustrum.daemonRunning?`daemon running (${X.claustrum.ckVersion??"ck ready"})`:X.claustrum.ckInstalled?"ck installed, daemon not running":"not installed";if(N.info(`OpenCode: ${G}`),N.info(`Pi: ${K}`),N.info(`Claustrum: ${L}`),!X.opencode.installed&&!X.pi.installed)return N.error("Neither OpenCode nor Pi was detected on this system."),y("Install OpenCode (https://opencode.ai) or Pi (https://github.com/badlogic/pi-mono) first."),1;let M=[];if(W){if(X.opencode.installed)M.push("opencode");if(X.pi.installed)M.push("pi")}else{let U=[];if(X.opencode.installed)U.push({value:"opencode",label:"OpenCode",hint:X.opencode.pluginInstalled?"already configured":"configure plugin + TUI sidebar"});if(X.pi.installed)U.push({value:"pi",label:"Pi",hint:X.pi.pluginInstalled?"already installed":"install provider extension"});let D=await S1({message:"Select integrations to configure:",options:U,initialValues:U.map((v)=>v.value),required:!0});if(s(D))return y("Setup cancelled."),0;M=D}if(M.length===0)return y("No integrations selected."),0;let k=!1;if(X.claustrum.daemonRunning&&X.claustrum.ckInstalled&&!Z)if(z)k=!0;else if(W)k=!0;else{let U=await a0({message:"Claustrum daemon is running. Use Claustrum custody to manage Anthropic accounts securely in the vault?",initialValue:!0});if(s(U))return y("Setup cancelled."),0;k=U}let E=!1;if(M.includes("pi")&&k&&X.pi.hasLocalAuth)if(W)E=!0;else{N.warn("Pi has a stored local Anthropic OAuth token. Claustrum custody replaces local credentials.");let U=await a0({message:"Remove local Pi Anthropic OAuth credential so Claustrum custody can serve requests?",initialValue:!0});if(s(U)||!U)return N.error("Claustrum custody cannot be enabled for Pi while a local OAuth token takes precedence."),y("Setup aborted."),1;E=!0}try{await Q0(j)}catch(U){if(U instanceof H0)return N.error(U.message),y("Setup aborted — quit active hosts and rerun setup."),1;throw U}if(Q){if(N.info("[dry-run] Planned actions:"),N.info(` - Target integrations: ${M.join(", ")}`),N.info(` - Claustrum custody: ${k?"enabled":"disabled"}`),E)N.info(" - Pi local OAuth token will be removed");return y("Dry run complete. No changes were made."),0}let B=await l1();if(M.includes("opencode")){Y.start("Configuring OpenCode plugin and TUI sidebar…");try{if(await $F(B,$),await JF(B,$),Y.stop("OpenCode configuration updated."),k){Y.start("Enrolling OpenCode into Claustrum custody…");let U=await r0("opencode",{runner:J,env:$});if(!U.ok)return Y.stop("Claustrum enrollment failed."),N.error(U.message),1;Y.stop(`OpenCode enrolled into Claustrum: ${U.message}`),Y.start("Installing Anthropic activation tombstone…"),await x1({authPath:b0($),fence:j}),Y.stop("Anthropic activation tombstone installed.")}}catch(U){return Y.stop("OpenCode setup failed."),N.error(U instanceof Error?U.message:String(U)),1}}if(M.includes("pi")){Y.start("Installing Pi Anthropic extension…");try{let U=await zF(B,J,$);if(!U.ok)return Y.stop("Pi extension installation failed."),N.error(U.message),1;if(Y.stop("Pi Anthropic extension installed."),k){if(E)Y.start("Removing local Pi Anthropic OAuth credential…"),await QF($),Y.stop("Local Pi Anthropic OAuth credential removed.");Y.start("Enrolling Pi into Claustrum custody…");let D=await r0("pi",{runner:J,env:$});if(!D.ok)return Y.stop("Pi Claustrum enrollment failed."),N.error(D.message),1;Y.stop(`Pi enrolled into Claustrum: ${D.message}`)}}catch(U){return Y.stop("Pi setup failed."),N.error(U instanceof Error?U.message:String(U)),1}}let O=[];if(M.includes("opencode"))O.push("• Start OpenCode normally (opencode).");if(M.includes("pi"))O.push("• Start Pi normally (pi).");if(k)O.push("• Manage accounts in Claustrum with: ck auth login --provider anthropic"),O.push(" Newly added accounts will be discovered automatically without restarting.");return p1(O.join(`
|
|
84
|
+
`),"Next Steps"),y("Setup complete!"),0}function Ff(){return{version:1,main:{type:"opencode",provider:"anthropic"},fallbackOn:[401,403,429],refresh:{enabled:!0,intervalMinutes:10,refreshBeforeExpiryMinutes:240},quota:{enabled:!0,checkIntervalMinutes:5,minimumRemaining:{five_hour:10,seven_day:20},failClosedOnUnknownQuota:!0},accounts:[]}}function XF(){console.log(`Usage:
|
|
85
|
+
opencode-anthropic-auth setup [--yes] [--dry-run]
|
|
3
86
|
opencode-anthropic-auth login [label]
|
|
4
87
|
opencode-anthropic-auth api add [label]
|
|
5
88
|
opencode-anthropic-auth list
|
|
6
89
|
opencode-anthropic-auth relay setup
|
|
7
90
|
|
|
8
91
|
Fallback accounts are stored in:
|
|
9
|
-
${
|
|
92
|
+
${e()}`)}function e0(F,f){let $=F?.trim();if(!$)throw Error(`${f} is required`);return $}async function v0(F){let $=await(F.fetchImpl??fetch)(`https://api.cloudflare.com/client/v4${F.path}`,{method:F.method,headers:{authorization:`Bearer ${F.token}`,...F.body instanceof FormData?{}:{"content-type":"application/json"},...F.headers},body:F.body}),J=await $.text(),j;try{j=JSON.parse(J)}catch{throw Error(`Cloudflare API returned ${$.status}: ${J}`)}if(!$.ok||j.success===!1){let W=j.errors?.map((Q)=>Q.message).filter(Boolean).join("; ");throw Error(W||`Cloudflare API returned ${$.status}`)}return j.result}async function ff(F,f,$,J){return v0({token:F,method:"POST",path:`/accounts/${f}/storage/kv/namespaces`,body:JSON.stringify({title:$}),fetchImpl:J})}async function $f(F){let f={main_module:"worker.js",compatibility_date:"2026-04-28",bindings:[{type:"kv_namespace",name:"RELAY_STATE",namespace_id:F.kvNamespaceId},{type:"secret_text",name:"RELAY_TOKEN",text:F.relayToken}]},$=new FormData;return $.set("metadata",JSON.stringify(f)),$.set("worker.js",new Blob([hF],{type:"application/javascript+module"}),"worker.js"),v0({token:F.token,method:"PUT",path:`/accounts/${F.accountId}/workers/scripts/${F.scriptName}`,body:$,fetchImpl:F.fetchImpl})}async function Jf(F,f,$,J){await v0({token:F,method:"POST",path:`/accounts/${f}/workers/scripts/${$}/subdomain`,body:JSON.stringify({enabled:!0,previews_enabled:!1}),fetchImpl:J})}async function jf(F,f,$){return v0({token:F,method:"GET",path:`/accounts/${f}/workers/subdomain`,fetchImpl:$}).catch(()=>null)}async function Wf(F={}){let f=F.fetchImpl??fetch,$=F.prompt??E0,J=e0(process.env.CLOUDFLARE_API_TOKEN?.trim()||await $("Cloudflare API token: "),"Cloudflare API token"),j=e0(process.env.CLOUDFLARE_ACCOUNT_ID||await $("Cloudflare account ID: "),"Cloudflare account ID"),W=await $("Worker name [opencode-anthropic-relay]: ")||"opencode-anthropic-relay",Q=`${W}-state`,Z=wF();console.log("Creating Cloudflare KV namespace...");let z=await ff(J,j,Q,f);console.log("Uploading relay Worker..."),await $f({token:J,accountId:j,scriptName:W,kvNamespaceId:z.id,relayToken:Z,fetchImpl:f}),await Jf(J,j,W,f).catch((L)=>{console.warn(`Could not enable workers.dev automatically: ${L instanceof Error?L.message:String(L)}`)});let Y=await jf(J,j,f),G=(Y?.subdomain?`https://${W}.${Y.subdomain}.workers.dev`:"")||e0(await E0("Relay Worker URL: "),"Relay Worker URL"),K=await q0()??Ff();K.relay={enabled:!0,url:G,token:Z,fallbackToDirect:!0,transport:"http"},await bF(K),console.log(`Relay enabled at ${G}`),console.log(`Config saved to ${e()}.`)}var I0=null;async function E0(F){return I0??=e3({input:s3,output:t3}),(await I0.question(F)).trim()}function Zf(){I0?.close(),I0=null}async function Qf(F,f={}){let $=f.prompt??E0,J=f.authorize??LF,j=f.exchange??UF;if(VF(await q0())==="claustrum")throw Error("Exit Claustrum mode first: /claude-account local");let W=F?.trim()||await $("Fallback account label (optional): "),Q=await J("max");console.log(`
|
|
10
93
|
Open this URL in your browser and complete Claude sign-in:
|
|
11
|
-
`),console.log(`${
|
|
12
|
-
`);let Z=await
|
|
13
|
-
Saved fallback account${
|
|
14
|
-
Saved API fallback route${J?` "${J}"`:""} (${
|
|
94
|
+
`),console.log(`${Q.url}
|
|
95
|
+
`);let Z=await $("Paste the full callback URL or authorization code here: "),z=await j(Z,Q.verifier,Q.redirectUri,Q.state);if(z.type==="failed")throw Error("Authentication failed");let Y=Date.now(),X={id:W||crypto.randomUUID(),label:W||void 0,type:"oauth",authLineageId:crypto.randomUUID(),access:z.access,refresh:z.refresh,expires:z.expires,enabled:!0,addedAt:Y,lastUsed:Y,lastRefreshedAt:Y},G=MF(X.label??X.id);await F1(X),await IF({accountId:X.id,credentialId:G,authFingerprint:PF(z.access,z.refresh),completedAt:Y},{accountStoragePath:e(),manifestPath:KF((await q0())?.claustrum,process.env),divergence:{statePath:HF(e()),lastVaultServedRecordVersion:NF({accountId:X.id,warn:(K)=>console.warn(`Fallback login had no served vault record for ${K}`)})}}),console.log(`
|
|
96
|
+
Saved fallback account${W?` "${W}"`:""}.`)}async function zf(F,f={}){let $=f.prompt??E0,J=F?.trim()||await $("API fallback label (optional): "),j=process.env.OPENCODE_ANTHROPIC_AUTH_API_BASE_URL?.trim()||(await $("Anthropic-compatible base URL [https://api.kie.ai/claude]: ")).trim()||"https://api.kie.ai/claude";if(!DF(j))throw Error("API fallback base URL must be an http(s) URL without embedded credentials");let W=process.env.OPENCODE_ANTHROPIC_AUTH_API_KEY?.trim()||await $("API key: ");if(!W.trim())throw Error("API key is required");let Z=(process.env.OPENCODE_ANTHROPIC_AUTH_API_AUTH_HEADER?.trim()||await $("Auth header [authorization-bearer|x-api-key] (default authorization-bearer): ")).trim().toLowerCase()==="x-api-key"?"x-api-key":"authorization-bearer",z=Date.now();await F1({id:J||crypto.randomUUID(),label:J||void 0,type:"api",apiKey:W.trim(),baseURL:j,authHeader:Z,enabled:!0,addedAt:z,lastUsed:z}),console.log(`
|
|
97
|
+
Saved API fallback route${J?` "${J}"`:""} (${j}).`)}async function Yf(){let F=await q0();if(!F?.accounts.length){console.log(`No fallback accounts found at ${e()}.`);return}for(let[f,$]of F.accounts.entries()){let J=$.label||$.id,j=$.enabled===!1?"disabled":"enabled";if(!kF($)){console.log(`${f+1}. ${J} (${j}) — API route ${$.baseURL}`);continue}let W=$.quota?.five_hour?.remainingPercent,Q=$.quota?.seven_day?.remainingPercent,Z=W===void 0&&Q===void 0?"quota unknown":`5h ${W??"?"}%, 1w ${Q??"?"}% remaining`;console.log(`${f+1}. ${J} (${j}) — ${Z}`)}}async function qf(){let[F,f,$]=process.argv.slice(2);if(!F||F==="help"||F==="--help"||F==="-h"){XF();return}if(F==="setup"){let J=await GF(process.argv.slice(3));if(J!==0)process.exitCode=J;return}if(F==="login"){await Qf(f);return}if(F==="api"&&f==="add"){await zf($);return}if(F==="list"){await Yf();return}if(F==="relay"&&f==="setup"){await Wf();return}XF(),process.exitCode=1}if(z0.main==z0.module)try{await qf()}catch(F){console.error(F instanceof Error?F.message:String(F)),process.exitCode=1}finally{Zf()}export{GF as runSetupCommand,Wf as relaySetup,Qf as login,zf as addApiRoute};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type AccountStorage, type ClaustrumCredential, type CustodyHandleManifest, type CustodyHandleResolution, type CustodyStatusState, type OAuthAccount } from '@cortexkit/anthropic-auth-core';
|
|
2
|
+
type CustodyDimensionsDeps = {
|
|
3
|
+
getCache: () => {
|
|
4
|
+
peek: (handle: string) => ClaustrumCredential | undefined;
|
|
5
|
+
} | null | undefined;
|
|
6
|
+
now: () => number;
|
|
7
|
+
resolveAccountCustodyHandle: (account: OAuthAccount, storage: AccountStorage) => CustodyHandleResolution;
|
|
8
|
+
usableAccessToken: (credential: ClaustrumCredential | undefined, now: number) => string | undefined;
|
|
9
|
+
hasIdentityMismatch: (account: OAuthAccount, credential: ClaustrumCredential | undefined) => boolean;
|
|
10
|
+
isBlocked: (accountId: string) => boolean;
|
|
11
|
+
isReauth: (accountId: string) => boolean;
|
|
12
|
+
getManifest: () => CustodyHandleManifest | undefined;
|
|
13
|
+
};
|
|
14
|
+
export declare function fallbackCustodyDimensions(storage: AccountStorage | null, deps: Pick<CustodyDimensionsDeps, 'getCache' | 'now' | 'resolveAccountCustodyHandle' | 'usableAccessToken'> & {
|
|
15
|
+
construction?: boolean;
|
|
16
|
+
}): {
|
|
17
|
+
fallbacks: "R" | "T";
|
|
18
|
+
evidence: "V" | "unknown";
|
|
19
|
+
} | {
|
|
20
|
+
fallbacks: 'M';
|
|
21
|
+
evidence: "N" | "unknown";
|
|
22
|
+
} | {
|
|
23
|
+
fallbacks: "R" | "T";
|
|
24
|
+
evidence: "N" | "V";
|
|
25
|
+
};
|
|
26
|
+
export declare function mainCustodyDimension(auth: {
|
|
27
|
+
type: string;
|
|
28
|
+
access?: string;
|
|
29
|
+
refresh?: string;
|
|
30
|
+
}): "R" | "T" | "X";
|
|
31
|
+
export declare function isFallbackAccountVaultServed(accountId: string, storage: AccountStorage | null, deps: Pick<CustodyDimensionsDeps, 'getCache' | 'now' | 'resolveAccountCustodyHandle' | 'usableAccessToken' | 'hasIdentityMismatch' | 'isBlocked'>): boolean;
|
|
32
|
+
export declare function custodyStateFor(account: {
|
|
33
|
+
id: string;
|
|
34
|
+
role: 'main' | 'fallback';
|
|
35
|
+
}, storage: AccountStorage | null, deps: CustodyDimensionsDeps, vaultServed?: boolean): CustodyStatusState;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type AccountStorage, type CustodyHandleAccount, type CustodyHandleManifest, type OAuthAccount } from '@cortexkit/anthropic-auth-core';
|
|
2
|
+
/**
|
|
3
|
+
* Returns valid manifest bindings that are not yet represented by an OAuth
|
|
4
|
+
* routing row. Existing disabled rows are intentionally retained: binding a
|
|
5
|
+
* credential must not silently override a user's routing preference.
|
|
6
|
+
*/
|
|
7
|
+
export declare function pendingClaustrumEnrollments(storage: AccountStorage, manifest: CustodyHandleManifest | undefined): CustodyHandleAccount[];
|
|
8
|
+
/** Build the secret-free routing row for a provider-verified manifest binding. */
|
|
9
|
+
export declare function materializeClaustrumEnrollment(input: {
|
|
10
|
+
storage: AccountStorage;
|
|
11
|
+
binding: CustodyHandleAccount;
|
|
12
|
+
providerAccountUuid: string;
|
|
13
|
+
now?: number;
|
|
14
|
+
}): OAuthAccount;
|