agent-shim 7.13.1 → 7.14.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.
Files changed (93) hide show
  1. package/dist/cli.cjs +95 -27
  2. package/dist/index.cjs +70 -7
  3. package/dist/index.mjs +70 -7
  4. package/dist/types/index.d.ts +2789 -40
  5. package/package.json +3 -1
  6. package/dist/types/checkReport.d.ts +0 -154
  7. package/dist/types/claudeShim.d.ts +0 -114
  8. package/dist/types/cli/bool.d.ts +0 -8
  9. package/dist/types/cli/commandDeps.d.ts +0 -39
  10. package/dist/types/cli/envBool.d.ts +0 -11
  11. package/dist/types/cli/pairs.d.ts +0 -19
  12. package/dist/types/cliError.d.ts +0 -27
  13. package/dist/types/codex/http.d.ts +0 -15
  14. package/dist/types/config/classify.d.ts +0 -49
  15. package/dist/types/config/load.d.ts +0 -42
  16. package/dist/types/config/schema.d.ts +0 -746
  17. package/dist/types/config/store.d.ts +0 -46
  18. package/dist/types/configProfilesStore.d.ts +0 -61
  19. package/dist/types/configure.d.ts +0 -170
  20. package/dist/types/credential.d.ts +0 -136
  21. package/dist/types/credentialCache.d.ts +0 -46
  22. package/dist/types/directoryRulesStore.d.ts +0 -43
  23. package/dist/types/doctorReport.d.ts +0 -117
  24. package/dist/types/frontdoor/capability.d.ts +0 -19
  25. package/dist/types/frontdoor/capture.d.ts +0 -58
  26. package/dist/types/frontdoor/connect.d.ts +0 -209
  27. package/dist/types/frontdoor/connectEffects.d.ts +0 -3
  28. package/dist/types/frontdoor/custody.d.ts +0 -32
  29. package/dist/types/frontdoor/ensure.d.ts +0 -36
  30. package/dist/types/frontdoor/headroomHop.d.ts +0 -22
  31. package/dist/types/frontdoor/pipeline.d.ts +0 -109
  32. package/dist/types/frontdoor/probe.d.ts +0 -13
  33. package/dist/types/frontdoor/realFrontDoorPort.d.ts +0 -5
  34. package/dist/types/frontdoor/route.d.ts +0 -112
  35. package/dist/types/frontdoor/server.d.ts +0 -44
  36. package/dist/types/frontdoor/state.d.ts +0 -57
  37. package/dist/types/frontdoor/supervisor.d.ts +0 -48
  38. package/dist/types/frontdoor/tap.d.ts +0 -9
  39. package/dist/types/frontdoor/trust.d.ts +0 -30
  40. package/dist/types/frontdoor/x509.d.ts +0 -11
  41. package/dist/types/headroom/ensure.d.ts +0 -31
  42. package/dist/types/headroom/headers.d.ts +0 -11
  43. package/dist/types/headroom/settings.d.ts +0 -13
  44. package/dist/types/headroom/source.d.ts +0 -8
  45. package/dist/types/headroom/state.d.ts +0 -77
  46. package/dist/types/headroom/supervisor.d.ts +0 -107
  47. package/dist/types/identityStore.d.ts +0 -85
  48. package/dist/types/launchWiring.d.ts +0 -49
  49. package/dist/types/launcher/argv.d.ts +0 -42
  50. package/dist/types/launcher/cascade.d.ts +0 -42
  51. package/dist/types/launcher/cliOverride.d.ts +0 -38
  52. package/dist/types/launcher/extraFlags.d.ts +0 -6
  53. package/dist/types/launcher/farm.d.ts +0 -168
  54. package/dist/types/launcher/flags.d.ts +0 -96
  55. package/dist/types/launcher/guard.d.ts +0 -57
  56. package/dist/types/launcher/identity.d.ts +0 -95
  57. package/dist/types/launcher/lock.d.ts +0 -41
  58. package/dist/types/launcher/pool.d.ts +0 -44
  59. package/dist/types/launcher/ports.d.ts +0 -135
  60. package/dist/types/launcher/spawn.d.ts +0 -20
  61. package/dist/types/launcher.d.ts +0 -98
  62. package/dist/types/legacy.d.ts +0 -29
  63. package/dist/types/pathNorm.d.ts +0 -14
  64. package/dist/types/paths.d.ts +0 -79
  65. package/dist/types/poolPickReport.d.ts +0 -44
  66. package/dist/types/poolStore.d.ts +0 -18
  67. package/dist/types/providersStore.d.ts +0 -137
  68. package/dist/types/realCredentialCache.d.ts +0 -11
  69. package/dist/types/realPorts.d.ts +0 -109
  70. package/dist/types/resolve/conditions.d.ts +0 -37
  71. package/dist/types/resolve/decide.d.ts +0 -45
  72. package/dist/types/resolve/extends.d.ts +0 -41
  73. package/dist/types/resolve/flatten.d.ts +0 -13
  74. package/dist/types/resolve/match.d.ts +0 -58
  75. package/dist/types/resolve/pipeline.d.ts +0 -33
  76. package/dist/types/resolve/plan.d.ts +0 -57
  77. package/dist/types/resolve/projects.d.ts +0 -61
  78. package/dist/types/resolve/reconcile.d.ts +0 -80
  79. package/dist/types/resolve/types.d.ts +0 -159
  80. package/dist/types/resolve/walk.d.ts +0 -85
  81. package/dist/types/resolve/walkPolicy.d.ts +0 -15
  82. package/dist/types/usage/account.d.ts +0 -20
  83. package/dist/types/usage/middleware.d.ts +0 -17
  84. package/dist/types/usage/pick.d.ts +0 -62
  85. package/dist/types/usage/plan.d.ts +0 -18
  86. package/dist/types/usage/poolPick.d.ts +0 -31
  87. package/dist/types/usage/preflight.d.ts +0 -20
  88. package/dist/types/usage/rateLimit.d.ts +0 -25
  89. package/dist/types/usage/read.d.ts +0 -70
  90. package/dist/types/usage/scan.d.ts +0 -24
  91. package/dist/types/usage/schema.d.ts +0 -318
  92. package/dist/types/usage/store.d.ts +0 -43
  93. package/dist/types/versionDiscovery.d.ts +0 -47
@@ -1,70 +0,0 @@
1
- import type { FarmFs } from "../launcher/ports";
2
- import { type LimitKind, type UsageRecord, type UsageSnapshot } from "./schema";
3
- /**
4
- * The read side of the usage store: pure over an injected filesystem, so the CLI, the library surface and tests all read the same way, and nothing here writes.
5
- */
6
- /** The filesystem reads the usage store's readers need. */
7
- export type UsageReadFs = Pick<FarmFs, "readFileUtf8" | "readdir">;
8
- /** The UTC day an instant falls on, as a segment names it. */
9
- export declare function segmentDay(epochMs: number): string;
10
- /** A segment's file name for one writer on one day. */
11
- export declare function segmentName(day: string, pid: number): string;
12
- /** One log segment found on disk. */
13
- export interface LogSegment {
14
- readonly name: string;
15
- readonly day: string;
16
- /** The epoch milliseconds the segment's day ends at: no record in it is later. */
17
- readonly endsAt: number;
18
- }
19
- /** Lists the log's segments, oldest day first; files that are not segments (a stray temporary file) are not the log's and are ignored. */
20
- export declare function listLogSegments(fs: Pick<FarmFs, "readdir">, logDir: string): readonly LogSegment[];
21
- /** What a log read found. */
22
- export interface UsageLogRead {
23
- /** Every valid record at or after the cut-off, oldest first. */
24
- readonly records: readonly UsageRecord[];
25
- /** Complete lines that did not parse as a record of this schema version: a corrupted line, or one a newer agent-shim wrote. Reported, never silently dropped. */
26
- readonly invalidLines: number;
27
- }
28
- /**
29
- * Reads the usage log, optionally only from `sinceMs` on. Each segment has a single writer that appends whole lines, so the only incomplete line a reader can meet is the last one of a segment still being written, which has no trailing newline yet; it is left for the next read rather than counted as invalid.
30
- */
31
- export declare function readUsageLog(fs: UsageReadFs, logDir: string, options?: {
32
- readonly sinceMs?: number;
33
- }): UsageLogRead;
34
- /** Raised for a snapshot file that exists but does not hold a snapshot of this schema version. */
35
- export declare class UsageSnapshotError extends Error {
36
- readonly file: string;
37
- constructor(file: string, detail: string);
38
- }
39
- /** The path of an identity's snapshot. Throws for an invalid identity name, which could otherwise name a path outside the snapshots directory. */
40
- export declare function snapshotPath(snapshotsDir: string, identity: string): string;
41
- /** Reads one identity's snapshot: undefined when it has none yet, `UsageSnapshotError` when the file is there but unreadable. */
42
- export declare function readUsageSnapshot(fs: Pick<FarmFs, "readFileUtf8">, snapshotsDir: string, identity: string): UsageSnapshot | undefined;
43
- /** Reads every identity's snapshot, by identity name. */
44
- export declare function listUsageSnapshots(fs: UsageReadFs, snapshotsDir: string): readonly UsageSnapshot[];
45
- /** Token totals across a set of records. */
46
- interface TokenTotals {
47
- readonly inputTokens: number;
48
- readonly outputTokens: number;
49
- readonly cacheCreationInputTokens: number;
50
- readonly cacheReadInputTokens: number;
51
- }
52
- /** The totals for one identity and provider over a set of records. */
53
- export interface UsageSummary {
54
- /** The identity, or undefined for requests from a launch that resolved none. */
55
- readonly identity: string | undefined;
56
- readonly provider: string;
57
- readonly requests: number;
58
- /** Responses with a status of 400 or above (refusals included). */
59
- readonly failed: number;
60
- /** Classified refusals, by kind. */
61
- readonly limits: Readonly<Record<LimitKind, number>>;
62
- readonly tokens: TokenTotals;
63
- readonly firstAt: string;
64
- readonly lastAt: string;
65
- /** The models the responses named, most-used first. */
66
- readonly models: readonly string[];
67
- }
68
- /** Groups records by identity and provider and totals each group, ordered by identity then provider. */
69
- export declare function summariseUsage(records: readonly UsageRecord[]): readonly UsageSummary[];
70
- export {};
@@ -1,24 +0,0 @@
1
- import type { ErrorInfo } from "./rateLimit";
2
- import type { TokenUsage } from "./schema";
3
- /**
4
- * Incremental scanners that pull usage metadata out of a response body as it streams past, without ever holding the body: the model, the `usage` token counts, and an error's type, code and message. Content (text deltas, tool input, message content) is skipped character by character and never accumulated, so memory stays bounded by the metadata itself whatever the response's size.
5
- */
6
- /** What a scan found. */
7
- export interface ScanResult {
8
- readonly model: string | undefined;
9
- readonly usage: TokenUsage | undefined;
10
- readonly error: ErrorInfo | undefined;
11
- }
12
- /** A body scanner: fed decoded text in arrival order, read once the body has ended. */
13
- export interface BodyScanner {
14
- readonly push: (text: string) => void;
15
- readonly result: () => ScanResult;
16
- }
17
- /**
18
- * Scans an Anthropic-format server-sent-events stream. Lines are split as they arrive, across chunk boundaries anywhere; an `event:` line names the event its `data:` lines belong to, and only metadata events' data is accumulated. A data line whose event is not named is held only until its leading `"type"` shows whether it is a metadata event, so content is never accumulated beyond those opening bytes.
19
- */
20
- export declare function createSseScanner(): BodyScanner;
21
- /**
22
- * Scans a JSON response body (a non-streaming Messages response, or an error body) for its top-level `model`, `usage` and `error`, capturing only those values' text. A small state machine tracks nesting and strings, so a `usage` key nested inside content is never mistaken for the top-level one, and content is walked past without being kept.
23
- */
24
- export declare function createJsonScanner(): BodyScanner;
@@ -1,318 +0,0 @@
1
- import { z } from "zod";
2
- /**
3
- * The usage store's one schema definition: every record the front door appends to the usage log, the per-identity snapshot other tools read, and the account metadata both carry. Each is a strict object, so a field not named here can never be written (the store validates every record and snapshot before it touches disk) and the published JSON Schemas (`schema/UsageRecord.schema.json`, `schema/UsageSnapshot.schema.json`) describe exactly what a reader can find.
4
- *
5
- * Metadata only, by construction: nothing here can hold a prompt, a response, tool content, or a credential. Rate-limit headers are kept by name from an allow-list of quota headers (`isRateLimitHeader`), never wholesale.
6
- */
7
- /** The version of the record and snapshot shapes below. A reader checks it before trusting a document; a change that is not purely additive bumps it. */
8
- export declare const USAGE_SCHEMA_VERSION = 1;
9
- /** Token counts from a response body's `usage` object, renamed to this project's casing. Each field is present only when the response reported it. */
10
- export declare const TokenUsageSchema: z.ZodObject<{
11
- inputTokens: z.ZodOptional<z.ZodNumber>;
12
- outputTokens: z.ZodOptional<z.ZodNumber>;
13
- cacheCreationInputTokens: z.ZodOptional<z.ZodNumber>;
14
- cacheReadInputTokens: z.ZodOptional<z.ZodNumber>;
15
- }, z.core.$strict>;
16
- export type TokenUsage = z.infer<typeof TokenUsageSchema>;
17
- /** The two kinds of refusal a consumer acts on differently: a short rate limit is worth retrying on the same credential once its wait has passed, an exhausted quota means moving to the next credential until the reset. */
18
- declare const LIMIT_KINDS: readonly ["rate-limited", "quota-exhausted"];
19
- export type LimitKind = (typeof LIMIT_KINDS)[number];
20
- /** A 429 (or 402) classified, with the wait or reset the upstream announced and the signals the classification rests on. */
21
- export declare const LimitClassificationSchema: z.ZodObject<{
22
- kind: z.ZodEnum<{
23
- "rate-limited": "rate-limited";
24
- "quota-exhausted": "quota-exhausted";
25
- }>;
26
- retryAfterSeconds: z.ZodOptional<z.ZodNumber>;
27
- resetAt: z.ZodOptional<z.ZodISODateTime>;
28
- window: z.ZodOptional<z.ZodString>;
29
- evidence: z.ZodArray<z.ZodString>;
30
- }, z.core.$strict>;
31
- export type LimitClassification = z.infer<typeof LimitClassificationSchema>;
32
- /** One routed request, appended to the usage log when its response has finished. */
33
- export declare const UsageRecordSchema: z.ZodObject<{
34
- schemaVersion: z.ZodLiteral<1>;
35
- at: z.ZodISODateTime;
36
- identity: z.ZodOptional<z.ZodString>;
37
- provider: z.ZodString;
38
- sessionId: z.ZodOptional<z.ZodString>;
39
- project: z.ZodOptional<z.ZodString>;
40
- route: z.ZodString;
41
- method: z.ZodString;
42
- endpoint: z.ZodString;
43
- model: z.ZodOptional<z.ZodString>;
44
- status: z.ZodNumber;
45
- latencyMs: z.ZodNumber;
46
- durationMs: z.ZodNumber;
47
- outcome: z.ZodEnum<{
48
- aborted: "aborted";
49
- completed: "completed";
50
- }>;
51
- usage: z.ZodOptional<z.ZodObject<{
52
- inputTokens: z.ZodOptional<z.ZodNumber>;
53
- outputTokens: z.ZodOptional<z.ZodNumber>;
54
- cacheCreationInputTokens: z.ZodOptional<z.ZodNumber>;
55
- cacheReadInputTokens: z.ZodOptional<z.ZodNumber>;
56
- }, z.core.$strict>>;
57
- rateLimitHeaders: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
58
- limit: z.ZodOptional<z.ZodObject<{
59
- kind: z.ZodEnum<{
60
- "rate-limited": "rate-limited";
61
- "quota-exhausted": "quota-exhausted";
62
- }>;
63
- retryAfterSeconds: z.ZodOptional<z.ZodNumber>;
64
- resetAt: z.ZodOptional<z.ZodISODateTime>;
65
- window: z.ZodOptional<z.ZodString>;
66
- evidence: z.ZodArray<z.ZodString>;
67
- }, z.core.$strict>>;
68
- requestId: z.ZodOptional<z.ZodString>;
69
- }, z.core.$strict>;
70
- export type UsageRecord = z.infer<typeof UsageRecordSchema>;
71
- /** One quota window from Anthropic's unified rate-limit headers. */
72
- declare const QuotaWindowSchema: z.ZodObject<{
73
- utilization: z.ZodOptional<z.ZodNumber>;
74
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
75
- status: z.ZodOptional<z.ZodString>;
76
- }, z.core.$strict>;
77
- export type QuotaWindow = z.infer<typeof QuotaWindowSchema>;
78
- /** Anthropic's unified subscription rate-limit state, parsed from the `anthropic-ratelimit-unified-*` headers (which the in-process Codex route also derives from the Codex backend's own quota headers). */
79
- export declare const UnifiedRateLimitSchema: z.ZodObject<{
80
- status: z.ZodOptional<z.ZodString>;
81
- fiveHour: z.ZodOptional<z.ZodObject<{
82
- utilization: z.ZodOptional<z.ZodNumber>;
83
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
84
- status: z.ZodOptional<z.ZodString>;
85
- }, z.core.$strict>>;
86
- sevenDay: z.ZodOptional<z.ZodObject<{
87
- utilization: z.ZodOptional<z.ZodNumber>;
88
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
89
- status: z.ZodOptional<z.ZodString>;
90
- }, z.core.$strict>>;
91
- representativeClaim: z.ZodOptional<z.ZodString>;
92
- resetAt: z.ZodOptional<z.ZodISODateTime>;
93
- overageStatus: z.ZodOptional<z.ZodString>;
94
- }, z.core.$strict>;
95
- export type UnifiedRateLimit = z.infer<typeof UnifiedRateLimitSchema>;
96
- /** The latest rate-limit state an upstream reported on any response. */
97
- declare const RateLimitStateSchema: z.ZodObject<{
98
- observedAt: z.ZodISODateTime;
99
- headers: z.ZodRecord<z.ZodString, z.ZodString>;
100
- unified: z.ZodOptional<z.ZodObject<{
101
- status: z.ZodOptional<z.ZodString>;
102
- fiveHour: z.ZodOptional<z.ZodObject<{
103
- utilization: z.ZodOptional<z.ZodNumber>;
104
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
105
- status: z.ZodOptional<z.ZodString>;
106
- }, z.core.$strict>>;
107
- sevenDay: z.ZodOptional<z.ZodObject<{
108
- utilization: z.ZodOptional<z.ZodNumber>;
109
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
110
- status: z.ZodOptional<z.ZodString>;
111
- }, z.core.$strict>>;
112
- representativeClaim: z.ZodOptional<z.ZodString>;
113
- resetAt: z.ZodOptional<z.ZodISODateTime>;
114
- overageStatus: z.ZodOptional<z.ZodString>;
115
- }, z.core.$strict>>;
116
- }, z.core.$strict>;
117
- export type RateLimitState = z.infer<typeof RateLimitStateSchema>;
118
- /** A classified refusal, with when it was seen and its status. */
119
- declare const LimitEventSchema: z.ZodObject<{
120
- kind: z.ZodEnum<{
121
- "rate-limited": "rate-limited";
122
- "quota-exhausted": "quota-exhausted";
123
- }>;
124
- retryAfterSeconds: z.ZodOptional<z.ZodNumber>;
125
- resetAt: z.ZodOptional<z.ZodISODateTime>;
126
- window: z.ZodOptional<z.ZodString>;
127
- evidence: z.ZodArray<z.ZodString>;
128
- observedAt: z.ZodISODateTime;
129
- status: z.ZodNumber;
130
- }, z.core.$strict>;
131
- export type LimitEvent = z.infer<typeof LimitEventSchema>;
132
- /** One quota window a provider reports through its own usage endpoint (as opposed to headers on a response): how much of it is used and when it resets. */
133
- declare const ProviderQuotaWindowSchema: z.ZodObject<{
134
- measures: z.ZodString;
135
- periodMs: z.ZodOptional<z.ZodNumber>;
136
- period: z.ZodOptional<z.ZodString>;
137
- utilization: z.ZodNumber;
138
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
139
- limit: z.ZodOptional<z.ZodNumber>;
140
- used: z.ZodOptional<z.ZodNumber>;
141
- remaining: z.ZodOptional<z.ZodNumber>;
142
- }, z.core.$strict>;
143
- export type ProviderQuotaWindow = z.infer<typeof ProviderQuotaWindowSchema>;
144
- /** A provider's quota as its usage endpoint last reported it. Pulled, not observed on a request, so it carries its own observation time. */
145
- export declare const ProviderQuotaSchema: z.ZodObject<{
146
- observedAt: z.ZodISODateTime;
147
- source: z.ZodString;
148
- level: z.ZodOptional<z.ZodString>;
149
- windows: z.ZodArray<z.ZodObject<{
150
- measures: z.ZodString;
151
- periodMs: z.ZodOptional<z.ZodNumber>;
152
- period: z.ZodOptional<z.ZodString>;
153
- utilization: z.ZodNumber;
154
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
155
- limit: z.ZodOptional<z.ZodNumber>;
156
- used: z.ZodOptional<z.ZodNumber>;
157
- remaining: z.ZodOptional<z.ZodNumber>;
158
- }, z.core.$strict>>;
159
- }, z.core.$strict>;
160
- export type ProviderQuota = z.infer<typeof ProviderQuotaSchema>;
161
- /** One provider's latest state under one identity. */
162
- declare const ProviderUsageStateSchema: z.ZodObject<{
163
- lastRequestAt: z.ZodISODateTime;
164
- lastStatus: z.ZodNumber;
165
- lastModel: z.ZodOptional<z.ZodString>;
166
- rateLimit: z.ZodOptional<z.ZodObject<{
167
- observedAt: z.ZodISODateTime;
168
- headers: z.ZodRecord<z.ZodString, z.ZodString>;
169
- unified: z.ZodOptional<z.ZodObject<{
170
- status: z.ZodOptional<z.ZodString>;
171
- fiveHour: z.ZodOptional<z.ZodObject<{
172
- utilization: z.ZodOptional<z.ZodNumber>;
173
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
174
- status: z.ZodOptional<z.ZodString>;
175
- }, z.core.$strict>>;
176
- sevenDay: z.ZodOptional<z.ZodObject<{
177
- utilization: z.ZodOptional<z.ZodNumber>;
178
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
179
- status: z.ZodOptional<z.ZodString>;
180
- }, z.core.$strict>>;
181
- representativeClaim: z.ZodOptional<z.ZodString>;
182
- resetAt: z.ZodOptional<z.ZodISODateTime>;
183
- overageStatus: z.ZodOptional<z.ZodString>;
184
- }, z.core.$strict>>;
185
- }, z.core.$strict>>;
186
- lastLimit: z.ZodOptional<z.ZodObject<{
187
- kind: z.ZodEnum<{
188
- "rate-limited": "rate-limited";
189
- "quota-exhausted": "quota-exhausted";
190
- }>;
191
- retryAfterSeconds: z.ZodOptional<z.ZodNumber>;
192
- resetAt: z.ZodOptional<z.ZodISODateTime>;
193
- window: z.ZodOptional<z.ZodString>;
194
- evidence: z.ZodArray<z.ZodString>;
195
- observedAt: z.ZodISODateTime;
196
- status: z.ZodNumber;
197
- }, z.core.$strict>>;
198
- quota: z.ZodOptional<z.ZodObject<{
199
- observedAt: z.ZodISODateTime;
200
- source: z.ZodString;
201
- level: z.ZodOptional<z.ZodString>;
202
- windows: z.ZodArray<z.ZodObject<{
203
- measures: z.ZodString;
204
- periodMs: z.ZodOptional<z.ZodNumber>;
205
- period: z.ZodOptional<z.ZodString>;
206
- utilization: z.ZodNumber;
207
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
208
- limit: z.ZodOptional<z.ZodNumber>;
209
- used: z.ZodOptional<z.ZodNumber>;
210
- remaining: z.ZodOptional<z.ZodNumber>;
211
- }, z.core.$strict>>;
212
- }, z.core.$strict>>;
213
- }, z.core.$strict>;
214
- export type ProviderUsageState = z.infer<typeof ProviderUsageStateSchema>;
215
- /**
216
- * The account fields copied from an identity's stored Claude login (`oauthAccount` in the identity's `.claude.json`): who the account is and which plan and tier it is on. Never the token, which Claude Code keeps elsewhere. Each field is present only when the stored login has it; a setup-token identity has no profile scope and so none of them (see issue #44).
217
- */
218
- export declare const AccountMetadataSchema: z.ZodObject<{
219
- accountUuid: z.ZodOptional<z.ZodString>;
220
- emailAddress: z.ZodOptional<z.ZodString>;
221
- displayName: z.ZodOptional<z.ZodString>;
222
- organizationUuid: z.ZodOptional<z.ZodString>;
223
- organizationName: z.ZodOptional<z.ZodString>;
224
- organizationType: z.ZodOptional<z.ZodString>;
225
- organizationRole: z.ZodOptional<z.ZodString>;
226
- workspaceRole: z.ZodOptional<z.ZodString>;
227
- billingType: z.ZodOptional<z.ZodString>;
228
- seatTier: z.ZodOptional<z.ZodString>;
229
- organizationRateLimitTier: z.ZodOptional<z.ZodString>;
230
- userRateLimitTier: z.ZodOptional<z.ZodString>;
231
- hasExtraUsageEnabled: z.ZodOptional<z.ZodBoolean>;
232
- subscriptionCreatedAt: z.ZodOptional<z.ZodString>;
233
- accountCreatedAt: z.ZodOptional<z.ZodString>;
234
- }, z.core.$strict>;
235
- export type AccountMetadata = z.infer<typeof AccountMetadataSchema>;
236
- /**
237
- * The latest state for one identity, rewritten atomically after each recorded response: the snapshot file other tools read (`~/.agent-shim/usage/snapshots/<identity>.json`) without shelling out to `agent-shim`.
238
- */
239
- export declare const UsageSnapshotSchema: z.ZodObject<{
240
- schemaVersion: z.ZodLiteral<1>;
241
- identity: z.ZodString;
242
- updatedAt: z.ZodISODateTime;
243
- account: z.ZodOptional<z.ZodObject<{
244
- accountUuid: z.ZodOptional<z.ZodString>;
245
- emailAddress: z.ZodOptional<z.ZodString>;
246
- displayName: z.ZodOptional<z.ZodString>;
247
- organizationUuid: z.ZodOptional<z.ZodString>;
248
- organizationName: z.ZodOptional<z.ZodString>;
249
- organizationType: z.ZodOptional<z.ZodString>;
250
- organizationRole: z.ZodOptional<z.ZodString>;
251
- workspaceRole: z.ZodOptional<z.ZodString>;
252
- billingType: z.ZodOptional<z.ZodString>;
253
- seatTier: z.ZodOptional<z.ZodString>;
254
- organizationRateLimitTier: z.ZodOptional<z.ZodString>;
255
- userRateLimitTier: z.ZodOptional<z.ZodString>;
256
- hasExtraUsageEnabled: z.ZodOptional<z.ZodBoolean>;
257
- subscriptionCreatedAt: z.ZodOptional<z.ZodString>;
258
- accountCreatedAt: z.ZodOptional<z.ZodString>;
259
- }, z.core.$strict>>;
260
- providers: z.ZodRecord<z.ZodString, z.ZodObject<{
261
- lastRequestAt: z.ZodISODateTime;
262
- lastStatus: z.ZodNumber;
263
- lastModel: z.ZodOptional<z.ZodString>;
264
- rateLimit: z.ZodOptional<z.ZodObject<{
265
- observedAt: z.ZodISODateTime;
266
- headers: z.ZodRecord<z.ZodString, z.ZodString>;
267
- unified: z.ZodOptional<z.ZodObject<{
268
- status: z.ZodOptional<z.ZodString>;
269
- fiveHour: z.ZodOptional<z.ZodObject<{
270
- utilization: z.ZodOptional<z.ZodNumber>;
271
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
272
- status: z.ZodOptional<z.ZodString>;
273
- }, z.core.$strict>>;
274
- sevenDay: z.ZodOptional<z.ZodObject<{
275
- utilization: z.ZodOptional<z.ZodNumber>;
276
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
277
- status: z.ZodOptional<z.ZodString>;
278
- }, z.core.$strict>>;
279
- representativeClaim: z.ZodOptional<z.ZodString>;
280
- resetAt: z.ZodOptional<z.ZodISODateTime>;
281
- overageStatus: z.ZodOptional<z.ZodString>;
282
- }, z.core.$strict>>;
283
- }, z.core.$strict>>;
284
- lastLimit: z.ZodOptional<z.ZodObject<{
285
- kind: z.ZodEnum<{
286
- "rate-limited": "rate-limited";
287
- "quota-exhausted": "quota-exhausted";
288
- }>;
289
- retryAfterSeconds: z.ZodOptional<z.ZodNumber>;
290
- resetAt: z.ZodOptional<z.ZodISODateTime>;
291
- window: z.ZodOptional<z.ZodString>;
292
- evidence: z.ZodArray<z.ZodString>;
293
- observedAt: z.ZodISODateTime;
294
- status: z.ZodNumber;
295
- }, z.core.$strict>>;
296
- quota: z.ZodOptional<z.ZodObject<{
297
- observedAt: z.ZodISODateTime;
298
- source: z.ZodString;
299
- level: z.ZodOptional<z.ZodString>;
300
- windows: z.ZodArray<z.ZodObject<{
301
- measures: z.ZodString;
302
- periodMs: z.ZodOptional<z.ZodNumber>;
303
- period: z.ZodOptional<z.ZodString>;
304
- utilization: z.ZodNumber;
305
- resetsAt: z.ZodOptional<z.ZodISODateTime>;
306
- limit: z.ZodOptional<z.ZodNumber>;
307
- used: z.ZodOptional<z.ZodNumber>;
308
- remaining: z.ZodOptional<z.ZodNumber>;
309
- }, z.core.$strict>>;
310
- }, z.core.$strict>>;
311
- }, z.core.$strict>>;
312
- }, z.core.$strict>;
313
- export type UsageSnapshot = z.infer<typeof UsageSnapshotSchema>;
314
- /**
315
- * Whether a response header is one the store keeps: the quota and rate-limit families the upstreams agent-shim routes to send (Anthropic's `anthropic-ratelimit-*`, the IETF draft's `ratelimit*`, the common `x-ratelimit-*`, the Codex backend's `x-codex-*` quota headers, which the Codex route forwards) and `retry-after`. Every one of these carries a number, a time or a status word; none carries a credential or content.
316
- */
317
- export declare function isRateLimitHeader(name: string): boolean;
318
- export {};
@@ -1,43 +0,0 @@
1
- import type { FarmFs } from "../launcher/ports";
2
- import type { LayoutPaths } from "../paths";
3
- import { type AccountMetadata, type ProviderQuota, type ProviderUsageState, type UsageRecord } from "./schema";
4
- /** The filesystem effects the usage store's writer performs, all owner-only. */
5
- export type UsageFs = Pick<FarmFs, "mkdirPrivate" | "writeFilePrivate" | "appendFilePrivate" | "readFileUtf8" | "readdir" | "removeRecursive">;
6
- /**
7
- * How long the usage log keeps records: seven days, the longest quota window any upstream agent-shim routes to enforces (Anthropic's subscription `seven_day` window, and the weekly windows z.ai's GLM Coding Plan and MiniMax's Token Plan document). Consumers ask the log how a credential's quota was spent within its current windows; a record older than the longest window can no longer count against any of them. Segments are pruned whole, by day, so the log always covers at least the full window.
8
- */
9
- export declare const USAGE_RETENTION_MS: number;
10
- /** Removes every log segment whose day ended before the retention window began. Safe to race: removing a segment another pruner already removed does nothing. */
11
- export declare function pruneUsageLog(fs: Pick<UsageFs, "readdir" | "removeRecursive">, logDir: string, nowMs: number): void;
12
- /** Everything the store's writer depends on. */
13
- export interface UsageStoreDeps {
14
- readonly fs: UsageFs;
15
- readonly paths: Pick<LayoutPaths, "usageDir" | "usageLogDir" | "usageSnapshotsDir">;
16
- /** This process's pid, which names its own log segments: one writer per segment is what makes concurrent writers safe without locking. */
17
- readonly pid: number;
18
- readonly now: () => number;
19
- /** The identity's current account metadata, copied into its snapshot on every write so the snapshot is never staler than the last request. */
20
- readonly readAccount: (identity: string) => AccountMetadata | undefined;
21
- readonly log: (line: string) => void;
22
- }
23
- /** The store's writer. */
24
- export interface UsageStore {
25
- /** Validates and appends one record, then refreshes its identity's snapshot. Throws on a write failure; the caller (the usage middleware) catches. */
26
- readonly record: (record: UsageRecord) => void;
27
- /** Attaches a provider's pulled quota to the identity's existing state for that provider, keeping the newer observation when one is already there. Returns false when the identity has no state for the provider (a quota is only ever attached to usage that was seen). Throws on a write failure. */
28
- readonly recordQuota: (identity: string, provider: string, quota: ProviderQuota) => boolean;
29
- }
30
- /**
31
- * Folds one record into its provider's latest state. Each part keeps whichever observation is newest, so records folded out of order (two door generations overlapping, each writing its own) still leave the latest state, never an older one.
32
- */
33
- export declare function foldProviderState(current: ProviderUsageState | undefined, record: UsageRecord): ProviderUsageState;
34
- /**
35
- * The usage store's writer, owned by the front-door process.
36
- *
37
- * The log is append-only JSON Lines under `usage/log/`, one segment per writing process per UTC day (`<YYYY-MM-DD>.<pid>.jsonl`). Every segment has exactly one writer, so concurrent writers (two door generations overlapping during a restart) can never interleave within a line, and readers (`agent-shim usage`, other tools) need no lock: the only partial line they can meet is a segment's unfinished last one, which they skip. Retention is enforced by pruning whole segments on the first write of each day.
38
- *
39
- * Each identity's snapshot (`usage/snapshots/<identity>.json`) is rewritten atomically (a temporary sibling renamed into place) after every record, so a reader always sees a whole snapshot. Two writers racing on one snapshot can each overwrite the other's newest observation for a provider, but never corrupt the file; the next record repairs it, and the log, not the snapshot, is the record of truth. A snapshot that cannot be read (a newer schema, a corrupted file) is replaced with a fresh one, and the replacement is logged.
40
- *
41
- * Everything is created owner-only: the directories 0700, the files 0600.
42
- */
43
- export declare function createUsageStore(deps: UsageStoreDeps): UsageStore;
@@ -1,47 +0,0 @@
1
- /** One entry observed inside a versions directory (e.g. ~/.local/share/claude/versions/2.1.220). */
2
- export interface VersionsDirEntry {
3
- /** The entry's own name — expected to be a plain dotted-numeric version like "2.1.220". */
4
- name: string;
5
- /** Whether the entry is a regular file (not a directory, symlink-to-directory, etc). */
6
- isFile: boolean;
7
- /** Whether the entry has at least one execute bit set. */
8
- isExecutable: boolean;
9
- /** The entry's size in bytes. */
10
- sizeBytes: number;
11
- }
12
- /** Injected dependencies for discoverClaudeBinary, so no test ever touches a real filesystem or PATH. */
13
- export interface DiscoverClaudeBinaryOptions {
14
- /** Directory to scan for versioned claude binaries. Defaults to ~/.local/share/claude/versions. */
15
- versionsDir?: string;
16
- /** Lists the entries of a versions directory. Injected so tests never touch the real filesystem. */
17
- listVersionsDir: (dir: string) => VersionsDirEntry[];
18
- /** The PATH-like list of directories to search as a fallback, in order. */
19
- pathDirs: string[];
20
- /** Looks up an executable of the given name inside one PATH directory, returning its full path if found. */
21
- findExecutableInDir: (dir: string, name: string) => string | undefined;
22
- /** This tool's own install directory(ies), excluded from the PATH fallback search to avoid self-selection. */
23
- ownInstallDirs: string[];
24
- }
25
- /** The result of a successful discovery. */
26
- export interface DiscoveredClaudeBinary {
27
- /** Full path to the discovered `claude` executable. */
28
- path: string;
29
- /** Which strategy found it. */
30
- source: "versions-dir" | "path-fallback";
31
- /** The version string, when discovered via the versions directory. */
32
- version?: string;
33
- }
34
- /** True when `name` is a plain dotted-numeric version string like "2.1.220" (never full semver — no pre-release/build metadata is expected here). */
35
- export declare function isNumericDottedVersion(name: string): boolean;
36
- /**
37
- * Compares two plain dotted-numeric version strings segment by segment, treating a missing trailing segment as 0 (so "2.1" sorts before "2.1.1"). Returns a negative number when `a` is the earlier version, a positive number when `a` is the later one, and 0 when equal. Throws if either string isn't a valid numeric-dotted version — callers must filter with isNumericDottedVersion first, since a naive string/lexicographic sort would incorrectly rank "2.9.0" ahead of "2.10.0".
38
- */
39
- export declare function compareVersions(a: string, b: string): number;
40
- /**
41
- * Filters `entries` to genuinely-executable, non-empty regular files whose name is a valid dotted-numeric version (skipping things like .DS_Store or a stray empty file), then picks the highest version by a real numeric-segment comparison. Returns undefined when nothing qualifies.
42
- */
43
- export declare function pickHighestVersion(entries: readonly VersionsDirEntry[]): string | undefined;
44
- /**
45
- * Discovers the real `claude` binary to launch: first by scanning the versions directory and picking the highest genuinely-executable version, then falling back to a PATH search for a `claude` executable (excluding this tool's own install directory, so the launcher never recursively selects itself). Throws a clear, actionable error when neither strategy finds anything — this is a deliberate improvement over the legacy bash tool, which crashed cryptically on a missing or empty versions directory instead of reporting the problem.
46
- */
47
- export declare function discoverClaudeBinary(options: DiscoverClaudeBinaryOptions): DiscoveredClaudeBinary;