@cortexkit/opencode-anthropic-auth 2.0.1 → 2.0.3

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.
Files changed (54) hide show
  1. package/README.md +35 -845
  2. package/dist/cli-failure.d.ts +6 -5
  3. package/dist/cli.js +57 -103
  4. package/dist/custody-mode.d.ts +1 -0
  5. package/dist/{index-52r2e1h9.js → index-5hyennzm.js} +1 -1
  6. package/dist/{index-p4wvcwhh.js → index-fncp6r0j.js} +1 -1
  7. package/dist/index-jmjevtm1.js +2 -0
  8. package/dist/index-kd89hcr3.js +2 -0
  9. package/dist/index-mdpyfkv3.js +464 -0
  10. package/dist/index-nfcp0m1t.js +42 -0
  11. package/dist/index-qttfa42y.js +2 -0
  12. package/dist/{index-3xqv3rw3.js → index-rftced5v.js} +1 -1
  13. package/dist/{index-zdgceztz.js → index-vjehtqnb.js} +1 -1
  14. package/dist/index.js +1 -1
  15. package/dist/quota-preflight.d.ts +1 -0
  16. package/dist/rpc/port-file.js +1 -1
  17. package/dist/rpc/protocol.js +1 -1
  18. package/dist/rpc/rpc-client.js +1 -1
  19. package/dist/rpc/rpc-dir.js +1 -1
  20. package/dist/setup/command.d.ts +5 -14
  21. package/dist/setup/native-activation.d.ts +14 -6
  22. package/dist/setup/native-enrollment.d.ts +15 -0
  23. package/dist/setup/native-local.d.ts +31 -1
  24. package/dist/setup/process-fence.d.ts +0 -6
  25. package/dist/setup/types.d.ts +9 -0
  26. package/dist/sidebar-state.d.ts +20 -2
  27. package/dist/sidebar-state.js +1 -1
  28. package/dist/transform.d.ts +17 -2
  29. package/dist/tui-preferences.js +1 -1
  30. package/dist/tui.d.ts +0 -2
  31. package/dist/v2/activation.d.ts +2 -0
  32. package/dist/v2/adapter.d.ts +8 -2
  33. package/dist/v2/cachekeep.d.ts +19 -0
  34. package/dist/v2/menu.d.ts +2 -1
  35. package/dist/v2/server.js +4 -4
  36. package/dist/v2/setup.d.ts +2 -0
  37. package/dist/v2/source.d.ts +1 -0
  38. package/dist/v2/tui.js +1 -1
  39. package/package.json +5 -5
  40. package/src/sidebar-state.ts +165 -29
  41. package/src/tui-compiled/sidebar-state.ts +165 -29
  42. package/src/tui-compiled/tui.tsx +363 -239
  43. package/src/tui.tsx +149 -48
  44. package/dist/index-04syas8a.js +0 -2
  45. package/dist/index-b3mxpp4w.js +0 -2
  46. package/dist/index-ynq181e8.js +0 -42
  47. package/dist/index-yxtdke11.js +0 -449
  48. package/dist/setup/activation.d.ts +0 -7
  49. package/dist/setup/command.test.d.ts +0 -1
  50. package/dist/setup/detect.d.ts +0 -8
  51. package/dist/setup/host-executable.d.ts +0 -3
  52. package/dist/setup/jsonc.d.ts +0 -9
  53. package/dist/setup/opencode-config.d.ts +0 -18
  54. package/dist/setup/pi.d.ts +0 -18
@@ -1,20 +1,11 @@
1
- import type { Writable } from 'node:stream';
2
- import { detectAll } from './detect.ts';
3
- import { activateNativeVaultForHost } from './native-activation.ts';
1
+ import { type SetupIO } from '@cortexkit/anthropic-auth-core';
2
+ import { completeNativeVaultActivation, preflightNativeVaultForHost } from './native-activation.ts';
4
3
  import { migrateNativeLocalForHost } from './native-local.ts';
5
4
  import { loginNativeOffline } from './native-login.ts';
6
- import type { CommandRunner, ProcessFence } from './types.ts';
7
- export interface SetupCommandOptions {
8
- runner?: CommandRunner;
9
- fence?: ProcessFence;
10
- env?: NodeJS.ProcessEnv;
11
- isInteractive?: boolean;
12
- /** Let tests substitute host detection and per-host vault activation. */
13
- detect?: typeof detectAll;
14
- activate?: typeof activateNativeVaultForHost;
5
+ export interface SetupCommandOptions extends SetupIO {
15
6
  migrateLocal?: typeof migrateNativeLocalForHost;
16
7
  localLogin?: typeof loginNativeOffline;
17
- /** Where setup prints its progress and errors; defaults to stdout. */
18
- output?: Writable;
8
+ vaultPreflight?: typeof preflightNativeVaultForHost;
9
+ vaultActivate?: typeof completeNativeVaultActivation;
19
10
  }
20
11
  export declare function runSetupCommand(argv?: string[], options?: SetupCommandOptions): Promise<number>;
@@ -1,7 +1,7 @@
1
1
  import { type NativeCustodyActivationHooks, type NativeCustodyInventory } from '@cortexkit/anthropic-auth-core';
2
2
  import { type NativeVaultEnrollmentOptions } from './native-enrollment.ts';
3
3
  import { type NativeSetupPaths } from './native-paths.ts';
4
- import type { CommandRunner, HarnessKind, ProcessFence } from './types.ts';
4
+ import { type CommandRunner, type HarnessKind, type ProcessFence } from './types.ts';
5
5
  export declare class NativeVaultActivationError extends Error {
6
6
  readonly code: 'auth-content-refused' | 'host-auth-invalid' | 'primary-conflict' | 'consent-required' | 'primary-unverified';
7
7
  constructor(code: 'auth-content-refused' | 'host-auth-invalid' | 'primary-conflict' | 'consent-required' | 'primary-unverified');
@@ -17,13 +17,21 @@ export interface NativeVaultActivationOptions {
17
17
  * production resolves them from the host's environment.
18
18
  */
19
19
  paths?: NativeSetupPaths;
20
+ /** Set false for OpenCode 2, whose setup must not read the OpenCode 1 auth file. */
21
+ inspectOpenCodeAuth?: boolean;
20
22
  enrollment?: Pick<NativeVaultEnrollmentOptions, 'paths' | 'client' | 'ckBinary' | 'connectionFile'>;
21
23
  discover?: () => Promise<NativeCustodyInventory>;
22
24
  hooks?: NativeCustodyActivationHooks;
23
25
  }
24
- /**
25
- * Enroll this stopped host, discover its verified default vault account and
26
- * leave the host auth slot untouched. Local credentials, migration journal,
27
- * account metadata and routing assignments are not inputs to this operation.
28
- */
26
+ export interface NativeVaultPreflight {
27
+ priorMode: 'local' | 'claustrum';
28
+ fingerprint: string;
29
+ separateOpenCodeLogin?: boolean;
30
+ }
31
+ export declare function fingerprintNativeVaultInputs(host: HarnessKind, options: NativeVaultActivationOptions): Promise<string>;
32
+ /** Validate vault inputs before the runner enrolls any selected host. */
33
+ export declare function preflightNativeVaultForHost(host: HarnessKind, options: NativeVaultActivationOptions): Promise<NativeVaultPreflight>;
34
+ /** Grant native-account read access and require a vault-backed default Claude account with an account identity before moving Pi's login aside. */
35
+ export declare function completeNativeVaultActivation(host: HarnessKind, options: NativeVaultActivationOptions, preflight: NativeVaultPreflight): Promise<'committed' | 'already-vault'>;
36
+ /** Outside runSetup, check inputs, enroll the host, then grant and activate vault access. runSetup owns enrollment and calls preflight and completion separately. */
29
37
  export declare function activateNativeVaultForHost(host: HarnessKind, options: NativeVaultActivationOptions): Promise<'committed' | 'already-vault'>;
@@ -1,5 +1,16 @@
1
1
  import { type ClaustrumEnrollmentClient, type ClaustrumEnrollmentPaths } from '@cortexkit/common-auth/claustrum';
2
2
  import type { CommandRunner, HarnessKind } from './types.ts';
3
+ export declare const NATIVE_VAULT_HOST_NAMES: {
4
+ readonly opencode: "anthropic-auth-opencode";
5
+ readonly pi: "anthropic-auth-pi";
6
+ };
7
+ /** Convert the token file resolved by getHostClaustrumEnrollmentPaths into runSetup's path inputs; the runner derives the matching state file itself. */
8
+ export declare function nativeVaultHostPaths(host: HarnessKind, env: NodeJS.ProcessEnv): {
9
+ stateDir: string;
10
+ host: HarnessKind;
11
+ override: string;
12
+ };
13
+ export declare function nativeVaultConnectionFile(host: HarnessKind, env: NodeJS.ProcessEnv): string;
3
14
  export interface NativeVaultEnrollmentOptions {
4
15
  env: NodeJS.ProcessEnv;
5
16
  runner: CommandRunner;
@@ -13,6 +24,8 @@ export interface NativeVaultEnrollmentOptions {
13
24
  client?: ClaustrumEnrollmentClient;
14
25
  ckBinary?: string;
15
26
  connectionFile?: string;
27
+ /** Defaults to granting native-account read access after enrollment. False leaves that grant to completeNativeVaultActivation, avoiding a duplicate grant. */
28
+ grantPermissions?: boolean;
16
29
  }
17
30
  export declare class NativeVaultEnrollmentError extends Error {
18
31
  readonly code: 'enrollment-refused' | 'enrollment-reset' | 'approval-refused' | 'permission-refused';
@@ -24,3 +37,5 @@ export declare class NativeVaultEnrollmentError extends Error {
24
37
  * account discovery and the credential-store switch are separate setup steps.
25
38
  */
26
39
  export declare function enrollNativeVaultForHost(host: HarnessKind, options: NativeVaultEnrollmentOptions): Promise<void>;
40
+ /** Grant this OpenCode or Pi principal read access to the vault's anthropic-native category; enrollment alone grants no provider access. */
41
+ export declare function grantNativeVaultForHost(host: HarnessKind, options: Pick<NativeVaultEnrollmentOptions, 'env' | 'runner' | 'processFence' | 'ckBinary'>): Promise<void>;
@@ -1,5 +1,6 @@
1
+ import { type NativeMigrationPreflight, readNativeMigrationJournal } from '@cortexkit/anthropic-auth-core';
1
2
  import { type NativeSetupPaths } from './native-paths';
2
- import type { HarnessKind, ProcessFence } from './types';
3
+ import { type HarnessKind, type ProcessFence } from './types';
3
4
  export interface NativeOfflineLogin {
4
5
  credential: {
5
6
  type: 'oauth';
@@ -15,6 +16,35 @@ export interface NativeLocalSetupOptions {
15
16
  paths?: NativeSetupPaths;
16
17
  removePiAnthropicAuth: boolean;
17
18
  login?: (host: HarnessKind) => Promise<NativeOfflineLogin>;
19
+ preflight?: NativeMigrationPreflight;
20
+ skipMigration?: boolean;
21
+ beforeCommit?: () => Promise<void>;
18
22
  }
23
+ export declare const SEPARATE_HOST_LOGIN_NOTICE = "OpenCode's separate Anthropic login is not used. Add that account through /claude Accounts if needed, or remove the separate login from OpenCode.";
24
+ export declare function requireNativeLocalEnrollment(hosts: readonly HarnessKind[], env: NodeJS.ProcessEnv): Promise<void>;
25
+ export declare function nativeLocalProcessFence(host: HarnessKind, options: NativeLocalSetupOptions): () => Promise<void>;
26
+ export declare function nativeSetupFileFingerprint(path: string): Promise<string>;
27
+ export declare function inspectSetupHostAuth(host: HarnessKind, path: string): Promise<{
28
+ kind: 'absent' | 'oauth' | 'api' | 'api_key' | 'activation';
29
+ digest: string;
30
+ realLogin: boolean;
31
+ }>;
32
+ export interface NativeLocalPlan {
33
+ paths: NativeSetupPaths;
34
+ generation2: boolean;
35
+ action: 'migration' | 'skip' | 'empty-init' | 'reuse';
36
+ slot?: Awaited<ReturnType<typeof inspectSetupHostAuth>>;
37
+ notice: boolean;
38
+ preflight?: NativeMigrationPreflight;
39
+ fingerprint: string;
40
+ authorityPhase: NonNullable<Awaited<ReturnType<typeof readNativeMigrationJournal>>>['phase'] | 'absent';
41
+ poolPopulation: boolean | 'not-evaluated';
42
+ }
43
+ /** Hash pool, journal and routing bytes and the host's Anthropic entry, so a credential replacement cannot hide behind an unchanged account count. */
44
+ export declare function fingerprintNativeLocalPlan(plan: NativeLocalPlan, env: NodeJS.ProcessEnv): Promise<string>;
45
+ /** Record journal status, the host's Anthropic entry and whether setup will import, skip import or initialize a new pool, without writing. */
46
+ export declare function planNativeLocalSetup(host: HarnessKind, options: NativeLocalSetupOptions, generation2: boolean): Promise<NativeLocalPlan>;
47
+ export declare function revalidateNativeLocalPlan(plan: NativeLocalPlan, options: NativeLocalSetupOptions): Promise<void>;
48
+ export declare function installAbsentNativePlaceholder(plan: Pick<NativeLocalPlan, 'paths' | 'slot'>, options: NativeLocalSetupOptions): Promise<void>;
19
49
  /** Transfer local credentials while hosts are stopped, before telling the user to restart. */
20
50
  export declare function migrateNativeLocalForHost(host: HarnessKind, options: NativeLocalSetupOptions): Promise<void>;
@@ -1,4 +1,3 @@
1
- import type { CommandRunner, ProcessFence } from './types.ts';
2
1
  export declare class ProcessInspectionError extends Error {
3
2
  readonly code = "process-inspection-failed";
4
3
  constructor();
@@ -13,8 +12,3 @@ export declare class ProcessFenceViolationError extends Error {
13
12
  command: string;
14
13
  }>);
15
14
  }
16
- export declare function createProcessFence(runner?: CommandRunner, options?: {
17
- platform?: NodeJS.Platform;
18
- }): ProcessFence;
19
- export declare const defaultProcessFence: ProcessFence;
20
- export declare function assertHostsStopped(fence?: ProcessFence): Promise<void>;
@@ -1,4 +1,11 @@
1
1
  export type HarnessKind = 'opencode' | 'pi';
2
+ export declare function setupRefusalMessage(error: unknown): string | undefined;
3
+ /** runSetup prints failures from its own stopped-host checks; provider callbacks need a displayable refusal for their separate process checks. */
4
+ export declare function setupProcessInspectionMessage(error: unknown): string | undefined;
5
+ /** A setup refusal whose message is safe to show on the terminal. */
6
+ export declare class SetupRefusal extends Error {
7
+ constructor(message: string);
8
+ }
2
9
  export interface HostDetection {
3
10
  kind: HarnessKind;
4
11
  installed: boolean;
@@ -22,6 +29,8 @@ export interface CommandRunnerResult {
22
29
  exitCode: number;
23
30
  stdout: string;
24
31
  stderr: string;
32
+ signal?: NodeJS.Signals | null;
33
+ spawnError?: boolean;
25
34
  }
26
35
  export interface CommandRunner {
27
36
  run(command: string, args: string[], options?: {
@@ -2,6 +2,7 @@ export interface QuotaWindow {
2
2
  usedPercent: number;
3
3
  remainingPercent: number;
4
4
  resetsAt?: string;
5
+ checkedAt?: number;
5
6
  }
6
7
  export interface ScopedQuotaWindow extends QuotaWindow {
7
8
  id: string;
@@ -10,6 +11,7 @@ export interface ScopedQuotaWindow extends QuotaWindow {
10
11
  modelName: string;
11
12
  }
12
13
  export interface AccountQuota {
14
+ checkedAt?: number;
13
15
  five_hour?: QuotaWindow;
14
16
  seven_day?: QuotaWindow;
15
17
  scoped?: ScopedQuotaWindow[];
@@ -36,6 +38,8 @@ export interface SidebarAccountState {
36
38
  label: string | undefined;
37
39
  quota: AccountQuota | null;
38
40
  enabled: boolean;
41
+ stateLine?: string;
42
+ quotaDated?: boolean;
39
43
  needsReauth: boolean;
40
44
  vaultReauth?: boolean;
41
45
  vaultServed?: boolean;
@@ -68,7 +72,10 @@ export interface PrimeSidebarAccountState {
68
72
  export interface SidebarState {
69
73
  main: {
70
74
  quota: AccountQuota | null;
75
+ enabled?: boolean;
71
76
  tierLabel?: string;
77
+ stateLine?: string;
78
+ quotaDated?: boolean;
72
79
  quotaBackedOff?: boolean;
73
80
  quotaBackoffUntil?: number;
74
81
  refreshBackedOff?: boolean;
@@ -140,8 +147,9 @@ export declare function resolveActiveAccount(state: SidebarState): {
140
147
  id: string;
141
148
  name: string;
142
149
  quota: AccountQuota | null;
150
+ stateLine?: string;
151
+ quotaDated?: boolean;
143
152
  };
144
- export declare function formatScopedQuotaLabel(title: string): string;
145
153
  /**
146
154
  * Pretty label for a recoverable-refusal source model (Fable 5/5.1 or Opus 5).
147
155
  * Falls back to the raw id for unrecognized ids so the sidebar never goes
@@ -155,12 +163,22 @@ export declare function formatPrimeAccountValue(account: PrimeSidebarAccountStat
155
163
  hasError: boolean;
156
164
  };
157
165
  export declare function getFableRecoverySummary(state: SidebarState, sessionId: string): string | undefined;
158
- export declare function getCollapsedQuotaSummary(quota: AccountQuota | null): {
166
+ /** Keep full shared names when they fit; truncate only to preserve row columns. */
167
+ export declare function formatQuotaRowLabel(name: string, width?: number): string;
168
+ export declare function getCollapsedQuotaSummary(quota: AccountQuota | null, now?: number): {
159
169
  fiveHourUsedPercent: number | null;
160
170
  sevenDayUsedPercent: number | null;
161
171
  scopedUsedPercents: number[];
162
172
  text: string | null;
173
+ stale: boolean;
163
174
  };
175
+ export declare function getCollapsedAccounts(state: SidebarState, showFallbacks?: boolean): {
176
+ id: string;
177
+ name: string;
178
+ quota: AccountQuota | null;
179
+ quotaDated: boolean | undefined;
180
+ active: boolean;
181
+ }[];
164
182
  export declare const FIVE_HOUR_MS: number;
165
183
  export declare const SEVEN_DAY_MS: number;
166
184
  export interface QuotaPacing {
@@ -1 +1 @@
1
- import{F as a,G as b,H as c,I as d,J as e,K as f,L as g,M as h,N as i,O as j,P as k,Q as l,R as m,S as n,T as o,U as p,V as q,W as r,X as s,Y as t,Z as u}from"./index-04syas8a.js";import"./index-yxtdke11.js";import"./index-p4wvcwhh.js";import"./index-3xqv3rw3.js";export{i as setSidebarState,k as resolveActiveAccount,c as normalizeSidebarState,a as getSidebarStateFile,h as getSidebarState,f as getInitialSidebarRoutingTestHooks,q as getFableRecoverySummary,r as getCollapsedQuotaSummary,l as formatScopedQuotaLabel,n as formatPrimeTime,o as formatPrimeCost,p as formatPrimeAccountValue,m as formatFallbackModelLabel,j as drainSidebarWrites,u as computeQuotaPacing,d as __setSidebarStateWriteTestHooks,e as __setInitialSidebarRoutingTestHooks,g as __acquireSidebarStateLockForTest,t as SEVEN_DAY_MS,s as FIVE_HOUR_MS,b as DEFAULT_SIDEBAR_STATE};
1
+ import{F as a,G as b,H as c,I as d,J as e,K as f,L as g,M as h,N as i,O as j,P as k,Q as l,R as m,S as n,T as o,U as p,V as q,W as r,X as s,Y as t,Z as u,_ as v}from"./index-qttfa42y.js";import"./index-mdpyfkv3.js";import"./index-fncp6r0j.js";import"./index-rftced5v.js";export{i as setSidebarState,k as resolveActiveAccount,c as normalizeSidebarState,a as getSidebarStateFile,h as getSidebarState,f as getInitialSidebarRoutingTestHooks,p as getFableRecoverySummary,r as getCollapsedQuotaSummary,s as getCollapsedAccounts,q as formatQuotaRowLabel,m as formatPrimeTime,n as formatPrimeCost,o as formatPrimeAccountValue,l as formatFallbackModelLabel,j as drainSidebarWrites,v as computeQuotaPacing,d as __setSidebarStateWriteTestHooks,e as __setInitialSidebarRoutingTestHooks,g as __acquireSidebarStateLockForTest,u as SEVEN_DAY_MS,t as FIVE_HOUR_MS,b as DEFAULT_SIDEBAR_STATE};
@@ -2,6 +2,17 @@ import { type BillingLineageFields, type Cache1hMode, type ClaudeCodeIdentity, t
2
2
  import { type OpenCodeEffortMarkerPlan } from './effort-history';
3
3
  import { type ServerSideFallbackOutcome } from './server-fallback';
4
4
  export declare const NON_STREAMING_DIAGNOSTICS_MAX_BYTES: number;
5
+ /** Request-local response spellings; null marks a spelling shared by multiple tools. */
6
+ export type ToolNameMap = ReadonlyMap<string, string | null> & {
7
+ readonly declaredHostNames: ReadonlySet<string>;
8
+ readonly hazardousWireNames: ReadonlySet<string>;
9
+ };
10
+ export declare function normalizeToolNameResponseError(error: unknown, toolNameMap?: ToolNameMap): unknown;
11
+ export declare function cancelUnsafeToolNameResponse(reader: {
12
+ cancel(reason?: unknown): Promise<void>;
13
+ readonly closed: Promise<void>;
14
+ releaseLock(): void;
15
+ }, error: unknown): Promise<void>;
5
16
  export type FetchInput = string | URL | Request;
6
17
  /**
7
18
  * Merge headers from a Request object and/or a RequestInit headers value
@@ -27,9 +38,10 @@ export declare function setOAuthHeaders(headers: Headers, accessToken: string, o
27
38
  */
28
39
  export declare function prefixToolNames(parsed: Record<string, unknown>): string;
29
40
  /**
30
- * Strip TOOL_PREFIX from tool names in streaming response text.
41
+ * Use the map supplied to onToolNameMap by rewriteRequestBody for this response's request.
42
+ * Unmatched or ambiguous names stay unchanged for the host to handle.
31
43
  */
32
- export declare function stripToolPrefix(text: string): string;
44
+ export declare function stripToolPrefix(text: string, toolNameMap?: ToolNameMap): string;
33
45
  /**
34
46
  * Check if TLS verification should be skipped for custom API endpoints.
35
47
  * Only effective when ANTHROPIC_BASE_URL is also set.
@@ -100,6 +112,7 @@ export declare function rewriteRequestBody(body: string, options?: {
100
112
  laneStart?: boolean;
101
113
  billingLineage?: BillingLineageFields;
102
114
  cacheDiagnosticsPreviousMessageId?: string | null;
115
+ onToolNameMap?: (map: ToolNameMap) => void;
103
116
  }): Promise<string>;
104
117
  type RelayUpstreamStatus = {
105
118
  status: number;
@@ -109,6 +122,8 @@ type RelayUpstreamStatus = {
109
122
  * Create a streaming response that strips the tool prefix from tool names.
110
123
  */
111
124
  export declare function createStrippedStream(response: Response, options?: {
125
+ toolNameMap?: ToolNameMap;
126
+ onToolNameRefusal?: () => void;
112
127
  perf?: RewritePerfCallback;
113
128
  onContentFilter?: (context?: {
114
129
  completedToolUse: boolean;
@@ -1,4 +1,4 @@
1
- import"./index-3xqv3rw3.js";import{readFileSync as k,watch as C}from"node:fs";import{mkdir as _,readFile as I,rename as E,writeFile as b}from"node:fs/promises";import{homedir as g}from"node:os";import{basename as F,dirname as P,join as N}from"node:path";import{clearTimeout as D,setTimeout as L}from"node:timers";import{applyEdits as T,modify as y,parse as f}from"jsonc-parser";var v="OPENCODE_TUI_PREFERENCES_FILE",h="tui-preferences.jsonc";function A(){let J=process.env[v];if(J)return J;let z=process.env.OPENCODE_CONFIG_DIR||N(process.env.XDG_CONFIG_HOME||N(g(),".config"),"opencode");return N(z,h)}function H(J){return typeof J==="object"&&J!==null&&!Array.isArray(J)}async function qq(){try{let J=await I(A(),"utf8"),z=[],q=f(J,z,{allowTrailingComma:!0});if(z.length>0)return{};return H(q)?q:{}}catch{return{}}}var m="anthropic-auth",p=160,R={forceToTop:!1,order:p,startCollapsed:!1,rememberCollapsed:!0,collapsed:null,pollMs:1500,refreshDebounceMs:200,header:{label:"CLAUDE",showVersion:!0},sections:{quota:!0,fallbackAccounts:!0,routing:!0,cache:!0,health:!0,pacing:!0},appearance:{barWidth:10,barFilledChar:"█",barEmptyChar:"░",warnThreshold:50,errorThreshold:80}};function $(J,z){return typeof J==="boolean"?J:z}function Y(J,z,q,X){if(typeof J!=="number"||!Number.isFinite(J))return z;return Math.min(Math.max(Math.round(J),q),X)}function c(J,z,q){if(typeof J!=="string"||J.length===0)return z;return J.slice(0,q)}function w(J,z){if(typeof J!=="string")return z;return[...J][0]??z}function zq(J){let z=J[m];if(!H(z))return structuredClone(R);let q=R,X=H(z.header)?z.header:{},Q=H(z.sections)?z.sections:{},Z=H(z.appearance)?z.appearance:{},G=Y(Z.warnThreshold,q.appearance.warnThreshold,0,99),V=Math.max(Y(Z.errorThreshold,q.appearance.errorThreshold,0,100),Math.min(G+1,100));return{forceToTop:$(z.forceToTop,q.forceToTop),order:Y(z.order,q.order,-1e4,1e4),startCollapsed:$(z.startCollapsed,q.startCollapsed),rememberCollapsed:$(z.rememberCollapsed,q.rememberCollapsed),collapsed:typeof z.collapsed==="boolean"?z.collapsed:null,pollMs:Y(z.pollMs,q.pollMs,500,30000),refreshDebounceMs:Y(z.refreshDebounceMs,q.refreshDebounceMs,50,5000),header:{label:c(X.label,q.header.label,20),showVersion:$(X.showVersion,q.header.showVersion)},sections:{quota:$(Q.quota,q.sections.quota),fallbackAccounts:$(Q.fallbackAccounts,q.sections.fallbackAccounts),routing:$(Q.routing,q.sections.routing),cache:$(Q.cache,q.sections.cache),health:$(Q.health,q.sections.health),pacing:$(Q.pacing,q.sections.pacing)},appearance:{barWidth:Y(Z.barWidth,q.appearance.barWidth,4,40),barFilledChar:w(Z.barFilledChar,q.appearance.barFilledChar),barEmptyChar:w(Z.barEmptyChar,q.appearance.barEmptyChar),warnThreshold:G,errorThreshold:V}}}var u=-1e5;function Jq(J,z,q){let X=J[z];if(!H(X))return q;if(X.forceToTop===!0)return u+Object.keys(J).indexOf(z);return Y(X.order,q,-1e4,1e4)}var s=`// Shared preferences for opencode TUI plugins.
1
+ import"./index-rftced5v.js";import{readFileSync as k,watch as C}from"node:fs";import{mkdir as _,readFile as I,rename as E,writeFile as b}from"node:fs/promises";import{homedir as g}from"node:os";import{basename as F,dirname as P,join as N}from"node:path";import{clearTimeout as D,setTimeout as L}from"node:timers";import{applyEdits as T,modify as y,parse as f}from"jsonc-parser";var v="OPENCODE_TUI_PREFERENCES_FILE",h="tui-preferences.jsonc";function A(){let J=process.env[v];if(J)return J;let z=process.env.OPENCODE_CONFIG_DIR||N(process.env.XDG_CONFIG_HOME||N(g(),".config"),"opencode");return N(z,h)}function H(J){return typeof J==="object"&&J!==null&&!Array.isArray(J)}async function qq(){try{let J=await I(A(),"utf8"),z=[],q=f(J,z,{allowTrailingComma:!0});if(z.length>0)return{};return H(q)?q:{}}catch{return{}}}var m="anthropic-auth",p=160,R={forceToTop:!1,order:p,startCollapsed:!1,rememberCollapsed:!0,collapsed:null,pollMs:1500,refreshDebounceMs:200,header:{label:"CLAUDE",showVersion:!0},sections:{quota:!0,fallbackAccounts:!0,routing:!0,cache:!0,health:!0,pacing:!0},appearance:{barWidth:10,barFilledChar:"█",barEmptyChar:"░",warnThreshold:50,errorThreshold:80}};function $(J,z){return typeof J==="boolean"?J:z}function Y(J,z,q,X){if(typeof J!=="number"||!Number.isFinite(J))return z;return Math.min(Math.max(Math.round(J),q),X)}function c(J,z,q){if(typeof J!=="string"||J.length===0)return z;return J.slice(0,q)}function w(J,z){if(typeof J!=="string")return z;return[...J][0]??z}function zq(J){let z=J[m];if(!H(z))return structuredClone(R);let q=R,X=H(z.header)?z.header:{},Q=H(z.sections)?z.sections:{},Z=H(z.appearance)?z.appearance:{},G=Y(Z.warnThreshold,q.appearance.warnThreshold,0,99),V=Math.max(Y(Z.errorThreshold,q.appearance.errorThreshold,0,100),Math.min(G+1,100));return{forceToTop:$(z.forceToTop,q.forceToTop),order:Y(z.order,q.order,-1e4,1e4),startCollapsed:$(z.startCollapsed,q.startCollapsed),rememberCollapsed:$(z.rememberCollapsed,q.rememberCollapsed),collapsed:typeof z.collapsed==="boolean"?z.collapsed:null,pollMs:Y(z.pollMs,q.pollMs,500,30000),refreshDebounceMs:Y(z.refreshDebounceMs,q.refreshDebounceMs,50,5000),header:{label:c(X.label,q.header.label,20),showVersion:$(X.showVersion,q.header.showVersion)},sections:{quota:$(Q.quota,q.sections.quota),fallbackAccounts:$(Q.fallbackAccounts,q.sections.fallbackAccounts),routing:$(Q.routing,q.sections.routing),cache:$(Q.cache,q.sections.cache),health:$(Q.health,q.sections.health),pacing:$(Q.pacing,q.sections.pacing)},appearance:{barWidth:Y(Z.barWidth,q.appearance.barWidth,4,40),barFilledChar:w(Z.barFilledChar,q.appearance.barFilledChar),barEmptyChar:w(Z.barEmptyChar,q.appearance.barEmptyChar),warnThreshold:G,errorThreshold:V}}}var u=-1e5;function Jq(J,z,q){let X=J[z];if(!H(X))return q;if(X.forceToTop===!0)return u+Object.keys(J).indexOf(z);return Y(X.order,q,-1e4,1e4)}var s=`// Shared preferences for opencode TUI plugins.
2
2
  // One top-level key per plugin (short name). See each plugin's README for
3
3
  // its supported settings. This file is safe to hand-edit; plugins update
4
4
  // individual keys in place and preserve comments.
package/dist/tui.d.ts CHANGED
@@ -1,7 +1,5 @@
1
1
  /** @jsxImportSource @opentui/solid */
2
- import { formatQuotaMoney } from '@cortexkit/anthropic-auth-core';
3
2
  import type { TuiPluginModule } from '@opencode-ai/plugin/tui';
4
- export { formatQuotaMoney };
5
3
  declare const plugin: TuiPluginModule & {
6
4
  id: string;
7
5
  };
@@ -1,5 +1,7 @@
1
1
  /** Explicit sign-in to the native Claude account pool creates this OAuth connection. Startup leaves existing OpenCode connections unchanged. */
2
2
  export declare const CLAUDE_POOL_LOGIN_METHOD_ID = "native-claude-oauth";
3
+ export declare const CLAUDE_POOL_LOGIN_METHOD_LABEL = "Claude Pro / Max (native account pool)";
4
+ export declare const CLAUDE_POOL_LOGIN_STEP = "In OpenCode, sign in to Anthropic with \"Claude Pro / Max (native account pool)\".";
3
5
  /**
4
6
  * Connects OpenCode to the Claude accounts held in the vault. It signs in to
5
7
  * nothing and stores no local account; only the host's placeholder is written.
@@ -99,9 +99,10 @@ type RewriteBodyOptions = NonNullable<Parameters<typeof rewriteRequestBody>[1]>;
99
99
  * lineage, effort plan, cache, fast mode, safety and diagnostics inputs. Two
100
100
  * options are left out because the adapter sets them: the Claude Code
101
101
  * identity, which the source returns with the credential, and the session id,
102
- * which is the host's own session id for the request.
102
+ * which is the host's own session id for the request. The tool-name callback
103
+ * is private to the adapter so response names stay bound to that send.
103
104
  */
104
- export type NativeAnthropicBodyOptions = Omit<RewriteBodyOptions, 'identity' | 'sessionId'>;
105
+ export type NativeAnthropicBodyOptions = Omit<RewriteBodyOptions, 'identity' | 'sessionId' | 'onToolNameMap'>;
105
106
  type StrippedStreamOptions = NonNullable<Parameters<typeof createStrippedStream>[1]>;
106
107
  /**
107
108
  * The response observers a source may attach to an OAuth response. Content
@@ -160,6 +161,11 @@ export interface NativeAnthropicSource<Q, P> {
160
161
  readonly requestOptions?: (input: NativeAnthropicRequestContext<P>) => Promise<NativeAnthropicBodyOptions> | NativeAnthropicBodyOptions;
161
162
  /** Rechecks policy after asynchronous rewriting, immediately before dispatch. */
162
163
  readonly admitRequest?: (input: NativeAnthropicAttemptContext<P>) => Promise<void> | void;
164
+ /** Observe the admitted OAuth wire body before any relay envelope is added. */
165
+ readonly onRequestPrepared?: (input: NativeAnthropicAttemptContext<P> & {
166
+ readonly url: string;
167
+ readonly bodyText: string;
168
+ }) => Promise<void> | void;
163
169
  /** Response observers for an OAuth response. */
164
170
  readonly responseOptions?: (input: NativeAnthropicResponseContext<P>) => NativeAnthropicResponseOptions | undefined;
165
171
  /** Quota carried by the upstream response headers, read once per response. */
@@ -0,0 +1,19 @@
1
+ import { CacheKeepSessionRegistry, type NativeAccountRuntime } from '@cortexkit/anthropic-auth-core';
2
+ import type { NativeSource } from './source';
3
+ export interface NativeCacheKeepOptions {
4
+ readonly now?: () => number;
5
+ readonly setIntervalImpl?: typeof globalThis.setInterval;
6
+ readonly clearIntervalImpl?: typeof globalThis.clearInterval;
7
+ readonly registryDirectory?: string;
8
+ }
9
+ /** Keep admitted hybrid-cache prefixes warm using fresh native authorization for each send. */
10
+ export declare function createNativeCacheKeep(options: NativeCacheKeepOptions & {
11
+ runtime: NativeAccountRuntime;
12
+ source: NativeSource;
13
+ fetch?: typeof fetch;
14
+ isSubagent?: (sessionID: string) => Promise<boolean>;
15
+ }): {
16
+ track(input: Parameters<NonNullable<NativeSource['onRequestPrepared']>>[0]): Promise<void>;
17
+ registry: CacheKeepSessionRegistry;
18
+ dispose(): Promise<void>;
19
+ };
package/dist/v2/menu.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type NativeAccountRuntime } from '@cortexkit/anthropic-auth-core';
1
+ import { type CacheKeepSessionRegistry, type NativeAccountRuntime } from '@cortexkit/anthropic-auth-core';
2
2
  import type { NativeMenuCapabilities } from './menu-contract';
3
3
  import type { NativeSource } from './source';
4
4
  export type { NativeMenuCapabilities } from './menu-contract';
@@ -6,5 +6,6 @@ export type { NativeMenuCapabilities } from './menu-contract';
6
6
  export declare function createNativeMenuCapabilities(options: {
7
7
  readonly runtime: NativeAccountRuntime;
8
8
  readonly source: NativeSource;
9
+ readonly cacheKeepRegistry?: CacheKeepSessionRegistry;
9
10
  readonly start: (sessionID: string, text: string) => Promise<void>;
10
11
  }): NativeMenuCapabilities;