@xenosystem/agent-cli 0.5.107 → 0.5.109

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 (76) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/index.js +1627 -1626
  3. package/dist/metafile-esm.json +1 -1
  4. package/dist/sdk-build-identity.json +4 -4
  5. package/node_modules/@xeno-corporation/account/LICENSE +39 -0
  6. package/node_modules/@xeno-corporation/account/README.md +211 -0
  7. package/node_modules/@xeno-corporation/account/dist/chunk-FELZILY4.mjs +60 -0
  8. package/node_modules/@xeno-corporation/account/dist/chunk-FELZILY4.mjs.map +1 -0
  9. package/node_modules/@xeno-corporation/account/dist/index.d.mts +883 -0
  10. package/node_modules/@xeno-corporation/account/dist/index.d.ts +883 -0
  11. package/node_modules/@xeno-corporation/account/dist/index.js +2301 -0
  12. package/node_modules/@xeno-corporation/account/dist/index.js.map +1 -0
  13. package/node_modules/@xeno-corporation/account/dist/index.mjs +2191 -0
  14. package/node_modules/@xeno-corporation/account/dist/index.mjs.map +1 -0
  15. package/node_modules/@xeno-corporation/account/dist/node.d.mts +35 -0
  16. package/node_modules/@xeno-corporation/account/dist/node.d.ts +35 -0
  17. package/node_modules/@xeno-corporation/account/dist/node.js +715 -0
  18. package/node_modules/@xeno-corporation/account/dist/node.js.map +1 -0
  19. package/node_modules/@xeno-corporation/account/dist/node.mjs +645 -0
  20. package/node_modules/@xeno-corporation/account/dist/node.mjs.map +1 -0
  21. package/node_modules/@xeno-corporation/account/dist/tokenStore-CnIo2ILq.d.mts +47 -0
  22. package/node_modules/@xeno-corporation/account/dist/tokenStore-CnIo2ILq.d.ts +47 -0
  23. package/node_modules/@xeno-corporation/account/package.json +60 -0
  24. package/node_modules/zod/LICENSE +21 -0
  25. package/node_modules/zod/README.md +3028 -0
  26. package/node_modules/zod/index.d.ts +2 -0
  27. package/node_modules/zod/lib/ZodError.d.ts +164 -0
  28. package/node_modules/zod/lib/ZodError.js +137 -0
  29. package/node_modules/zod/lib/__tests__/Mocker.d.ts +17 -0
  30. package/node_modules/zod/lib/__tests__/Mocker.js +57 -0
  31. package/node_modules/zod/lib/benchmarks/datetime.d.ts +5 -0
  32. package/node_modules/zod/lib/benchmarks/datetime.js +54 -0
  33. package/node_modules/zod/lib/benchmarks/discriminatedUnion.d.ts +5 -0
  34. package/node_modules/zod/lib/benchmarks/discriminatedUnion.js +79 -0
  35. package/node_modules/zod/lib/benchmarks/index.d.ts +1 -0
  36. package/node_modules/zod/lib/benchmarks/index.js +59 -0
  37. package/node_modules/zod/lib/benchmarks/ipv4.d.ts +5 -0
  38. package/node_modules/zod/lib/benchmarks/ipv4.js +54 -0
  39. package/node_modules/zod/lib/benchmarks/object.d.ts +5 -0
  40. package/node_modules/zod/lib/benchmarks/object.js +70 -0
  41. package/node_modules/zod/lib/benchmarks/primitives.d.ts +5 -0
  42. package/node_modules/zod/lib/benchmarks/primitives.js +170 -0
  43. package/node_modules/zod/lib/benchmarks/realworld.d.ts +5 -0
  44. package/node_modules/zod/lib/benchmarks/realworld.js +56 -0
  45. package/node_modules/zod/lib/benchmarks/string.d.ts +5 -0
  46. package/node_modules/zod/lib/benchmarks/string.js +55 -0
  47. package/node_modules/zod/lib/benchmarks/union.d.ts +5 -0
  48. package/node_modules/zod/lib/benchmarks/union.js +79 -0
  49. package/node_modules/zod/lib/errors.d.ts +5 -0
  50. package/node_modules/zod/lib/errors.js +17 -0
  51. package/node_modules/zod/lib/external.d.ts +6 -0
  52. package/node_modules/zod/lib/external.js +22 -0
  53. package/node_modules/zod/lib/helpers/enumUtil.d.ts +8 -0
  54. package/node_modules/zod/lib/helpers/enumUtil.js +2 -0
  55. package/node_modules/zod/lib/helpers/errorUtil.d.ts +9 -0
  56. package/node_modules/zod/lib/helpers/errorUtil.js +8 -0
  57. package/node_modules/zod/lib/helpers/parseUtil.d.ts +78 -0
  58. package/node_modules/zod/lib/helpers/parseUtil.js +125 -0
  59. package/node_modules/zod/lib/helpers/partialUtil.d.ts +8 -0
  60. package/node_modules/zod/lib/helpers/partialUtil.js +2 -0
  61. package/node_modules/zod/lib/helpers/typeAliases.d.ts +2 -0
  62. package/node_modules/zod/lib/helpers/typeAliases.js +2 -0
  63. package/node_modules/zod/lib/helpers/util.d.ts +82 -0
  64. package/node_modules/zod/lib/helpers/util.js +142 -0
  65. package/node_modules/zod/lib/index.d.ts +4 -0
  66. package/node_modules/zod/lib/index.js +33 -0
  67. package/node_modules/zod/lib/index.mjs +4382 -0
  68. package/node_modules/zod/lib/index.umd.js +4497 -0
  69. package/node_modules/zod/lib/locales/en.d.ts +3 -0
  70. package/node_modules/zod/lib/locales/en.js +129 -0
  71. package/node_modules/zod/lib/standard-schema.d.ts +102 -0
  72. package/node_modules/zod/lib/standard-schema.js +2 -0
  73. package/node_modules/zod/lib/types.d.ts +1062 -0
  74. package/node_modules/zod/lib/types.js +3823 -0
  75. package/node_modules/zod/package.json +122 -0
  76. package/package.json +1 -1
@@ -0,0 +1,883 @@
1
+ import { z } from 'zod';
2
+ import { a as DpopSigner, T as TokenStore } from './tokenStore-CnIo2ILq.js';
3
+ export { D as DpopProofArgs, K as Keychain, k as keychainStore, m as memoryStore, n as normalizeDpopHtu } from './tokenStore-CnIo2ILq.js';
4
+
5
+ /**
6
+ * The XENO Account & Ledger contract — canonical types.
7
+ *
8
+ * These Zod schemas ARE the contract every branch (app) and the origin
9
+ * (xeno-platform) speak. See `XENO ACCOUNT - ARCHITECTURE.md`. Money is always
10
+ * integer **micro-credits** (1 credit = 1_000_000 µcr) — never a float.
11
+ */
12
+ /** 1 credit expressed in the integer base unit. */
13
+ declare const MICRO_PER_CREDIT = 1000000;
14
+ /** A surface = the originating app/branch, the "from where" attribution. */
15
+ declare const surfaceSchema: z.ZodString;
16
+ type Surface = z.infer<typeof surfaceSchema>;
17
+ /**
18
+ * The canonical XENO account as a branch sees it. `id` is the canonical
19
+ * `platform_user_id`; identity is keyed on (provider, subject) upstream, never
20
+ * on the email — `email` here is contact/display only.
21
+ */
22
+ declare const accountSchema: z.ZodObject<{
23
+ id: z.ZodString;
24
+ email: z.ZodString;
25
+ username: z.ZodDefault<z.ZodNullable<z.ZodString>>;
26
+ displayName: z.ZodDefault<z.ZodNullable<z.ZodString>>;
27
+ avatarUrl: z.ZodDefault<z.ZodNullable<z.ZodString>>;
28
+ emailVerified: z.ZodDefault<z.ZodBoolean>;
29
+ /** Linked app surfaces for this account (unified-account view). */
30
+ linkedSurfaces: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
31
+ }, "strip", z.ZodTypeAny, {
32
+ id: string;
33
+ email: string;
34
+ username: string | null;
35
+ displayName: string | null;
36
+ avatarUrl: string | null;
37
+ emailVerified: boolean;
38
+ linkedSurfaces: string[];
39
+ }, {
40
+ id: string;
41
+ email: string;
42
+ username?: string | null | undefined;
43
+ displayName?: string | null | undefined;
44
+ avatarUrl?: string | null | undefined;
45
+ emailVerified?: boolean | undefined;
46
+ linkedSurfaces?: string[] | undefined;
47
+ }>;
48
+ type Account = z.infer<typeof accountSchema>;
49
+ declare const tokenSetSchema: z.ZodObject<{
50
+ accessToken: z.ZodString;
51
+ /** Opaque or JWT; the SDK treats it as opaque. */
52
+ tokenType: z.ZodDefault<z.ZodString>;
53
+ expiresAt: z.ZodDefault<z.ZodNullable<z.ZodDate>>;
54
+ refreshToken: z.ZodDefault<z.ZodNullable<z.ZodString>>;
55
+ /** OIDC ID token (authentication only — never sent to resource APIs). */
56
+ idToken: z.ZodDefault<z.ZodNullable<z.ZodString>>;
57
+ scope: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
58
+ /** Session id claim, the join key for back-channel logout. */
59
+ sid: z.ZodDefault<z.ZodNullable<z.ZodString>>;
60
+ /** Signature-verified claims; never populated by unverified decoding. */
61
+ accessClaims: z.ZodDefault<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
62
+ idClaims: z.ZodDefault<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
63
+ }, "strip", z.ZodTypeAny, {
64
+ accessToken: string;
65
+ tokenType: string;
66
+ expiresAt: Date | null;
67
+ refreshToken: string | null;
68
+ idToken: string | null;
69
+ scope: string[];
70
+ sid: string | null;
71
+ accessClaims: Record<string, unknown> | null;
72
+ idClaims: Record<string, unknown> | null;
73
+ }, {
74
+ accessToken: string;
75
+ tokenType?: string | undefined;
76
+ expiresAt?: Date | null | undefined;
77
+ refreshToken?: string | null | undefined;
78
+ idToken?: string | null | undefined;
79
+ scope?: string[] | undefined;
80
+ sid?: string | null | undefined;
81
+ accessClaims?: Record<string, unknown> | null | undefined;
82
+ idClaims?: Record<string, unknown> | null | undefined;
83
+ }>;
84
+ type TokenSet = z.infer<typeof tokenSetSchema>;
85
+ /** Raw OAuth 2.0 token endpoint response (snake_case, as servers emit it). */
86
+ declare const oauthTokenResponseSchema: z.ZodObject<{
87
+ access_token: z.ZodString;
88
+ token_type: z.ZodDefault<z.ZodString>;
89
+ expires_in: z.ZodOptional<z.ZodNumber>;
90
+ refresh_token: z.ZodOptional<z.ZodString>;
91
+ id_token: z.ZodOptional<z.ZodString>;
92
+ scope: z.ZodOptional<z.ZodString>;
93
+ }, "strip", z.ZodTypeAny, {
94
+ access_token: string;
95
+ token_type: string;
96
+ scope?: string | undefined;
97
+ expires_in?: number | undefined;
98
+ refresh_token?: string | undefined;
99
+ id_token?: string | undefined;
100
+ }, {
101
+ access_token: string;
102
+ scope?: string | undefined;
103
+ token_type?: string | undefined;
104
+ expires_in?: number | undefined;
105
+ refresh_token?: string | undefined;
106
+ id_token?: string | undefined;
107
+ }>;
108
+ type OAuthTokenResponse = z.infer<typeof oauthTokenResponseSchema>;
109
+ /**
110
+ * The three balances every double-entry wallet exposes. Gate spend decisions
111
+ * on `availableMicro` (most conservative). All values are integer micro-credits.
112
+ */
113
+ declare const balanceSchema: z.ZodObject<{
114
+ /** Settled balance. */
115
+ postedMicro: z.ZodNumber;
116
+ /** Settled minus active holds. */
117
+ pendingMicro: z.ZodNumber;
118
+ /** Most conservative spendable amount — gate approvals on this. */
119
+ availableMicro: z.ZodNumber;
120
+ currency: z.ZodDefault<z.ZodLiteral<"credits">>;
121
+ asOf: z.ZodDefault<z.ZodDate>;
122
+ }, "strip", z.ZodTypeAny, {
123
+ postedMicro: number;
124
+ pendingMicro: number;
125
+ availableMicro: number;
126
+ currency: "credits";
127
+ asOf: Date;
128
+ }, {
129
+ postedMicro: number;
130
+ pendingMicro: number;
131
+ availableMicro: number;
132
+ currency?: "credits" | undefined;
133
+ asOf?: Date | undefined;
134
+ }>;
135
+ type Balance = z.infer<typeof balanceSchema>;
136
+ declare const meterAggregationSchema: z.ZodEnum<["sum", "count", "max", "min", "unique_count", "latest"]>;
137
+ type MeterAggregation = z.infer<typeof meterAggregationSchema>;
138
+ /**
139
+ * A usage event posted to the meter. `transactionId` MUST be deterministic
140
+ * (a hash of the business event), never a random id minted at send time — it
141
+ * is the dedup key (32–34 day window) that makes metering exactly-once.
142
+ */
143
+ declare const usageEventSchema: z.ZodObject<{
144
+ surface: z.ZodString;
145
+ /** Stable, producer-supplied dedup id. */
146
+ transactionId: z.ZodString;
147
+ operation: z.ZodString;
148
+ model: z.ZodDefault<z.ZodNullable<z.ZodString>>;
149
+ provider: z.ZodDefault<z.ZodNullable<z.ZodString>>;
150
+ /** Pre-computed cost in micro-credits, if the caller priced it. */
151
+ costMicro: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
152
+ inputTokens: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
153
+ outputTokens: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
154
+ /** Arbitrary attribution dimensions (project, workspace, …). */
155
+ dimensions: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
156
+ occurredAt: z.ZodOptional<z.ZodDate>;
157
+ }, "strip", z.ZodTypeAny, {
158
+ surface: string;
159
+ transactionId: string;
160
+ operation: string;
161
+ model: string | null;
162
+ provider: string | null;
163
+ costMicro: number | null;
164
+ inputTokens: number | null;
165
+ outputTokens: number | null;
166
+ dimensions: Record<string, string>;
167
+ occurredAt?: Date | undefined;
168
+ }, {
169
+ surface: string;
170
+ transactionId: string;
171
+ operation: string;
172
+ model?: string | null | undefined;
173
+ provider?: string | null | undefined;
174
+ costMicro?: number | null | undefined;
175
+ inputTokens?: number | null | undefined;
176
+ outputTokens?: number | null | undefined;
177
+ dimensions?: Record<string, string> | undefined;
178
+ occurredAt?: Date | undefined;
179
+ }>;
180
+ type UsageEvent = z.infer<typeof usageEventSchema>;
181
+ declare const usageResultSchema: z.ZodObject<{
182
+ accepted: z.ZodBoolean;
183
+ /** True when the event was a duplicate (idempotent no-op). */
184
+ duplicate: z.ZodDefault<z.ZodBoolean>;
185
+ costMicro: z.ZodNumber;
186
+ transactionId: z.ZodString;
187
+ balance: z.ZodDefault<z.ZodNullable<z.ZodObject<{
188
+ /** Settled balance. */
189
+ postedMicro: z.ZodNumber;
190
+ /** Settled minus active holds. */
191
+ pendingMicro: z.ZodNumber;
192
+ /** Most conservative spendable amount — gate approvals on this. */
193
+ availableMicro: z.ZodNumber;
194
+ currency: z.ZodDefault<z.ZodLiteral<"credits">>;
195
+ asOf: z.ZodDefault<z.ZodDate>;
196
+ }, "strip", z.ZodTypeAny, {
197
+ postedMicro: number;
198
+ pendingMicro: number;
199
+ availableMicro: number;
200
+ currency: "credits";
201
+ asOf: Date;
202
+ }, {
203
+ postedMicro: number;
204
+ pendingMicro: number;
205
+ availableMicro: number;
206
+ currency?: "credits" | undefined;
207
+ asOf?: Date | undefined;
208
+ }>>>;
209
+ }, "strip", z.ZodTypeAny, {
210
+ transactionId: string;
211
+ costMicro: number;
212
+ accepted: boolean;
213
+ duplicate: boolean;
214
+ balance: {
215
+ postedMicro: number;
216
+ pendingMicro: number;
217
+ availableMicro: number;
218
+ currency: "credits";
219
+ asOf: Date;
220
+ } | null;
221
+ }, {
222
+ transactionId: string;
223
+ costMicro: number;
224
+ accepted: boolean;
225
+ duplicate?: boolean | undefined;
226
+ balance?: {
227
+ postedMicro: number;
228
+ pendingMicro: number;
229
+ availableMicro: number;
230
+ currency?: "credits" | undefined;
231
+ asOf?: Date | undefined;
232
+ } | null | undefined;
233
+ }>;
234
+ type UsageResult = z.infer<typeof usageResultSchema>;
235
+ /** A two-phase hold (reserve → settle/void) for hard per-use gating. */
236
+ declare const holdRequestSchema: z.ZodObject<{
237
+ surface: z.ZodString;
238
+ /** Idempotency key for the hold itself. */
239
+ holdId: z.ZodString;
240
+ amountMicro: z.ZodNumber;
241
+ operation: z.ZodString;
242
+ expiresInSeconds: z.ZodDefault<z.ZodNumber>;
243
+ dimensions: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
244
+ }, "strip", z.ZodTypeAny, {
245
+ surface: string;
246
+ operation: string;
247
+ dimensions: Record<string, string>;
248
+ holdId: string;
249
+ amountMicro: number;
250
+ expiresInSeconds: number;
251
+ }, {
252
+ surface: string;
253
+ operation: string;
254
+ holdId: string;
255
+ amountMicro: number;
256
+ dimensions?: Record<string, string> | undefined;
257
+ expiresInSeconds?: number | undefined;
258
+ }>;
259
+ type HoldRequest = z.infer<typeof holdRequestSchema>;
260
+ declare const holdSchema: z.ZodObject<{
261
+ holdId: z.ZodString;
262
+ state: z.ZodEnum<["held", "settled", "voided", "expired"]>;
263
+ amountMicro: z.ZodNumber;
264
+ settledMicro: z.ZodDefault<z.ZodNumber>;
265
+ balance: z.ZodDefault<z.ZodNullable<z.ZodObject<{
266
+ /** Settled balance. */
267
+ postedMicro: z.ZodNumber;
268
+ /** Settled minus active holds. */
269
+ pendingMicro: z.ZodNumber;
270
+ /** Most conservative spendable amount — gate approvals on this. */
271
+ availableMicro: z.ZodNumber;
272
+ currency: z.ZodDefault<z.ZodLiteral<"credits">>;
273
+ asOf: z.ZodDefault<z.ZodDate>;
274
+ }, "strip", z.ZodTypeAny, {
275
+ postedMicro: number;
276
+ pendingMicro: number;
277
+ availableMicro: number;
278
+ currency: "credits";
279
+ asOf: Date;
280
+ }, {
281
+ postedMicro: number;
282
+ pendingMicro: number;
283
+ availableMicro: number;
284
+ currency?: "credits" | undefined;
285
+ asOf?: Date | undefined;
286
+ }>>>;
287
+ }, "strip", z.ZodTypeAny, {
288
+ balance: {
289
+ postedMicro: number;
290
+ pendingMicro: number;
291
+ availableMicro: number;
292
+ currency: "credits";
293
+ asOf: Date;
294
+ } | null;
295
+ holdId: string;
296
+ amountMicro: number;
297
+ state: "held" | "settled" | "voided" | "expired";
298
+ settledMicro: number;
299
+ }, {
300
+ holdId: string;
301
+ amountMicro: number;
302
+ state: "held" | "settled" | "voided" | "expired";
303
+ balance?: {
304
+ postedMicro: number;
305
+ pendingMicro: number;
306
+ availableMicro: number;
307
+ currency?: "credits" | undefined;
308
+ asOf?: Date | undefined;
309
+ } | null | undefined;
310
+ settledMicro?: number | undefined;
311
+ }>;
312
+ type Hold = z.infer<typeof holdSchema>;
313
+ declare const authzCheckSchema: z.ZodObject<{
314
+ /** e.g. `user:abc` or `agent:scout`. */
315
+ subject: z.ZodString;
316
+ relation: z.ZodString;
317
+ /** e.g. `workspace:acme` or `post:123`. */
318
+ object: z.ZodString;
319
+ context: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
320
+ }, "strip", z.ZodTypeAny, {
321
+ object: string;
322
+ subject: string;
323
+ relation: string;
324
+ context: Record<string, unknown>;
325
+ }, {
326
+ object: string;
327
+ subject: string;
328
+ relation: string;
329
+ context?: Record<string, unknown> | undefined;
330
+ }>;
331
+ type AuthzCheck = z.infer<typeof authzCheckSchema>;
332
+ declare const authzResultSchema: z.ZodObject<{
333
+ allowed: z.ZodBoolean;
334
+ /** Optional reason/trace for debugging (never authoritative). */
335
+ reason: z.ZodDefault<z.ZodNullable<z.ZodString>>;
336
+ }, "strip", z.ZodTypeAny, {
337
+ allowed: boolean;
338
+ reason: string | null;
339
+ }, {
340
+ allowed: boolean;
341
+ reason?: string | null | undefined;
342
+ }>;
343
+ type AuthzResult = z.infer<typeof authzResultSchema>;
344
+ /** Convert whole credits → integer micro-credits. */
345
+ declare function toMicro(credits: number): number;
346
+ /** Convert integer micro-credits → whole credits (may be fractional). */
347
+ declare function fromMicro(micro: number): number;
348
+
349
+ /**
350
+ * Normalised error taxonomy for the account client. Every failure a branch can
351
+ * see maps to one of these codes so callers branch on `code`, never on strings.
352
+ */
353
+ type AccountErrorCode = 'DISABLED' | 'UNREACHABLE' | 'INVALID_TOKEN' | 'INSUFFICIENT_CREDITS' | 'CONFLICT' | 'INVALID_RESPONSE' | 'BAD_REQUEST' | 'NOT_FOUND' | 'RATE_LIMITED' | 'PLATFORM_ERROR';
354
+ declare class AccountError extends Error {
355
+ readonly code: AccountErrorCode;
356
+ readonly httpStatus: number | null;
357
+ readonly retryable: boolean;
358
+ readonly retryAfterMs: number | null;
359
+ readonly oauthError: string | null;
360
+ constructor(args: {
361
+ code: AccountErrorCode;
362
+ message: string;
363
+ httpStatus?: number | null;
364
+ retryable?: boolean;
365
+ retryAfterMs?: number | null;
366
+ oauthError?: string | null;
367
+ });
368
+ }
369
+ /** Map an HTTP status to the right error code. */
370
+ declare function codeForStatus(status: number): AccountErrorCode;
371
+
372
+ /**
373
+ * Minimal, dependency-free HTTP transport for the account client.
374
+ *
375
+ * Design rules (from `XENO ACCOUNT - ARCHITECTURE.md` §4.4):
376
+ * - Mutations carry an `Idempotency-Key`; the SDK NEVER auto-retries a mutation
377
+ * without one (would risk a double-charge). With a key, retrying is safe
378
+ * because the origin replays the first response.
379
+ * - GETs are safely retried on network/5xx with capped backoff.
380
+ * - The bearer token is sent in the Authorization header, never logged.
381
+ */
382
+ interface TransportOptions {
383
+ /** Injectable for tests; defaults to global fetch. */
384
+ fetchImpl?: typeof fetch;
385
+ timeoutMs?: number;
386
+ /** Retry attempts for idempotent requests (GET, or mutation with a key). */
387
+ maxRetries?: number;
388
+ userAgent?: string;
389
+ /** Maximum decoded response bytes. Oversized responses fail, never truncate. */
390
+ maxResponseBytes?: number;
391
+ }
392
+ interface RequestArgs {
393
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE';
394
+ url: string;
395
+ token?: string | null;
396
+ tokenType?: 'Bearer' | 'DPoP';
397
+ body?: unknown;
398
+ /** Required to make a mutation retry-safe. */
399
+ idempotencyKey?: string;
400
+ /** Extra headers (e.g. DPoP proof). */
401
+ headers?: Record<string, string>;
402
+ /** Host-owned authorization refreshed for each attempt; DPoP proofs are single use. */
403
+ authorization?: RequestAuthorizationProvider;
404
+ /** Only canonical OAuth grant endpoints opt into safe error-code extraction. */
405
+ oauthErrorResponse?: boolean;
406
+ /** Caller cancellation is nonretryable and covers authorization/body as well as fetch. */
407
+ signal?: AbortSignal;
408
+ }
409
+ interface RequestAuthorization {
410
+ token: string;
411
+ tokenType: 'Bearer' | 'DPoP';
412
+ headers?: Record<string, string>;
413
+ }
414
+ type RequestAuthorizationProvider = (method: RequestArgs['method'], url: string) => Promise<RequestAuthorization>;
415
+ type AuthorizationInput = string | RequestAuthorization | RequestAuthorizationProvider;
416
+ declare class Transport {
417
+ private readonly fetchImpl;
418
+ private readonly timeoutMs;
419
+ private readonly maxRetries;
420
+ private readonly userAgent;
421
+ private readonly maxResponseBytes;
422
+ constructor(opts?: TransportOptions);
423
+ /** Perform a request and return parsed JSON (or null for empty bodies). */
424
+ request<T = unknown>(args: RequestArgs): Promise<T>;
425
+ private once;
426
+ }
427
+
428
+ /**
429
+ * Account client — the identity-read side. Resolves a token to its canonical
430
+ * XENO account.
431
+ *
432
+ * Targets the v2 `/api/v2/me`, with a graceful fall-back to the legacy
433
+ * `/api/auth/me` envelope (`{ success, user: {...} }`) so it works against the
434
+ * live platform today, before the v2 surface ships.
435
+ */
436
+ declare class AccountClient {
437
+ private readonly base;
438
+ private readonly transport;
439
+ constructor(base: string, transport: Transport);
440
+ /** Resolve a token to its account, or throw an AccountError. */
441
+ me(auth: AuthorizationInput): Promise<Account>;
442
+ }
443
+ /**
444
+ * Normalise either a v2 account or the legacy `{ user }` envelope into the
445
+ * canonical {@link Account}. Tolerant of snake/camel; null only if no id+email.
446
+ */
447
+ declare function normalize(body: unknown): Account | null;
448
+
449
+ /** Caller-facing input types (defaults not yet applied). */
450
+ type UsageEventInput = z.input<typeof usageEventSchema>;
451
+ type HoldRequestInput = z.input<typeof holdRequestSchema>;
452
+ /**
453
+ * Ledger client — the spend side of the contract. Targets the origin's
454
+ * `/api/v2/ledger/*` surface. Every mutation is idempotent: usage events key on
455
+ * a deterministic `transactionId`, holds on a `holdId`, and both are sent as the
456
+ * `Idempotency-Key` so a retry can never double-charge.
457
+ *
458
+ * Spend decisions gate on `balance.availableMicro` (the most conservative of the
459
+ * three balances). All amounts are integer micro-credits.
460
+ */
461
+ declare class LedgerClient {
462
+ private readonly apiBase;
463
+ private readonly transport;
464
+ constructor(apiBase: string, transport: Transport);
465
+ /** Posted / pending / available balance for the token's account. */
466
+ getBalance(auth: AuthorizationInput): Promise<Balance>;
467
+ /**
468
+ * Record a usage event (the meter). Idempotent on `transactionId`; a duplicate
469
+ * returns `{ duplicate: true }` and does not charge again.
470
+ */
471
+ recordUsage(auth: AuthorizationInput, event: UsageEventInput): Promise<UsageResult>;
472
+ /**
473
+ * Reserve credits for a per-use action (phase 1 of two-phase spend). Rejected
474
+ * with `INSUFFICIENT_CREDITS` if `available < amount`. Idempotent on `holdId`.
475
+ */
476
+ hold(auth: AuthorizationInput, req: HoldRequestInput): Promise<Hold>;
477
+ /**
478
+ * Settle a hold for the actual cost (phase 2). Posting less than the held
479
+ * amount auto-restores the remainder. Idempotent on `holdId`.
480
+ */
481
+ settle(auth: AuthorizationInput, holdId: string, actualCostMicro: number): Promise<Hold>;
482
+ /** Release a hold without charging (failure/cancel). Idempotent on `holdId`. */
483
+ void(auth: AuthorizationInput, holdId: string): Promise<Hold>;
484
+ }
485
+
486
+ /**
487
+ * Authorization client — ReBAC checks against the origin's central authz
488
+ * service (OpenFGA-backed). A branch asks "may this subject perform this
489
+ * relation on this object?"; the origin is the single source of truth so
490
+ * cross-app permission inheritance works without per-app role sync.
491
+ *
492
+ * Fail-closed: any transport error surfaces as an AccountError; callers must
493
+ * treat a non-`allowed` result (or an error) as deny.
494
+ */
495
+ declare class AuthzClient {
496
+ private readonly apiBase;
497
+ private readonly transport;
498
+ constructor(apiBase: string, transport: Transport);
499
+ check(auth: AuthorizationInput, check: AuthzCheck): Promise<AuthzResult>;
500
+ }
501
+
502
+ /**
503
+ * OIDC relying-party flows (OAuth 2.1 / RFC 9700 compliant):
504
+ * - Authorization Code + PKCE (S256) for web + native (RFC 8252).
505
+ * - Device Authorization Grant (RFC 8628) for CLI / headless.
506
+ *
507
+ * No implicit flow, no ROPC — both are forbidden. PKCE is always used, even for
508
+ * confidential clients.
509
+ */
510
+ interface OidcConfig {
511
+ /** Issuer base, e.g. https://xenostudio.ai (endpoints derived or overridden). */
512
+ issuer: string;
513
+ clientId: string;
514
+ /** Confidential clients only; public clients (SPA/CLI/native) omit it. */
515
+ clientSecret?: string;
516
+ redirectUri?: string;
517
+ scopes?: string[];
518
+ authorizeUrl?: string;
519
+ tokenUrl?: string;
520
+ deviceAuthorizationUrl?: string;
521
+ jwksUrl?: string;
522
+ /** Required for every public-client token. The private key remains host-owned. */
523
+ dpopSigner: DpopSigner;
524
+ }
525
+ interface PkcePair {
526
+ verifier: string;
527
+ challenge: string;
528
+ }
529
+ /**
530
+ * RFC 7636 PKCE pair (S256). Browser-safe: uses Web Crypto (`globalThis.crypto`),
531
+ * available in Node 20+ AND every browser — no `node:crypto`, so this build
532
+ * imports cleanly in a web SPA and an Electron renderer (XENO AUTH §11, §14.3).
533
+ * Async because Web Crypto's SHA-256 (`subtle.digest`) is async.
534
+ */
535
+ declare function generatePkce(): Promise<PkcePair>;
536
+ declare function generateState(): string;
537
+ /**
538
+ * Build the authorize URL for the Authorization Code + PKCE flow. The caller
539
+ * persists `{ state, verifier }` (e.g. encrypted in a cookie/flow token) and
540
+ * passes the verifier back to {@link exchangeCode}.
541
+ */
542
+ declare function buildAuthorizeUrl(cfg: OidcConfig, args: {
543
+ state: string;
544
+ codeChallenge: string;
545
+ redirectUri?: string;
546
+ scopes?: string[];
547
+ nonce?: string;
548
+ prompt?: 'login';
549
+ maxAge?: number;
550
+ acrValues?: 'urn:xeno:acr:fresh';
551
+ }): string;
552
+ /** Exchange an authorization code for tokens (carries the PKCE verifier). */
553
+ declare function exchangeCode(cfg: OidcConfig, transport: Transport, args: {
554
+ code: string;
555
+ codeVerifier: string;
556
+ redirectUri?: string;
557
+ expectedNonce: string;
558
+ expectedScopes?: string[];
559
+ signal?: AbortSignal;
560
+ }): Promise<TokenSet>;
561
+ /**
562
+ * Refresh tokens. The origin rotates the refresh token on every use
563
+ * (RFC 9700 §2.2.2) — always persist the returned `refreshToken`, and treat a
564
+ * confirmed invalid_grant as re-auth required. A lost reply is uncertain and
565
+ * must not be replayed blindly; the owning client/store retains that state.
566
+ */
567
+ declare function refreshTokens(cfg: OidcConfig, transport: Transport, refreshToken: string): Promise<TokenSet>;
568
+ interface DeviceAuthorization {
569
+ deviceCode: string;
570
+ userCode: string;
571
+ verificationUri: string;
572
+ verificationUriComplete: string | null;
573
+ expiresAt: Date;
574
+ intervalSeconds: number;
575
+ }
576
+ declare function startDeviceAuthorization(cfg: OidcConfig, transport: Transport, scopes?: string[]): Promise<DeviceAuthorization>;
577
+ /**
578
+ * Poll the token endpoint for a device grant, honouring `authorization_pending`
579
+ * / `slow_down` per RFC 8628. Resolves when the user approves, rejects on
580
+ * expiry/denial. `onPending` lets a CLI print progress.
581
+ */
582
+ declare function pollDeviceToken(cfg: OidcConfig, transport: Transport, device: DeviceAuthorization, opts?: {
583
+ sleep?: (ms: number) => Promise<void>;
584
+ signal?: AbortSignal;
585
+ }): Promise<TokenSet>;
586
+
587
+ interface BrokerTokenRequest {
588
+ clientId: string;
589
+ scopes: string[];
590
+ resource: 'https://api.xenostudio.ai';
591
+ childDpopJkt: string;
592
+ }
593
+ /** Transport is supplied by Hub/Electron main after OS peer verification. */
594
+ interface BrokerAdapter {
595
+ getToken(request: BrokerTokenRequest): Promise<TokenSet | null>;
596
+ logout?(): Promise<void>;
597
+ }
598
+
599
+ interface VerifiedAccessClaims {
600
+ iss: string;
601
+ sub: string;
602
+ aud: string | string[];
603
+ exp: number;
604
+ iat: number;
605
+ sid: string;
606
+ client_id: string;
607
+ azp: string;
608
+ scope: string;
609
+ typ: 'at+jwt';
610
+ auth_epoch: number;
611
+ auth_time?: number;
612
+ acr?: string;
613
+ amr?: string[];
614
+ cnf: {
615
+ jkt: string;
616
+ };
617
+ act?: {
618
+ client_id: 'xeno-hub';
619
+ installation_id_hash: string;
620
+ sub?: string;
621
+ };
622
+ }
623
+ interface VerifiedIdClaims {
624
+ iss: string;
625
+ sub: string;
626
+ aud: string | string[];
627
+ exp: number;
628
+ iat: number;
629
+ sid: string;
630
+ auth_time: number;
631
+ nonce?: string;
632
+ email?: string;
633
+ email_verified?: boolean;
634
+ preferred_username?: string;
635
+ name?: string;
636
+ picture?: string;
637
+ }
638
+ interface VerifiedLogoutClaims {
639
+ iss: string;
640
+ aud: string | string[];
641
+ exp: number;
642
+ iat: number;
643
+ jti: string;
644
+ sid?: string;
645
+ sub?: string;
646
+ events: {
647
+ 'http://schemas.openid.net/event/backchannel-logout': Record<string, never>;
648
+ };
649
+ }
650
+ declare function verifyAccessToken(args: {
651
+ token: string;
652
+ transport: Transport;
653
+ issuer: string;
654
+ clientId: string;
655
+ dpopJkt: string;
656
+ jwksUrl?: string;
657
+ expectedScopes?: string[];
658
+ requireBrokerActor?: boolean;
659
+ }): Promise<VerifiedAccessClaims>;
660
+ declare function verifyIdToken(args: {
661
+ token: string;
662
+ transport: Transport;
663
+ issuer: string;
664
+ clientId: string;
665
+ jwksUrl?: string;
666
+ expectedNonce?: string;
667
+ expectedSubject?: string;
668
+ }): Promise<VerifiedIdClaims>;
669
+ /** Verify an OpenID Connect Back-Channel Logout Token before local revocation. */
670
+ declare function verifyLogoutToken(args: {
671
+ token: string;
672
+ transport: Transport;
673
+ issuer: string;
674
+ clientId: string;
675
+ jwksUrl?: string;
676
+ }): Promise<VerifiedLogoutClaims>;
677
+
678
+ /**
679
+ * Configuration for a branch (app) wiring into the XENO account origin.
680
+ *
681
+ * issuer — the origin's auth base (e.g. https://xenostudio.ai)
682
+ * apiBase — the origin's private API base for ledger/authz
683
+ * (e.g. https://api.xenostudio.ai)
684
+ * surface — this app's attribution tag, e.g. 'xeno_post'
685
+ */
686
+ interface XenoAccountClientConfig {
687
+ issuer: string;
688
+ apiBase: string;
689
+ surface: Surface;
690
+ oidc: Omit<OidcConfig, 'issuer'>;
691
+ transport?: TransportOptions;
692
+ /** Where the rotating refresh token lives (default: memory). Desktop/CLI pass
693
+ * a keychainStore; web passes a cookie/memory store (XENO AUTH §11). */
694
+ store?: TokenStore;
695
+ /** Explicit credential override — chain step 2 (XENO_API_KEY / provisioned key /
696
+ * remote-run token). Bypasses interactive paths. Defaults to env XENO_API_KEY. */
697
+ apiKey?: string;
698
+ /** Optional Hub broker. Failure falls through to this app's own refresh. */
699
+ broker?: BrokerAdapter;
700
+ }
701
+ /**
702
+ * The one client every XENO branch uses. Composes identity (OIDC + /me),
703
+ * ledger (idempotent metering + two-phase holds) and authz (ReBAC) behind a
704
+ * single, framework-agnostic facade.
705
+ *
706
+ * Standalone-first: a branch only constructs this in cloud mode (when a
707
+ * platform URL is configured). With it absent, the app runs on its own auth.
708
+ */
709
+ declare class XenoAccountClient {
710
+ readonly surface: Surface;
711
+ readonly account: AccountClient;
712
+ readonly ledger: LedgerClient;
713
+ readonly authz: AuthzClient;
714
+ private readonly oidcConfig;
715
+ private readonly transport;
716
+ private readonly store;
717
+ private readonly apiKey?;
718
+ private readonly broker?;
719
+ private readonly refreshStoreKey;
720
+ private readonly refreshPendingKey;
721
+ private access;
722
+ private user;
723
+ private interactive?;
724
+ private resolutionFlight;
725
+ private generation;
726
+ private locallySignedOut;
727
+ private readonly listeners;
728
+ constructor(cfg: XenoAccountClientConfig);
729
+ /**
730
+ * Return a valid Bearer for the gate, walking the chain:
731
+ * 1 in-memory access token → 2 explicit override (apiKey/XENO_API_KEY) →
732
+ * 3 [broker — host-wired] → 4 this product's own refresh token →
733
+ * 5 interactive sign-in (host-provided; skipped when `silent`) → null.
734
+ */
735
+ getAccessToken(opts?: {
736
+ scopes?: string[];
737
+ silent?: boolean;
738
+ }): Promise<string | null>;
739
+ private resolveSession;
740
+ /** Register the host's interactive sign-in (loopback PKCE / device grant). */
741
+ setInteractiveSignIn(fn: (scopes?: string[]) => Promise<TokenSet>): void;
742
+ isAuthenticated(): boolean;
743
+ currentUser(): Account | null;
744
+ /** Subscribe to login/refresh/logout/backchannel. Returns an unsubscribe fn. */
745
+ onAuthChanged(cb: (a: Account | null) => void): () => void;
746
+ /** Local wipe only, used after durable host-side invalidation/reconciliation. */
747
+ signOutLocal(): Promise<void>;
748
+ /** Revoke this subject-owned session, then always clear local state. */
749
+ signOut(): Promise<{
750
+ serverRevoked: boolean;
751
+ }>;
752
+ /** Step-up protected, subject-keyed global logout. Only authorized clients can call it. */
753
+ signOutEverywhere(): Promise<void>;
754
+ private setUnauthenticated;
755
+ private emit;
756
+ private storeRead;
757
+ private cacheCurrent;
758
+ private exclusiveStore;
759
+ private reserveSignIn;
760
+ private resolveInteractive;
761
+ /** Cache the access token, persist the rotated refresh token, update the user. */
762
+ private applyTokenSet;
763
+ private cancelCommittedSignIn;
764
+ /**
765
+ * Begin "Continue with XENO". Returns the authorize URL to redirect to, plus
766
+ * the `{ state, verifier }` the caller MUST persist (encrypted) to complete
767
+ * the flow in {@link completeSignIn}.
768
+ */
769
+ beginSignIn(args?: {
770
+ redirectUri?: string;
771
+ scopes?: string[];
772
+ fresh?: boolean;
773
+ }): Promise<{
774
+ url: string;
775
+ state: string;
776
+ nonce: string;
777
+ pkce: PkcePair;
778
+ }>;
779
+ /** Complete the code flow: exchange `code` (with the saved verifier) for tokens,
780
+ * then cache the access token + persist the refresh token + set the user. */
781
+ completeSignIn(args: {
782
+ code: string;
783
+ codeVerifier: string;
784
+ expectedNonce: string;
785
+ expectedScopes?: string[];
786
+ redirectUri?: string;
787
+ signal?: AbortSignal;
788
+ }): Promise<TokenSet>;
789
+ private bindSignInCancellation;
790
+ /** Headers for one sender-constrained resource request. */
791
+ authorization(method: string, url: string, opts?: {
792
+ scopes?: string[];
793
+ silent?: boolean;
794
+ }): Promise<RequestAuthorization | null>;
795
+ /** Verify and sender-constrain a previously persisted access token. Server
796
+ * consumers use this for encrypted per-workspace sessions without placing
797
+ * those tokens into the process-global client cache. */
798
+ authorizationForToken(token: string, method: string, url: string, expectedScopes?: string[]): Promise<RequestAuthorization>;
799
+ /** Verify a provider-originated Back-Channel Logout Token. */
800
+ verifyBackchannelLogout(token: string): Promise<VerifiedLogoutClaims>;
801
+ private createProof;
802
+ /** Rotate tokens. Persist the returned refreshToken; a failure means re-auth. */
803
+ refresh(refreshToken: string): Promise<TokenSet>;
804
+ startDeviceLogin(scopes?: string[]): Promise<DeviceAuthorization>;
805
+ awaitDeviceLogin(device: Awaited<ReturnType<XenoAccountClient['startDeviceLogin']>>, opts?: {
806
+ signal?: AbortSignal;
807
+ }): Promise<TokenSet>;
808
+ }
809
+
810
+ interface BffSessionState {
811
+ authenticated: boolean;
812
+ user?: {
813
+ id: string;
814
+ email?: string;
815
+ displayName?: string | null;
816
+ };
817
+ expiresAt?: string;
818
+ }
819
+ /** Browser facade for the server-held web session. It never receives tokens. */
820
+ declare class BffSessionClient {
821
+ private readonly baseUrl;
822
+ private readonly fetchImpl;
823
+ private readonly csrf;
824
+ constructor(baseUrl: string | undefined, fetchImpl: typeof fetch | undefined, csrf: () => string | null);
825
+ loginUrl(returnUrl: string): string;
826
+ session(): Promise<BffSessionState>;
827
+ refresh(idempotencyKey: string): Promise<BffSessionState>;
828
+ logout(): Promise<void>;
829
+ private request;
830
+ }
831
+
832
+ /**
833
+ * redaction — the runtime guard that a token-shaped string never lands in a log
834
+ * (XENO AUTH §12; complements the connector-kit CI lint that fails on
835
+ * `accessToken`/`refreshToken` in a log call). Use `redact(x)` before logging
836
+ * anything that might carry a JWT / opaque token.
837
+ */
838
+ /** Mask any token-shaped substrings, keeping a short prefix for correlation. */
839
+ declare function redact(input: unknown): string;
840
+
841
+ interface DpopReplayStore {
842
+ /** Atomic insert-if-absent, retained through expiresAtMs. Unavailable is an error, not true. */
843
+ consume(input: {
844
+ keyThumbprint: string;
845
+ proofId: string;
846
+ method: string;
847
+ url: string;
848
+ expiresAtMs: number;
849
+ }): Promise<boolean>;
850
+ }
851
+ interface ResourceAuthorizationOptions {
852
+ issuer: string;
853
+ clientIds: readonly string[];
854
+ transport: Transport;
855
+ replayStore: DpopReplayStore;
856
+ /** Trusted origin revocation/epoch read. No token or private proof is passed to logs. */
857
+ sessionActive(claims: Readonly<VerifiedAccessClaims>, token: string): Promise<boolean>;
858
+ }
859
+ interface ResourceRequest {
860
+ method: string;
861
+ url: string;
862
+ authorization: string;
863
+ proof: string;
864
+ scopes?: readonly string[];
865
+ nonce?: string;
866
+ }
867
+ interface ResourceAuthorizationReceipt {
868
+ readonly claims: Readonly<VerifiedAccessClaims>;
869
+ /** Rechecks original identity without consuming the same proof again. */
870
+ revalidate(): Promise<void>;
871
+ }
872
+ /** Canonical resource-server verification. Identity is not a product capability grant. */
873
+ declare function createResourceRequestAuthorizer(options: ResourceAuthorizationOptions): {
874
+ authorize(request: ResourceRequest): Promise<ResourceAuthorizationReceipt>;
875
+ };
876
+ /** Current origin introspection, not a decoded-JWT or positive-cache substitute. */
877
+ declare function createOidcIntrospectionSessionAuthority(options: {
878
+ issuer: string;
879
+ fetchImpl?: typeof fetch;
880
+ timeoutMs?: number;
881
+ }): (claims: Readonly<VerifiedAccessClaims>, token: string) => Promise<boolean>;
882
+
883
+ export { type Account, AccountClient, AccountError, type AccountErrorCode, type AuthorizationInput, type AuthzCheck, AuthzClient, type AuthzResult, type Balance, BffSessionClient, type BffSessionState, type BrokerAdapter, type BrokerTokenRequest, type DeviceAuthorization, type DpopReplayStore, DpopSigner, type Hold, type HoldRequest, type HoldRequestInput, LedgerClient, MICRO_PER_CREDIT, type MeterAggregation, type OAuthTokenResponse, type OidcConfig, type PkcePair, type RequestArgs, type RequestAuthorization, type RequestAuthorizationProvider, type ResourceAuthorizationOptions, type ResourceAuthorizationReceipt, type ResourceRequest, type Surface, type TokenSet, TokenStore, Transport, type TransportOptions, type UsageEvent, type UsageEventInput, type UsageResult, type VerifiedAccessClaims, type VerifiedIdClaims, type VerifiedLogoutClaims, XenoAccountClient, type XenoAccountClientConfig, accountSchema, authzCheckSchema, authzResultSchema, balanceSchema, buildAuthorizeUrl, codeForStatus, createOidcIntrospectionSessionAuthority, createResourceRequestAuthorizer, exchangeCode, fromMicro, generatePkce, generateState, holdRequestSchema, holdSchema, meterAggregationSchema, normalize, oauthTokenResponseSchema, pollDeviceToken, redact, refreshTokens, startDeviceAuthorization, surfaceSchema, toMicro, tokenSetSchema, usageEventSchema, usageResultSchema, verifyAccessToken, verifyIdToken, verifyLogoutToken };