@k9o/core 1.1.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@ export { GateClient } from '@k9o/gate';
10
10
  import { KiboClient } from '@k9o/kibo';
11
11
  export { AttestationTier, CreateSecretInput, KiboClient, KmsProvider, ListSecretsInput, ListSecretsResult, MoveSecretResult, RevealChallenge, RevealSecretResult, RotateSecretResult, SecretSummary, SecretVisibility, StoreZkDekInput, UpdateSecretInput, UpdateSecretResult, ZkDekHandle, ZkDekRecord } from '@k9o/kibo';
12
12
  export { KError, KErrorWire, kerrorFromWire } from './kerror.js';
13
- export { orgPath, platformPath, projectPath, resolveBaseUrl, validateBaseUrl, validateSlug } from './url-grammar.js';
13
+ export { ApiHost, DEFAULT_BASE_URL, orgPath, parseApiHost, platformPath, projectPath, resolveBaseUrl, validateBaseUrl, validateSlug } from './url-grammar.js';
14
14
 
15
15
  /**
16
16
  * Data-plane DSL: `client.from(collection).select()` etc.
@@ -164,45 +164,94 @@ declare function makeFromFactory(config: HttpClientConfig): (collection: string)
164
164
  * `discovery.ts`):
165
165
  * - `client.projects.list()` → GET /projects
166
166
  * - `client.projects.create({...})` → POST /projects
167
- * - `client.projects.get(slug)` → GET /@<projectSlug>/project
168
- * - `client.projects.update(slug,...)` → PATCH /@<projectSlug>/project
167
+ * - `client.projects.get(slug)` → GET /projects/<projectSlug>
168
+ * - `client.projects.update(slug,...)` → PATCH /projects/<projectSlug>
169
169
  *
170
- * The `list` + `create` operations operate org-plane and require
171
- * `orgSlug` to be bound on the client (or the bearer token to carry
172
- * an org context). The `get` + `update` operations
173
- * operate member-plane and use the project slug.
170
+ * All four operations are org-plane: the client needs an org context
171
+ * (an `orgSlug` or a bearer token that carries one). Input property
172
+ * names are the gateway's body property names.
174
173
  *
175
- * Per: all methods throw KError on non-2xx.
174
+ * All methods throw KError on non-2xx.
176
175
  */
177
176
 
178
177
  /**
179
- * Project shape. Fields are typed per the canonical shape;
180
- * the gateway may return additional fields that this type doesn't
181
- * narrow — those are accessible via `as unknown as` widening.
178
+ * Project record, as the gateway returns it. Field names are passed through unchanged.
179
+ * Lists and creates also carry `capabilities`; lists add `accessLevel`.
182
180
  */
183
181
  type Project = {
184
182
  /** `proj_<base62>`. */
185
183
  id: string;
186
184
  slug: string;
187
- name: string;
188
- custodyMode: "managed" | "byok" | "hyok";
189
- createdAt: string;
190
- updatedAt: string | null;
191
185
  orgId: string;
186
+ displayName: string;
187
+ description: string | null;
188
+ productScope: string;
189
+ /** Region code of the project's data. */
190
+ region: string;
191
+ custodyMode: "PLATFORM_MANAGED" | "SKR" | "BYOK" | "HYOK";
192
+ /** `provisioning` while the project is being set up, then `active`; other values may appear. */
193
+ status: string;
194
+ /** The caller's role on the project, or `null` when the caller is not a member. */
195
+ role: string | null;
196
+ deletedAt: string | null;
197
+ createdAt: string;
198
+ /** Soft-delete retention window in days. */
199
+ softDeleteRetentionDays: number;
200
+ /** Regions the project's data may live in; `[region]` for a single-region project. */
201
+ residencySet: ReadonlyArray<string>;
202
+ /** `"strict"`, or `{ fallbackRegion }` when a catch-all region is set. */
203
+ residencyPolicy: "strict" | {
204
+ fallbackRegion: string;
205
+ };
206
+ processingContexts: ReadonlyArray<string>;
207
+ /** Present on list and create responses: what the caller may write. */
208
+ capabilities?: {
209
+ authFlows: {
210
+ write: boolean;
211
+ };
212
+ authProviders: {
213
+ write: boolean;
214
+ };
215
+ } | undefined;
216
+ /** Present on list responses: `member` or `locked`. */
217
+ accessLevel?: "member" | "locked" | undefined;
192
218
  };
193
219
  /**
194
220
  * Project-creation input.
195
221
  */
196
222
  type CreateProjectInput = {
197
- slug: string;
198
- name: string;
199
- custodyMode?: "managed" | "byok" | "hyok" | undefined;
223
+ /** Display name (1 to 128 characters). Required. */
224
+ displayName: string;
225
+ /** URL slug (lowercase); the gateway derives one from `displayName` when omitted. */
226
+ slug?: string | undefined;
227
+ productScope?: "core" | "kibo" | undefined;
228
+ /** Region code of the project's data. */
229
+ region?: string | undefined;
230
+ defaultProjectRegion?: string | undefined;
231
+ custodyMode?: "PLATFORM_MANAGED" | "SKR" | "BYOK" | "HYOK" | undefined;
232
+ processingContexts?: ReadonlyArray<string> | undefined;
233
+ execSeamConfined?: boolean | undefined;
234
+ showroomVertical?: string | undefined;
235
+ persona?: string | undefined;
236
+ showroomLocale?: {
237
+ code: string;
238
+ currency: string;
239
+ moneyScale: number;
240
+ } | undefined;
241
+ /** Makes a retried create return the first result instead of a second project. */
242
+ idempotencyKey?: string | undefined;
200
243
  };
201
244
  /**
202
245
  * Project-update patch.
203
246
  */
204
247
  type UpdateProjectInput = {
205
- name?: string;
248
+ slug?: string | undefined;
249
+ displayName?: string | undefined;
250
+ description?: string | null | undefined;
251
+ region?: string | undefined;
252
+ productScope?: string | undefined;
253
+ softDeleteRetentionDays?: number | undefined;
254
+ processingContexts?: ReadonlyArray<string> | undefined;
206
255
  };
207
256
  /**
208
257
  * Factory — produces the `client.projects.*` namespace bound to the
@@ -234,7 +283,8 @@ declare function makeProjectsNamespace(config: HttpClientConfig): {
234
283
  * `storage-locations.ts` and is unchanged.
235
284
  *
236
285
  * Bucket names are logical: the platform resolves them to a physical store, so a developer never sees a
237
- * physical bucket or key. Signed URLs require an explicit `expiresIn` (no default, max 7 days).
286
+ * physical bucket or key. Signed URLs require an explicit `expiresIn` (no default). The gateway accepts 1 to 604800 seconds but never
287
+ * signs for longer than 900 seconds, and the answer's `expiresIn` is the lifetime it actually used.
238
288
  *
239
289
  * What is NOT here yet, by design: a signed PUT (a method- and content-type-bound upload URL). The gateway has
240
290
  * no route for it; uploads go through the multipart `upload` below.
@@ -243,14 +293,15 @@ declare function makeProjectsNamespace(config: HttpClientConfig): {
243
293
  /** A bucket. */
244
294
  type StorageBucket = {
245
295
  name: string;
246
- /** `true` removes the authentication requirement on GET; per-object access policies still apply. */
296
+ /** Stored and returned, not enforced: setting it does not yet change who can read objects. */
247
297
  public: boolean;
248
298
  /** Bytes; `null` = no limit. */
249
299
  fileSizeLimit: number | null;
250
300
  /** MIME allow-list; empty = any. */
251
301
  allowedMimeTypes: string[];
302
+ /** Stored and returned, not enforced: the platform does not keep object versions yet. */
252
303
  versioning: boolean;
253
- /** Lifecycle auto-expiry in days; `null` = never. */
304
+ /** Stored and returned, not enforced: nothing deletes objects after this many days yet. `null` = never. */
254
305
  deleteAfterDays: number | null;
255
306
  createdAt: string;
256
307
  updatedAt: string;
@@ -261,20 +312,26 @@ type StorageBucket = {
261
312
  };
262
313
  /** Options for `createBucket`. The bucket name is the first argument (3 to 63 chars, lowercase, digits, hyphens). */
263
314
  type CreateBucketOptions = {
315
+ /** Stored, not enforced yet (see `StorageBucket.public`). */
264
316
  public?: boolean;
265
317
  fileSizeLimit?: number;
266
318
  allowedMimeTypes?: string[] | null;
319
+ /** Stored, not enforced yet. */
267
320
  versioning?: boolean;
321
+ /** Stored, not enforced yet. */
268
322
  deleteAfterDays?: number;
269
323
  /** Link the bucket to one of the project's storage locations (see `client.storage.locations`). */
270
324
  byosBindingId?: string;
271
325
  };
272
326
  /** Fields you may change on a bucket. `null` clears a limit; `allowedMimeTypes: null` allows any type. */
273
327
  type UpdateBucketOptions = {
328
+ /** Stored, not enforced yet. */
274
329
  public?: boolean;
275
330
  fileSizeLimit?: number | null;
276
331
  allowedMimeTypes?: string[] | null;
332
+ /** Stored, not enforced yet. */
277
333
  versioning?: boolean;
334
+ /** Stored, not enforced yet. */
278
335
  deleteAfterDays?: number | null;
279
336
  /** `null` unlinks the bucket from its storage location. */
280
337
  byosBindingId?: string | null;
@@ -294,11 +351,15 @@ type UploadOptions = {
294
351
  metadata?: Record<string, string>;
295
352
  };
296
353
  type SignedUrlOptions = {
297
- /** Seconds, required: 1 to 604800 (7 days). There is deliberately no default. */
354
+ /**
355
+ * Seconds, required: 1 to 604800. There is deliberately no default. The gateway clamps the lifetime to 900
356
+ * seconds (15 minutes); read `expiresIn` in the answer for the lifetime you got.
357
+ */
298
358
  expiresIn: number;
299
359
  /** `true` makes the download an attachment (`Content-Disposition: attachment`). */
300
360
  download?: boolean;
301
361
  };
362
+ /** `expiresIn` is the lifetime the gateway used: at most 900 seconds, even when you asked for more. */
302
363
  type SignedUrl = {
303
364
  signedUrl: string;
304
365
  expiresIn: number;
@@ -429,64 +490,6 @@ declare function makeStorageNamespace(config: HttpClientConfig): {
429
490
  };
430
491
  };
431
492
 
432
- /**
433
- * `client.metadata.*` — cross-surface metadata query (`k9o.metadata.*`).
434
- *
435
- * Client-side surface for `POST /@:projectSlug/metadata/query`. The wire shape is fixed here ahead of the
436
- * server route: until the gateway ships that route, calling `.execute()` returns a 404 rather than a result.
437
- * Once it is available, only `telemetry:*` surfaces return data at first; collection and storage metadata
438
- * follow as their server-side schemas land.
439
- *
440
- * `textSearch`/`vectorSearch` are explicitly a later increment (Inc 5) — not implemented
441
- * here; adding stub methods for an unspecified future mode would be speculative, not spec-grounded.
442
- */
443
-
444
- /** The three cross-surface slices. */
445
- type MetadataSlice = "collection" | "storage" | "telemetry";
446
- /** operator vocabulary (= JSON-policy set), mirrored verbatim from the gateway's
447
- * `metadata-query-parse.ts` so a typo can't silently pass client-side and fail only server-side. */
448
- declare const METADATA_OPERATORS: readonly ["eq", "neq", "gt", "gte", "lt", "lte", "contains", "startsWith", "endsWith", "in", "notIn", "and", "or", "not"];
449
- type MetadataOperator = (typeof METADATA_OPERATORS)[number];
450
- /** A surface label `<slice>:<scope>`, e.g. `collection:posts`, `storage:images`,
451
- * `telemetry:auth.session.created`. */
452
- type MetadataSurface = `${MetadataSlice}:${string}`;
453
- type MetadataWhereClause = {
454
- readonly field: string;
455
- readonly op: MetadataOperator;
456
- readonly value: unknown;
457
- };
458
- /**
459
- * One result row: "each record carries its surface + scope + the queried metadata
460
- * fields plus a back-reference id" — `recordId` (collection), `objectPath` (storage), or `eventId`
461
- * (telemetry), depending on which surface the row came from. Exact field names are provisional
462
- * pending Inc 2 landing a concrete response schema; kept loose (`metadata: Record<string, unknown>`)
463
- * rather than guessing a shape that isn't coined in code anywhere yet.
464
- */
465
- type MetadataQueryRecord = {
466
- surface: MetadataSurface;
467
- scope: string;
468
- recordId?: string;
469
- objectPath?: string;
470
- eventId?: string;
471
- metadata: Record<string, unknown>;
472
- };
473
- type MetadataQueryResult = {
474
- records: readonly MetadataQueryRecord[];
475
- nextCursor: string | null;
476
- };
477
- /** The `k9o.metadata.from(...).where(...).limit(...).execute()` builder. Immutable —
478
- * every chained call returns a new builder, so a partially-built query can be safely reused/branched. */
479
- type MetadataQueryBuilder = {
480
- where(field: string, op: MetadataOperator, value: unknown): MetadataQueryBuilder;
481
- limit(n: number): MetadataQueryBuilder;
482
- cursor(c: string | null): MetadataQueryBuilder;
483
- execute(): Promise<Envelope<MetadataQueryResult>>;
484
- };
485
- declare function makeMetadataNamespace(config: HttpClientConfig): {
486
- /** Start a cross-surface metadata query against one or more surfaces. */
487
- from(surface: MetadataSurface | readonly MetadataSurface[]): MetadataQueryBuilder;
488
- };
489
-
490
493
  /**
491
494
  * Migration lifecycle SDK — `client.migrations.*`.
492
495
  *
@@ -660,32 +663,73 @@ type Migration = {
660
663
  policy?: MigrationPolicy;
661
664
  };
662
665
  /**
663
- * Applied-migration record returned by `list` + `get`.
666
+ * Applied-migration record returned by `list` + `get`. `get` also carries `opPayload`
667
+ * (the migration body as submitted, or `null` for old migrations).
664
668
  */
665
669
  type AppliedMigration = {
666
670
  version: number;
667
671
  slug: string;
668
672
  checksum: string;
669
673
  appliedAt: string;
674
+ noPolicy: boolean;
675
+ affectedCollections: ReadonlyArray<string>;
676
+ opPayload?: unknown;
670
677
  };
678
+ /** A migration that `apply` or `applyPending` just applied. Carries no `appliedAt`. */
679
+ type AppliedMigrationRow = {
680
+ version: number;
681
+ slug: string;
682
+ checksum: string;
683
+ };
684
+ /** A migration `apply` left alone, e.g. `already_applied`. */
685
+ type SkippedMigrationRow = {
686
+ version: number;
687
+ slug: string;
688
+ reason: string;
689
+ };
690
+ /** Result of `apply`. */
691
+ type ApplyMigrationsResult = {
692
+ applied: ReadonlyArray<AppliedMigrationRow>;
693
+ skipped: ReadonlyArray<SkippedMigrationRow>;
694
+ };
695
+ /** Result of `applyPending`: `pendingId` is the queued row that was applied. */
696
+ type ApplyPendingResult = ApplyMigrationsResult & {
697
+ pendingId: string;
698
+ };
699
+ type PendingMigrationStatus = "queued" | "pending_approval" | "applied" | "rejected" | "cancelled";
671
700
  /**
672
701
  * Pending migration record returned by `listPending`.
673
702
  */
674
703
  type PendingMigration = {
675
- pendingId: string;
704
+ id: string;
676
705
  version: number;
677
706
  slug: string;
678
707
  checksum: string;
679
- submittedAt: string;
680
- submittedBy: string;
708
+ status: PendingMigrationStatus;
709
+ affectedCollections: ReadonlyArray<string>;
710
+ /** Approval that gates a `pending_approval` row, else `null`. */
711
+ approvalId: string | null;
712
+ queuedAt: string;
713
+ queuedBy: string;
714
+ decidedAt: string | null;
715
+ decidedBy: string | null;
716
+ decisionReason: string | null;
717
+ };
718
+ /** One row of the `queue` answer. */
719
+ type QueuedMigration = {
720
+ /** The pending id to pass to `applyPending`, `rejectPending` or `deletePending`. */
721
+ id: string;
722
+ version: number;
723
+ slug: string;
724
+ status: "queued" | "pending_approval";
725
+ approvalId: string | null;
726
+ affectedCollections: ReadonlyArray<string>;
681
727
  };
682
728
  declare function makeMigrationsNamespace(config: HttpClientConfig): {
683
729
  /** Apply migrations immediately (PROJECT_ADMIN minimum). */
684
730
  apply(input: {
685
731
  migrations: ReadonlyArray<Migration>;
686
- }): Promise<Envelope<{
687
- applied: ReadonlyArray<AppliedMigration>;
688
- }>>;
732
+ }): Promise<Envelope<ApplyMigrationsResult>>;
689
733
  /** List applied migrations on the project. */
690
734
  list(): Promise<Envelope<ReadonlyArray<AppliedMigration>>>;
691
735
  /** Get a single applied migration by version. */
@@ -693,27 +737,29 @@ declare function makeMigrationsNamespace(config: HttpClientConfig): {
693
737
  /** Queue migrations for maker-checker approval. */
694
738
  queue(input: {
695
739
  migrations: ReadonlyArray<Migration>;
696
- }): Promise<Envelope<{
697
- pending: ReadonlyArray<PendingMigration>;
698
- }>>;
699
- /** List pending (queued, not yet approved) migrations. */
700
- listPending(): Promise<Envelope<ReadonlyArray<PendingMigration>>>;
740
+ }): Promise<Envelope<ReadonlyArray<QueuedMigration>>>;
741
+ /** List pending migrations: `queued` ones by default, or those with the given `status`. */
742
+ listPending(opts?: {
743
+ status?: PendingMigrationStatus | undefined;
744
+ }): Promise<Envelope<ReadonlyArray<PendingMigration>>>;
701
745
  /**
702
746
  * Apply a queued migration by id (same-actor fast path — floors at
703
747
  * PROJECT_ADMIN; a `pending_approval` row, i.e. a protected-collection
704
748
  * migration awaiting a distinct-admin's review, is refused here and
705
749
  * needs its own approval flow, not this call).
706
750
  */
707
- applyPending(pendingId: string): Promise<Envelope<AppliedMigration>>;
751
+ applyPending(pendingId: string): Promise<Envelope<ApplyPendingResult>>;
708
752
  /** Reject a pending migration (transitions to rejected; does not apply). */
709
753
  rejectPending(pendingId: string, input?: {
710
754
  reason?: string;
711
755
  }): Promise<Envelope<{
712
- rejected: boolean;
756
+ pendingId: string;
757
+ status: "rejected";
713
758
  }>>;
714
759
  /** Delete a pending migration from the queue. */
715
760
  deletePending(pendingId: string): Promise<Envelope<{
716
- deleted: boolean;
761
+ pendingId: string;
762
+ status: "cancelled";
717
763
  }>>;
718
764
  };
719
765
 
@@ -723,15 +769,14 @@ declare function makeMigrationsNamespace(config: HttpClientConfig): {
723
769
  * Backed by the gateway functions and invoke routes.
724
770
  *
725
771
  * Wire mapping:
726
- * - `deploy({ name, runtime, code, ... })` → POST /@<slug>/functions
772
+ * - `deploy({ name, runtime, tier, artifactKey, version })` → POST /@<slug>/functions
727
773
  * - `list()` → GET /@<slug>/functions
728
774
  * - `get(name)` → GET /@<slug>/functions/<name>
729
775
  * - `delete(name)` → DELETE /@<slug>/functions/<name>
730
776
  * - `invoke(name, payload)` → POST /@<slug>/functions/<name>/invoke
731
777
  *
732
- * Per: deploy requires PROJECT_ADMIN; invoke authority is per
733
- * function manifest. Per: deploy returns 202 with status
734
- * `deploying`; the function is ready when status flips to `active`.
778
+ * Deploy requires PROJECT_ADMIN and returns with status `deploying`; the
779
+ * function is ready when status flips to `active`.
735
780
  */
736
781
 
737
782
  /**
@@ -741,50 +786,78 @@ type FunctionRecord = {
741
786
  /** `fn_<base62>`. */
742
787
  id: string;
743
788
  name: string;
744
- runtime: "wasm" | "bun" | "node";
745
- status: "deploying" | "active" | "retired" | "failed";
746
- tier: "low" | "medium" | "high";
789
+ runtime: DeployFunctionInput["runtime"];
790
+ tier: "gateway" | "sandbox";
791
+ entryPoint: string;
792
+ version: string;
793
+ status: "deploying" | "active" | "error" | "retired";
794
+ /** Who manages the function: a developer deploy, or an extension (`extension:<id>`). */
795
+ source: string;
796
+ description: string | null;
747
797
  createdAt: string;
748
- updatedAt: string | null;
798
+ deployedAt: string | null;
799
+ retiredAt: string | null;
800
+ errorDetail: string | null;
749
801
  };
750
802
  /**
751
- * Deploy input. The `code` field is the runtime bundle (base64-encoded
752
- * WASM or JS source).
803
+ * Deploy input. The function's bytes are uploaded first (the gateway's
804
+ * function-artifact upload returns the `artifactKey`); deploy references
805
+ * that artifact.
753
806
  */
754
807
  type DeployFunctionInput = {
808
+ /** Function name (1 to 128 characters). */
755
809
  name: string;
756
- runtime: "wasm" | "bun" | "node";
757
- code: string;
758
- tier?: "low" | "medium" | "high";
759
- config?: Record<string, unknown>;
810
+ runtime: "bun" | "python" | "go" | "java" | "kotlin" | "dotnet" | "swift" | "php" | "ruby" | "rust" | "tinygo" | "zig" | "assemblyscript";
811
+ /** `gateway` runs WebAssembly in the gateway; `sandbox` runs an OCI image archive. */
812
+ tier: "gateway" | "sandbox";
813
+ /** Content-addressed key of the uploaded artifact. */
814
+ artifactKey: string;
815
+ /** Version label for this deploy (1 to 64 characters). */
816
+ version: string;
817
+ description?: string | undefined;
818
+ };
819
+ /** Optional invoke controls; property names are the gateway's. */
820
+ type InvokeFunctionOptions = {
821
+ /** Run asynchronously instead of waiting for the result. */
822
+ background?: boolean | undefined;
823
+ delegation?: {
824
+ token: string;
825
+ invokeSessionId?: string | undefined;
826
+ } | undefined;
827
+ onBehalfOf?: string | undefined;
828
+ confinedTo?: string | undefined;
760
829
  };
761
830
  declare function makeFunctionsNamespace(config: HttpClientConfig): {
762
- /** Deploy or redeploy a function. Returns the function record with status. */
831
+ /**
832
+ * Upload a function artifact and get back its content-addressed `artifactKey`, to pass to `deploy`.
833
+ * `POST /@<projectSlug>/functions/artifacts` with the raw bytes: a WebAssembly module for the gateway tier (up to
834
+ * 16 MiB) or an OCI image archive for the sandbox tier (up to 256 MiB). Uploading the same bytes again returns the same key.
835
+ */
836
+ uploadArtifact(bytes: Uint8Array | ArrayBuffer | Blob, kind: "wasm" | "tar"): Promise<Envelope<{
837
+ artifactKey: string;
838
+ }>>;
839
+ /** Deploy or redeploy a function from an uploaded artifact. Returns the function record with status. */
763
840
  deploy(input: DeployFunctionInput): Promise<Envelope<FunctionRecord>>;
764
841
  /** List deployed functions (cursor pagination). */
765
842
  list(opts?: {
766
843
  limit?: number;
767
844
  cursor?: string;
768
845
  status?: FunctionRecord["status"];
846
+ tier?: FunctionRecord["tier"];
847
+ source?: string;
769
848
  }): Promise<Envelope<ReadonlyArray<FunctionRecord>>>;
770
849
  /** Get a function by name. */
771
850
  get(name: string): Promise<Envelope<FunctionRecord>>;
772
- /** Retire a function. Returns confirmation; the function name enters a 24h cooldown. */
773
- delete(name: string): Promise<Envelope<{
774
- retired: boolean;
775
- cooldownUntil: string;
776
- }>>;
851
+ /** Retire a function. Returns the retired record; the function name enters a 24h cooldown. */
852
+ delete(name: string): Promise<Envelope<FunctionRecord>>;
777
853
  /**
778
- * Invoke a function. The `payload` is passed to the function runtime
779
- * verbatim; the gateway returns whatever the function returns wrapped
780
- * in the standard envelope.
781
- *
782
- * Per: invoke authority is per-function (declared in the
783
- * function manifest). Per: streaming responses use the
784
- * subscription/async-iterator pattern; this method covers the
854
+ * Invoke a function. The `payload` is sent as the `payload` field of
855
+ * the request body and passed to the function runtime verbatim; the
856
+ * gateway returns whatever the function returns wrapped in the standard
857
+ * envelope. Invoke authority is per function. This method covers the
785
858
  * request-response variant only.
786
859
  */
787
- invoke<TResult = unknown, TPayload = unknown>(name: string, payload: TPayload): Promise<Envelope<TResult>>;
860
+ invoke<TResult = unknown, TPayload = unknown>(name: string, payload?: TPayload, options?: InvokeFunctionOptions): Promise<Envelope<TResult>>;
788
861
  };
789
862
 
790
863
  /**
@@ -802,66 +875,88 @@ declare function makeFunctionsNamespace(config: HttpClientConfig): {
802
875
  * - `delete(bundleId)` → DELETE /@<slug>/policies/<id>
803
876
  * - `publish(bundleId)` → POST /@<slug>/policies/<id>/publish
804
877
  *
805
- * Per: only Pathmaker-class roles author policy; only
806
- * Custodian-class roles publish. `validate` is read-only and any role
807
- * with policy-read can lint a candidate bundle.
878
+ * Only authoring roles write policy and only custodian roles publish.
879
+ * `validate` is read-only and any role with policy-read can lint a
880
+ * candidate document.
808
881
  */
809
882
 
810
883
  type PolicyBundle = {
811
884
  /** `pol_<base62>`. */
812
885
  id: string;
813
- name: string;
814
- version: number;
815
- status: "draft" | "published" | "deactivated";
816
- rules: Record<string, unknown>;
886
+ projectId: string;
887
+ status: "draft" | "published" | "superseded";
888
+ /** The policy document. */
889
+ policy: PolicyDocument;
890
+ /** The rules catalogue, when the bundle carries one. */
891
+ rules?: unknown;
892
+ createdBy: string;
817
893
  createdAt: string;
818
894
  publishedAt: string | null;
819
- createdBy: string;
895
+ supersededAt: string | null;
896
+ supersededBy: string | null;
897
+ source: "rest" | "migration" | "cli";
898
+ editorMode: "visual" | "json" | "unspecified";
899
+ supersededReason: string | null;
900
+ /** Id of a queued publish awaiting a second approver, else `null`. */
901
+ pendingChangeId: string | null;
902
+ };
903
+ /** Answer of `publish`: the publish is queued for approval (HTTP 202). */
904
+ type PolicyPublishResult = {
905
+ pendingChangeId: string;
906
+ bundleId: string;
907
+ status: "pending_approval";
820
908
  };
909
+ /**
910
+ * The policy document: sections keyed by resource kind (`collections`,
911
+ * `storage`, `tools`, `functions`, `secrets`, `streams`, `analytics`);
912
+ * other keys are allowed.
913
+ */
914
+ type PolicyDocument = Record<string, unknown>;
821
915
  type CreatePolicyInput = {
822
- name: string;
823
- rules: Record<string, unknown>;
916
+ policy: PolicyDocument;
917
+ rules?: unknown;
918
+ editorMode?: "visual" | "json" | "unspecified" | undefined;
824
919
  };
825
920
  type UpdatePolicyInput = {
826
- name?: string;
827
- rules?: Record<string, unknown>;
921
+ policy: PolicyDocument;
922
+ rules?: unknown;
923
+ editorMode?: "visual" | "json" | "unspecified" | undefined;
828
924
  };
925
+ type ValidatePolicyInput = {
926
+ policy: PolicyDocument;
927
+ rules?: unknown;
928
+ };
929
+ /** Validation failures are errors, so a successful validate always answers `{ valid: true }`. */
829
930
  type ValidatePolicyResult = {
830
- valid: boolean;
831
- errors: ReadonlyArray<{
832
- rule: string;
833
- message: string;
834
- }>;
835
- warnings: ReadonlyArray<{
836
- rule: string;
837
- message: string;
838
- }>;
931
+ valid: true;
932
+ };
933
+ /** Optional publish controls; property names are the gateway's. */
934
+ type PublishPolicyOptions = {
935
+ acknowledgeSelfLockout?: boolean | undefined;
839
936
  };
840
937
  declare function makePoliciesNamespace(config: HttpClientConfig): {
841
938
  /** Return the currently-active policy for the project. */
842
939
  current(): Promise<Envelope<PolicyBundle | null>>;
843
- /** List all policy bundles (draft + published + deactivated). */
940
+ /** List all policy bundles (draft + published + superseded). */
844
941
  list(opts?: {
845
942
  status?: PolicyBundle["status"] | undefined;
846
- limit?: number | undefined;
847
- cursor?: string | undefined;
848
943
  }): Promise<Envelope<ReadonlyArray<PolicyBundle>>>;
849
944
  /** Create a draft policy bundle. */
850
945
  create(input: CreatePolicyInput): Promise<Envelope<PolicyBundle>>;
851
- /** Lint a candidate rule set without persisting. */
852
- validate(input: {
853
- rules: Record<string, unknown>;
854
- }): Promise<Envelope<ValidatePolicyResult>>;
946
+ /** Lint a candidate policy document without persisting. */
947
+ validate(input: ValidatePolicyInput): Promise<Envelope<ValidatePolicyResult>>;
855
948
  /** Get a single bundle by id. */
856
949
  get(bundleId: string): Promise<Envelope<PolicyBundle>>;
857
- /** Patch a draft bundle. Cannot patch published bundles (publish→republish flow). */
950
+ /** Replace a draft bundle's policy document. Cannot patch published bundles (publish→republish flow). */
858
951
  update(bundleId: string, patch: UpdatePolicyInput): Promise<Envelope<PolicyBundle>>;
859
- /** Delete a draft bundle. Cannot delete published bundles. */
860
- delete(bundleId: string): Promise<Envelope<{
861
- deleted: boolean;
862
- }>>;
863
- /** Publish a draft bundle — transitions to `published` + becomes active for the project. */
864
- publish(bundleId: string): Promise<Envelope<PolicyBundle>>;
952
+ /** Delete a draft bundle. Cannot delete published bundles. The gateway answers 204 with no body. */
953
+ delete(bundleId: string): Promise<Envelope<undefined>>;
954
+ /**
955
+ * Publish a draft bundle. The gateway answers 202 with `{ pendingChangeId, bundleId }`: the publish waits for
956
+ * approval, then the bundle becomes active. Pass `acknowledgeSelfLockout: true` to proceed when the bundle
957
+ * would remove your own read access to a collection.
958
+ */
959
+ publish(bundleId: string, options?: PublishPolicyOptions): Promise<Envelope<PolicyPublishResult>>;
865
960
  };
866
961
 
867
962
  /**
@@ -870,21 +965,17 @@ declare function makePoliciesNamespace(config: HttpClientConfig): {
870
965
  * Backed by the gateway audit-log routes.
871
966
  *
872
967
  * Wire mapping:
873
- * - `query({ since, until, type, actorId, targetKind, targetId, limit, cursor })`
968
+ * - `query({ eventType, actorId, after, before, limit, cursor })`
874
969
  * → GET /@<slug>/audit-log?...
875
970
  *
876
- * The endpoint accepts cursor-paginated reverse-chronological queries.
877
- * `type` is the audit-event namespace (e.g. `data.write.access.insert`,
878
- * `gate.signin.success`) per the event-name taxonomy +
879
- * `feedback_error_code_namespace_boundary_and_prefix.md` cement.
971
+ * Option names are the gateway's query parameter names. The endpoint
972
+ * accepts cursor-paginated reverse-chronological queries. `eventType` is
973
+ * the audit-event name (e.g. `data.write.access.insert`).
880
974
  *
881
- * Returns audit events with full context payload — actorId / targetKind /
882
- * targetId / payload / occurredAt / requestId / traceId.
975
+ * Returns audit events with full context payload.
883
976
  */
884
977
 
885
- /**
886
- * Audit event record `_sys.audit_log` shape.
887
- */
978
+ /** Audit event record. */
888
979
  type AuditEvent = {
889
980
  id: string;
890
981
  /** Dotted namespace (e.g. `data.write.access.insert`). */
@@ -898,18 +989,14 @@ type AuditEvent = {
898
989
  traceId: string | null;
899
990
  };
900
991
  type AuditQueryOpts = {
901
- /** ISO 8601 lower bound (inclusive). */
902
- since?: string | undefined;
903
- /** ISO 8601 upper bound (exclusive). */
904
- until?: string | undefined;
905
- /** Filter by event type (exact match; future cycles may add prefix-match). */
906
- type?: string | undefined;
992
+ /** Filter by event type. */
993
+ eventType?: string | undefined;
907
994
  /** Filter by actor. */
908
995
  actorId?: string | undefined;
909
- /** Filter by target resource kind. */
910
- targetKind?: string | undefined;
911
- /** Filter by target resource id. */
912
- targetId?: string | undefined;
996
+ /** ISO 8601 lower bound: only events after this instant. */
997
+ after?: string | undefined;
998
+ /** ISO 8601 upper bound: only events before this instant. */
999
+ before?: string | undefined;
913
1000
  /** Page size (per-tier max bounded server-side). */
914
1001
  limit?: number | undefined;
915
1002
  /** Cursor from prior response. */
@@ -920,15 +1007,13 @@ declare function makeAuditNamespace(config: HttpClientConfig): {
920
1007
  * Query the audit log. Returns reverse-chronological events matching
921
1008
  * all supplied filters (AND composition).
922
1009
  *
923
- * Per RBAC: requires `AUDIT_READER` role minimum; Custodian-
924
- * class roles inherit. Project-level audit is project-scoped (this
925
- * endpoint); platform-level audit is admin-only (separate surface).
1010
+ * Requires the `AUDIT_READER` role at minimum. This endpoint is
1011
+ * project-scoped.
926
1012
  */
927
1013
  query(opts?: AuditQueryOpts): Promise<Envelope<ReadonlyArray<AuditEvent>>>;
928
1014
  /**
929
1015
  * Convenience: live-tail recent events. Currently single-shot read
930
- * with `since` defaulted to "1 minute ago"; subscription-mode tail
931
- * (SSE) lands when the streaming layer ships pattern.
1016
+ * with `after` defaulted to "1 minute ago".
932
1017
  */
933
1018
  tail(opts?: {
934
1019
  sinceMinutes?: number;
@@ -960,14 +1045,27 @@ declare function makeAuditNamespace(config: HttpClientConfig): {
960
1045
  * is exposed as an API).
961
1046
  */
962
1047
 
1048
+ /**
1049
+ * Org record, as the gateway returns it. `list` rows add `viaToken` and `consoleDomain`;
1050
+ * `get`, `current` and `restore` add `customDomain` and `deletedAt`.
1051
+ */
963
1052
  type Org = {
964
1053
  /** `org_<base62>`. */
965
1054
  id: string;
966
1055
  slug: string;
967
- name: string;
968
- status: "active" | "suspended" | "soft-deleted";
1056
+ displayName: string;
1057
+ products: ReadonlyArray<string>;
1058
+ billingTier: string;
1059
+ signupProduct: string;
1060
+ /** The caller's role in the org. */
1061
+ role: string;
969
1062
  createdAt: string;
970
- updatedAt: string | null;
1063
+ customDomain?: string | null | undefined;
1064
+ deletedAt?: string | null | undefined;
1065
+ /** List rows only: `true` when the org is reached through the token rather than a membership. */
1066
+ viaToken?: boolean | undefined;
1067
+ /** List rows only: the org's Console host. */
1068
+ consoleDomain?: string | undefined;
971
1069
  };
972
1070
  declare function makeOrgsNamespace(config: HttpClientConfig): {
973
1071
  /** List orgs accessible to the caller. */
@@ -983,27 +1081,27 @@ declare function makeOrgsNamespace(config: HttpClientConfig): {
983
1081
  /**
984
1082
  * Compute LLMs SDK — `client.compute.llms.*`.
985
1083
  *
986
- * Compute LLMs registry. Curated 9-model library
987
- * + 4-endpoint family + per-model tier-gating.
1084
+ * Compute LLMs registry: a curated model library, four endpoints and
1085
+ * per-model tier gating.
988
1086
  *
989
- * Wire mapping (project-plane;):
1087
+ * Wire mapping (project-plane):
990
1088
  * - list() → GET /@<slug>/compute/llms
991
1089
  * - read(modelId) → GET /@<slug>/compute/llms/<model-id>
992
1090
  * - invoke(modelId, ...) → POST /@<slug>/compute/llms/<model-id>/invoke
993
1091
  * - invokeStream(modelId,...) → POST /@<slug>/compute/llms/<model-id>/invoke-stream (SSE)
994
1092
  *
995
- * Per RBAC: list/read against all cohort roles; invoke +
996
- * invokeStream require PROJECT_AUTHOR or PROJECT_ADMIN (LLM cost gate).
997
- * Per, surfaces K9O_LLM_PROVIDER_UNAVAILABLE (503) +
998
- * reuses K9O_MODEL_NOT_DECLARED / K9O_TIER_FEATURE_GATED /
999
- * K9O_AGENT_INFERENCE_TIMEOUT.
1093
+ * RBAC: list/read against all cohort roles; invoke + invokeStream require
1094
+ * PROJECT_AUTHOR or PROJECT_ADMIN (LLM cost gate). External-provider models
1095
+ * answer 501 `K9O_NOT_IMPLEMENTED` until the provider client is built.
1096
+ * Surfaces K9O_LLM_PROVIDER_UNAVAILABLE (503), K9O_MODEL_NOT_DECLARED and
1097
+ * K9O_TIER_FEATURE_GATED.
1000
1098
  */
1001
1099
 
1002
- /** Curated 9-model closed enum at v2 launch (extensible v2.x). */
1100
+ /** Curated model ids. */
1003
1101
  type LLMModelId = "mistral-7b" | "mistral-8x7b" | "llama-3-8b" | "llama-3-70b" | "claude-3-5-sonnet" | "gpt-4o" | "gpt-4o-mini" | "text-embedding-3-small" | "text-embedding-3-large";
1004
1102
  type LLMProviderClass = "self-hosted" | "external";
1005
1103
  type LLMModality = "text-completion" | "text-completion+tool-use" | "embeddings";
1006
- /** Model metadata + (cost transparency). */
1104
+ /** Model metadata with per-model cost. */
1007
1105
  type LLMModel = {
1008
1106
  id: LLMModelId;
1009
1107
  providerClass: LLMProviderClass;
@@ -1012,43 +1110,68 @@ type LLMModel = {
1012
1110
  tierGate: string;
1013
1111
  contextWindow: number;
1014
1112
  capabilities: ReadonlyArray<string>;
1015
- /** Per-model token cost for cost-transparency. */
1113
+ /** Per-model token cost. */
1016
1114
  costPerMillionInputTokens: number;
1017
1115
  costPerMillionOutputTokens: number;
1018
1116
  };
1019
- /** Inference parameters (passed through to provider). */
1117
+ /** Inference parameters the route reads; sent flat in the request body. */
1020
1118
  type LLMInvokeParams = {
1119
+ /** 1 to 32000. */
1021
1120
  maxTokens?: number;
1121
+ /** 0 to 2. */
1022
1122
  temperature?: number;
1023
- topP?: number;
1024
- stop?: ReadonlyArray<string>;
1025
- [key: string]: unknown;
1123
+ /** Free-form usage label recorded with the call. */
1124
+ usageType?: string;
1125
+ };
1126
+ /** Token counts the model server reported for a call. */
1127
+ type LLMUsage = {
1128
+ promptTokens: number;
1129
+ completionTokens: number;
1130
+ totalTokens: number;
1026
1131
  };
1027
- /** Synchronous inference response `/invoke`. */
1132
+ /** Synchronous inference response from `/invoke`. */
1028
1133
  type LLMResponse = {
1029
- completion: string;
1030
- tokensUsed: number;
1031
- latencyMs: number;
1134
+ modelId: string;
1135
+ /** The generated text. */
1136
+ content: string;
1137
+ finishReason: string | null;
1138
+ usage: LLMUsage;
1139
+ usageType: string;
1032
1140
  };
1033
- /** Streaming chunk `/invoke-stream` (SSE per-token). */
1141
+ /**
1142
+ * One chunk of the `/invoke-stream` response: the model server's OpenAI-style
1143
+ * chat-completion chunk, passed through unchanged. Read incremental text from
1144
+ * `choices[0].delta.content`; the final chunk may carry `usage`.
1145
+ */
1034
1146
  type LLMStreamChunk = {
1035
- /** Incremental completion delta. */
1036
- delta: string;
1037
- /** True on the terminal chunk. */
1038
- done?: boolean;
1039
- /** Populated on terminal chunk. */
1040
- tokensUsed?: number;
1147
+ id?: string;
1148
+ object?: string;
1149
+ model?: string;
1150
+ choices?: ReadonlyArray<{
1151
+ index?: number;
1152
+ delta?: {
1153
+ role?: string;
1154
+ content?: string | null;
1155
+ };
1156
+ finish_reason?: string | null;
1157
+ }>;
1158
+ usage?: {
1159
+ prompt_tokens?: number;
1160
+ completion_tokens?: number;
1161
+ total_tokens?: number;
1162
+ } | null;
1163
+ [key: string]: unknown;
1041
1164
  };
1042
1165
  type LLMInvokeInput = {
1043
1166
  prompt: string;
1044
1167
  params?: LLMInvokeParams;
1045
1168
  };
1046
- /** Error code coined in (others reused). */
1169
+ /** Error codes specific to LLM calls. */
1047
1170
  declare const LLM_ERROR_CODES: {
1048
1171
  readonly PROVIDER_UNAVAILABLE: "K9O_LLM_PROVIDER_UNAVAILABLE";
1049
1172
  };
1050
1173
  declare function makeComputeNamespace(config: HttpClientConfig): {
1051
- /** LLM registry + inference — `client.compute.llms.*`. */
1174
+ /** LLM registry + inference — `client.compute.llms.*` . */
1052
1175
  llms: {
1053
1176
  /** GET /@<slug>/compute/llms — list models available to the project tier. */
1054
1177
  list(opts?: {
@@ -1064,11 +1187,10 @@ declare function makeComputeNamespace(config: HttpClientConfig): {
1064
1187
  invoke(modelId: LLMModelId | string, input: LLMInvokeInput): Promise<Envelope<LLMResponse>>;
1065
1188
  /**
1066
1189
  * POST /@<slug>/compute/llms/<model-id>/invoke-stream — streaming
1067
- * inference (SSE; per-token delta for low-latency UX).
1190
+ * inference (SSE; the model server's OpenAI-style chunks).
1068
1191
  * Returns an async iterable of `LLMStreamChunk` — caller writes
1069
1192
  * `for await (const chunk of client.compute.llms.invokeStream(...))`.
1070
- * The SDK handles SSE framing internally per
1071
- * `feedback_sdk_abstracted_primitive_default_to_richer_interaction.md`.
1193
+ * The SDK handles SSE framing internally.
1072
1194
  */
1073
1195
  invokeStream(modelId: LLMModelId | string, input: LLMInvokeInput): AsyncGenerator<LLMStreamChunk, void, void>;
1074
1196
  };
@@ -1083,33 +1205,56 @@ declare function makeComputeNamespace(config: HttpClientConfig): {
1083
1205
  * across accessible orgs) — `client.org` is the singular bound-org
1084
1206
  * namespace with member / group / smtp / audit / gate sub-namespaces.
1085
1207
  *
1086
- * Org-plane URL grammar: requests route against the
1087
- * `<orgSlug>.api.k9o.io/` org subdomain WITHOUT the `@<projectSlug>/`
1088
- * prefix used by project-plane requests. The gateway resolves the org
1089
- * context from the subdomain.
1208
+ * Org-plane URL grammar: requests go to the org's API host (`<orgSlug>.api.<apex>`) WITHOUT the
1209
+ * `@<projectSlug>/` prefix used by project-plane requests. The gateway resolves the org context from the host.
1090
1210
  */
1091
1211
 
1092
1212
  type OrgMember = {
1093
- /** `u_<base62>`. */
1213
+ /** `usr_<base62>`. */
1094
1214
  userId: string;
1215
+ orgId: string;
1095
1216
  email: string;
1096
- /** Org-level role enum. */
1217
+ displayName: string;
1218
+ /** Org-level role. */
1097
1219
  role: "ORG_OWNER" | "ORG_ADMIN" | "ORG_BILLING_ADMIN" | "ORG_MEMBER";
1098
- joinedAt: string;
1099
- status: "active" | "invited" | "suspended";
1220
+ invitedAt: string;
1221
+ /** `null` until the invitation is accepted. */
1222
+ acceptedAt: string | null;
1223
+ status: "active" | "suspended";
1224
+ /** `invited` until accepted, then the same as `status`. */
1225
+ state: "invited" | "active" | "suspended";
1226
+ suspendedAt: string | null;
1227
+ };
1228
+ /**
1229
+ * Answer of `members.invite` when the email has no account yet (HTTP 202): an invitation was created
1230
+ * instead of a member. `delivery` says whether the invitation email went out.
1231
+ */
1232
+ type OrgInviteResult = {
1233
+ invitation: {
1234
+ id: string;
1235
+ orgId: string;
1236
+ email: string;
1237
+ role: OrgMember["role"];
1238
+ expiresAt: string;
1239
+ };
1240
+ delivery: "sent" | "not_configured" | "failed";
1100
1241
  };
1101
1242
  type OrgGroup = {
1102
1243
  /** `grp_<base62>`. */
1103
1244
  id: string;
1245
+ orgId: string;
1104
1246
  name: string;
1105
- memberCount: number;
1247
+ description: string | null;
1248
+ /** Groups come from an identity provider. */
1249
+ source: "idp";
1250
+ sourceGroupId: string;
1106
1251
  createdAt: string;
1107
1252
  };
1108
1253
  type OrgRoleGrant = {
1109
1254
  /** `grt_<base62>`. */
1110
1255
  id: string;
1111
1256
  userId: string;
1112
- role: "ORG_ADMIN" | "ORG_BILLING_ADMIN";
1257
+ role: "ORG_OWNER" | "ORG_ADMIN" | "ORG_BILLING_ADMIN" | "ORG_AUDITOR" | "ORG_MEMBER";
1113
1258
  grantedBy: string;
1114
1259
  grantedAt: string;
1115
1260
  revokedAt: string | null;
@@ -1117,229 +1262,198 @@ type OrgRoleGrant = {
1117
1262
  viaDelegationId: string | null;
1118
1263
  };
1119
1264
  /**
1120
- * Org-level audit event 6-event family.
1121
- *
1122
- * Event types (closed set at v2.1.132):
1123
- * - `data.write.org.member_invited`
1124
- * - `data.write.org.member_removed`
1125
- * - `data.write.org.role_granted`
1126
- * - `data.write.org.role_revoked`
1127
- * - `data.write.org.idp_config_changed`
1128
- * - `data.write.org.settings_updated`
1129
- *
1130
- * `targetKind` is `org` for all; `targetId` is the orgId.
1265
+ * Org-level audit event: member invited or removed, role granted or revoked, identity provider
1266
+ * or settings changed.
1131
1267
  */
1132
1268
  type OrgAuditEvent = {
1133
1269
  id: string;
1134
1270
  type: string;
1135
1271
  actorId: string | null;
1136
- targetKind: "org";
1137
- targetId: string;
1272
+ targetKind: string | null;
1273
+ targetId: string | null;
1138
1274
  payload: Record<string, unknown>;
1139
- occurredAt: string;
1275
+ createdAt: string;
1140
1276
  requestId: string | null;
1141
1277
  traceId: string | null;
1142
1278
  };
1143
1279
  /**
1144
- * Org SMTP configuration. Sensitive fields (passwordRef)
1145
- * are sequestered in Kibo enclave; the SDK stores only the reference.
1280
+ * Org SMTP configuration, as the gateway takes it in the `smtpConfig` field of PATCH /org.
1281
+ * The password is never sent: `passwordRef` is a reference to a stored secret.
1146
1282
  */
1147
1283
  type SmtpConfig = {
1148
1284
  host: string;
1149
1285
  port: number;
1150
1286
  username: string;
1151
- /** Kibo enclave credential reference; opaque token. */
1287
+ /** Reference to the stored SMTP password; opaque token. */
1152
1288
  passwordRef: string;
1153
- fromEmail: string;
1154
- fromName: string;
1155
- encryption: "none" | "starttls" | "tls";
1156
- replyToEmail?: string | undefined;
1289
+ fromAddress: string;
1290
+ fromName?: string | undefined;
1157
1291
  };
1158
1292
  type SmtpTestEmailInput = {
1159
1293
  to: string;
1160
- /** Optional override of the from address for the test send (defaults to fromEmail). */
1161
- fromOverride?: string | undefined;
1294
+ subject?: string | undefined;
1162
1295
  };
1163
1296
  type SmtpTestEmailResult = {
1164
- ok: boolean;
1165
- /** Diagnostic message returned by the SMTP server (success or error detail). */
1166
- diagnostic: string;
1167
- /** ISO 8601 timestamp of the test attempt. */
1168
- attemptedAt: string;
1297
+ accepted: boolean;
1298
+ /** Which SMTP configuration serves the org: `org` when it has its own, else `platform`. */
1299
+ resolvedTier: "org" | "platform";
1300
+ to: string;
1301
+ /** `true` while the gateway does not send the message itself. */
1302
+ dryRun: boolean;
1303
+ };
1304
+ type OrgDefaultLlm = {
1305
+ orgId: string;
1306
+ defaultModelId: string;
1307
+ updatedAt: string;
1308
+ updatedBy: string | null;
1169
1309
  };
1310
+ type OrgIdpProviderKind = "google" | "github" | "microsoft" | "oidc" | "saml" | "scim" | "ldap" | "active_directory" | "apple" | "facebook" | "twitter";
1170
1311
  type OrgIdpProvider = {
1171
- /** `idp_<base62>`. */
1172
1312
  id: string;
1173
- name: string;
1174
- /** Protocol/vendor (e.g. "okta-saml", "azure-ad-oidc", "google-workspace"). */
1175
- kind: string;
1313
+ idpProvider: OrgIdpProviderKind;
1314
+ displayName: string;
1315
+ clientId: string;
1176
1316
  enabled: boolean;
1177
1317
  createdAt: string;
1178
1318
  };
1319
+ /** Body of POST /identity-providers. `clientSecretRef` is a reference to a stored secret, never the secret itself. */
1179
1320
  type CreateOrgIdpInput = {
1180
- name: string;
1181
- kind: string;
1182
- config: Record<string, unknown>;
1321
+ idpProvider: OrgIdpProviderKind;
1322
+ displayName: string;
1323
+ clientId: string;
1324
+ clientSecretRef: string;
1325
+ tierGating: "free_tier_ok" | "ridge_plus";
1326
+ redirectUri?: string | undefined;
1327
+ metadataUrl?: string | null | undefined;
1328
+ attributeMap?: Record<string, unknown> | undefined;
1329
+ enabled?: boolean | undefined;
1330
+ };
1331
+ /** Body of PATCH /identity-providers/<id>. */
1332
+ type UpdateOrgIdpInput = {
1333
+ displayName?: string | undefined;
1334
+ clientId?: string | undefined;
1335
+ clientSecretRef?: string | undefined;
1336
+ redirectUri?: string | undefined;
1337
+ metadataUrl?: string | null | undefined;
1338
+ attributeMap?: Record<string, unknown> | undefined;
1339
+ enabled?: boolean | undefined;
1183
1340
  };
1184
1341
  declare function makeOrgNamespace(config: HttpClientConfig): {
1185
- /** Member lifecycle — list / invite / get / remove. */
1342
+ /** Member lifecycle — list / invite / remove. */
1186
1343
  members: {
1187
- /** GET /members (org-plane LIST). */
1344
+ /** GET /members (org-plane LIST). The route is not paged; it filters by userId, role, acceptanceStatus, status and state. */
1188
1345
  list(opts?: {
1189
- limit?: number | undefined;
1190
- cursor?: string | undefined;
1191
- status?: OrgMember["status"] | undefined;
1346
+ userId?: string | undefined;
1347
+ role?: OrgMember["role"] | undefined;
1348
+ acceptanceStatus?: "accepted" | "pending" | undefined;
1349
+ status?: "active" | "suspended" | undefined;
1350
+ state?: string | undefined;
1192
1351
  }): Promise<Envelope<ReadonlyArray<OrgMember>>>;
1193
- /** POST /members — invite a new org member by email. */
1352
+ /**
1353
+ * POST /members — add a member by email. An existing user becomes a member at once (201, the member row);
1354
+ * an unknown email gets an invitation (202, `{ invitation, delivery }`).
1355
+ */
1194
1356
  invite(input: {
1195
1357
  email: string;
1196
1358
  role: OrgMember["role"];
1197
- }): Promise<Envelope<OrgMember>>;
1198
- /** GET /members/<userId> — single-read (existing endpoint). */
1199
- get(userId: string): Promise<Envelope<OrgMember>>;
1200
- /** DELETE /members/<userId> — remove a member from the org. */
1201
- remove(userId: string): Promise<Envelope<{
1202
- removed: boolean;
1203
- }>>;
1359
+ }): Promise<Envelope<OrgMember | OrgInviteResult>>;
1360
+ /** DELETE /members/<userId> — remove a member from the org. The gateway answers 204 with no body. */
1361
+ remove(userId: string): Promise<Envelope<undefined>>;
1204
1362
  };
1205
- /** Group lifecycle — list / create / get / delete. */
1363
+ /** Groups — list / get (read-only). */
1206
1364
  groups: {
1207
1365
  /** GET /groups (org-plane LIST). */
1208
1366
  list(opts?: {
1209
- limit?: number;
1210
- cursor?: string;
1367
+ userId?: string | undefined;
1211
1368
  }): Promise<Envelope<ReadonlyArray<OrgGroup>>>;
1212
- /** POST /groups — create a new group. */
1213
- create(input: {
1214
- name: string;
1215
- }): Promise<Envelope<OrgGroup>>;
1216
- /** GET /groups/<groupId> — single-read (pre-cement existing endpoint). */
1369
+ /** GET /groups/<groupId> — single-read. */
1217
1370
  get(groupId: string): Promise<Envelope<OrgGroup>>;
1218
- /** DELETE /groups/<groupId> — remove a group. */
1219
- delete(groupId: string): Promise<Envelope<{
1220
- deleted: boolean;
1221
- }>>;
1222
1371
  };
1223
- /** Org-plane audit log — query / tail. Distinct from project-plane `client.audit`. */
1372
+ /** Org-plane audit log — query. Distinct from project-plane `client.audit`. */
1224
1373
  auditLog: {
1225
1374
  /**
1226
- * GET /audit-log (org-plane).
1227
- * Distinct from project-plane `client.audit.query()` which routes to
1228
- * `@<projectSlug>/audit-log`. Org-plane events cover the 6-event family
1229
- * (member_invited/removed/role_granted/revoked/
1230
- * idp_config_changed/settings_updated).
1375
+ * GET /audit-log (org-plane), newest first. The route reads `type` and `limit` (1 to 500, default 100) only.
1376
+ * Distinct from project-plane `client.audit.query()` which routes to `@<projectSlug>/audit-log`.
1231
1377
  */
1232
1378
  query(opts?: {
1233
- since?: string | undefined;
1234
- until?: string | undefined;
1235
1379
  type?: string | undefined;
1236
- actorId?: string | undefined;
1237
- targetKind?: string | undefined;
1238
- targetId?: string | undefined;
1239
1380
  limit?: number | undefined;
1240
- cursor?: string | undefined;
1241
- }): Promise<Envelope<ReadonlyArray<OrgAuditEvent>>>;
1242
- /** Convenience: recent events (defaults to 5 minute window). */
1243
- tail(opts?: {
1244
- sinceMinutes?: number;
1245
- limit?: number;
1246
1381
  }): Promise<Envelope<ReadonlyArray<OrgAuditEvent>>>;
1247
1382
  };
1248
1383
  /** Gate (IAK) org-level surfaces — role-grants + IdP-providers. */
1249
1384
  gate: {
1250
1385
  roles: {
1251
- /** GET /org-role-grants — list active grants ask 4. */
1252
- list(opts?: {
1253
- userId?: string | undefined;
1254
- role?: OrgRoleGrant["role"] | undefined;
1255
- includeRevoked?: boolean | undefined;
1256
- }): Promise<Envelope<ReadonlyArray<OrgRoleGrant>>>;
1257
- /** POST /org-role-grants — grant an ORG_ADMIN or ORG_BILLING_ADMIN role. */
1386
+ /** GET /role-grants — list role grants. */
1387
+ list(): Promise<Envelope<ReadonlyArray<OrgRoleGrant>>>;
1388
+ /** POST /role-grants — grant an org role. */
1258
1389
  grant(input: {
1259
1390
  userId: string;
1260
1391
  role: OrgRoleGrant["role"];
1392
+ decisionReason?: string | undefined;
1261
1393
  }): Promise<Envelope<OrgRoleGrant>>;
1262
- /** GET /org-role-grants/<grantId> — single-read. */
1394
+ /** GET /role-grants/<grantId> — single-read. */
1263
1395
  get(grantId: string): Promise<Envelope<OrgRoleGrant>>;
1264
- /** DELETE /org-role-grants/<grantId> — revoke a grant (soft delete; sets revokedAt). */
1265
- revoke(grantId: string): Promise<Envelope<OrgRoleGrant>>;
1396
+ /** DELETE /role-grants/<grantId> — revoke a grant (soft delete; sets revokedAt). */
1397
+ revoke(grantId: string, opts?: {
1398
+ decisionReason?: string | undefined;
1399
+ }): Promise<Envelope<OrgRoleGrant>>;
1266
1400
  };
1267
1401
  idpProviders: {
1268
- /** GET /idp-providers — list configured org operator IdP providers ask 7. */
1402
+ /** GET /identity-providers — list configured identity providers. */
1269
1403
  list(): Promise<Envelope<ReadonlyArray<OrgIdpProvider>>>;
1270
- /** POST /idp-providers — create a new IdP integration. */
1404
+ /** POST /identity-providers — create a new IdP integration. */
1271
1405
  create(input: CreateOrgIdpInput): Promise<Envelope<OrgIdpProvider>>;
1272
- /** GET /idp-providers/<idpId>. */
1406
+ /** GET /identity-providers/<idpId>. */
1273
1407
  get(idpId: string): Promise<Envelope<OrgIdpProvider>>;
1274
- /** PATCH /idp-providers/<idpId> — update config or enable/disable. */
1275
- configure(idpId: string, patch: {
1276
- name?: string;
1277
- enabled?: boolean;
1278
- config?: Record<string, unknown>;
1279
- }): Promise<Envelope<OrgIdpProvider>>;
1280
- /** DELETE /idp-providers/<idpId>. */
1408
+ /** PATCH /identity-providers/<idpId> — update settings or enable/disable. */
1409
+ configure(idpId: string, patch: UpdateOrgIdpInput): Promise<Envelope<OrgIdpProvider>>;
1410
+ /** DELETE /identity-providers/<idpId>. */
1281
1411
  delete(idpId: string): Promise<Envelope<{
1282
1412
  deleted: boolean;
1283
1413
  }>>;
1284
1414
  };
1285
1415
  };
1286
- /** Org-level SMTP config — get / set / test / unset. */
1416
+ /** Org-level SMTP config — set / test / unset. */
1287
1417
  smtp: {
1288
1418
  /**
1289
- * GET /org/smtp — read current SMTP config.
1290
- * Returns null when no org-level SMTP is configured (falls back to
1291
- * platform SMTP 3-tier cascade).
1419
+ * PATCH /org with `smtpConfig` body — set or update SMTP. Answers the org record.
1420
+ * The body carries `passwordRef` (a reference to the stored password), not the password.
1292
1421
  */
1293
- get(): Promise<Envelope<SmtpConfig | null>>;
1294
- /**
1295
- * PATCH /orgs/<orgSlug> with `smtpConfig` body — set or update SMTP.
1296
- * PATCH on the org resource accepts smtpConfig.
1297
- * Passwords route through Kibo enclave — SDK accepts plaintext at
1298
- * the SDK boundary; gateway stores the reference.
1299
- */
1300
- set(config_: Omit<SmtpConfig, "passwordRef"> & {
1301
- password: string;
1302
- }): Promise<Envelope<SmtpConfig>>;
1422
+ set(config_: SmtpConfig): Promise<Envelope<Org>>;
1303
1423
  /**
1304
1424
  * POST /org/smtp/test-email — send a diagnostic email to verify config.
1305
1425
  * 5/hour rate limit; RFC 5322 validation;
1306
1426
  * 3-tier resolution (platform→org→project) of effective SMTP.
1307
1427
  */
1308
1428
  test(input: SmtpTestEmailInput): Promise<Envelope<SmtpTestEmailResult>>;
1309
- /** PATCH /orgs/<orgSlug> with `smtpConfig: null` — clear org-level SMTP. */
1310
- unset(): Promise<Envelope<{
1311
- cleared: boolean;
1312
- }>>;
1429
+ /** PATCH /org with `smtpConfig: null` — clear org-level SMTP. Answers the org record. */
1430
+ unset(): Promise<Envelope<Org>>;
1313
1431
  };
1314
1432
  /** Org-default LLM — get / set (ORG_ADMIN). */
1315
1433
  defaultLLM: {
1316
1434
  /**
1317
- * GET /org/default-llm — read the org-default LLM model id
1318
- *. Returns `null` when no explicit default is set (gateway
1319
- * falls back to `mistral-7b`). ORG_ADMIN read; tier-gated.
1435
+ * GET /default-llm — read the org-default LLM model id.
1436
+ * Any accepted member of the org may read it.
1320
1437
  */
1321
- get(): Promise<Envelope<LLMModelId | null>>;
1438
+ get(): Promise<Envelope<OrgDefaultLlm>>;
1322
1439
  /**
1323
- * PATCH /org/default-llm — set the org-default LLM.
1324
- * ORG_ADMIN only. The model must be available to the org's tier per
1440
+ * PATCH /default-llm — set the org-default LLM.
1441
+ * ORG_ADMIN or ORG_OWNER only. The model must be available to the org's tier
1325
1442
  * or the gateway returns K9O_TIER_FEATURE_GATED.
1326
1443
  */
1327
1444
  set(input: {
1328
1445
  modelId: LLMModelId;
1329
- }): Promise<Envelope<LLMModelId>>;
1446
+ }): Promise<Envelope<{
1447
+ orgId: string;
1448
+ defaultModelId: string;
1449
+ }>>;
1330
1450
  };
1331
1451
  /**
1332
- * GET /org — read the current org (slug + name + status + settings).
1452
+ * GET /org — read the current org (slug, displayName, products, billing tier, your role).
1333
1453
  * Mirrors `client.orgs.current()` for symmetry; `client.org.get()` is
1334
1454
  * the singular-namespace convention for use within an org-bound client.
1335
1455
  */
1336
- get(): Promise<Envelope<{
1337
- id: string;
1338
- slug: string;
1339
- name: string;
1340
- status: string;
1341
- createdAt: string;
1342
- }>>;
1456
+ get(): Promise<Envelope<Org>>;
1343
1457
  };
1344
1458
 
1345
1459
  /**
@@ -1351,145 +1465,112 @@ declare function makeOrgNamespace(config: HttpClientConfig): {
1351
1465
  *
1352
1466
  * Wire mapping (gateway uses platform-plane / cross-org `/me/...` routes):
1353
1467
  * - `client.me.profile.get/update` → GET/PATCH /me
1354
- * - `client.me.sessions.list/revoke` → GET/DELETE /me/sessions
1355
- * - `client.me.apiTokens.list/create/delete` → GET/POST/DELETE /me/api-tokens (not available yet)
1356
- * - `client.me.notifications.list/markRead` → GET/PATCH /me/notifications (not available yet)
1357
- * - `client.me.auditLog.query` → GET /me/audit-log (not available yet)
1358
- * - `client.me.dataExport.request` → POST /me/data-export (not available yet)
1359
- *
1360
- * Profile, sessions and MFA setup are served by the existing gateway routes
1361
- * `me.ts` + `mfa.ts`.
1468
+ * - `client.me.sessions.list` → GET /me/sessions
1469
+ * - `client.me.sessions.revoke` → POST /auth/sessions/<sessionId>/revoke
1470
+ * - `client.me.sessions.revokeAll` → POST /me/sessions/revoke-all
1471
+ * - `client.me.apiTokens.list/create/delete` → GET/POST/DELETE /me/api-tokens
1362
1472
  */
1363
1473
 
1364
1474
  type MyProfile = {
1365
- /** `u_<base62>`. */
1475
+ /** `usr_<base62>`. */
1366
1476
  id: string;
1367
1477
  email: string;
1368
- displayName: string | null;
1478
+ displayName: string;
1479
+ mfaEnabled: boolean;
1480
+ verifiedAt: string | null;
1481
+ /** Set while the account is in its deletion grace period. */
1482
+ deletedAt: string | null;
1483
+ deletionRequestedAt: string | null;
1484
+ deletionScheduledFor: string | null;
1485
+ avatarUrl: string | null;
1486
+ /** BCP 47 language tag, or `null` when unset. */
1487
+ locale: string | null;
1488
+ /** IANA time zone name, or `null` when unset. */
1489
+ timezone: string | null;
1369
1490
  /** ISO 8601. */
1370
1491
  createdAt: string;
1371
- /** Last activity timestamp. */
1372
- lastActiveAt: string | null;
1492
+ /** ISO 8601. */
1493
+ updatedAt: string;
1373
1494
  };
1374
1495
  type MySession = {
1375
1496
  /** `sess_<base62>`. */
1376
1497
  id: string;
1377
- /** Initial sign-in time. */
1378
- createdAt: string;
1379
- /** Most recent activity time. */
1380
- lastSeenAt: string;
1498
+ userId: string;
1499
+ /** Sign-in time. */
1500
+ issuedAt: string;
1501
+ expiresAt: string;
1502
+ revokedAt: string | null;
1503
+ mfaVerifiedAt: string | null;
1381
1504
  userAgent: string | null;
1382
1505
  ipAddress: string | null;
1506
+ /** Always `null` for now. */
1507
+ geoCountry: string | null;
1383
1508
  /** Whether this session is the one issuing the current request. */
1384
- current: boolean;
1509
+ isCurrentSession: boolean;
1510
+ };
1511
+ /** Fields `profile.update` may change; `null` clears `locale` and `timezone`. */
1512
+ type UpdateMyProfileInput = {
1513
+ displayName?: string | undefined;
1514
+ /** BCP 47 language tag, for example `de-DE`. */
1515
+ locale?: string | null | undefined;
1516
+ /** IANA time zone name, for example `Europe/Berlin`. */
1517
+ timezone?: string | null | undefined;
1385
1518
  };
1386
1519
  type MyApiToken = {
1387
- /** `tok_<base62>`. */
1520
+ /** `pat_<base62>`. */
1388
1521
  id: string;
1389
- name: string;
1522
+ userId: string;
1523
+ orgId: string;
1524
+ label: string;
1525
+ scopeManifest: CreateMyApiTokenInput["scopeManifest"];
1526
+ ttlSeconds: number;
1390
1527
  /** ISO 8601. */
1391
1528
  createdAt: string;
1392
- /** ISO 8601 or null for non-expiring tokens. */
1393
- expiresAt: string | null;
1394
- /** Last 4 chars for display. */
1395
- suffix: string;
1396
- scope: string;
1397
- };
1398
- type MyNotification = {
1399
- id: string;
1400
- type: string;
1401
- payload: Record<string, unknown>;
1402
- createdAt: string;
1403
- readAt: string | null;
1529
+ /** ISO 8601. */
1530
+ expiresAt: string;
1531
+ lastUsedAt: string | null;
1532
+ revokedReason: string | null;
1533
+ status: "active" | "revoked" | "expired";
1534
+ };
1535
+ /** Body of POST /me/api-tokens. Each `scopeManifest` field narrows the token; `null` or absent leaves it unrestricted. */
1536
+ type CreateMyApiTokenInput = {
1537
+ label: string;
1538
+ scopeManifest: {
1539
+ operations?: ReadonlyArray<"read" | "write" | "admin"> | null | undefined;
1540
+ projects?: ReadonlyArray<string> | null | undefined;
1541
+ resourceClasses?: ReadonlyArray<string> | null | undefined;
1542
+ collections?: Record<string, unknown> | null | undefined;
1543
+ cidrs?: ReadonlyArray<string> | null | undefined;
1544
+ };
1545
+ /** Token lifetime in seconds (60 to 31536000). */
1546
+ ttlSeconds?: number | undefined;
1404
1547
  };
1405
1548
  declare function makeMeNamespace(config: HttpClientConfig): {
1406
1549
  profile: {
1407
1550
  /** GET /me — operator profile (cross-org). */
1408
1551
  get(): Promise<Envelope<MyProfile>>;
1409
- /** PATCH /me — update mutable profile fields (displayName). */
1410
- update(patch: {
1411
- displayName?: string | null;
1412
- }): Promise<Envelope<MyProfile>>;
1552
+ /** PATCH /me — update mutable profile fields (displayName, locale, timezone). */
1553
+ update(patch: UpdateMyProfileInput): Promise<Envelope<MyProfile>>;
1413
1554
  };
1414
1555
  sessions: {
1415
1556
  /** GET /me/sessions — list active sessions for the operator. */
1416
1557
  list(): Promise<Envelope<ReadonlyArray<MySession>>>;
1417
- /** DELETE /me/sessions/<sessionId> — revoke a specific session. */
1558
+ /** POST /auth/sessions/<sessionId>/revoke — revoke a specific session. */
1418
1559
  revoke(sessionId: string): Promise<Envelope<{
1419
1560
  revoked: boolean;
1420
1561
  }>>;
1421
- /** DELETE /me/sessions (no path) — revoke all sessions except the current one. */
1562
+ /** POST /me/sessions/revoke-all — revoke all of the operator's sessions except the current one. */
1422
1563
  revokeAll(): Promise<Envelope<{
1423
1564
  revoked: number;
1424
1565
  }>>;
1425
1566
  };
1426
- /**
1427
- * API tokens for personal scripting. The gateway endpoints are not available yet,
1428
- * so these methods return K9O_NOT_FOUND until they ship.
1429
- */
1567
+ /** Personal access tokens for scripting. */
1430
1568
  apiTokens: {
1431
1569
  list(): Promise<Envelope<ReadonlyArray<MyApiToken>>>;
1432
- create(input: {
1433
- name: string;
1434
- expiresInDays?: number | undefined;
1435
- scope?: string | undefined;
1436
- }): Promise<Envelope<MyApiToken & {
1437
- token: string;
1438
- }>>;
1439
- delete(tokenId: string): Promise<Envelope<{
1440
- deleted: boolean;
1441
- }>>;
1442
- };
1443
- /**
1444
- * Notifications — operator-targeted (account-level events). Forward-
1445
- * cycle substrate; methods route correctly when gateway ships.
1446
- */
1447
- notifications: {
1448
- list(opts?: {
1449
- unreadOnly?: boolean | undefined;
1450
- limit?: number | undefined;
1451
- cursor?: string | undefined;
1452
- }): Promise<Envelope<ReadonlyArray<MyNotification>>>;
1453
- markRead(notificationId: string): Promise<Envelope<MyNotification>>;
1454
- markAllRead(): Promise<Envelope<{
1455
- marked: number;
1456
- }>>;
1457
- };
1458
- /**
1459
- * Operator-self audit log — actions performed BY this operator across
1460
- * orgs. Distinct from `client.audit` (project-plane) and
1461
- * `client.org.auditLog` (org-plane).
1462
- */
1463
- auditLog: {
1464
- query(opts?: {
1465
- since?: string | undefined;
1466
- until?: string | undefined;
1467
- type?: string | undefined;
1468
- limit?: number | undefined;
1469
- cursor?: string | undefined;
1470
- }): Promise<Envelope<ReadonlyArray<{
1471
- id: string;
1472
- type: string;
1473
- occurredAt: string;
1474
- payload: Record<string, unknown>;
1475
- }>>>;
1476
- };
1477
- /**
1478
- * Personal data export per GDPR-style requests. Returns a job id
1479
- * the operator polls for completion.
1480
- */
1481
- dataExport: {
1482
- request(input?: {
1483
- format?: "json" | "csv";
1484
- }): Promise<Envelope<{
1485
- jobId: string;
1486
- status: "queued" | "in-progress" | "ready";
1487
- }>>;
1488
- status(jobId: string): Promise<Envelope<{
1489
- jobId: string;
1490
- status: "queued" | "in-progress" | "ready" | "failed";
1491
- downloadUrl: string | null;
1570
+ create(input: CreateMyApiTokenInput): Promise<Envelope<MyApiToken & {
1571
+ plaintext: string;
1492
1572
  }>>;
1573
+ delete(tokenId: string): Promise<Envelope<MyApiToken>>;
1493
1574
  };
1494
1575
  };
1495
1576
 
@@ -1580,7 +1661,7 @@ declare const DASHBOARD_ERROR_CODES: {
1580
1661
  * Workflows substrate. Mirrors
1581
1662
  * `_sys.workflows` + `_sys.workflow_runs` row shapes.
1582
1663
  *
1583
- * Wire mapping (project-plane;):
1664
+ * Wire mapping (project-plane):
1584
1665
  * - list() → GET /@<slug>/workflows
1585
1666
  * - create(workflow) → POST /@<slug>/workflows
1586
1667
  * - read(id) → GET /@<slug>/workflows/<wfl-id>
@@ -1591,9 +1672,9 @@ declare const DASHBOARD_ERROR_CODES: {
1591
1672
  * - runs.read(id, runId) → GET /@<slug>/workflows/<wfl-id>/runs/<wfr-id>
1592
1673
  * - runs.cancel(id, runId) → POST /@<slug>/workflows/<wfl-id>/runs/<wfr-id>/cancel
1593
1674
  *
1594
- * Per RBAC: create/update/delete/trigger/cancel require
1675
+ * RBAC: create/update/delete/trigger/cancel require
1595
1676
  * PROJECT_AUTHOR; list/read/runs read against all cohort roles subject
1596
- * to RLS. Per, surfaces 6 K9O_WORKFLOW_* error codes (see
1677
+ * to RLS. Surfaces 6 K9O_WORKFLOW_* error codes (see
1597
1678
  * `WORKFLOW_ERROR_CODES`); callers narrow on `error.code`.
1598
1679
  */
1599
1680
 
@@ -1616,7 +1697,7 @@ type WorkflowAction = {
1616
1697
  /** Sibling steps with parallel:true execute concurrently. */
1617
1698
  parallel?: boolean;
1618
1699
  };
1619
- /** Workflow record `_sys.workflows` row. */
1700
+ /** Workflow record. */
1620
1701
  type Workflow = {
1621
1702
  /** `wfl_<base62>`. */
1622
1703
  id: string;
@@ -1647,7 +1728,7 @@ type WorkflowRunStep = {
1647
1728
  outputSummary?: unknown;
1648
1729
  costSubtotal?: number;
1649
1730
  };
1650
- /** Workflow run record `_sys.workflow_runs` row. */
1731
+ /** Workflow run record. */
1651
1732
  type WorkflowRun = {
1652
1733
  /** `wfr_<base62>`. */
1653
1734
  id: string;
@@ -1772,23 +1853,20 @@ declare function makeAiNamespace(config: HttpClientConfig): {
1772
1853
  * yielding `RealtimeEvent`s — the caller writes idiomatic
1773
1854
  * `for await (const event of client.realtime.subscribe(topic)) { ... }`.
1774
1855
  *
1775
- * Per `feedback_sdk_abstracted_primitive_default_to_richer_interaction.md`
1776
- * +: the SDK chooses the transport (WebSocket primary → SSE
1777
- * → poll), transparently. SPLIT (polling) is the SDK-internal fallback
1778
- * when WebSocket / SSE are unavailable — NOT a consumer-side design
1779
- * choice. The consumer sees one uniform async iterable regardless.
1856
+ * Transport: SSE over `GET /@<slug>/realtime/subscribe`. The gateway
1857
+ * serves no WebSocket upgrade and no durable replay, so neither is
1858
+ * offered; after an `event: resync` frame the client re-reads current
1859
+ * state from the data plane and resubscribes.
1780
1860
  *
1781
- * Wire mapping (project-plane;):
1782
- * - subscribe → GET /@<slug>/realtime/subscribe?topic=<t>&filter=<jsonb> (WS/SSE upgrade)
1783
- * - replay → POST /@<slug>/realtime/replay { topic, fromSequence, untilSequence?, limit? }
1861
+ * Wire mapping (project-plane):
1862
+ * - subscribe → GET /@<slug>/realtime/subscribe?topic=<t>&filter=<jsonb> (SSE)
1784
1863
  *
1785
- * Per, `filter` + RLS compose (filter narrows, RLS gates).
1786
- * Per, surfaces no new codes — reuses K9O_INVALID_FILTER +
1787
- * K9O_SUBSCRIPTION_LIMIT_EXCEEDED + K9O_TIER_FEATURE_GATED.
1864
+ * `filter` + RLS compose (filter narrows, RLS gates). Surfaces
1865
+ * K9O_INVALID_FILTER, K9O_SUBSCRIPTION_LIMIT_EXCEEDED and K9O_TIER_FEATURE_GATED.
1788
1866
  */
1789
1867
 
1790
1868
  /**
1791
- * The 6 closed subscription topic families. Concrete
1869
+ * The 6 closed subscription topic families . Concrete
1792
1870
  * topic strings carry a dynamic segment (collection name, resource id,
1793
1871
  * event family) — use `realtimeTopic.*` builders to construct them.
1794
1872
  */
@@ -1796,7 +1874,7 @@ type RealtimeTopicFamily = "collections" | "studio.workflows.runs" | "studio.que
1796
1874
  /** A concrete topic string, e.g. `studio.dashboards.refresh.dsh_abc`. */
1797
1875
  type RealtimeTopic = string;
1798
1876
  /**
1799
- * Typed builders for the 6 topic families. Prefer these
1877
+ * Typed builders for the 6 topic families . Prefer these
1800
1878
  * over hand-built strings for compile-time family safety.
1801
1879
  */
1802
1880
  declare const realtimeTopic: {
@@ -1813,15 +1891,13 @@ declare const realtimeTopic: {
1813
1891
  /** `audit.org.<event-family>` — org-plane audit events. */
1814
1892
  readonly auditOrg: (eventFamily: string) => RealtimeTopic;
1815
1893
  };
1816
- /** Per-topic filter predicate (vocabulary). */
1894
+ /** Per-topic filter predicate . */
1817
1895
  type RealtimeFilter = Record<string, unknown>;
1818
- /** A single realtime event delivered on a subscription. */
1896
+ /** A single realtime event, as the gateway frames it (wire spelling). */
1819
1897
  type RealtimeEvent<T = unknown> = {
1820
1898
  topic: RealtimeTopic;
1821
1899
  /** Event type within the topic family (e.g. `row_inserted`, `workflow.run.completed`). */
1822
- type: string;
1823
- /** Monotonic sequence number — use as `fromSequence` for replay catch-up. */
1824
- sequence: number;
1900
+ eventType: string;
1825
1901
  payload: T;
1826
1902
  occurredAt: string;
1827
1903
  };
@@ -1829,57 +1905,30 @@ type SubscribeOptions = {
1829
1905
  filter?: RealtimeFilter;
1830
1906
  /** Abort the subscription (closes the underlying transport). */
1831
1907
  signal?: AbortSignal;
1832
- /**
1833
- * Force a transport instead of the WebSocket → SSE → poll cascade.
1834
- * Mainly for tests + constrained runtimes. Omit for production —
1835
- * the SDK picks the richest available transport.
1836
- */
1837
- transport?: RealtimeTransportKind;
1838
- /** Poll-transport interval in ms (default 2000). Only used when polling. */
1839
- pollIntervalMs?: number;
1840
1908
  };
1841
- type RealtimeTransportKind = "websocket" | "sse" | "poll";
1842
1909
  /**
1843
1910
  * A live subscription. It is itself an async iterable (`for await`) and
1844
- * exposes `close()` for explicit teardown + `transport` for diagnostics.
1911
+ * exposes `close()` for explicit teardown.
1845
1912
  */
1846
1913
  type RealtimeSubscription<T = unknown> = AsyncIterable<RealtimeEvent<T>> & {
1847
1914
  /** Stop the subscription + release the underlying transport. */
1848
1915
  close(): void;
1849
- /** The transport actually selected (post-fallback). */
1850
- readonly transport: RealtimeTransportKind;
1851
- };
1852
- type ReplayInput = {
1853
- topic: RealtimeTopic;
1854
- filter?: RealtimeFilter;
1855
- fromSequence: number;
1856
- untilSequence?: number;
1857
- limit?: number;
1858
1916
  };
1859
1917
  declare function makeRealtimeNamespace(config: HttpClientConfig): {
1860
1918
  /**
1861
1919
  * Subscribe to a topic. Returns a `RealtimeSubscription` — an async
1862
- * iterable of `RealtimeEvent`s. The SDK selects the richest available
1863
- * transport (WebSocket → SSE → poll); the caller's
1864
- * `for await` loop is transport-agnostic.
1920
+ * iterable of `RealtimeEvent`s over SSE.
1865
1921
  *
1866
1922
  * ```ts
1867
1923
  * const sub = client.realtime.subscribe(
1868
1924
  * realtimeTopic.dashboardRefresh("dsh_abc"),
1869
1925
  * );
1870
1926
  * for await (const event of sub) {
1871
- * if (event.type === "dashboard.widget.data_refreshed") rerender(event.payload);
1927
+ * if (event.eventType === "dashboard.widget.data_refreshed") rerender(event.payload);
1872
1928
  * }
1873
1929
  * ```
1874
1930
  */
1875
1931
  subscribe<T = unknown>(topic: RealtimeTopic, options?: SubscribeOptions): RealtimeSubscription<T>;
1876
- /**
1877
- * One-shot historical replay — catch up on missed
1878
- * events from `fromSequence`. Capped at 10k events server-side;
1879
- * paginate via the returned events' `sequence`. Use the highest
1880
- * `sequence` you've seen as the next `fromSequence`.
1881
- */
1882
- replay<T = unknown>(input: ReplayInput): Promise<Envelope<ReadonlyArray<RealtimeEvent<T>>>>;
1883
1932
  };
1884
1933
 
1885
1934
  /**
@@ -2083,9 +2132,6 @@ type K9oClient = {
2083
2132
  * `client.kibo.vault.secrets` (credential pre-create): this namespace only registers a caller-supplied
2084
2133
  * `credentialRef` string, never creates or resolves one. */
2085
2134
  storage: ReturnType<typeof makeStorageNamespace>;
2086
- /** Cross-surface metadata query — `client.metadata.from(...).where(...).execute()`. Client-side
2087
- * only until the gateway's Inc-2 route lands; see `metadata.ts` for status. */
2088
- metadata: ReturnType<typeof makeMetadataNamespace>;
2089
2135
  /** Migration lifecycle — `client.migrations.apply()` etc. */
2090
2136
  migrations: ReturnType<typeof makeMigrationsNamespace>;
2091
2137
  /** Function deploy + invoke — `client.functions.deploy()` etc. */
@@ -2106,7 +2152,7 @@ type K9oClient = {
2106
2152
  compute: ReturnType<typeof makeComputeNamespace>;
2107
2153
  /** Platform AI primitives — `client.ai.embed({ model?, input })`. */
2108
2154
  ai: ReturnType<typeof makeAiNamespace>;
2109
- /** Realtime subscriptions — `client.realtime.subscribe()` / `.replay()`. */
2155
+ /** Realtime subscriptions — `client.realtime.subscribe()` (SSE). */
2110
2156
  realtime: ReturnType<typeof makeRealtimeNamespace>;
2111
2157
  /** Gate (Identity-Aware Kernel) — composed from `@k9o/gate`. Available when projectSlug is bound on the client. */
2112
2158
  readonly gate: GateClient;
@@ -2124,4 +2170,4 @@ type K9oClient = {
2124
2170
  */
2125
2171
  declare function createClient(options: CreateClientOptions): K9oClient;
2126
2172
 
2127
- export { type ActionRule, type AppliedMigration, type AuditEvent, type AuditQueryOpts, BYOS_CRED_FORMAT_VERSION, BYOS_CRED_REF_PREFIX, BYOS_CRED_VAULT_NAME_PREFIX, BYOS_PROVIDER_SCHEME, type ByosCredInput, type ByosCredProvider, type CollectionPolicy, type ColumnReferences, type ColumnSpec, type CreateBucketOptions, CreateClientOptions, type CreateDashboardInput, type CreateOrgIdpInput, type CreatePolicyInput, type CreateProjectInput, type CreateStorageLocationInput, type CreateWorkflowInput, DASHBOARD_ERROR_CODES, type Dashboard, type DashboardListFilters, type DashboardStatus, type DeletedBucket, type DeployFunctionInput, type EmbedInput, type EmbedResult, type EmbeddingModelId, Envelope, FilterOp, type FunctionRecord, type IndexSpec, type K9oClient, type LLMInvokeInput, type LLMInvokeParams, type LLMModality, type LLMModel, type LLMModelId, type LLMProviderClass, type LLMResponse, type LLMStreamChunk, LLM_ERROR_CODES, METADATA_OPERATORS, type MetadataOperator, type MetadataQueryBuilder, type MetadataQueryRecord, type MetadataQueryResult, type MetadataSlice, type MetadataSurface, type MetadataWhereClause, type Migration, type MigrationPolicy, type MyApiToken, type MyNotification, type MyProfile, type MySession, type Operation, type Org, type OrgAuditEvent, type OrgGroup, type OrgIdpProvider, type OrgMember, type OrgRoleGrant, type PendingMigration, type PolicyBundle, type Project, type ProviderRegionProvider, type RealtimeEvent, type RealtimeFilter, type RealtimeSubscription, type RealtimeTopic, type RealtimeTopicFamily, type RealtimeTransportKind, type RelationshipSpec, type RemovedObject, type ReplayInput, type RetiredStorageLocation, type SignedUrl, type SignedUrlOptions, type SmtpConfig, type SmtpTestEmailInput, type SmtpTestEmailResult, type StorageBucket, type StorageBucketPolicy, type StorageLocation, type StorageLocationCustodyMode, type StorageLocationProvider, type StorageLocationProviderParams, type StorageLocationTestResult, type StorageObject, type SubscribeOptions, type UpdateBucketOptions, type UpdateDashboardInput, type UpdatePolicyInput, type UpdateProjectInput, type UpdateStorageLocationInput, type UpdateWorkflowInput, type UploadOptions, type ValidatePolicyResult, WORKFLOW_ERROR_CODES, type Widget, type WidgetDataSourceMode, type WidgetType, type Workflow, type WorkflowAction, type WorkflowActionType, type WorkflowListFilters, type WorkflowRun, type WorkflowRunListFilters, type WorkflowRunStatus, type WorkflowRunStep, type WorkflowStatus, type WorkflowTriggerType, assertProviderRegion, byosCredVaultName, byosCredentialRef, createClient, encodeByosCredential, isProviderRegion, realtimeTopic };
2173
+ export { type ActionRule, type AppliedMigration, type AppliedMigrationRow, type ApplyMigrationsResult, type ApplyPendingResult, type AuditEvent, type AuditQueryOpts, BYOS_CRED_FORMAT_VERSION, BYOS_CRED_REF_PREFIX, BYOS_CRED_VAULT_NAME_PREFIX, BYOS_PROVIDER_SCHEME, type ByosCredInput, type ByosCredProvider, type CollectionPolicy, type ColumnReferences, type ColumnSpec, type CreateBucketOptions, CreateClientOptions, type CreateDashboardInput, type CreateMyApiTokenInput, type CreateOrgIdpInput, type CreatePolicyInput, type CreateProjectInput, type CreateStorageLocationInput, type CreateWorkflowInput, DASHBOARD_ERROR_CODES, type Dashboard, type DashboardListFilters, type DashboardStatus, type DeletedBucket, type DeployFunctionInput, type EmbedInput, type EmbedResult, type EmbeddingModelId, Envelope, FilterOp, type FunctionRecord, type IndexSpec, type K9oClient, type LLMInvokeInput, type LLMInvokeParams, type LLMModality, type LLMModel, type LLMModelId, type LLMProviderClass, type LLMResponse, type LLMStreamChunk, type LLMUsage, LLM_ERROR_CODES, type Migration, type MigrationPolicy, type MyApiToken, type MyProfile, type MySession, type Operation, type Org, type OrgAuditEvent, type OrgDefaultLlm, type OrgGroup, type OrgIdpProvider, type OrgIdpProviderKind, type OrgInviteResult, type OrgMember, type OrgRoleGrant, type PendingMigration, type PendingMigrationStatus, type PolicyBundle, type PolicyDocument, type PolicyPublishResult, type Project, type ProviderRegionProvider, type PublishPolicyOptions, type QueuedMigration, type RealtimeEvent, type RealtimeFilter, type RealtimeSubscription, type RealtimeTopic, type RealtimeTopicFamily, type RelationshipSpec, type RemovedObject, type RetiredStorageLocation, type SignedUrl, type SignedUrlOptions, type SkippedMigrationRow, type SmtpConfig, type SmtpTestEmailInput, type SmtpTestEmailResult, type StorageBucket, type StorageBucketPolicy, type StorageLocation, type StorageLocationCustodyMode, type StorageLocationProvider, type StorageLocationProviderParams, type StorageLocationTestResult, type StorageObject, type SubscribeOptions, type UpdateBucketOptions, type UpdateDashboardInput, type UpdateMyProfileInput, type UpdateOrgIdpInput, type UpdatePolicyInput, type UpdateProjectInput, type UpdateStorageLocationInput, type UpdateWorkflowInput, type UploadOptions, type ValidatePolicyResult, WORKFLOW_ERROR_CODES, type Widget, type WidgetDataSourceMode, type WidgetType, type Workflow, type WorkflowAction, type WorkflowActionType, type WorkflowListFilters, type WorkflowRun, type WorkflowRunListFilters, type WorkflowRunStatus, type WorkflowRunStep, type WorkflowStatus, type WorkflowTriggerType, assertProviderRegion, byosCredVaultName, byosCredentialRef, createClient, encodeByosCredential, isProviderRegion, realtimeTopic };