@onesi/genesis 0.0.1-stage → 0.2.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 (113) hide show
  1. package/README.md +29 -0
  2. package/dist/auto.d.ts +1010 -0
  3. package/dist/auto.js +125 -0
  4. package/dist/beacons.d.ts +145 -0
  5. package/dist/beacons.js +148 -0
  6. package/dist/blinds-owner-enrollment.d.ts +280 -0
  7. package/dist/blinds-owner-enrollment.js +169 -0
  8. package/dist/client.d.ts +52 -0
  9. package/dist/client.js +384 -0
  10. package/dist/context.d.ts +50 -0
  11. package/dist/context.js +153 -0
  12. package/dist/dials.d.ts +299 -0
  13. package/dist/dials.js +100 -0
  14. package/dist/errors.d.ts +35 -0
  15. package/dist/errors.js +66 -0
  16. package/dist/flares.d.ts +202 -0
  17. package/dist/flares.js +61 -0
  18. package/dist/fleets.d.ts +218 -0
  19. package/dist/fleets.js +189 -0
  20. package/dist/flocks.d.ts +439 -0
  21. package/dist/flocks.js +98 -0
  22. package/dist/foundry-billing.d.ts +97 -0
  23. package/dist/foundry-billing.js +107 -0
  24. package/dist/foundry.d.ts +424 -0
  25. package/dist/foundry.js +133 -0
  26. package/dist/garden.d.ts +754 -0
  27. package/dist/garden.js +76 -0
  28. package/dist/gateway.d.ts +365 -0
  29. package/dist/gateway.js +82 -0
  30. package/dist/gears.d.ts +226 -0
  31. package/dist/gears.js +42 -0
  32. package/dist/generated/operations.d.ts +4 -0
  33. package/dist/generated/operations.js +65134 -0
  34. package/dist/generated/schema.d.ts +87658 -0
  35. package/dist/generated/schema.js +1 -0
  36. package/dist/genesis.d.ts +9574 -0
  37. package/dist/genesis.js +271 -0
  38. package/dist/genesis.openapi.json +128522 -0
  39. package/dist/henry.d.ts +369 -0
  40. package/dist/henry.js +268 -0
  41. package/dist/hives-cells.d.ts +127 -0
  42. package/dist/hives-cells.js +151 -0
  43. package/dist/hives-environment.d.ts +37 -0
  44. package/dist/hives-environment.js +80 -0
  45. package/dist/hives-functions.d.ts +36 -0
  46. package/dist/hives-functions.js +185 -0
  47. package/dist/hives-marketplace.d.ts +128 -0
  48. package/dist/hives-marketplace.js +187 -0
  49. package/dist/hives-node.d.ts +9 -0
  50. package/dist/hives-node.js +155 -0
  51. package/dist/hives-operations.d.ts +451 -0
  52. package/dist/hives-operations.js +43 -0
  53. package/dist/hives-platform.d.ts +149 -0
  54. package/dist/hives-platform.js +183 -0
  55. package/dist/hives-queue-consumer.d.ts +56 -0
  56. package/dist/hives-queue-consumer.js +95 -0
  57. package/dist/hives-queue-funding.d.ts +28 -0
  58. package/dist/hives-queue-funding.js +81 -0
  59. package/dist/hives-queues.d.ts +137 -0
  60. package/dist/hives-queues.js +143 -0
  61. package/dist/hives-resources-transport.d.ts +23 -0
  62. package/dist/hives-resources-transport.js +204 -0
  63. package/dist/hives-response.d.ts +2 -0
  64. package/dist/hives-response.js +32 -0
  65. package/dist/hives-runtimes.d.ts +34 -0
  66. package/dist/hives-runtimes.js +32 -0
  67. package/dist/hives-sse.d.ts +24 -0
  68. package/dist/hives-sse.js +111 -0
  69. package/dist/hives-topics.d.ts +51 -0
  70. package/dist/hives-topics.js +79 -0
  71. package/dist/hives-upload.d.ts +9 -0
  72. package/dist/hives-upload.js +23 -0
  73. package/dist/hives-volumes.d.ts +64 -0
  74. package/dist/hives-volumes.js +117 -0
  75. package/dist/iam-directory.d.ts +8 -0
  76. package/dist/iam-directory.js +23 -0
  77. package/dist/iam.d.ts +391 -0
  78. package/dist/iam.js +92 -0
  79. package/dist/idempotency.d.ts +7 -0
  80. package/dist/idempotency.js +39 -0
  81. package/dist/index.d.ts +47 -0
  82. package/dist/index.js +37 -0
  83. package/dist/instances.d.ts +200 -0
  84. package/dist/instances.js +43 -0
  85. package/dist/lanes.d.ts +267 -0
  86. package/dist/lanes.js +41 -0
  87. package/dist/minds-agent.d.ts +88 -0
  88. package/dist/minds-agent.js +233 -0
  89. package/dist/minds-engine.d.ts +394 -0
  90. package/dist/minds-engine.js +555 -0
  91. package/dist/minds-owner.d.ts +110 -0
  92. package/dist/minds-owner.js +226 -0
  93. package/dist/minds.d.ts +377 -0
  94. package/dist/minds.js +228 -0
  95. package/dist/orgs.d.ts +405 -0
  96. package/dist/orgs.js +63 -0
  97. package/dist/relays-enrollment.d.ts +33 -0
  98. package/dist/relays-enrollment.js +115 -0
  99. package/dist/runner-grant.d.ts +10 -0
  100. package/dist/runner-grant.js +133 -0
  101. package/dist/runner.d.ts +72 -0
  102. package/dist/runner.js +117 -0
  103. package/dist/scopes.d.ts +310 -0
  104. package/dist/scopes.js +40 -0
  105. package/dist/taps.d.ts +118 -0
  106. package/dist/taps.js +45 -0
  107. package/dist/traces.d.ts +574 -0
  108. package/dist/traces.js +97 -0
  109. package/dist/types.d.ts +98 -0
  110. package/dist/types.js +1 -0
  111. package/dist/urls.d.ts +6 -0
  112. package/dist/urls.js +31 -0
  113. package/package.json +49 -1
@@ -0,0 +1,280 @@
1
+ import type { GenesisClient } from './client.js';
2
+ import type { OperationInput } from './types.js';
3
+ export declare const isBlindsOwnerOperation: (id: string) => boolean;
4
+ /** One original-human operation; all public metadata, no arbitrary signing payload or private key. */
5
+ export declare function blindsOwnerTransport(options: {
6
+ operationId: string;
7
+ input: Record<string, unknown>;
8
+ routing: string;
9
+ url: string;
10
+ credential: () => Promise<string | undefined>;
11
+ fetch: typeof fetch;
12
+ signal?: AbortSignal;
13
+ }): Promise<Response>;
14
+ export declare function blindsModule(client: GenesisClient): {
15
+ credentials: {
16
+ /** Variable names only; values never leave Blinds. */
17
+ list: (init?: {
18
+ signal?: AbortSignal;
19
+ }) => Promise<{
20
+ credentials: string[];
21
+ }>;
22
+ /** Connect a static credential. The value is KMS-encrypted and never returned. */
23
+ store: (body: OperationInput<"blinds_storeCredential">["body"], init?: {
24
+ signal?: AbortSignal;
25
+ idempotencyKey?: string;
26
+ }) => Promise<{
27
+ variable_name: string;
28
+ }>;
29
+ revoke: (variable: string, init?: {
30
+ signal?: AbortSignal;
31
+ idempotencyKey?: string;
32
+ }) => Promise<unknown>;
33
+ /** Revoke every credential in the selected organization. Bulk and irreversible. */
34
+ revokeAll: (init?: {
35
+ signal?: AbortSignal;
36
+ idempotencyKey?: string;
37
+ }) => Promise<{
38
+ revoked: number;
39
+ }>;
40
+ };
41
+ oauth: {
42
+ connections: (init?: {
43
+ signal?: AbortSignal;
44
+ }) => Promise<{
45
+ connections: import("./index.js").components["schemas"]["Blinds.OAuthConnection"][];
46
+ total: number;
47
+ }>;
48
+ /** Catalog providers that use OAuth 2.0. */
49
+ providers: (query?: {
50
+ q?: string;
51
+ category?: string;
52
+ limit?: number;
53
+ offset?: number;
54
+ }, init?: {
55
+ signal?: AbortSignal;
56
+ }) => Promise<{
57
+ providers: import("./index.js").components["schemas"]["Blinds.ProviderSummary"][];
58
+ total: number;
59
+ limit: number;
60
+ offset: number;
61
+ }>;
62
+ };
63
+ /** What a credential can be bound to: auth mode and allowed destination domains. */
64
+ providers: {
65
+ list: (query?: {
66
+ q?: string;
67
+ category?: string;
68
+ limit?: number;
69
+ offset?: number;
70
+ } & {
71
+ auth_mode?: string;
72
+ }, init?: {
73
+ signal?: AbortSignal;
74
+ }) => Promise<{
75
+ providers: import("./index.js").components["schemas"]["Blinds.ProviderSummary"][];
76
+ total: number;
77
+ limit: number;
78
+ offset: number;
79
+ }>;
80
+ get: (slug: string, init?: {
81
+ signal?: AbortSignal;
82
+ }) => Promise<{
83
+ provider: import("./index.js").components["schemas"]["Blinds.ProviderSummary"];
84
+ oauth2?: {
85
+ authorization_url?: string;
86
+ token_url?: string;
87
+ refresh_url?: string | null;
88
+ revocation_url?: string | null;
89
+ default_scopes?: string[];
90
+ scopes_separator?: string;
91
+ supports_refresh?: boolean;
92
+ supports_pkce?: boolean;
93
+ pkce_method?: string | null;
94
+ } | null;
95
+ api_key?: {
96
+ placement?: string;
97
+ key_name?: string;
98
+ prefix?: string | null;
99
+ } | null;
100
+ destination: {
101
+ allowed_domains?: string[];
102
+ allow_subdomains?: boolean;
103
+ require_tls?: boolean;
104
+ allowed_ports?: number[];
105
+ };
106
+ auth_header_template?: Record<string, never> | null;
107
+ }>;
108
+ };
109
+ settings: {
110
+ get: (init?: {
111
+ signal?: AbortSignal;
112
+ }) => Promise<{
113
+ consent_policy: "never" | "per_variable" | "per_delegate";
114
+ dashboard_notifications: boolean;
115
+ email_notifications: boolean;
116
+ slack_notifications: boolean;
117
+ updated_at: string;
118
+ }>;
119
+ update: (body: OperationInput<"blinds_updateSettings">["body"], init?: {
120
+ signal?: AbortSignal;
121
+ idempotencyKey?: string;
122
+ }) => Promise<{
123
+ consent_policy: "never" | "per_variable" | "per_delegate";
124
+ dashboard_notifications: boolean;
125
+ email_notifications: boolean;
126
+ slack_notifications: boolean;
127
+ updated_at: string;
128
+ }>;
129
+ };
130
+ agents: (init?: {
131
+ signal?: AbortSignal;
132
+ }) => Promise<{
133
+ agents: import("./index.js").components["schemas"]["Blinds.AgentSummary"][];
134
+ }>;
135
+ alerts: (init?: {
136
+ signal?: AbortSignal;
137
+ }) => Promise<{
138
+ events: import("./index.js").components["schemas"]["Blinds.ActivityEvent"][];
139
+ }>;
140
+ /** The receipt for a mutation, by the Idempotency-Key it was sent with. Read it after an uncertain outcome; never replay. */
141
+ operations: {
142
+ get: (operation_id: string, init?: {
143
+ signal?: AbortSignal;
144
+ }) => Promise<{
145
+ operation_id: string;
146
+ state: "pending" | "completed";
147
+ response_status?: number | null;
148
+ response?: unknown;
149
+ }>;
150
+ };
151
+ consent: {
152
+ pending: (init?: {
153
+ signal?: AbortSignal;
154
+ }) => Promise<{
155
+ requests: import("./index.js").components["schemas"]["Blinds.ConsentPending"][];
156
+ }>;
157
+ records: (init?: {
158
+ signal?: AbortSignal;
159
+ }) => Promise<{
160
+ records: import("./index.js").components["schemas"]["Blinds.ConsentRecord"][];
161
+ }>;
162
+ approve: (consent_id: string, body: OperationInput<"blinds_approveConsent">["body"], init?: {
163
+ signal?: AbortSignal;
164
+ idempotencyKey?: string;
165
+ }) => Promise<unknown>;
166
+ deny: (consent_id: string, init?: {
167
+ signal?: AbortSignal;
168
+ idempotencyKey?: string;
169
+ }) => Promise<unknown>;
170
+ revoke: (consent_id: string, init?: {
171
+ signal?: AbortSignal;
172
+ idempotencyKey?: string;
173
+ }) => Promise<unknown>;
174
+ };
175
+ delegates: {
176
+ list: (init?: {
177
+ signal?: AbortSignal;
178
+ }) => Promise<{
179
+ delegates: import("./index.js").components["schemas"]["Blinds.Delegate"][];
180
+ }>;
181
+ create: (body: OperationInput<"blinds_createDelegate">["body"], init?: {
182
+ signal?: AbortSignal;
183
+ idempotencyKey?: string;
184
+ }) => Promise<{
185
+ delegate_id: string;
186
+ parent_id?: string | null;
187
+ name: string;
188
+ issuer_did: string;
189
+ delegated_variables: string[];
190
+ max_depth?: number;
191
+ current_depth?: number;
192
+ ttl_seconds?: number;
193
+ created_at?: string;
194
+ expires_at: string;
195
+ }>;
196
+ revoke: (delegate_id: string, init?: {
197
+ signal?: AbortSignal;
198
+ idempotencyKey?: string;
199
+ }) => Promise<unknown>;
200
+ };
201
+ activity: (init?: {
202
+ signal?: AbortSignal;
203
+ }) => Promise<{
204
+ events: import("./index.js").components["schemas"]["Blinds.ActivityEvent"][];
205
+ }>;
206
+ ownerEnrollment: {
207
+ reserve: (body: OperationInput<"blinds_ownerReserve">["body"], init?: {
208
+ signal?: AbortSignal;
209
+ }) => Promise<{
210
+ schemaVersion: 1;
211
+ requestId: string;
212
+ edReservationId: string;
213
+ operationId: string;
214
+ publicKey: string;
215
+ state: "key_ready" | "attached";
216
+ expiresAtMs: number;
217
+ originalOrganizationGeneration: number;
218
+ }>;
219
+ sign: (body: OperationInput<"blinds_ownerSign">["body"], init?: {
220
+ signal?: AbortSignal;
221
+ }) => Promise<{
222
+ schemaVersion: 1;
223
+ requestId: string;
224
+ edReservationId: string;
225
+ enrollmentIntentId: string;
226
+ operationId: string;
227
+ signingPayloadSha256: string;
228
+ signatureMultibase: string;
229
+ }>;
230
+ attach: (body: OperationInput<"blinds_ownerAttach">["body"], init?: {
231
+ signal?: AbortSignal;
232
+ }) => Promise<{
233
+ schemaVersion: 1;
234
+ requestId: string;
235
+ edReservationId: string;
236
+ enrollmentIntentId: string;
237
+ state: "attached";
238
+ creation: {
239
+ intent_id: string;
240
+ operation_id: string;
241
+ creation_receipt_id: string;
242
+ agent_id: string;
243
+ canonical_did: string;
244
+ registered_public_key: string;
245
+ owner: {
246
+ issuer: "https://auth.life.one";
247
+ original_owner: string;
248
+ organization_generation: number;
249
+ scope: {
250
+ platform_id: "blinds";
251
+ organization_id: string;
252
+ workspace_id: string | null;
253
+ project_id: string | null;
254
+ environment_id: "sandbox" | "live";
255
+ };
256
+ };
257
+ };
258
+ }>;
259
+ ensureP256: (body: OperationInput<"blinds_ownerP256Ensure">["body"], init?: {
260
+ signal?: AbortSignal;
261
+ }) => Promise<{
262
+ schemaVersion: 1;
263
+ requestId: string;
264
+ edReservationId: string;
265
+ enrollmentIntentId: string;
266
+ state: "ready";
267
+ dpopPublicJwk: {
268
+ kty: "EC";
269
+ crv: "P-256";
270
+ x: string;
271
+ y: string;
272
+ };
273
+ senderJkt: string;
274
+ }>;
275
+ };
276
+ };
277
+ /** Blinds admits a mutation only with one UUID Idempotency-Key, the logical operation ID it
278
+ * records a receipt under. Take the caller's (input.idempotency_key or the header) so a retry
279
+ * after an uncertain outcome is recognised, else mint a new one. Never retried here. */
280
+ export declare function blindsOperationKey(operationId: string, input: Record<string, unknown>, headers: Record<string, string>): string;
@@ -0,0 +1,169 @@
1
+ import { GenesisError } from './errors.js';
2
+ const operations = ['blinds_ownerReserve', 'blinds_ownerSign', 'blinds_ownerAttach', 'blinds_ownerP256Ensure'];
3
+ export const isBlindsOwnerOperation = (id) => operations.includes(id);
4
+ const uuid = (v) => typeof v === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(v);
5
+ /** One original-human operation; all public metadata, no arbitrary signing payload or private key. */
6
+ export async function blindsOwnerTransport(options) {
7
+ const { operationId, input, signal } = options;
8
+ const error = (status, type) => new GenesisError({ status, type, operationId,
9
+ message: 'Blinds owner enrollment was not confirmed. Preserve the original operation and locators; do not replay an unknown outcome automatically.' });
10
+ if (options.routing !== 'gateway')
11
+ throw error(0, 'invalid_request');
12
+ const body = input.body;
13
+ if (!body || typeof body !== 'object' || Array.isArray(body) || body.schemaVersion !== 1 || !uuid(body.requestId))
14
+ throw error(0, 'invalid_request');
15
+ const serialized = JSON.stringify(body);
16
+ if (new TextEncoder().encode(serialized).byteLength > 2048)
17
+ throw error(0, 'invalid_request');
18
+ const controller = new AbortController(), cancel = () => controller.abort(signal?.reason);
19
+ if (signal?.aborted)
20
+ cancel();
21
+ else
22
+ signal?.addEventListener('abort', cancel, { once: true });
23
+ const timer = setTimeout(() => controller.abort(), 12_000);
24
+ let abort = () => { };
25
+ const bounded = async (promise) => {
26
+ controller.signal.throwIfAborted();
27
+ try {
28
+ return await Promise.race([promise, new Promise((_, reject) => { abort = () => reject(error(0, 'transport_error')); controller.signal.addEventListener('abort', abort, { once: true }); })]);
29
+ }
30
+ finally {
31
+ controller.signal.removeEventListener('abort', abort);
32
+ }
33
+ };
34
+ try {
35
+ const credential = await bounded(options.credential());
36
+ controller.signal.throwIfAborted();
37
+ if (!credential)
38
+ throw error(401, 'unauthenticated');
39
+ const response = await bounded(options.fetch(options.url, { method: 'POST', body: serialized,
40
+ headers: { authorization: `Bearer ${credential}`, 'content-type': 'application/json', accept: 'application/json', 'x-l1fe-request-id': body.requestId },
41
+ redirect: 'error', cache: 'no-store', signal: controller.signal }).then(response => { if (controller.signal.aborted) {
42
+ void response.body?.cancel().catch(() => { });
43
+ throw error(0, 'transport_error');
44
+ } return response; }));
45
+ if (response.status !== 200) {
46
+ void response.body?.cancel().catch(() => { });
47
+ throw error(response.status, 'unconfirmed_operation');
48
+ }
49
+ if (!response.body || !/^application\/json(?:;|$)/i.test(response.headers.get('content-type') ?? ''))
50
+ throw error(0, 'invalid_response');
51
+ const reader = response.body.getReader(), chunks = [];
52
+ let length = 0;
53
+ const stop = () => { void reader.cancel().catch(() => { }); };
54
+ controller.signal.addEventListener('abort', stop, { once: true });
55
+ try {
56
+ for (;;) {
57
+ const r = await bounded(reader.read());
58
+ if (r.done)
59
+ break;
60
+ length += r.value.length;
61
+ if (length > 16384)
62
+ throw error(0, 'invalid_response');
63
+ chunks.push(r.value);
64
+ }
65
+ }
66
+ finally {
67
+ controller.signal.removeEventListener('abort', stop);
68
+ stop();
69
+ try {
70
+ reader.releaseLock();
71
+ }
72
+ catch { /* pending cancelled read */ }
73
+ }
74
+ const data = new Uint8Array(length);
75
+ let offset = 0;
76
+ for (const chunk of chunks) {
77
+ data.set(chunk, offset);
78
+ offset += chunk.length;
79
+ }
80
+ let value;
81
+ try {
82
+ value = JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(data));
83
+ }
84
+ catch {
85
+ throw error(0, 'invalid_response');
86
+ }
87
+ if (!value || value.schemaVersion !== 1 || value.requestId !== body.requestId || !uuid(value.edReservationId)
88
+ || operationId === 'blinds_ownerReserve' && value.operationId !== body.operationId
89
+ || operationId !== 'blinds_ownerReserve' && (value.edReservationId !== body.edReservationId || value.enrollmentIntentId !== body.enrollmentIntentId))
90
+ throw error(0, 'invalid_response');
91
+ return Response.json(value, { headers: { 'cache-control': 'no-store' } });
92
+ }
93
+ catch (e) {
94
+ if (e instanceof GenesisError)
95
+ throw e;
96
+ throw error(0, 'transport_error');
97
+ }
98
+ finally {
99
+ clearTimeout(timer);
100
+ controller.abort();
101
+ signal?.removeEventListener('abort', cancel);
102
+ }
103
+ }
104
+ export function blindsModule(client) {
105
+ const write = (id, input, init = {}) => client.request(id, { ...input, ...(init.idempotencyKey ? { idempotency_key: init.idempotencyKey } : {}) }, { signal: init.signal });
106
+ const read = (id, init = {}, input = {}) => client.request(id, input, init);
107
+ return {
108
+ credentials: {
109
+ /** Variable names only; values never leave Blinds. */
110
+ list: (init) => read('blinds_listCredentials', init),
111
+ /** Connect a static credential. The value is KMS-encrypted and never returned. */
112
+ store: (body, init) => write('blinds_storeCredential', { body }, init),
113
+ revoke: (variable, init) => write('blinds_deleteCredential', { variable }, init),
114
+ /** Revoke every credential in the selected organization. Bulk and irreversible. */
115
+ revokeAll: (init) => write('blinds_revokeAllCredentials', { all: 'true' }, init),
116
+ },
117
+ oauth: {
118
+ connections: (init) => read('blinds_listOAuthConnections', init),
119
+ /** Catalog providers that use OAuth 2.0. */
120
+ providers: (query = {}, init) => read('blinds_listOAuthProviders', init, query),
121
+ },
122
+ /** What a credential can be bound to: auth mode and allowed destination domains. */
123
+ providers: {
124
+ list: (query = {}, init) => read('blinds_listProviders', init, query),
125
+ get: (slug, init) => read('blinds_getProvider', init, { slug }),
126
+ },
127
+ settings: {
128
+ get: (init) => read('blinds_getSettings', init),
129
+ update: (body, init) => write('blinds_updateSettings', { body }, init),
130
+ },
131
+ agents: (init) => read('blinds_listAgents', init),
132
+ alerts: (init) => read('blinds_listAlerts', init),
133
+ /** The receipt for a mutation, by the Idempotency-Key it was sent with. Read it after an uncertain outcome; never replay. */
134
+ operations: { get: (operation_id, init) => read('blinds_getOperation', init, { operation_id }) },
135
+ consent: {
136
+ pending: (init) => read('blinds_listPendingConsent', init),
137
+ records: (init) => read('blinds_listConsentRecords', init),
138
+ approve: (consent_id, body, init) => write('blinds_approveConsent', { consent_id, body }, init),
139
+ deny: (consent_id, init) => write('blinds_denyConsent', { consent_id }, init),
140
+ revoke: (consent_id, init) => write('blinds_revokeConsent', { consent_id }, init),
141
+ },
142
+ delegates: {
143
+ list: (init) => read('blinds_listDelegates', init),
144
+ create: (body, init) => write('blinds_createDelegate', { body }, init),
145
+ revoke: (delegate_id, init) => write('blinds_revokeDelegate', { delegate_id }, init),
146
+ },
147
+ activity: (init) => read('blinds_listActivity', init),
148
+ ownerEnrollment: {
149
+ reserve: (body, init = {}) => client.request('blinds_ownerReserve', { body }, init),
150
+ sign: (body, init = {}) => client.request('blinds_ownerSign', { body }, init),
151
+ attach: (body, init = {}) => client.request('blinds_ownerAttach', { body }, init),
152
+ ensureP256: (body, init = {}) => client.request('blinds_ownerP256Ensure', { body }, init),
153
+ }
154
+ };
155
+ }
156
+ const blindsKey = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
157
+ /** Blinds admits a mutation only with one UUID Idempotency-Key, the logical operation ID it
158
+ * records a receipt under. Take the caller's (input.idempotency_key or the header) so a retry
159
+ * after an uncertain outcome is recognised, else mint a new one. Never retried here. */
160
+ export function blindsOperationKey(operationId, input, headers) {
161
+ const names = Object.keys(headers).filter(name => name.toLowerCase() === 'idempotency-key');
162
+ const given = [...names.map(name => headers[name]), ...(input.idempotency_key === undefined ? [] : [input.idempotency_key])];
163
+ if (new Set(given).size > 1 || given.some(v => typeof v !== 'string' || !blindsKey.test(v))) {
164
+ throw new GenesisError({ status: 0, type: 'invalid_request', message: 'A Blinds mutation takes one UUID idempotency key.', operationId });
165
+ }
166
+ for (const name of names)
167
+ delete headers[name];
168
+ return headers['idempotency-key'] = given[0] ?? crypto.randomUUID();
169
+ }
@@ -0,0 +1,52 @@
1
+ import { type OperationId } from './generated/operations.js';
2
+ import type { OperationInput, OperationOutput, OperationMeta } from './types.js';
3
+ /** The Genesis API gateway. `https://console.life.one/api` remains an alias for the same gateway. */
4
+ export declare const DEFAULT_BASE_URL = "https://os.one.ml/api";
5
+ /** Returns a bearer credential (API key, M2M token or saved login token), or undefined. */
6
+ export type CredentialProvider = () => string | undefined | Promise<string | undefined>;
7
+ export interface GenesisOptions {
8
+ /** One account org API key (WorkOS). Env: GENESIS_API_KEY */
9
+ apiKey?: string;
10
+ /** WorkOS M2M access token or session token. Env: GENESIS_TOKEN */
11
+ token?: string;
12
+ /** Fallback credential source, e.g. the CLI's saved `genesis login` (keychain). */
13
+ credentials?: CredentialProvider;
14
+ /** Gateway base URL. Env: GENESIS_BASE_URL. Default https://os.one.ml/api */
15
+ baseUrl?: string;
16
+ /**
17
+ * 'gateway' (default): call os.one.ml/api/v1/<service>/... (Genesis API gateway)
18
+ * 'direct': call each service's own upstream host (for local dev or when the gateway is unavailable;
19
+ * the credential must then be one that service itself accepts).
20
+ */
21
+ routing?: 'gateway' | 'direct';
22
+ /** Per-service upstream override in direct mode, e.g. { relays: 'http://localhost:3000/api' }. */
23
+ upstreams?: Record<string, string>;
24
+ fetch?: typeof fetch;
25
+ headers?: Record<string, string>;
26
+ userAgent?: string;
27
+ }
28
+ export declare class GenesisClient {
29
+ readonly baseUrl: string;
30
+ readonly routing: 'gateway' | 'direct';
31
+ private readonly opts;
32
+ private readonly fetchImpl;
33
+ protected get contextFetch(): typeof fetch;
34
+ constructor(opts?: GenesisOptions);
35
+ static operations: Readonly<Record<OperationId, OperationMeta>>;
36
+ static services: import("./types.js").ServiceMeta[];
37
+ /** Resolve the credential: explicit apiKey > token > env GENESIS_API_KEY > GENESIS_TOKEN > provider. */
38
+ credential(): Promise<string | undefined>;
39
+ /** Build the URL for an operation (exposed for tests and `--dry-run`). */
40
+ url(operationId: OperationId, input?: Record<string, unknown>): string;
41
+ /** Call any Genesis operation by id, fully typed from the merged spec. */
42
+ request<K extends OperationId>(operationId: K, input?: OperationInput<K>, init?: {
43
+ signal?: AbortSignal;
44
+ headers?: Record<string, string>;
45
+ }): Promise<OperationOutput<K>>;
46
+ /** Raw Response. Completed Hives guest responses retain their actual status, including non-2xx. */
47
+ raw(operationId: OperationId, input?: Record<string, unknown>, init?: {
48
+ signal?: AbortSignal;
49
+ headers?: Record<string, string>;
50
+ }): Promise<Response>;
51
+ private dispatch;
52
+ }