primitive-admin 1.2.0-alpha.11 → 1.2.0-alpha.13

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 (55) hide show
  1. package/dist/src/commands/agent-sessions.d.ts +26 -10
  2. package/dist/src/commands/agent-sessions.js +80 -83
  3. package/dist/src/commands/agent-sessions.js.map +1 -1
  4. package/dist/src/commands/init.js +108 -34
  5. package/dist/src/commands/init.js.map +1 -1
  6. package/dist/src/commands/locks.d.ts +5 -3
  7. package/dist/src/commands/locks.js +17 -61
  8. package/dist/src/commands/locks.js.map +1 -1
  9. package/dist/src/commands/rule-sets.d.ts +1 -1
  10. package/dist/src/commands/rule-sets.js +0 -1
  11. package/dist/src/commands/rule-sets.js.map +1 -1
  12. package/dist/src/commands/sync.d.ts +28 -0
  13. package/dist/src/commands/sync.js +255 -70
  14. package/dist/src/commands/sync.js.map +1 -1
  15. package/dist/src/lib/api-client.d.ts +6 -4
  16. package/dist/src/lib/api-client.js +4 -14
  17. package/dist/src/lib/api-client.js.map +1 -1
  18. package/dist/src/lib/config-object-descriptor.js +1 -0
  19. package/dist/src/lib/config-object-descriptor.js.map +1 -1
  20. package/dist/src/lib/db-codegen/dbTypeIR.d.ts +13 -0
  21. package/dist/src/lib/db-codegen/dbTypeIR.js +13 -0
  22. package/dist/src/lib/db-codegen/dbTypeIR.js.map +1 -1
  23. package/dist/src/lib/db3-type-models.d.ts +92 -0
  24. package/dist/src/lib/db3-type-models.js +321 -0
  25. package/dist/src/lib/db3-type-models.js.map +1 -0
  26. package/dist/src/lib/function-db-types.d.ts +3 -1
  27. package/dist/src/lib/function-db-types.js +42 -8
  28. package/dist/src/lib/function-db-types.js.map +1 -1
  29. package/dist/src/lib/function-typecheck.js +3 -0
  30. package/dist/src/lib/function-typecheck.js.map +1 -1
  31. package/dist/src/lib/generated-config-surfaces.d.ts +19 -2
  32. package/dist/src/lib/generated-config-surfaces.js +38 -3
  33. package/dist/src/lib/generated-config-surfaces.js.map +1 -1
  34. package/dist/src/lib/generated-sdk-types.d.ts +1 -1
  35. package/dist/src/lib/generated-sdk-types.js +1 -1
  36. package/dist/src/lib/generated-sdk-types.js.map +1 -1
  37. package/dist/src/lib/init-assets.d.ts +2 -6
  38. package/dist/src/lib/init-assets.js +11 -27
  39. package/dist/src/lib/init-assets.js.map +1 -1
  40. package/dist/src/lib/init-ios-links.d.ts +11 -7
  41. package/dist/src/lib/init-ios-links.js +28 -22
  42. package/dist/src/lib/init-ios-links.js.map +1 -1
  43. package/dist/src/lib/init-schema.d.ts +15 -0
  44. package/dist/src/lib/init-schema.js +54 -0
  45. package/dist/src/lib/init-schema.js.map +1 -1
  46. package/dist/src/lib/session-scope.d.ts +26 -0
  47. package/dist/src/lib/session-scope.js +58 -0
  48. package/dist/src/lib/session-scope.js.map +1 -0
  49. package/dist/src/lib/sync-resource-types.d.ts +54 -0
  50. package/dist/src/lib/sync-resource-types.js +92 -1
  51. package/dist/src/lib/sync-resource-types.js.map +1 -1
  52. package/dist/src/lib/template.d.ts +39 -3
  53. package/dist/src/lib/template.js +103 -14
  54. package/dist/src/lib/template.js.map +1 -1
  55. package/package.json +2 -2
@@ -9,5 +9,5 @@
9
9
  * Regenerate with:
10
10
  * node cli/scripts/gen-sdk-types.mjs
11
11
  */
12
- export const SDK_TYPES_SOURCE = "// GENERATED by scripts/generate-function-profile.mjs from openapi.json.\n// DO NOT EDIT. Run `pnpm functions:profile` and commit the result; the\n// freshness guard in tests/api/spec/function-profile.test.ts fails when this\n// file and a fresh generation diverge.\n\n/**\n * Type surface of `primitive-functions` — what a server function's author writes\n * against (#3180). The published package's RUNTIME is a stub that throws from\n * every export on purpose: the platform substitutes its own copy at invoke\n * time, and reaching the stub means it did not.\n *\n * WHICH USER A CALL IS ABOUT. Every `ctx.api` and `ctx.agents` call that is\n * about one user says which user in `userId`. Omitted, it means the invoking\n * user (`ctx.user`); in a run with no caller (cron, a webhook, the system\n * door, a nested start under one of them) it must be named, or the call\n * rejects with `FUNCTION_SUBJECT_REQUIRED`. Naming a user other than the\n * invoking user — whether `userId` is optional or required on the call — is\n * allowed in a run with no caller or one an app owner or admin invoked, with\n * the role read at the call. An ordinary member's run may name another member\n * only when its function's TOML declares `users:readAny` (on a read: their\n * memberships, collections, documents, root document, inbox, devices and\n * agent sessions) or `users:actAsAny` (on a call that acts as them:\n * notifications read and devices, `ctx.agents` session calls,\n * `ctx.db3` `asUser`, their aliases); otherwise, and in every run an\n * agent drives (a tool, context or history run and anything it starts), it\n * rejects with `SUBJECT_USER_FORBIDDEN`. A named user who is not a member of\n * the app rejects with `SUBJECT_USER_NOT_FOUND`. Calls that hand something\n * to a user (`notifications.send`, `users.setProfile`, a channel grant)\n * and app-wide reads are outside this rule.\n */\n\n/**\n * The signed-in user who invoked the function over HTTP.\n *\n * Attribution, never authority (#3279): function code acts as the system\n * whoever called it, so this says WHO asked, and the rows the function writes\n * are attributed to them. A trigger fire has no caller and `ctx.user` is\n * null.\n */\nexport interface FunctionUser {\n userId: string;\n email: string | null;\n}\n\n/**\n * What started this invocation. Narrow on `kind`.\n *\n * The same union the runtime builds (`src/server-functions/trigger-descriptor.ts`),\n * held identical by `tests/api/spec/function-trigger-declarations-3281.test.ts`:\n * a field the fire path sets is declared here, and nothing is declared here\n * that the fire path does not set.\n */\nexport type FunctionTrigger =\n /**\n * An HTTP invocation: the caller is `ctx.user`.\n *\n * `runKey` is the key a `start` was coalesced by (#3562) — what you\n * passed as `runKey` to make the run a singleton — and null when the\n * start named none, or when the call was an `invoke`, which coalesces\n * nothing.\n */\n | { kind: \"http\"; runKey: string | null }\n /** A verified webhook delivery to the function's own key. */\n | {\n kind: \"webhook\";\n /** The webhook key, which is the function key. */\n webhookKey: string;\n /** The platform's webhook row the delivery log lives under. */\n webhookId: string;\n /** The provider's event id (`X-Webhook-Event-Id`), when it sent one. */\n externalEventId: string | null;\n }\n /** A cron entry firing, scheduled or from the `functions triggers fire` diagnostic. */\n | {\n kind: \"cron\";\n /** The `[[function.triggers.cron]]` entry's `name`. */\n name: string;\n /** The platform's cron row. */\n triggerId: string;\n /** ISO 8601. The instant the fire was scheduled for; a diagnostic fire's is \"now\". */\n scheduledFor: string;\n /** Present, and true, only on the diagnostic fire: nothing was scheduled. */\n manual?: true;\n }\n /**\n * Another function started this one with `ctx.functions.start` (#3280).\n *\n * `functionKey` names the PARENT, and `runId` its run — null when the\n * parent was a request invocation over HTTP, which writes no run row.\n * `runKey` is the key the parent's start named, or null (#3562).\n */\n | {\n kind: \"function\";\n functionKey: string;\n runId: string | null;\n runKey: string | null;\n }\n /**\n * An admin ran this function as the SYSTEM, from outside any trigger\n * (#3448) — `primitive functions invoke --as system`.\n *\n * `ctx.user` is null and the code runs with the app's system authority, as\n * it does for a cron or webhook fire. `userId` names the admin who asked:\n * attribution, never the principal the code runs as. `runKey` is the key\n * the admin's start named, or null (#3562).\n */\n | { kind: \"manual\"; userId: string; runKey: string | null }\n /**\n * An agent turn called this function as one of its tools.\n *\n * `ctx.user` is the turn's initiator, whose `access` gate the call\n * passed, and `ctx.tool` carries the session's ids, members and\n * variables, and the turn's context, timezone and locale. `callId` is the same on every attempt of the call, so use\n * it as an idempotency key. `toolName` is the declared tool name, which\n * may differ from the function's key.\n */\n | {\n kind: \"tool\";\n sessionId: string;\n turnId: string;\n callId: string;\n toolName: string;\n }\n /** An agent turn asked this function for its turn context. */\n | { kind: \"context\"; sessionId: string; turnId: string }\n /** An agent turn asked this function for the history to send the model. */\n | { kind: \"history\"; sessionId: string; turnId: string }\n /**\n * One flush of a db3 of a type a `[[function.triggers.db3]]` entry\n * watches: a client's socket batch, a records-route write or a partial\n * bulk that accepted at least one entry. `from` and `to` are the flush's\n * first and last log numbers. The run's input carries the changed records'\n * keys and change kinds, not their values: read what you need through\n * `ctx.db3(trigger.db3Id, trigger.type)`.\n *\n * A watcher that writes the db3 it watches starts another run per flush,\n * bounded only by its `ratePerMinute`; branch on\n * `ctx.trigger.kind === \"db3\"` to skip the writes a flush of your own\n * started.\n */\n | {\n kind: \"db3\";\n db3Id: string;\n type: string;\n triggerId: string;\n from: number;\n to: number;\n };\n\n/** The door names `ctx.trigger.kind` can hold. */\nexport type FunctionTriggerKind = FunctionTrigger[\"kind\"];\n\n/**\n * The agent session a tool call belongs to — `ctx.tool`, set only when\n * `ctx.trigger.kind === \"tool\"`.\n *\n * Variables and members describe the session; they grant nothing. Check what\n * `ctx.user` (the turn's initiator) may do before acting for them.\n */\nexport interface FunctionToolContext {\n readonly sessionId: string;\n /**\n * The session's document, which holds its messages.\n * @deprecated Use `sessionId` with the session API (`ctx.agents`,\n * `ctx.api.agentSessions`); the field remains until a later breaking release.\n */\n readonly documentId: string;\n readonly turnId: string;\n /** The call's id, the same on every attempt: an idempotency key. */\n readonly callId: string;\n /** The tool's declared name. */\n readonly toolName: string;\n /** The session's owner. */\n readonly ownerUserId: string;\n /** The session's members by role, besides the owner. */\n readonly members: {\n readonly viewerUserIds: string[];\n readonly participantUserIds: string[];\n };\n /** The session's variables, set when it was created. */\n readonly variables: Record<string, unknown>;\n /**\n * The turn's validated context: the object the member's send carried,\n * checked against the agent's `turnContext.schema`, or the return of the\n * agent's context function. The same values the system prompt rendered as\n * `turn.*`. Null when the turn carried none.\n */\n readonly context: Record<string, unknown> | null;\n /**\n * The IANA timezone the turn's send carried, such as\n * `\"Pacific/Auckland\"`; the prompt's `turn.timezone`. Null when it\n * carried none.\n */\n readonly timezone: string | null;\n /**\n * The BCP 47 locale the turn's send carried, such as `\"en-NZ\"`; the\n * prompt's `turn.locale`. Null when it carried none.\n */\n readonly locale: string | null;\n /**\n * Attach an app-only artifact to this call's row, replacing any earlier\n * one. The model never sees it; your app reads it from the call's row —\n * `artifact`, or, for one over 64 KiB of JSON or past the agent's\n * `maxRowBytes`, the blob on the session's document named by\n * `artifactBlobId`. At most 4 MiB of JSON: a larger value rejects with\n * `AGENT_ARTIFACT_TOO_LARGE`, and a call that already has its result with\n * `AGENT_CALL_NOT_RUNNING`.\n */\n attachArtifact(value: unknown): Promise<void>;\n}\n\n/** The result shape of an operation that answers in response headers. */\nexport interface HeaderResult {\n status: number;\n headers: Record<string, string>;\n}\n\n/**\n * A platform call that was refused. `errorCode` carries the gateway's own\n * codes (`FUNCTION_ROUTE_NOT_ALLOWED`, `FUNCTION_EGRESS_DENIED`, …) as well\n * as the route's.\n */\nexport interface PrimitivePlatformError extends Error {\n status: number;\n errorCode: string | null;\n /**\n * The route's structured `details`, or null when its refusal carries none\n * (#3803). `AGENT_SESSION_VARIABLES_INVALID` lists `errors` as\n * `{ path, message }`.\n */\n details: unknown;\n}\n\n/**\n * The typed HTTP profile, generated from the platform's OpenAPI document. Its\n * namespaces mirror the operation ids: agentSessions, analytics, blobBuckets, channels, collections, configVars, connections, databaseTypeConfigs, databases, db3, documents, email, functions, groups, integrations, locks, notifications, prompts, resourceMetadata, secrets, users.\n * Methods take one options object carrying the operation's path parameters,\n * query parameters, request headers (under their wire names) and `body`.\n *\n * Generated from the same operations as the runtime profile, so a method that\n * type-checks is a method the platform publishes — and a missing path\n * parameter or a missing required header is a compile error rather than a\n * `TypeError` at invoke time. Every call runs with the app's own SYSTEM\n * authority (#3279): the invocation gate was the authorization. The two\n * namespaces the gateway does not admit are still declared: they exist, they\n * answer the gateway's structured denial, and hiding them would make a route's\n * availability look like a typo. Those are `databaseTypeConfigs` whole, and\n * `functions` except for `functions.start` — the nested-start door #3280\n * admits by name, which `ctx.functions.start` calls. `functions.invoke`\n * stays refused: same-run composition is an import.\n */\nexport interface FunctionApi {\n \"agentSessions\": {\n /** `agentSessions.addMember` — POST /agent-sessions/{sessionId}/members. Add a member to an agent session, or change their role */\n \"addMember\"(args: {\n \"sessionId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `agentSessions.answer` — POST /agent-sessions/{sessionId}/calls/{callId}/answer. Answer a paused agent turn's call */\n \"answer\"(args: {\n \"sessionId\": string | number;\n \"callId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `agentSessions.attachArtifact` — POST /agent-sessions/{sessionId}/calls/{callId}/artifact. Attach an artifact to a running agent tool call (ctx.tool.attachArtifact) */\n \"attachArtifact\"(args: {\n \"sessionId\": string | number;\n \"callId\": string | number;\n body: unknown;\n }): Promise<any>;\n \"attachments\": {\n /** `agentSessions.attachments.downloadHeaders` — HEAD /agent-sessions/{sessionId}/attachments/{blobId}/download. Get an agent session attachment's download headers */\n \"downloadHeaders\"(args: {\n \"sessionId\": string | number;\n \"blobId\": string | number;\n \"disposition\"?: string | number | boolean;\n }): Promise<HeaderResult>;\n /** `agentSessions.attachments.downloadUrl` — GET /agent-sessions/{sessionId}/attachments/{blobId}/download. Download an agent session attachment */\n \"downloadUrl\"(args: {\n \"sessionId\": string | number;\n \"blobId\": string | number;\n \"disposition\"?: string | number | boolean;\n }): Promise<Uint8Array>;\n /** `agentSessions.attachments.upload` — PUT /agent-sessions/{sessionId}/attachments/{blobId}. Upload an agent session attachment */\n \"upload\"(args: {\n \"sessionId\": string | number;\n \"blobId\": string | number;\n \"X-Blob-Filename\": string | number;\n \"X-Blob-Size\": string | number;\n \"X-Blob-Sha256\": string | number;\n \"Content-Type\"?: string | number;\n body: ArrayBuffer | Uint8Array | string;\n }): Promise<any>;\n };\n /** `agentSessions.cancel` — POST /agent-sessions/{sessionId}/cancel. Cancel an agent session's active turn */\n \"cancel\"(args: {\n \"sessionId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `agentSessions.create` — POST /agent-sessions. Create an agent session (ctx.agents.createSession) */\n \"create\"(args: {\n body: unknown;\n }): Promise<any>;\n /** `agentSessions.delete` — DELETE /agent-sessions/{sessionId}. Delete an agent session (ctx.agents.deleteSession) */\n \"delete\"(args: {\n \"sessionId\": string | number;\n \"userId\"?: string | number;\n }): Promise<any>;\n /** `agentSessions.get` — GET /agent-sessions/{sessionId}. Get an agent session */\n \"get\"(args: {\n \"sessionId\": string | number;\n \"userId\"?: string | number;\n }): Promise<any>;\n /** `agentSessions.list` — GET /agent-sessions. List one user's agent sessions */\n \"list\"(args?: {\n \"userId\"?: string | number;\n \"agent\"?: string | number | boolean;\n \"scope\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `agentSessions.markRead` — POST /agent-sessions/{sessionId}/read. Mark an agent session read */\n \"markRead\"(args: {\n \"sessionId\": string | number;\n }): Promise<any>;\n /** `agentSessions.recordEvent` — POST /agent-sessions/{sessionId}/events. Record an event in an agent session (ctx.agents.recordEvent) */\n \"recordEvent\"(args: {\n \"sessionId\": string | number;\n \"userId\"?: string | number;\n body: unknown;\n }): Promise<any>;\n /** `agentSessions.removeMember` — DELETE /agent-sessions/{sessionId}/members/{userId}. Remove a member from an agent session */\n \"removeMember\"(args: {\n \"sessionId\": string | number;\n \"userId\": string | number;\n }): Promise<any>;\n /** `agentSessions.rename` — PATCH /agent-sessions/{sessionId}. Rename an agent session */\n \"rename\"(args: {\n \"sessionId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `agentSessions.send` — POST /agent-sessions/{sessionId}/messages. Send a message to an agent session */\n \"send\"(args: {\n \"sessionId\": string | number;\n body: unknown;\n }): Promise<any>;\n };\n \"analytics\": {\n /** `analytics.cohortRetention` — GET /analytics/cohort-retention. Cohort retention metrics */\n \"cohortRetention\"(args?: {\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<any>;\n /** `analytics.dailyActive` — GET /analytics/daily-active. Daily active user time series */\n \"dailyActive\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<any>;\n /** `analytics.errorGroups` — GET /analytics/errors/groups. Group failure events by fingerprint with per-day count buckets */\n \"errorGroups\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n \"filter\"?: Record<string, Record<string, string | number | boolean | Array<string | number | boolean>>>;\n }): Promise<any>;\n /** `analytics.integrationUsage` — GET /analytics/integrations. Integration usage metrics */\n \"integrationUsage\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<any>;\n /** `analytics.listEvents` — GET /analytics/events. List analytics events */\n \"listEvents\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"page\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n \"filter\"?: Record<string, Record<string, string | number | boolean | Array<string | number | boolean>>>;\n }): Promise<any>;\n /** `analytics.listEventsGrouped` — GET /analytics/events/grouped. List analytics events grouped by dimension */\n \"listEventsGrouped\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"groupBy\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n \"filter\"?: Record<string, Record<string, string | number | boolean | Array<string | number | boolean>>>;\n }): Promise<any>;\n /** `analytics.overviewDau` — GET /analytics/overview/dau. Daily active users overview */\n \"overviewDau\"(args?: {\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<any>;\n /** `analytics.overviewGrowth` — GET /analytics/overview/growth. User growth overview */\n \"overviewGrowth\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<any>;\n /** `analytics.overviewMau` — GET /analytics/overview/mau. Monthly active users overview */\n \"overviewMau\"(args?: {\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<any>;\n /** `analytics.overviewWau` — GET /analytics/overview/wau. Weekly active users overview */\n \"overviewWau\"(args?: {\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<any>;\n /** `analytics.rollingActive` — GET /analytics/rolling-active. Rolling active user time series */\n \"rollingActive\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<any>;\n /** `analytics.searchUsers` — GET /analytics/users/search. Search app users for analytics */\n \"searchUsers\"(args?: {\n \"q\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"signupDay\"?: string | number | boolean;\n \"signupStartDay\"?: string | number | boolean;\n \"signupEndDay\"?: string | number | boolean;\n \"offset\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<any>;\n /** `analytics.topPrompts` — GET /analytics/prompts/top. List the most-executed prompts */\n \"topPrompts\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<any>;\n /** `analytics.topUsers` — GET /analytics/users/top. List the most active users */\n \"topUsers\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<any>;\n /** `analytics.userDetail` — GET /analytics/users/{userUlid}/detail. Detailed analytics for a single user */\n \"userDetail\"(args: {\n \"userUlid\": string | number;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<any>;\n /** `analytics.userSnapshot` — GET /analytics/users/{userUlid}/snapshot. Activity snapshot for a single user */\n \"userSnapshot\"(args: {\n \"userUlid\": string | number;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<any>;\n /** `analytics.writeForUser` — POST /analytics/write-for-user. Write an analytics event for a subject user under a grant */\n \"writeForUser\"(args: {\n body: unknown;\n }): Promise<any>;\n };\n \"blobBuckets\": {\n /** `blobBuckets.createBucket` — POST /blob-buckets. Create a blob bucket */\n \"createBucket\"(args: {\n body: unknown;\n }): Promise<any>;\n /** `blobBuckets.delete` — DELETE /blob-buckets/{bucketId}/blobs/{blobId}. Delete a blob */\n \"delete\"(args: {\n \"bucketId\": string | number;\n \"blobId\": string | number;\n }): Promise<any>;\n /** `blobBuckets.deleteBatch` — POST /blob-buckets/{bucketId}/blobs/delete. Batch delete blobs from a bucket */\n \"deleteBatch\"(args: {\n \"bucketId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `blobBuckets.deleteBucket` — DELETE /blob-buckets/{bucketId}. Delete a blob bucket */\n \"deleteBucket\"(args: {\n \"bucketId\": string | number;\n }): Promise<any>;\n /** `blobBuckets.download` — GET /blob-buckets/{bucketId}/blobs/{blobId}. Download a blob (anonymous allowed for public buckets) */\n \"download\"(args: {\n \"bucketId\": string | number;\n \"blobId\": string | number;\n \"disposition\"?: string | number | boolean;\n }): Promise<Uint8Array>;\n /** `blobBuckets.downloadSigned` — GET /blob-buckets/{bucketId}/blobs/{blobId}/signed. Download a blob via a signed URL token */\n \"downloadSigned\"(args: {\n \"bucketId\": string | number;\n \"blobId\": string | number;\n \"token\"?: string | number | boolean;\n }): Promise<Uint8Array>;\n /** `blobBuckets.getBucket` — GET /blob-buckets/{bucketId}. Get a blob bucket by id */\n \"getBucket\"(args: {\n \"bucketId\": string | number;\n }): Promise<any>;\n /** `blobBuckets.getMetadata` — GET /blob-buckets/{bucketId}/blobs/{blobId}/metadata. Get blob metadata (anonymous allowed for public buckets) */\n \"getMetadata\"(args: {\n \"bucketId\": string | number;\n \"blobId\": string | number;\n }): Promise<any>;\n /** `blobBuckets.getSignedUrl` — POST /blob-buckets/{bucketId}/blobs/{blobId}/signed-url. Create a signed download URL for a blob */\n \"getSignedUrl\"(args: {\n \"bucketId\": string | number;\n \"blobId\": string | number;\n body?: unknown;\n }): Promise<any>;\n /** `blobBuckets.list` — GET /blob-buckets/{bucketId}/blobs. List blobs in a bucket (anonymous allowed for public buckets) */\n \"list\"(args: {\n \"bucketId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `blobBuckets.listBuckets` — GET /blob-buckets. List blob buckets */\n \"listBuckets\"(args?: Record<string, never>): Promise<any>;\n /** `blobBuckets.updateBucket` — PATCH /blob-buckets/{bucketId}. Update a blob bucket */\n \"updateBucket\"(args: {\n \"bucketId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `blobBuckets.upload` — POST /blob-buckets/{bucketId}/blobs. Upload a blob to a bucket */\n \"upload\"(args: {\n \"bucketId\": string | number;\n \"X-Blob-Filename\": string | number;\n \"X-Blob-Tags\"?: string | number;\n \"Content-Type\"?: string | number;\n body: ArrayBuffer | Uint8Array | string;\n }): Promise<any>;\n };\n \"channels\": {\n /** `channels.authorize` — POST /channels/{channel}/grants. Issue a channel grant under a server function's grant */\n \"authorize\"(args: {\n \"channel\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `channels.publish` — POST /channels/{channel}/publish. Publish a message to a channel under a server function's grant */\n \"publish\"(args: {\n \"channel\": string | number;\n body: unknown;\n }): Promise<any>;\n };\n \"collections\": {\n /** `collections.addDocument` — POST /collections/{collectionId}/documents. Add a document to a collection */\n \"addDocument\"(args: {\n \"collectionId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `collections.addMember` — POST /collections/{collectionId}/members. Add a member to a collection */\n \"addMember\"(args: {\n \"collectionId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `collections.create` — POST /collections. Create a collection */\n \"create\"(args: {\n body: unknown;\n }): Promise<any>;\n /** `collections.delete` — DELETE /collections/{collectionId}. Delete a collection */\n \"delete\"(args: {\n \"collectionId\": string | number;\n }): Promise<any>;\n /** `collections.get` — GET /collections/{collectionId}. Get a collection by id */\n \"get\"(args: {\n \"collectionId\": string | number;\n }): Promise<any>;\n /**\n * `collections.getAccess` — GET /collections/{collectionId}/access. DEPRECATED — Get a collection's access summary; use GET /collections/{collectionId}/members (removal: #4718)\n * @deprecated Use GET /collections/{collectionId}/members (removal: #4718)\n */\n \"getAccess\"(args: {\n \"collectionId\": string | number;\n }): Promise<any>;\n /**\n * `collections.grantGroupPermission` — POST /collections/{collectionId}/group-permissions. DEPRECATED — Grant a group permission on a collection; use POST /collections/{collectionId}/members with groupId and role (removal: #4718)\n * @deprecated Use POST /collections/{collectionId}/members with groupId and role (removal: #4718)\n */\n \"grantGroupPermission\"(args: {\n \"collectionId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `collections.list` — GET /collections. List collections */\n \"list\"(args?: {\n \"userId\"?: string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `collections.listByCustodian` — GET /holdings/collections. List the collections one custodian holds, from a server function */\n \"listByCustodian\"(args?: {\n \"custodian\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `collections.listCollectionsForDocument` — GET /documents/{documentId}/collections. List collections a document belongs to (reverse lookup) */\n \"listCollectionsForDocument\"(args: {\n \"documentId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `collections.listDb3` — GET /collections/{collectionId}/db3. List db3s in a collection */\n \"listDb3\"(args: {\n \"collectionId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `collections.listDocuments` — GET /collections/{collectionId}/documents. List documents in a collection */\n \"listDocuments\"(args: {\n \"collectionId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `collections.listForUser` — GET /users/{userId}/collections. List the collections an app user is a direct member of */\n \"listForUser\"(args: {\n \"userId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `collections.listMembers` — GET /collections/{collectionId}/members. List a collection's members */\n \"listMembers\"(args: {\n \"collectionId\": string | number;\n }): Promise<any>;\n /** `collections.listPendingInvitations` — GET /collections/{collectionId}/pending-invitations. List a collection's pending invitations */\n \"listPendingInvitations\"(args: {\n \"collectionId\": string | number;\n }): Promise<any>;\n /** `collections.removeDocument` — DELETE /collections/{collectionId}/documents/{documentId}. Remove a document from a collection */\n \"removeDocument\"(args: {\n \"collectionId\": string | number;\n \"documentId\": string | number;\n }): Promise<any>;\n /** `collections.removeMember` — DELETE /collections/{collectionId}/members/{principal}. Remove a member from a collection */\n \"removeMember\"(args: {\n \"collectionId\": string | number;\n \"principal\": string | number;\n }): Promise<any>;\n /** `collections.resolveRole` — GET /collections/{collectionId}/role. Resolve a user's role on a collection */\n \"resolveRole\"(args: {\n \"collectionId\": string | number;\n \"userId\"?: string | number;\n }): Promise<any>;\n /**\n * `collections.revokeGroupPermission` — DELETE /collections/{collectionId}/group-permissions/{groupType}/{groupId}. DEPRECATED — Revoke a group permission on a collection, by type; use DELETE /collections/{collectionId}/members/group:{groupId} (removal: #4718)\n * @deprecated Use DELETE /collections/{collectionId}/members/group:{groupId} (removal: #4718)\n */\n \"revokeGroupPermission\"(args: {\n \"collectionId\": string | number;\n \"groupType\": string | number;\n \"groupId\": string | number;\n }): Promise<any>;\n /** `collections.setMemberRole` — PATCH /collections/{collectionId}/members/{principal}. Change a collection member's role */\n \"setMemberRole\"(args: {\n \"collectionId\": string | number;\n \"principal\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `collections.transfer` — POST /collections/{collectionId}/transfer. Transfer a collection to another user or to the app */\n \"transfer\"(args: {\n \"collectionId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `collections.update` — PATCH /collections/{collectionId}. Update a collection */\n \"update\"(args: {\n \"collectionId\": string | number;\n body: unknown;\n }): Promise<any>;\n };\n \"configVars\": {\n /** `configVars.get` — GET /config-vars/{name}. Read an app config var under a server function's grants */\n \"get\"(args: {\n \"name\": string | number;\n }): Promise<any>;\n };\n \"connections\": {\n /** `connections.send` — POST /connections/{connectionId}/send. Send a realtime message to one connection of this app */\n \"send\"(args: {\n \"connectionId\": string | number;\n body: unknown;\n }): Promise<any>;\n };\n \"databaseTypeConfigs\": {\n /** `databaseTypeConfigs.create` — POST /databases/types. Create a database type */\n \"create\"(args: {\n \"dryRun\"?: string | number | boolean;\n body: unknown;\n }): Promise<any>;\n /** `databaseTypeConfigs.delete` — DELETE /databases/types/{databaseType}. Delete a database type */\n \"delete\"(args: {\n \"databaseType\": string | number;\n }): Promise<any>;\n /** `databaseTypeConfigs.get` — GET /databases/types/{databaseType}. Get a database type */\n \"get\"(args: {\n \"databaseType\": string | number;\n }): Promise<any>;\n /** `databaseTypeConfigs.getReindexStatus` — GET /databases/types/{databaseType}/reindex-status. Status of the index back-provision fan-out for a type */\n \"getReindexStatus\"(args: {\n \"databaseType\": string | number;\n \"runId\"?: string | number | boolean;\n }): Promise<any>;\n /** `databaseTypeConfigs.list` — GET /databases/types. List database types */\n \"list\"(args?: Record<string, never>): Promise<any>;\n /** `databaseTypeConfigs.scaffoldSchema` — POST /databases/types/{databaseType}/schema:scaffold. Scaffold a starter schema for a database type */\n \"scaffoldSchema\"(args: {\n \"databaseType\": string | number;\n }): Promise<any>;\n /** `databaseTypeConfigs.update` — PATCH /databases/types/{databaseType}. Update a database type */\n \"update\"(args: {\n \"databaseType\": string | number;\n \"dryRun\"?: string | number | boolean;\n body: unknown;\n }): Promise<any>;\n };\n \"databases\": {\n /** `databases.addManager` — PUT /databases/{databaseId}/permissions. Set a user's database permission */\n \"addManager\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `databases.create` — POST /databases. Create a database */\n \"create\"(args: {\n body: unknown;\n }): Promise<any>;\n /** `databases.delete` — DELETE /databases/{databaseId}. Delete a database */\n \"delete\"(args: {\n \"databaseId\": string | number;\n }): Promise<any>;\n /** `databases.get` — GET /databases/{databaseId}. Get a database by id */\n \"get\"(args: {\n \"databaseId\": string | number;\n }): Promise<any>;\n /** `databases.grantGroupPermission` — POST /databases/{databaseId}/group-permissions. Grant a group permission on a database */\n \"grantGroupPermission\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `databases.list` — GET /databases. List databases */\n \"list\"(args?: Record<string, never>): Promise<any>;\n /** `databases.listGroupPermissions` — GET /databases/{databaseId}/group-permissions. List a database's group permissions */\n \"listGroupPermissions\"(args: {\n \"databaseId\": string | number;\n }): Promise<any>;\n /** `databases.listPermissions` — GET /databases/{databaseId}/permissions. List a database's user permissions */\n \"listPermissions\"(args: {\n \"databaseId\": string | number;\n }): Promise<any>;\n \"records\": {\n /** `databases.records.addToSet` — POST /databases/{databaseId}/records/stringset/add. Database records: stringset/add (app admin or owner) */\n \"addToSet\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `databases.records.aggregate` — POST /databases/{databaseId}/records/aggregate. Database records: aggregate (app admin or owner) */\n \"aggregate\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `databases.records.batch` — POST /databases/{databaseId}/records/batch. Database records: batch (app admin or owner) */\n \"batch\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `databases.records.count` — POST /databases/{databaseId}/records/count. Database records: count (app admin or owner) */\n \"count\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `databases.records.delete` — POST /databases/{databaseId}/records/delete. Database records: delete (app admin or owner) */\n \"delete\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `databases.records.describe` — GET /databases/{databaseId}/records/describe. Database records: describe (app admin or owner) */\n \"describe\"(args: {\n \"databaseId\": string | number;\n \"modelName\"?: string | number | boolean;\n }): Promise<any>;\n /** `databases.records.dropIndex` — POST /databases/{databaseId}/records/index/drop. Database records: index/drop (app admin or owner) */\n \"dropIndex\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `databases.records.dropUniqueConstraint` — POST /databases/{databaseId}/records/unique-constraint/drop. Database records: unique-constraint/drop (app admin or owner) */\n \"dropUniqueConstraint\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `databases.records.increment` — POST /databases/{databaseId}/records/increment. Database records: increment (app admin or owner) */\n \"increment\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `databases.records.listIndexes` — GET /databases/{databaseId}/records/indexes. Database records: indexes (app admin or owner) */\n \"listIndexes\"(args: {\n \"databaseId\": string | number;\n \"modelName\"?: string | number | boolean;\n }): Promise<any>;\n /** `databases.records.listUniqueConstraints` — GET /databases/{databaseId}/records/unique-constraints. Database records: unique-constraints (app admin or owner) */\n \"listUniqueConstraints\"(args: {\n \"databaseId\": string | number;\n \"modelName\"?: string | number | boolean;\n }): Promise<any>;\n /** `databases.records.models` — GET /databases/{databaseId}/records/models. Database records: models (app admin or owner) */\n \"models\"(args: {\n \"databaseId\": string | number;\n \"modelName\"?: string | number | boolean;\n }): Promise<any>;\n /** `databases.records.patch` — POST /databases/{databaseId}/records/patch. Database records: patch (app admin or owner) */\n \"patch\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `databases.records.query` — POST /databases/{databaseId}/records/query. Database records: query (app admin or owner) */\n \"query\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<{ items: any[]; hasMore: boolean; nextCursor?: string; prevCursor?: string }>;\n /** `databases.records.registerIndex` — POST /databases/{databaseId}/records/index/register. Database records: index/register (app admin or owner) */\n \"registerIndex\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `databases.records.registerUniqueConstraint` — POST /databases/{databaseId}/records/unique-constraint/register. Database records: unique-constraint/register (app admin or owner) */\n \"registerUniqueConstraint\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `databases.records.removeFromSet` — POST /databases/{databaseId}/records/stringset/remove. Database records: stringset/remove (app admin or owner) */\n \"removeFromSet\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `databases.records.save` — POST /databases/{databaseId}/records/save. Database records: save (app admin or owner) */\n \"save\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `databases.records.syncIndexes` — POST /databases/{databaseId}/records/indexes/sync. Database records: indexes/sync (app admin or owner) */\n \"syncIndexes\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n };\n /** `databases.reindex` — POST /databases/{databaseId}/reindex. Reindex a database */\n \"reindex\"(args: {\n \"databaseId\": string | number;\n }): Promise<any>;\n /** `databases.revokeGroupPermission` — DELETE /databases/{databaseId}/group-permissions/{groupId}. Revoke a group permission on a database */\n \"revokeGroupPermission\"(args: {\n \"databaseId\": string | number;\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<any>;\n /**\n * `databases.revokeGroupPermissionByType` — DELETE /databases/{databaseId}/group-permissions/{groupType}/{groupId}. DEPRECATED — Revoke a group permission on a database, by type; use DELETE /databases/{databaseId}/group-permissions/{groupId} (removal: #4718)\n * @deprecated Use DELETE /databases/{databaseId}/group-permissions/{groupId} (removal: #4718)\n */\n \"revokeGroupPermissionByType\"(args: {\n \"databaseId\": string | number;\n \"groupType\": string | number;\n \"groupId\": string | number;\n }): Promise<any>;\n /** `databases.revokePermission` — DELETE /databases/{databaseId}/permissions/{userId}. Remove a user's database permission */\n \"revokePermission\"(args: {\n \"databaseId\": string | number;\n \"userId\": string | number;\n }): Promise<any>;\n /** `databases.transferOwnership` — POST /databases/{databaseId}/permissions/transfer. Transfer database ownership */\n \"transferOwnership\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `databases.update` — PATCH /databases/{databaseId}. Update a database */\n \"update\"(args: {\n \"databaseId\": string | number;\n body: unknown;\n }): Promise<any>;\n };\n \"db3\": {\n /** `db3.abortIngest` — POST /db3/{db3Id}/ingest/{sessionId}/abort. Abort a db3 bulk load */\n \"abortIngest\"(args: {\n \"db3Id\": string | number;\n \"sessionId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `db3.addTag` — POST /db3/{db3Id}/tags. Add a tag to a db3 */\n \"addTag\"(args: {\n \"db3Id\": string | number;\n body: unknown;\n }): Promise<any>;\n \"aliases\": {\n /** `db3.aliases.listForDocument` — GET /db3/{db3Id}/aliases. List aliases bound to a db3 */\n \"listForDocument\"(args: {\n \"db3Id\": string | number;\n }): Promise<any>;\n };\n /** `db3.approveAccessRequest` — POST /db3/{db3Id}/access-requests/{requestId}/approve. Approve a db3 access request */\n \"approveAccessRequest\"(args: {\n \"db3Id\": string | number;\n \"requestId\": string | number;\n body?: unknown;\n }): Promise<any>;\n \"blobs\": {\n /** `db3.blobs.delete` — DELETE /db3/{db3Id}/blobs/{blobId}. Delete a db3 blob */\n \"delete\"(args: {\n \"db3Id\": string | number;\n \"blobId\": string | number;\n }): Promise<any>;\n /** `db3.blobs.downloadHeaders` — HEAD /db3/{db3Id}/blobs/{blobId}/download. Get db3 blob download headers (ETag/304 support) */\n \"downloadHeaders\"(args: {\n \"db3Id\": string | number;\n \"blobId\": string | number;\n }): Promise<HeaderResult>;\n /** `db3.blobs.downloadUrl` — GET /db3/{db3Id}/blobs/{blobId}/download. Download a db3 blob's bytes */\n \"downloadUrl\"(args: {\n \"db3Id\": string | number;\n \"blobId\": string | number;\n \"disposition\"?: string | number | boolean;\n }): Promise<Uint8Array>;\n /** `db3.blobs.get` — GET /db3/{db3Id}/blobs/{blobId}. Get a db3 blob's metadata */\n \"get\"(args: {\n \"db3Id\": string | number;\n \"blobId\": string | number;\n }): Promise<any>;\n /** `db3.blobs.list` — GET /db3/{db3Id}/blobs. List blobs attached to a db3 */\n \"list\"(args: {\n \"db3Id\": string | number;\n }): Promise<any>;\n /** `db3.blobs.upload` — PUT /db3/{db3Id}/blobs/{blobId}. Upload a db3 blob with a client-specified id (immutable + idempotent) */\n \"upload\"(args: {\n \"db3Id\": string | number;\n \"blobId\": string | number;\n \"X-Blob-Filename\": string | number;\n \"X-Blob-Size\": string | number;\n \"X-Blob-Sha256\": string | number;\n \"Content-Type\"?: string | number;\n body: ArrayBuffer | Uint8Array | string;\n }): Promise<any>;\n };\n /** `db3.clearLinkAccess` — DELETE /db3/{db3Id}/link-access. Turn off the db3's link access */\n \"clearLinkAccess\"(args: {\n \"db3Id\": string | number;\n }): Promise<any>;\n /** `db3.commitIngest` — POST /db3/{db3Id}/ingest/{sessionId}/commit. Commit a db3 bulk load: its rows apply in the background */\n \"commitIngest\"(args: {\n \"db3Id\": string | number;\n \"sessionId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `db3.create` — POST /db3. Create a db3 */\n \"create\"(args: {\n body: unknown;\n }): Promise<any>;\n /** `db3.createIngest` — POST /db3/{db3Id}/ingest. Open a bulk-load session on a db3 */\n \"createIngest\"(args: {\n \"db3Id\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `db3.delete` — DELETE /db3/{db3Id}. Delete a db3 */\n \"delete\"(args: {\n \"db3Id\": string | number;\n }): Promise<any>;\n /** `db3.denyAccessRequest` — POST /db3/{db3Id}/access-requests/{requestId}/deny. Deny a db3 access request */\n \"denyAccessRequest\"(args: {\n \"db3Id\": string | number;\n \"requestId\": string | number;\n body?: unknown;\n }): Promise<any>;\n /** `db3.exportChain` — GET /db3/{db3Id}/export/chain. Export a db3's chain: its current segment, signed for download */\n \"exportChain\"(args: {\n \"db3Id\": string | number;\n }): Promise<any>;\n /** `db3.get` — GET /db3/{db3Id}. Get a db3 */\n \"get\"(args: {\n \"db3Id\": string | number;\n }): Promise<any>;\n /** `db3.getAppAccess` — GET /db3/{db3Id}/app-access. Read a db3's app access */\n \"getAppAccess\"(args: {\n \"db3Id\": string | number;\n }): Promise<any>;\n /** `db3.getIngest` — GET /db3/{db3Id}/ingest/{sessionId}. Get one db3 bulk-load session */\n \"getIngest\"(args: {\n \"db3Id\": string | number;\n \"sessionId\": string | number;\n }): Promise<any>;\n /** `db3.getLinkAccess` — GET /db3/{db3Id}/link-access. Get the db3's \"anyone with the link\" access level */\n \"getLinkAccess\"(args: {\n \"db3Id\": string | number;\n }): Promise<any>;\n /** `db3.getOrCreateWithAlias` — POST /db3/get-or-create-with-alias. Get the db3 bound to an alias, creating it if absent */\n \"getOrCreateWithAlias\"(args: {\n body: unknown;\n }): Promise<any>;\n /** `db3.getPermissions` — GET /db3/{db3Id}/permissions. List a db3's user permissions */\n \"getPermissions\"(args: {\n \"db3Id\": string | number;\n }): Promise<any>;\n /** `db3.getSchema` — GET /db3/{db3Id}/schema. Introspect a db3's model schema */\n \"getSchema\"(args: {\n \"db3Id\": string | number;\n }): Promise<any>;\n /** `db3.getSnapshot` — GET /db3/{db3Id}/snapshots/{buildId}. Get one of a db3's segment exports */\n \"getSnapshot\"(args: {\n \"db3Id\": string | number;\n \"buildId\": string | number;\n }): Promise<any>;\n /** `db3.getStats` — GET /db3/{db3Id}/stats. Get a db3's stats */\n \"getStats\"(args: {\n \"db3Id\": string | number;\n }): Promise<any>;\n /** `db3.getSync` — GET /db3/{db3Id}/sync. Read whether a db3 is synced */\n \"getSync\"(args: {\n \"db3Id\": string | number;\n }): Promise<any>;\n /** `db3.getType` — GET /db3/{db3Id}/type. Read a db3's type */\n \"getType\"(args: {\n \"db3Id\": string | number;\n }): Promise<any>;\n /** `db3.grantGroupPermission` — POST /db3/{db3Id}/group-permissions. Grant a group permission on a db3 */\n \"grantGroupPermission\"(args: {\n \"db3Id\": string | number;\n body: unknown;\n }): Promise<any>;\n \"indexes\": {\n /** `db3.indexes.drop` — DELETE /db3/{db3Id}/indexes/{name}. Drop a db3's registered index */\n \"drop\"(args: {\n \"db3Id\": string | number;\n \"name\": string | number;\n }): Promise<any>;\n /** `db3.indexes.list` — GET /db3/{db3Id}/indexes. List a db3's indexes */\n \"list\"(args: {\n \"db3Id\": string | number;\n }): Promise<any>;\n /** `db3.indexes.register` — POST /db3/{db3Id}/indexes. Register an index on a db3 */\n \"register\"(args: {\n \"db3Id\": string | number;\n body: unknown;\n }): Promise<any>;\n };\n /** `db3.listAccessRequests` — GET /db3/{db3Id}/access-requests. List access requests for a db3 */\n \"listAccessRequests\"(args: {\n \"db3Id\": string | number;\n }): Promise<any>;\n /** `db3.listGroupPermissions` — GET /db3/{db3Id}/group-permissions. List a db3's group permissions */\n \"listGroupPermissions\"(args: {\n \"db3Id\": string | number;\n }): Promise<any>;\n /** `db3.listIngests` — GET /db3/{db3Id}/ingest. List a db3's bulk-load sessions, newest first */\n \"listIngests\"(args: {\n \"db3Id\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `db3.listPendingInvitations` — GET /db3/{db3Id}/pending-invitations. List a db3's pending (deferred) invitations */\n \"listPendingInvitations\"(args: {\n \"db3Id\": string | number;\n }): Promise<any>;\n /** `db3.listSnapshots` — GET /db3/{db3Id}/snapshots. List a db3's segment exports, newest first */\n \"listSnapshots\"(args: {\n \"db3Id\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n \"records\": {\n /** `db3.records.aggregate` — POST /db3/{db3Id}/records/{model}/aggregate. Aggregate records in a db3 model */\n \"aggregate\"(args: {\n \"db3Id\": string | number;\n \"model\": string | number;\n \"userId\"?: string | number;\n body: unknown;\n }): Promise<any>;\n /** `db3.records.bulk` — POST /db3/{db3Id}/records/bulk. Apply an atomic multi-model record blob to a db3 (create/patch/delete/upsert) */\n \"bulk\"(args: {\n \"db3Id\": string | number;\n \"userId\"?: string | number;\n body: unknown;\n }): Promise<any>;\n /** `db3.records.count` — GET /db3/{db3Id}/records/{model}/count. Count records in a db3 model */\n \"count\"(args: {\n \"db3Id\": string | number;\n \"model\": string | number;\n \"userId\"?: string | number;\n \"filter\"?: Record<string, unknown> | string;\n }): Promise<any>;\n /** `db3.records.delete` — DELETE /db3/{db3Id}/records/{model}/{recordId}. Delete a record from a db3 model */\n \"delete\"(args: {\n \"db3Id\": string | number;\n \"model\": string | number;\n \"recordId\": string | number;\n \"requestId\"?: string | number | boolean;\n \"condition\"?: string | number | boolean;\n \"userId\"?: string | number;\n }): Promise<any>;\n /** `db3.records.increment` — POST /db3/{db3Id}/records/{model}/{recordId}/increment. Increment numeric fields of a record in a db3 model */\n \"increment\"(args: {\n \"db3Id\": string | number;\n \"model\": string | number;\n \"recordId\": string | number;\n \"userId\"?: string | number;\n body: unknown;\n }): Promise<any>;\n /** `db3.records.patch` — PATCH /db3/{db3Id}/records/{model}/{recordId}. Merge fields into an existing record in a db3 model */\n \"patch\"(args: {\n \"db3Id\": string | number;\n \"model\": string | number;\n \"recordId\": string | number;\n \"userId\"?: string | number;\n body: unknown;\n }): Promise<any>;\n /** `db3.records.query` — GET /db3/{db3Id}/records/{model}. Query records in a db3 model */\n \"query\"(args: {\n \"db3Id\": string | number;\n \"model\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"userId\"?: string | number;\n \"filter\"?: Record<string, unknown> | string;\n \"sort\"?: Record<string, unknown> | string;\n \"include\"?: unknown[] | string;\n }): Promise<any>;\n /** `db3.records.save` — POST /db3/{db3Id}/records/{model}. Create or replace a record in a db3 model */\n \"save\"(args: {\n \"db3Id\": string | number;\n \"model\": string | number;\n \"userId\"?: string | number;\n body: unknown;\n }): Promise<any>;\n };\n /** `db3.removePermissionByEmail` — DELETE /db3/{db3Id}/permissions. Revoke a user's permission on a db3 by email (?email=) */\n \"removePermissionByEmail\"(args: {\n \"db3Id\": string | number;\n \"email\"?: string | number | boolean;\n }): Promise<any>;\n /** `db3.removePermissionByUserId` — DELETE /db3/{db3Id}/permissions/{userId}. Revoke a user's permission on a db3 by user id */\n \"removePermissionByUserId\"(args: {\n \"db3Id\": string | number;\n \"userId\": string | number;\n }): Promise<any>;\n /** `db3.removeTag` — DELETE /db3/{db3Id}/tags/{tag}. Remove a tag from a db3 */\n \"removeTag\"(args: {\n \"db3Id\": string | number;\n \"tag\": string | number;\n }): Promise<any>;\n /** `db3.requestAccess` — POST /db3/{db3Id}/access-requests. Request access to a db3 */\n \"requestAccess\"(args: {\n \"db3Id\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `db3.requestSnapshot` — POST /db3/{db3Id}/snapshots. Start a segment export of a db3 now */\n \"requestSnapshot\"(args: {\n \"db3Id\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `db3.revokeGroupPermission` — DELETE /db3/{db3Id}/group-permissions/{groupId}. Revoke a group permission on a db3 */\n \"revokeGroupPermission\"(args: {\n \"db3Id\": string | number;\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<any>;\n /** `db3.room` — GET /db3/{db3Id}/room. Inspect a db3's room */\n \"room\"(args: {\n \"db3Id\": string | number;\n \"refused\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `db3.setAppAccess` — PUT /db3/{db3Id}/app-access. Grant a db3 to every user of the app */\n \"setAppAccess\"(args: {\n \"db3Id\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `db3.setLinkAccess` — PUT /db3/{db3Id}/link-access. Set the db3's \"anyone with the link\" access level */\n \"setLinkAccess\"(args: {\n \"db3Id\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `db3.setOwnerRow` — PUT /db3/{db3Id}/owner-row. Remove or restore a db3's owner row */\n \"setOwnerRow\"(args: {\n \"db3Id\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `db3.setSync` — PUT /db3/{db3Id}/sync. Turn a db3's sync on or off */\n \"setSync\"(args: {\n \"db3Id\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `db3.setType` — PUT /db3/{db3Id}/type. Attach a type to a db3 */\n \"setType\"(args: {\n \"db3Id\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `db3.transfer` — POST /db3/{db3Id}/transfer. Transfer a db3 to another user or to the app */\n \"transfer\"(args: {\n \"db3Id\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `db3.updatePermissions` — PUT /db3/{db3Id}/permissions. Grant or update a user's permission on a db3 */\n \"updatePermissions\"(args: {\n \"db3Id\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `db3.uploadIngestChunk` — POST /db3/{db3Id}/ingest/{sessionId}/chunks. Upload one chunk of a db3 bulk load */\n \"uploadIngestChunk\"(args: {\n \"db3Id\": string | number;\n \"sessionId\": string | number;\n body: FormData | ArrayBuffer | Uint8Array | string;\n }): Promise<any>;\n /** `db3.validateAccess` — POST /db3/{db3Id}/validate-access. Resolve effective access to a db3, for the caller or a named user */\n \"validateAccess\"(args: {\n \"db3Id\": string | number;\n body?: unknown;\n }): Promise<any>;\n };\n \"documents\": {\n /** `documents.abortIngest` — POST /documents/{documentId}/ingest/{sessionId}/abort. Abort a bulk-load session before its swap */\n \"abortIngest\"(args: {\n \"documentId\": string | number;\n \"sessionId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `documents.addTag` — POST /documents/{documentId}/tags. Add a tag to a document */\n \"addTag\"(args: {\n \"documentId\": string | number;\n body: unknown;\n }): Promise<any>;\n \"aliases\": {\n /** `documents.aliases.delete` — DELETE /document-aliases/{scope}/{aliasKey}. Delete a (scope, aliasKey) document alias binding */\n \"delete\"(args: {\n \"scope\": string | number;\n \"aliasKey\": string | number;\n \"userId\"?: string | number;\n }): Promise<any>;\n /** `documents.aliases.listForDocument` — GET /documents/{documentId}/aliases. List aliases bound to a document */\n \"listForDocument\"(args: {\n \"documentId\": string | number;\n }): Promise<any>;\n /** `documents.aliases.resolve` — GET /document-aliases/{scope}/{aliasKey}. Resolve the document bound to a (scope, aliasKey) alias */\n \"resolve\"(args: {\n \"scope\": string | number;\n \"aliasKey\": string | number;\n \"userId\"?: string | number;\n }): Promise<any>;\n /** `documents.aliases.set` — PUT /document-aliases/{scope}/{aliasKey}. Bind a (scope, aliasKey) alias to a document */\n \"set\"(args: {\n \"scope\": string | number;\n \"aliasKey\": string | number;\n body: unknown;\n }): Promise<any>;\n };\n /** `documents.approveAccessRequest` — POST /documents/{documentId}/access-requests/{requestId}/approve. Approve a document access request */\n \"approveAccessRequest\"(args: {\n \"documentId\": string | number;\n \"requestId\": string | number;\n body?: unknown;\n }): Promise<any>;\n \"blobs\": {\n /** `documents.blobs.delete` — DELETE /documents/{documentId}/blobs/{blobId}. Delete a document blob */\n \"delete\"(args: {\n \"documentId\": string | number;\n \"blobId\": string | number;\n }): Promise<any>;\n /** `documents.blobs.downloadHeaders` — HEAD /documents/{documentId}/blobs/{blobId}/download. Get document blob download headers (ETag/304 support) */\n \"downloadHeaders\"(args: {\n \"documentId\": string | number;\n \"blobId\": string | number;\n }): Promise<HeaderResult>;\n /** `documents.blobs.downloadUrl` — GET /documents/{documentId}/blobs/{blobId}/download. Download a document blob's bytes */\n \"downloadUrl\"(args: {\n \"documentId\": string | number;\n \"blobId\": string | number;\n \"disposition\"?: string | number | boolean;\n }): Promise<Uint8Array>;\n /** `documents.blobs.get` — GET /documents/{documentId}/blobs/{blobId}. Get a document blob's metadata */\n \"get\"(args: {\n \"documentId\": string | number;\n \"blobId\": string | number;\n }): Promise<any>;\n /** `documents.blobs.list` — GET /documents/{documentId}/blobs. List blobs attached to a document */\n \"list\"(args: {\n \"documentId\": string | number;\n }): Promise<any>;\n /** `documents.blobs.upload` — PUT /documents/{documentId}/blobs/{blobId}. Upload a document blob with a client-specified id (immutable + idempotent) */\n \"upload\"(args: {\n \"documentId\": string | number;\n \"blobId\": string | number;\n \"X-Blob-Filename\": string | number;\n \"X-Blob-Size\": string | number;\n \"X-Blob-Sha256\": string | number;\n \"Content-Type\"?: string | number;\n body: ArrayBuffer | Uint8Array | string;\n }): Promise<any>;\n };\n /** `documents.clearLinkAccess` — DELETE /documents/{documentId}/link-access. Turn off the document's link access */\n \"clearLinkAccess\"(args: {\n \"documentId\": string | number;\n }): Promise<any>;\n /** `documents.commitIngest` — POST /documents/{documentId}/ingest/{sessionId}/commit. Commit a bulk-load session: freeze its manifest and apply it */\n \"commitIngest\"(args: {\n \"documentId\": string | number;\n \"sessionId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `documents.create` — POST /documents. Create a new document */\n \"create\"(args: {\n body: unknown;\n }): Promise<any>;\n /** `documents.createIngest` — POST /documents/{documentId}/ingest. Open a bulk-load session on a large document */\n \"createIngest\"(args: {\n \"documentId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `documents.createWithAlias` — POST /documents/create-with-alias. Create a document and bind it to an alias */\n \"createWithAlias\"(args: {\n body: unknown;\n }): Promise<any>;\n /** `documents.debugDumpUpdates` — POST /documents/{documentId}/debug/dump-updates. Dump a document's raw CRDT update log (debug) */\n \"debugDumpUpdates\"(args: {\n \"documentId\": string | number;\n \"limit\"?: string | number | boolean;\n \"offset\"?: string | number | boolean;\n \"includeData\"?: string | number | boolean;\n \"includeR2Data\"?: string | number | boolean;\n body?: unknown;\n }): Promise<any>;\n /** `documents.debugMerge` — POST /documents/{documentId}/debug/merge. Force-merge a document's pending updates (debug) */\n \"debugMerge\"(args: {\n \"documentId\": string | number;\n body?: unknown;\n }): Promise<any>;\n /** `documents.debugMergeBlock` — POST /documents/{documentId}/debug/merge-block. Merge a specific update block of a document (debug) */\n \"debugMergeBlock\"(args: {\n \"documentId\": string | number;\n body?: unknown;\n }): Promise<any>;\n /** `documents.debugRestore` — POST /documents/debug/restore. Restore a document from a prior state snapshot (debug) */\n \"debugRestore\"(args: {\n body: unknown;\n }): Promise<any>;\n /** `documents.debugStats` — GET /documents/{documentId}/debug/stats. Get document storage/update stats (debug) */\n \"debugStats\"(args: {\n \"documentId\": string | number;\n }): Promise<any>;\n /** `documents.delete` — DELETE /documents/{documentId}. Delete a document */\n \"delete\"(args: {\n \"documentId\": string | number;\n }): Promise<any>;\n /** `documents.denyAccessRequest` — POST /documents/{documentId}/access-requests/{requestId}/deny. Deny a document access request */\n \"denyAccessRequest\"(args: {\n \"documentId\": string | number;\n \"requestId\": string | number;\n body?: unknown;\n }): Promise<any>;\n /** `documents.exportChain` — GET /documents/{documentId}/export/chain. Export chain of a large document (snapshot + sealed overlays + open epoch) */\n \"exportChain\"(args: {\n \"documentId\": string | number;\n }): Promise<any>;\n /** `documents.exportState` — GET /documents/{documentId}/export/state. Export a document's encoded CRDT state */\n \"exportState\"(args: {\n \"documentId\": string | number;\n }): Promise<any>;\n /** `documents.get` — GET /documents/{documentId}. Get a single document by id */\n \"get\"(args: {\n \"documentId\": string | number;\n }): Promise<any>;\n /** `documents.getImportChainStatus` — GET /documents/{documentId}/import/chain. How far a large document's chain import has got */\n \"getImportChainStatus\"(args: {\n \"documentId\": string | number;\n }): Promise<any>;\n /** `documents.getIngest` — GET /documents/{documentId}/ingest/{sessionId}. One bulk-load session's status */\n \"getIngest\"(args: {\n \"documentId\": string | number;\n \"sessionId\": string | number;\n }): Promise<any>;\n /** `documents.getLinkAccess` — GET /documents/{documentId}/link-access. Get the document's \"anyone with the link\" access level */\n \"getLinkAccess\"(args: {\n \"documentId\": string | number;\n }): Promise<any>;\n /** `documents.getOrCreateWithAlias` — POST /documents/get-or-create-with-alias. Get the document bound to an alias, creating it if absent (idempotent) */\n \"getOrCreateWithAlias\"(args: {\n body: unknown;\n }): Promise<any>;\n /** `documents.getPermissions` — GET /documents/{documentId}/permissions. List a document's user permissions */\n \"getPermissions\"(args: {\n \"documentId\": string | number;\n }): Promise<any>;\n /** `documents.getSchema` — GET /documents/{documentId}/schema. Introspect a document's model schema */\n \"getSchema\"(args: {\n \"documentId\": string | number;\n }): Promise<any>;\n /** `documents.getSnapshot` — GET /documents/{documentId}/snapshots/{buildId}. One snapshot build with its verification result */\n \"getSnapshot\"(args: {\n \"documentId\": string | number;\n \"buildId\": string | number;\n }): Promise<any>;\n /** `documents.getStats` — GET /documents/{documentId}/stats. Document statistics (record/model/blob counts, approximate size) */\n \"getStats\"(args: {\n \"documentId\": string | number;\n }): Promise<any>;\n /** `documents.grantGroupPermission` — POST /documents/{documentId}/group-permissions. Grant a group permission on a document */\n \"grantGroupPermission\"(args: {\n \"documentId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `documents.importChain` — POST /documents/{documentId}/import/chain. Install an uploaded chain into a large document */\n \"importChain\"(args: {\n \"documentId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `documents.importChainArtifact` — POST /documents/{documentId}/import/chain/artifact. Upload one artifact of a large document's import chain */\n \"importChainArtifact\"(args: {\n \"documentId\": string | number;\n \"kind\"?: string | number | boolean;\n \"epoch\"?: string | number | boolean;\n \"buildId\"?: string | number | boolean;\n \"model\"?: string | number | boolean;\n \"index\"?: string | number | boolean;\n body: ArrayBuffer | Uint8Array | string;\n }): Promise<any>;\n /** `documents.importState` — POST /documents/{documentId}/import/state. Import encoded CRDT state into a document */\n \"importState\"(args: {\n \"documentId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `documents.listAccessRequests` — GET /documents/{documentId}/access-requests. List access requests for a document */\n \"listAccessRequests\"(args: {\n \"documentId\": string | number;\n }): Promise<any>;\n /** `documents.listGroupPermissions` — GET /documents/{documentId}/group-permissions. List a document's group permissions */\n \"listGroupPermissions\"(args: {\n \"documentId\": string | number;\n }): Promise<any>;\n /** `documents.listIngests` — GET /documents/{documentId}/ingest. List a large document's bulk-load sessions, newest first */\n \"listIngests\"(args: {\n \"documentId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `documents.listOwnedByUser` — GET /users/{userId}/owned-documents. List the documents an app user owns */\n \"listOwnedByUser\"(args: {\n \"userId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"tag\"?: string | number | boolean;\n \"includeRoot\"?: string | number | boolean;\n \"forward\"?: string | number | boolean;\n }): Promise<any>;\n /** `documents.listPendingInvitations` — GET /documents/{documentId}/pending-invitations. List a document's pending (deferred) invitations */\n \"listPendingInvitations\"(args: {\n \"documentId\": string | number;\n }): Promise<any>;\n /** `documents.listSharedWithUser` — GET /users/{userId}/shared-documents. List the documents directly shared with an app user */\n \"listSharedWithUser\"(args: {\n \"userId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"tag\"?: string | number | boolean;\n }): Promise<any>;\n /** `documents.listSnapshots` — GET /documents/{documentId}/snapshots. List a large document's snapshot builds, newest first */\n \"listSnapshots\"(args: {\n \"documentId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `documents.open` — POST /documents/open. Open a document for collaboration (resolves access + alias) */\n \"open\"(args: {\n body: unknown;\n }): Promise<any>;\n \"records\": {\n /** `documents.records.aggregate` — POST /documents/{documentId}/records/{model}/aggregate. Aggregate records in a document model (count/sum/avg/min/max, optional grouping) */\n \"aggregate\"(args: {\n \"documentId\": string | number;\n \"model\": string | number;\n \"documentFormat\"?: string | number | boolean;\n body: unknown;\n }): Promise<any>;\n /** `documents.records.bulk` — POST /documents/{documentId}/records/bulk. Apply an atomic multi-model record blob to a document (create/patch/delete/upsert) */\n \"bulk\"(args: {\n \"documentId\": string | number;\n \"documentFormat\"?: string | number | boolean;\n body: unknown;\n }): Promise<any>;\n /** `documents.records.count` — GET /documents/{documentId}/records/{model}/count. Count records in a document model */\n \"count\"(args: {\n \"documentId\": string | number;\n \"model\": string | number;\n \"documentFormat\"?: string | number | boolean;\n \"filter\"?: Record<string, unknown> | string;\n }): Promise<any>;\n /** `documents.records.delete` — DELETE /documents/{documentId}/records/{model}/{recordId}. Delete a record from a document model */\n \"delete\"(args: {\n \"documentId\": string | number;\n \"model\": string | number;\n \"recordId\": string | number;\n \"documentFormat\"?: string | number | boolean;\n \"requestId\"?: string | number | boolean;\n \"condition\"?: string | number | boolean;\n }): Promise<any>;\n /** `documents.records.patch` — PATCH /documents/{documentId}/records/{model}/{recordId}. Merge fields into an existing record in a document model */\n \"patch\"(args: {\n \"documentId\": string | number;\n \"model\": string | number;\n \"recordId\": string | number;\n \"documentFormat\"?: string | number | boolean;\n body: unknown;\n }): Promise<any>;\n /** `documents.records.query` — GET /documents/{documentId}/records/{model}. Query records in a document model */\n \"query\"(args: {\n \"documentId\": string | number;\n \"model\": string | number;\n \"documentFormat\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"filter\"?: Record<string, unknown> | string;\n \"sort\"?: Record<string, unknown> | string;\n \"include\"?: unknown[] | string;\n }): Promise<any>;\n /** `documents.records.save` — POST /documents/{documentId}/records/{model}. Create or replace a record in a document model */\n \"save\"(args: {\n \"documentId\": string | number;\n \"model\": string | number;\n \"documentFormat\"?: string | number | boolean;\n body: unknown;\n }): Promise<any>;\n };\n /** `documents.removePermissionByEmail` — DELETE /documents/{documentId}/permissions. Revoke a user's permission on a document by email (?email=) */\n \"removePermissionByEmail\"(args: {\n \"documentId\": string | number;\n \"email\"?: string | number | boolean;\n }): Promise<any>;\n /** `documents.removePermissionByUserId` — DELETE /documents/{documentId}/permissions/{userId}. Revoke a user's permission on a document by user id */\n \"removePermissionByUserId\"(args: {\n \"documentId\": string | number;\n \"userId\": string | number;\n }): Promise<any>;\n /** `documents.removeTag` — DELETE /documents/{documentId}/tags/{tag}. Remove a tag from a document */\n \"removeTag\"(args: {\n \"documentId\": string | number;\n \"tag\": string | number;\n }): Promise<any>;\n /** `documents.requestAccess` — POST /documents/{documentId}/access-requests. Request access to a document */\n \"requestAccess\"(args: {\n \"documentId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `documents.requestSnapshot` — POST /documents/{documentId}/snapshots. Snapshot a large document now: seal the open epoch and build a base */\n \"requestSnapshot\"(args: {\n \"documentId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `documents.revokeGroupPermission` — DELETE /documents/{documentId}/group-permissions/{groupId}. Revoke a group permission on a document */\n \"revokeGroupPermission\"(args: {\n \"documentId\": string | number;\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<any>;\n /**\n * `documents.revokeGroupPermissionByType` — DELETE /documents/{documentId}/group-permissions/{groupType}/{groupId}. DEPRECATED — Revoke a group permission on a document, by type; use DELETE /documents/{documentId}/group-permissions/{groupId} (removal: #4718)\n * @deprecated Use DELETE /documents/{documentId}/group-permissions/{groupId} (removal: #4718)\n */\n \"revokeGroupPermissionByType\"(args: {\n \"documentId\": string | number;\n \"groupType\": string | number;\n \"groupId\": string | number;\n }): Promise<any>;\n /** `documents.room` — GET /documents/{documentId}/room. Inspect a record-log document's room */\n \"room\"(args: {\n \"documentId\": string | number;\n \"refused\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `documents.setLinkAccess` — PUT /documents/{documentId}/link-access. Set the document's \"anyone with the link\" access level */\n \"setLinkAccess\"(args: {\n \"documentId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `documents.transferOwnership` — POST /documents/{documentId}/permissions/transfer. Transfer ownership of a document to another user */\n \"transferOwnership\"(args: {\n \"documentId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `documents.update` — PUT /documents/{documentId}. Update a document's metadata */\n \"update\"(args: {\n \"documentId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `documents.updatePermissions` — PUT /documents/{documentId}/permissions. Grant or update a user's permission on a document */\n \"updatePermissions\"(args: {\n \"documentId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `documents.uploadIngestChunk` — POST /documents/{documentId}/ingest/{sessionId}/chunks. Upload one chunk of a bulk-load session's artifact */\n \"uploadIngestChunk\"(args: {\n \"documentId\": string | number;\n \"sessionId\": string | number;\n body: FormData | ArrayBuffer | Uint8Array | string;\n }): Promise<any>;\n /** `documents.validateAccess` — POST /documents/{documentId}/validate-access. Resolve effective access to a document, for the caller or a named user */\n \"validateAccess\"(args: {\n \"documentId\": string | number;\n body?: unknown;\n }): Promise<any>;\n };\n \"email\": {\n /** `email.send` — POST /emails/send. Send an application email under a server function's grant */\n \"send\"(args: {\n body: unknown;\n }): Promise<any>;\n };\n \"functions\": {\n /** `functions.getStatus` — GET /functions/runs/{runId}/status. Get the status of a function run by run id */\n \"getStatus\"(args: {\n \"runId\": string | number;\n }): Promise<any>;\n /** `functions.getStatusByRunKey` — GET /functions/{functionKey}/instances/{runKey}/status. Get the status of a function run by run key */\n \"getStatusByRunKey\"(args: {\n \"functionKey\": string | number;\n \"runKey\": string | number;\n \"contextDocId\"?: string | number | boolean;\n }): Promise<any>;\n /** `functions.invoke` — POST /functions/{functionKey}. Invoke a server function and answer its result */\n \"invoke\"(args: {\n \"functionKey\": string | number;\n body?: unknown;\n }): Promise<any>;\n /** `functions.invokeAsSystem` — POST /functions/{functionKey}/invoke-as-system. Invoke a server function as the system, with no caller */\n \"invokeAsSystem\"(args: {\n \"functionKey\": string | number;\n body?: unknown;\n }): Promise<any>;\n /** `functions.listRunSteps` — GET /functions/runs/{runId}/steps. List a function run's steps, oldest first */\n \"listRunSteps\"(args: {\n \"runId\": string | number;\n }): Promise<any>;\n /** `functions.listRuns` — GET /functions/runs. List the caller's own function runs */\n \"listRuns\"(args?: {\n \"functionKey\"?: string | number | boolean;\n \"contextDocId\"?: string | number | boolean;\n \"status\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"forward\"?: string | number | boolean;\n }): Promise<any>;\n /** `functions.logs` — GET /functions/{functionKey}/logs. List a server function's invocation logs, newest first */\n \"logs\"(args: {\n \"functionKey\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"runId\"?: string | number | boolean;\n }): Promise<any>;\n /** `functions.start` — POST /functions/{functionKey}/start. Start a server function as a task run */\n \"start\"(args: {\n \"functionKey\": string | number;\n body?: unknown;\n }): Promise<any>;\n /** `functions.startAsSystem` — POST /functions/{functionKey}/start-as-system. Start a server function as a task run, as the system */\n \"startAsSystem\"(args: {\n \"functionKey\": string | number;\n body?: unknown;\n }): Promise<any>;\n /** `functions.terminate` — POST /functions/{functionKey}/instances/{runKey}/terminate. Terminate a function run */\n \"terminate\"(args: {\n \"functionKey\": string | number;\n \"runKey\": string | number;\n \"contextDocId\"?: string | number | boolean;\n }): Promise<any>;\n };\n \"groups\": {\n /** `groups.addMember` — POST /groups/{groupId}/members. Add a member to a group */\n \"addMember\"(args: {\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n body: unknown;\n }): Promise<any>;\n /**\n * `groups.addMemberByType` — POST /groups/{groupType}/{groupId}/members. DEPRECATED — Add a member to a group, by type; use POST /groups/{groupId}/members (removal: #4718)\n * @deprecated Use POST /groups/{groupId}/members (removal: #4718)\n */\n \"addMemberByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `groups.create` — POST /groups. Create a group */\n \"create\"(args: {\n body: unknown;\n }): Promise<any>;\n /** `groups.delete` — DELETE /groups/{groupId}. Delete a group */\n \"delete\"(args: {\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<any>;\n /**\n * `groups.deleteByType` — DELETE /groups/{groupType}/{groupId}. DEPRECATED — Delete a group, by type; use DELETE /groups/{groupId} (removal: #4718)\n * @deprecated Use DELETE /groups/{groupId} (removal: #4718)\n */\n \"deleteByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n }): Promise<any>;\n /** `groups.get` — GET /groups/{groupId}. Get a group */\n \"get\"(args: {\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<any>;\n /**\n * `groups.getByType` — GET /groups/{groupType}/{groupId}. DEPRECATED — Get a group, by type; use GET /groups/{groupId} (removal: #4718)\n * @deprecated Use GET /groups/{groupId} (removal: #4718)\n */\n \"getByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n }): Promise<any>;\n /** `groups.list` — GET /groups. List groups */\n \"list\"(args?: {\n \"type\"?: string | number | boolean;\n \"includeSystem\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `groups.listByCustodian` — GET /holdings/groups. List the groups one custodian holds, from a server function */\n \"listByCustodian\"(args?: {\n \"custodian\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `groups.listDatabases` — GET /groups/{groupId}/databases. List databases shared with a group */\n \"listDatabases\"(args: {\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<any>;\n /**\n * `groups.listDatabasesByType` — GET /groups/{groupType}/{groupId}/databases. DEPRECATED — List databases shared with a group, by type; use GET /groups/{groupId}/databases (removal: #4718)\n * @deprecated Use GET /groups/{groupId}/databases (removal: #4718)\n */\n \"listDatabasesByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n }): Promise<any>;\n /** `groups.listDb3` — GET /groups/{groupId}/db3. List db3s shared with a group */\n \"listDb3\"(args: {\n \"groupId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"groupType\"?: string | number | boolean;\n }): Promise<any>;\n /**\n * `groups.listDb3ByType` — GET /groups/{groupType}/{groupId}/db3. DEPRECATED — List db3s shared with a group, by type; use GET /groups/{groupId}/db3 (removal: #4718)\n * @deprecated Use GET /groups/{groupId}/db3 (removal: #4718)\n */\n \"listDb3ByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `groups.listDocuments` — GET /groups/{groupId}/documents. List documents shared with a group */\n \"listDocuments\"(args: {\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<any>;\n /**\n * `groups.listDocumentsByType` — GET /groups/{groupType}/{groupId}/documents. DEPRECATED — List documents shared with a group, by type; use GET /groups/{groupId}/documents (removal: #4718)\n * @deprecated Use GET /groups/{groupId}/documents (removal: #4718)\n */\n \"listDocumentsByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n }): Promise<any>;\n /** `groups.listMembers` — GET /groups/{groupId}/members. List a group's members */\n \"listMembers\"(args: {\n \"groupId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"include\"?: string | number | boolean;\n \"groupType\"?: string | number | boolean;\n }): Promise<any>;\n /**\n * `groups.listMembersByType` — GET /groups/{groupType}/{groupId}/members. DEPRECATED — List a group's members, by type; use GET /groups/{groupId}/members (removal: #4718)\n * @deprecated Use GET /groups/{groupId}/members (removal: #4718)\n */\n \"listMembersByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"include\"?: string | number | boolean;\n }): Promise<any>;\n /** `groups.listPendingInvitations` — GET /groups/{groupId}/pending-invitations. List a group's pending invitations */\n \"listPendingInvitations\"(args: {\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<any>;\n /**\n * `groups.listPendingInvitationsByType` — GET /groups/{groupType}/{groupId}/pending-invitations. DEPRECATED — List a group's pending invitations, by type; use GET /groups/{groupId}/pending-invitations (removal: #4718)\n * @deprecated Use GET /groups/{groupId}/pending-invitations (removal: #4718)\n */\n \"listPendingInvitationsByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n }): Promise<any>;\n /** `groups.listUserMemberships` — GET /users/{userId}/memberships. List a user's group memberships */\n \"listUserMemberships\"(args: {\n \"userId\": string | number;\n \"includeSystem\"?: string | number | boolean;\n \"type\"?: string | number | boolean;\n }): Promise<any>;\n /** `groups.removeMember` — DELETE /groups/{groupId}/members/{userId}. Remove a specific member from a group */\n \"removeMember\"(args: {\n \"groupId\": string | number;\n \"userId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<any>;\n /** `groups.removeMemberByEmail` — DELETE /groups/{groupId}/members. Remove a group member or pending invitation by email */\n \"removeMemberByEmail\"(args: {\n \"groupId\": string | number;\n \"email\"?: string | number | boolean;\n \"groupType\"?: string | number | boolean;\n }): Promise<any>;\n /**\n * `groups.removeMemberByEmailByType` — DELETE /groups/{groupType}/{groupId}/members. DEPRECATED — Remove a group member or pending invitation by email, by type; use DELETE /groups/{groupId}/members (removal: #4718)\n * @deprecated Use DELETE /groups/{groupId}/members (removal: #4718)\n */\n \"removeMemberByEmailByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n \"email\"?: string | number | boolean;\n }): Promise<any>;\n /**\n * `groups.removeMemberByType` — DELETE /groups/{groupType}/{groupId}/members/{userId}. DEPRECATED — Remove a specific member from a group, by type; use DELETE /groups/{groupId}/members/{userId} (removal: #4718)\n * @deprecated Use DELETE /groups/{groupId}/members/{userId} (removal: #4718)\n */\n \"removeMemberByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n \"userId\": string | number;\n }): Promise<any>;\n /** `groups.setMemberRole` — PATCH /groups/{groupId}/members/{userId}. Change a member's role */\n \"setMemberRole\"(args: {\n \"groupId\": string | number;\n \"userId\": string | number;\n \"groupType\"?: string | number | boolean;\n body: unknown;\n }): Promise<any>;\n /** `groups.transfer` — POST /groups/{groupId}/transfer. Transfer a group to another user or to the app */\n \"transfer\"(args: {\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n body: unknown;\n }): Promise<any>;\n /** `groups.update` — PATCH /groups/{groupId}. Update a group */\n \"update\"(args: {\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n body: unknown;\n }): Promise<any>;\n /**\n * `groups.updateByType` — PATCH /groups/{groupType}/{groupId}. DEPRECATED — Update a group, by type; use PATCH /groups/{groupId} (removal: #4718)\n * @deprecated Use PATCH /groups/{groupId} (removal: #4718)\n */\n \"updateByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n body: unknown;\n }): Promise<any>;\n };\n \"integrations\": {\n /** `integrations.call` — POST /integrations/{integrationKey}/call. Call an integration under a server function's grants */\n \"call\"(args: {\n \"integrationKey\": string | number;\n body?: unknown;\n }): Promise<any>;\n /** `integrations.list` — GET /integrations. List integrations configured for the app */\n \"list\"(args?: Record<string, never>): Promise<any>;\n };\n \"locks\": {\n /** `locks.list` — GET /locks. List all currently-held named locks in the app */\n \"list\"(args?: Record<string, never>): Promise<any>;\n /** `locks.release` — POST /locks/release. Release a held named lock (requires the acquire handle) */\n \"release\"(args: {\n body: unknown;\n }): Promise<any>;\n /** `locks.renew` — POST /locks/renew. Extend the lease on a held named lock */\n \"renew\"(args: {\n body: unknown;\n }): Promise<any>;\n /** `locks.status` — POST /locks/status. Report the current holder of a named lock */\n \"status\"(args: {\n body: unknown;\n }): Promise<any>;\n /** `locks.tryAcquire` — POST /locks/acquire. Attempt to acquire a named lock (one attempt, or with waitMs a bounded server-side wait) */\n \"tryAcquire\"(args: {\n body: unknown;\n }): Promise<any>;\n };\n \"notifications\": {\n /** `notifications.list` — GET /notifications. List the caller's in-app notification inbox (newest first) */\n \"list\"(args?: {\n \"userId\"?: string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `notifications.listDevices` — GET /me/push-tokens. List the caller's registered push devices */\n \"listDevices\"(args?: {\n \"userId\"?: string | number;\n }): Promise<any>;\n /** `notifications.markAllRead` — POST /notifications/read-all. Mark all of the caller's notifications as read */\n \"markAllRead\"(args?: {\n \"userId\"?: string | number;\n }): Promise<any>;\n /** `notifications.markRead` — PATCH /notifications/{notificationId}/read. Mark one of the caller's notifications as read */\n \"markRead\"(args: {\n \"notificationId\": string | number;\n \"userId\"?: string | number;\n }): Promise<any>;\n /** `notifications.registerDevice` — POST /me/push-tokens. Register (upsert) the caller's device push token */\n \"registerDevice\"(args: {\n \"userId\"?: string | number;\n body: unknown;\n }): Promise<any>;\n /** `notifications.send` — POST /notifications/send. Send a notification to an app user (durable in-app inbox row + live WS frame) */\n \"send\"(args: {\n body: unknown;\n }): Promise<any>;\n /** `notifications.unreadCount` — GET /notifications/unread-count. Count the caller's unread notifications */\n \"unreadCount\"(args?: {\n \"userId\"?: string | number;\n }): Promise<any>;\n /** `notifications.unregisterDevice` — DELETE /me/push-tokens/{token}. Unregister one of the caller's device push tokens */\n \"unregisterDevice\"(args: {\n \"token\": string | number;\n \"userId\"?: string | number;\n }): Promise<any>;\n };\n \"prompts\": {\n /** `prompts.run` — POST /prompts/{promptKey}/run. Run a prompt under a server function's grants */\n \"run\"(args: {\n \"promptKey\": string | number;\n body?: unknown;\n }): Promise<any>;\n };\n \"resourceMetadata\": {\n /** `resourceMetadata.delete` — DELETE /resources/{resourceType}/{resourceId}/metadata/{category}. Delete a resource's metadata for a category (idempotent) */\n \"delete\"(args: {\n \"resourceType\": string | number;\n \"resourceId\": string | number;\n \"category\": string | number;\n }): Promise<any>;\n /** `resourceMetadata.get` — GET /resources/{resourceType}/{resourceId}/metadata/{category}. Read a resource's metadata for a category */\n \"get\"(args: {\n \"resourceType\": string | number;\n \"resourceId\": string | number;\n \"category\": string | number;\n }): Promise<any>;\n /** `resourceMetadata.getBatch` — POST /resources/metadata/batch. Batch-read resource metadata (partial success) */\n \"getBatch\"(args: {\n \"debug\"?: string | number | boolean;\n body: unknown;\n }): Promise<any>;\n /** `resourceMetadata.list` — GET /resources/{resourceType}/{resourceId}/metadata. List all metadata categories on a resource */\n \"list\"(args: {\n \"resourceType\": string | number;\n \"resourceId\": string | number;\n }): Promise<any>;\n /** `resourceMetadata.resolve` — POST /metadata/resolve. Resolve a resource by a category's unique metadata value */\n \"resolve\"(args: {\n body: unknown;\n }): Promise<any>;\n /** `resourceMetadata.set` — PUT /resources/{resourceType}/{resourceId}/metadata/{category}. Write a resource's metadata for a category */\n \"set\"(args: {\n \"resourceType\": string | number;\n \"resourceId\": string | number;\n \"category\": string | number;\n body: unknown;\n }): Promise<any>;\n };\n \"secrets\": {\n /** `secrets.get` — GET /secrets/{name}. Read an app secret under a server function's grants */\n \"get\"(args: {\n \"name\": string | number;\n }): Promise<any>;\n };\n \"users\": {\n /** `users.getBasic` — GET /users/{userId}/basic. Get a user's basic public profile */\n \"getBasic\"(args: {\n \"userId\": string | number;\n }): Promise<any>;\n /** `users.getProfiles` — POST /users/profiles. Look up user profiles in bulk */\n \"getProfiles\"(args: {\n body: unknown;\n }): Promise<any>;\n /** `users.getRootDocument` — GET /users/{userId}/root-document. Get an app user's root document id */\n \"getRootDocument\"(args: {\n \"userId\": string | number;\n }): Promise<any>;\n /** `users.list` — GET /users. List app users */\n \"list\"(args?: {\n \"email\"?: string | number | boolean;\n \"userId\"?: string | number;\n \"name\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<any>;\n /** `users.lookup` — GET /users/lookup. Look up a user by identifier */\n \"lookup\"(args?: {\n \"email\"?: string | number | boolean;\n }): Promise<any>;\n /**\n * `users.remove` — DELETE /users/{userId}. DEPRECATED — remove a user from the app; use the admin API's PUT apps/:appId/users/:userId/disable (`primitive users disable`)\n * @deprecated Use the admin API's PUT apps/:appId/users/:userId/disable (`primitive users disable`)\n */\n \"remove\"(args: {\n \"userId\": string | number;\n }): Promise<any>;\n /** `users.send` — POST /users/{userId}/send. Send a realtime message to a member of this app */\n \"send\"(args: {\n \"userId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `users.setProfile` — PATCH /users/{userId}/profile. Set a user's display name and avatar */\n \"setProfile\"(args: {\n \"userId\": string | number;\n body: unknown;\n }): Promise<any>;\n /** `users.setRole` — PUT /users/{userId}/role. Set a user's app role */\n \"setRole\"(args: {\n \"userId\": string | number;\n body: unknown;\n }): Promise<any>;\n };\n}\n\n/**\n * The app's database types, model by model — EMPTY here and filled by the\n * declaration `primitive config push` writes into the config tree's\n * `functions/` directory (#3182). A tree that has pushed once therefore types\n * `ctx.db` against its own schemas; one that has not gets the open form and\n * still compiles.\n */\nexport interface DatabaseSchemas {}\n\n/**\n * The type keys `ctx.db` accepts.\n *\n * Every key the augmentation declares, and NOTHING else, once a tree has\n * pushed: naming a type the app does not have is a compile error. Before that\n * — an unaugmented tree, a function written before the first push —\n * `DatabaseSchemas` is empty and `keyof` it is `never`, which would make the\n * argument unwritable rather than open. So the empty case widens to `string`\n * and the handle is untyped instead of unusable.\n */\nexport type DatabaseTypeKeys = [keyof DatabaseSchemas] extends [never]\n ? string\n : keyof DatabaseSchemas & string;\n\n/** A model's row shape, or an open record for a type with no schema. */\nexport type DatabaseModels<K extends string> = K extends keyof DatabaseSchemas\n ? DatabaseSchemas[K]\n : Record<string, Record<string, unknown>>;\n\n/**\n * The app's functions, key by key — EMPTY here and filled by the declaration\n * `primitive config push` writes into the config tree's `functions/`\n * directory (`primitive-function-types.d.ts`): each key's declared input and\n * output types, from its `inputSchema` and `outputSchema`. It is what types\n * `defineFunction(\"<key>\", handler)`.\n */\nexport interface FunctionSchemas {}\n\n/**\n * The keys `defineFunction(key, handler)` accepts: every key the augmentation\n * declares once a tree has pushed, so a key the tree does not declare is a\n * compile error — and `string` before that, the `DatabaseTypeKeys` rule, so an\n * unaugmented tree keeps compiling.\n */\nexport type FunctionKeys = [keyof FunctionSchemas] extends [never]\n ? string\n : keyof FunctionSchemas & string;\n\n/** A declared function's input type, or `any` when nothing is declared. */\nexport type FunctionInput<K extends string> = K extends keyof FunctionSchemas\n ? FunctionSchemas[K] extends { input: infer I }\n ? I\n : any\n : any;\n\n/** A declared function's output type, or `any` when nothing is declared. */\nexport type FunctionOutput<K extends string> = K extends keyof FunctionSchemas\n ? FunctionSchemas[K] extends { output: infer O }\n ? O\n : any\n : any;\n\n/**\n * The model names one database type addresses — its own, or any name at all\n * for a type that declares no schema (the DO is schemaless, so a grant on such\n * a type is legal and there is simply nothing to narrow to).\n */\nexport type DatabaseModelNames<TModels> = [keyof TModels] extends [never]\n ? string\n : keyof TModels & string;\n\n/**\n * A row as the platform HANDS IT BACK: whatever the schema declared, plus the\n * record identity the platform owns (#3450).\n *\n * Every stored record has an `id`. A save that arrives without one is given a\n * ULID, a projection always keeps it, and `delete` and `patch` take nothing\n * else — so a function that queries a model and then moves one of its rows\n * needs the id of the row it just read. A schema is free to say nothing about\n * that field, and most do; the identity is the platform's, not the schema's,\n * so it is added here rather than rendered into each declaration.\n *\n * A declared `id` is REPLACED, never intersected: one declared optional would\n * stay optional on a read row it is always present on, and one declared with\n * some other type would intersect to `never` and be unusable. The platform\n * stamps a string whatever the schema says.\n *\n * An `any` row stays `any` — `DatabaseHandle<any>` is `defineQuery`'s default\n * handle, and turning its rows into an object with one known member would\n * narrow code that was deliberately left open.\n *\n * Writes are untouched: every one of them takes `Partial<TRow>`, so a row a\n * function BUILDS still needs no id.\n */\nexport type PlatformRow<TRow> = 0 extends 1 & TRow\n ? TRow\n : Omit<TRow, \"id\"> & { id: string };\n\n/** One model's row shape, open when the type declares no schema. */\nexport type DatabaseModelRow<TModels, M extends string> =\n M extends keyof TModels\n ? PlatformRow<TModels[M]>\n : Record<string, unknown> & { id: string };\n\n/**\n * One model of one database, scoped: the `modelName` every records call needs\n * is bound once, so a call names an operation and its own arguments.\n *\n * Filters and options are ordinary objects. Inline filter typing arrives with\n * unified schemas — the intent's decision, not an omission — so what is typed\n * today is the model name and the row shape a read hands back.\n */\nexport type ModelScopedBody<TBody = Record<string, unknown>> = TBody & {\n /**\n * Bound by the handle. Reserved so a body cannot look like a second way to\n * choose a model: the runtime assigns the handle's own model last, and a row\n * type that said otherwise would be a lie about what came back.\n */\n modelName?: never;\n};\n\n/**\n * One write inside a model-scoped batch. Every batch verb is a write, so a\n * batch on a model needs that model's write grant whatever the ops are.\n */\nexport type ModelBatchOperation<TRow> = {\n op: \"save\" | \"patch\" | \"delete\" | \"increment\" | \"addToSet\" | \"removeFromSet\";\n id?: string;\n data?: Partial<TRow>;\n /** Bound by the handle, for the same reason every other call's is. */\n modelName?: never;\n [key: string]: unknown;\n};\n\nexport interface DatabaseModelHandle<TRow> {\n /**\n * One page of this model's rows, in the decided envelope — `{ items,\n * hasMore, nextCursor? }` (#3287), the same shape `ctx.doc(...)`,\n * `ctx.users.list` and the client library answer. The route's own wire\n * shape is unchanged; the SDK is where the one name lives, so shared paging\n * code can be written once.\n */\n query(body?: ModelScopedBody): Promise<{ items: TRow[]; hasMore: boolean; nextCursor?: string }>;\n count(body?: ModelScopedBody): Promise<any>;\n aggregate(body: ModelScopedBody): Promise<any>;\n save(body: ModelScopedBody<{ id?: string; data: Partial<TRow>; [key: string]: unknown }>): Promise<any>;\n /**\n * Change some fields of ONE row — `databases.records.patch`, with this\n * handle's model bound (#3450).\n *\n * The record id is positional and the body may not carry another, for the\n * same reason it may not name another model: the runtime assigns both LAST,\n * so a body that appeared to choose either would be a lie about which row\n * moved. `condition`, `stringSets` and the rest of the operation's own keys\n * pass through untouched.\n */\n patch(\n recordId: string,\n body: ModelScopedBody<{ data: Partial<TRow>; id?: never; [key: string]: unknown }>\n ): Promise<any>;\n /**\n * Remove ONE row by the id a read handed back — `databases.records.delete`,\n * with this handle's model bound (#3450). An optional `condition` makes it\n * conditional, and travels untouched.\n */\n delete(\n recordId: string,\n body?: ModelScopedBody<{ condition?: Record<string, unknown>; id?: never }>\n ): Promise<any>;\n /** Several writes to THIS model in one request; the binding is per item. */\n batch(body: {\n operations: Array<ModelBatchOperation<TRow>>;\n atomic?: boolean;\n }): Promise<any>;\n}\n\n/** One database, typed by the database TYPE key its grant names. */\nexport interface DatabaseHandle<TModels> {\n /** The database this handle addresses — part of every query cache key. */\n databaseId: string;\n /** The type key this handle was opened with. */\n databaseType: string;\n model<M extends DatabaseModelNames<TModels>>(\n modelName: M\n ): DatabaseModelHandle<DatabaseModelRow<TModels, M>>;\n /**\n * A batch may also SPAN models, and then it names each one itself — the\n * model-scoped form above is the typed way to write the common case.\n */\n batch(body: {\n operations: Array<Record<string, unknown>>;\n atomic?: boolean;\n }): Promise<any>;\n}\n\n/**\n * The app's DOCUMENT models — EMPTY here and filled by the declaration\n * `primitive config push` writes into the config tree's `functions/` directory\n * (`primitive-document-types.d.ts`, from the project's `models/models.toml`).\n * A project with no document schema gets the open form and still compiles.\n */\nexport interface DocumentSchemas {}\n\n/** The model names `ctx.doc(id).model()` accepts — every declared one, or `string` before a push. */\nexport type DocumentModelNames = [keyof DocumentSchemas] extends [never]\n ? string\n : keyof DocumentSchemas & string;\n\n/**\n * A document model's row shape, or an open record for an undeclared schema —\n * carrying the platform's record identity either way (#3450), by the same rule\n * and for the same reason as a database row: the records DO is one\n * implementation, and `patch` and `delete` here take an id too.\n */\nexport type DocumentModelRow<M extends string> = M extends keyof DocumentSchemas\n ? PlatformRow<DocumentSchemas[M]>\n : Record<string, unknown> & { id: string };\n\n/**\n * One related-records spec of a document model read's `include` (#4692),\n * answered on a db3 (a format-3 document) as `_related` on each record.\n */\nexport interface DocumentIncludeSpec {\n /** The related model. */\n model: string;\n /**\n * `refersTo`: this record's `sourceField` holds the related id (one record\n * or null). `hasMany`: the related `foreignKey` holds this record's\n * `localField` (an array). `refersToMany`: this record's `sourceField`\n * holds an array of ids (the records in member order, missing ones dropped).\n */\n type: \"refersTo\" | \"hasMany\" | \"refersToMany\";\n sourceField?: string;\n foreignKey?: string;\n /** The field the related `foreignKey` matches; `id` when omitted. */\n localField?: string;\n /** The key in `_related`; the model name when omitted. */\n as?: string;\n filter?: Record<string, unknown>;\n sort?: Record<string, 1 | -1>;\n /** Related rows per parent, `hasMany` only. */\n limit?: number;\n projection?: Record<string, 0 | 1>;\n /** Nested specs for the related records, to depth 3 in all. */\n include?: DocumentIncludeSpec[];\n}\n\n/** The options a document model read takes: a filter object (or its JSON), a page size, a cursor. */\nexport interface DocumentQueryOptions {\n filter?: Record<string, unknown> | string;\n /**\n * The order of the rows: each field maps to 1 (ascending) or -1\n * (descending), and key order is precedence, as in { createdAt: -1 }. `id`\n * breaks ties unless you name it. `limit` and `cursor` apply to the\n * ordered rows; pass the same sort with a `cursor`, since a cursor from\n * another sort is refused with a 400.\n */\n sort?: Record<string, 1 | -1>;\n /**\n * Records per page: 100 when omitted, at most 10,000; a larger value is\n * refused with a 400 naming the maximum, never clamped. A page also ends\n * before the record that would take it past 8 MiB (the sum of each\n * record's JSON in UTF-8 bytes; the envelope is not counted), answering\n * `hasMore: true` and a `nextCursor` that continues from the last record\n * returned; a single record larger than 8 MiB is answered alone. A page\n * that fills `limit` exactly also answers `hasMore: true`; loop on\n * `hasMore` rather than counting rows.\n */\n limit?: number;\n cursor?: string;\n /**\n * The document format you expect (#3764). When it disagrees with the format\n * the platform resolved, the call is refused with a 409\n * DOCUMENT_FORMAT_MISMATCH rather than answered out of the wrong tables.\n * Usually stated once on the handle, as ctx.doc(id, { documentFormat: 2 }),\n * rather than per read.\n */\n documentFormat?: 1 | 2 | 3;\n /**\n * Related records to answer with each record on a db3 (a format-3\n * document), as `_related`; ignored on a format-1 document. Nested to depth\n * 3. The response, `_related` included, is at most 8 MiB and a `hasMany`\n * spec reads at most 1,000 related rows per request; past either the read is\n * refused with a 400 DB3_PAGE_TOO_LARGE, never cut.\n */\n include?: DocumentIncludeSpec[] | string;\n}\n\n/**\n * One document model, bound to its document and its model name — a thin\n * binding over `ctx.api.documents.records.*` with the route's own shapes.\n */\n/**\n * One op of a document `batch` — the `documents.records.bulk` blob's shape,\n * typed to this handle's model (#3455).\n *\n * `model` is NOT a member: the handle already names it and assigns it last, so\n * a multi-model blob stays on the raw `ctx.api.documents.records.bulk`\n * operation rather than becoming a second way to say the same thing.\n *\n * `upsert` addresses the record by a unique constraint the model declares:\n * `data` carries every field of `constraint`, the record holding that key\n * gets `data` merged into it, and when none does one is created (at `id`\n * when given, else at a new id) with the model's defaults.\n */\nexport type DocumentBatchOp<TRow> =\n | { action: \"create\" | \"patch\"; id: string; data: Partial<TRow>; precondition?: Record<string, unknown> }\n | { action: \"delete\"; id: string; precondition?: Record<string, unknown> }\n | { action: \"upsert\"; constraint: string; id?: string; data: Partial<TRow>; precondition?: Record<string, unknown> };\n\n/**\n * What `documents.records.bulk` answers: the blob's aggregate effect.\n * `upserted` has one entry per `upsert` op, in input order: the op's\n * `index`, the record's `id`, and whether the op `created` it.\n */\nexport interface DocumentBulkResult {\n applied: number;\n added: Array<{ model: string; id: string }>;\n updated: Array<{ model: string; id: string }>;\n deleted: number;\n upserted: Array<{ index: number; model: string; id: string; created: boolean }>;\n}\n\nexport interface DocumentModelHandle<TRow> {\n /**\n * One page of the model's records: 100 by default, up to 10,000 with\n * `limit`, and at most 8 MiB of record JSON unless a single larger record\n * is answered alone. Pass `nextCursor` back as `cursor` while\n * `hasMore` is true.\n */\n query(options?: DocumentQueryOptions): Promise<{ items: Array<TRow & { _related?: Record<string, any> }>; hasMore: boolean; nextCursor?: string }>;\n count(options?: { filter?: Record<string, unknown> | string }): Promise<{ count: number }>;\n aggregate(body: Record<string, unknown>): Promise<any>;\n save(body: { id: string; data: Partial<TRow>; options?: Record<string, unknown> }): Promise<{ record: TRow }>;\n patch(recordId: string, body: { data: Partial<TRow>; options?: Record<string, unknown> }): Promise<{ record: TRow }>;\n delete(recordId: string): Promise<{ deleted: boolean }>;\n /**\n * Apply an ordered blob of this model's ops in ONE transaction — all of it\n * commits or none of it does, and connected clients see one update.\n *\n * One model's ops, by construction: every op's `model` is this handle's.\n * A blob that spans models is the raw `ctx.api.documents.records.bulk`\n * operation's job.\n */\n batch(ops: Array<DocumentBatchOp<TRow>>): Promise<DocumentBulkResult>;\n}\n\n/** A document, addressed once; its models are typed from `DocumentSchemas`. */\nexport interface DocumentHandle {\n documentId: string;\n model<M extends DocumentModelNames>(modelName: M): DocumentModelHandle<DocumentModelRow<M>>;\n}\n\n/**\n * The app's db3 types, model by model — EMPTY here and filled by the\n * declaration `primitive config push` writes into the config tree's\n * `functions/` directory (`primitive-db3-types.d.ts`, from `db3-types/` and\n * `database-type-configs/`). A tree that has not pushed gets the open form\n * and still compiles.\n */\nexport interface Db3Schemas {}\n\n/**\n * The type keys `ctx.db3` accepts: every key the augmentation declares and\n * nothing else once a tree has pushed, and any string before that.\n */\nexport type Db3TypeKeys = [keyof Db3Schemas] extends [never]\n ? string\n : keyof Db3Schemas & string;\n\n/** A db3 type's models, or an open record for a type with no schema. */\nexport type Db3Models<K extends string> = K extends keyof Db3Schemas\n ? Db3Schemas[K]\n : Record<string, Record<string, unknown>>;\n\n/** The model names a db3 type declares, or `string` for one that declares none. */\nexport type Db3ModelNames<TModels> = [keyof TModels] extends [never]\n ? string\n : keyof TModels & string;\n\n/** One db3 model's row shape, carrying the platform's record identity. */\nexport type Db3ModelRow<TModels, M extends string> = M extends keyof TModels\n ? PlatformRow<TModels[M]>\n : Record<string, unknown> & { id: string };\n\n/**\n * One op of a db3 `bulk`, typed to a model's row. `condition` is a guard in\n * the query filter grammar: the op applies only when the record is live and\n * matches it.\n */\nexport type Db3BulkOp<TRow = Record<string, unknown>> =\n | { action: \"create\"; id?: string; data: Partial<TRow>; condition?: Record<string, unknown>; requestId?: string }\n | { action: \"patch\"; id: string; data: Partial<TRow>; condition?: Record<string, unknown>; requestId?: string }\n | { action: \"delete\"; id: string; condition?: Record<string, unknown>; requestId?: string }\n | { action: \"upsert\"; constraint: string; id?: string; data: Partial<TRow>; condition?: Record<string, unknown>; requestId?: string }\n | { action: \"increment\"; id: string; fields: Record<string, number>; condition?: Record<string, unknown>; requestId?: string };\n\n/**\n * What `db3.records.bulk` answers. With `atomic: false` each op is applied on\n * its own and `results` names each one, a refused op carrying its `code`.\n */\nexport interface Db3BulkResult {\n applied: number;\n added: Array<{ model: string; id: string; appliedFields?: Record<string, unknown> }>;\n updated: Array<{ model: string; id: string; appliedFields?: Record<string, unknown> }>;\n deleted: number;\n upserted?: Array<{ index: number; model: string; id: string; created: boolean; appliedFields?: Record<string, unknown> }>;\n incremented?: Array<{ index: number; model: string; id: string; values: Record<string, number> }>;\n atomic?: boolean;\n results?: Array<\n | { index: number; model: string; id: string; ok: true; kind: string; values?: Record<string, number>; appliedFields?: Record<string, unknown>; requestId?: string }\n | { index: number; model: string; id?: string; ok: false; code: string; status: number; error: string; reason?: string; requestId?: string }\n >;\n requestId?: string;\n}\n\n/**\n * One db3 model, bound to its db3 and its model name — a thin binding over\n * `ctx.api.db3.records.*` with the routes' own answers. A refusal rejects\n * with the route's error: a failing `condition` is 409\n * `DB3_CONDITION_NOT_MET`, a missing record on `increment` 404\n * `DB3_RECORD_NOT_FOUND`, a model the type does not declare 400\n * `DB3_MODEL_NOT_DECLARED`.\n */\nexport interface Db3ModelHandle<TRow> {\n /** The record with this id, or `null` when there is none. */\n get(recordId: string): Promise<TRow | null>;\n /** One page of records: pass `nextCursor` back as `cursor` while `hasMore` is true. */\n query(options?: DocumentQueryOptions): Promise<{ items: Array<TRow & { _related?: Record<string, any> }>; hasMore: boolean; nextCursor?: string }>;\n count(options?: { filter?: Record<string, unknown> | string }): Promise<{ count: number }>;\n /** Counts, sums, averages, minimums and maximums, resolved to the bare row array. */\n aggregate(body: Record<string, unknown>): Promise<any[]>;\n /**\n * Create or replace a record; the id is minted when omitted. `ifNotExists`\n * applies only when no record has the id, `upsertOn` lands on the record\n * holding the same unique key. `appliedFields` names what the type's hook\n * rules wrote.\n */\n save(body: {\n id?: string;\n data: Partial<TRow>;\n condition?: Record<string, unknown>;\n ifNotExists?: boolean;\n upsertOn?: string;\n requestId?: string;\n }): Promise<{ record: TRow; appliedFields?: Record<string, unknown> }>;\n /** Merge fields into an existing record. */\n patch(\n recordId: string,\n body: { data: Partial<TRow>; condition?: Record<string, unknown>; requestId?: string }\n ): Promise<{ record: TRow; appliedFields?: Record<string, unknown> }>;\n /** Delete a record; deleting one that does not exist is not an error unless a `condition` asks. */\n delete(recordId: string, body?: { condition?: Record<string, unknown>; requestId?: string }): Promise<{ deleted: boolean }>;\n /** Add each delta to its numeric field, and answer each field's new value. */\n increment(\n recordId: string,\n fields: Record<string, number>,\n options?: { condition?: Record<string, unknown>; requestId?: string }\n ): Promise<{ record: TRow; values: Record<string, number> }>;\n /** This model's ops in one request: one transaction, or each on its own with `atomic: false`. */\n bulk(ops: Array<Db3BulkOp<TRow>>, options?: { atomic?: boolean; requestId?: string }): Promise<Db3BulkResult>;\n}\n\n/**\n * A db3, addressed once and typed by the type its `ctx.db3` call names.\n * Every call is a `db3.records.*` operation on the app's own authority: the\n * handle confers nothing and needs no grant.\n */\nexport interface Db3Handle<TModels> {\n db3Id: string;\n /** The type key this handle was opened with. */\n type: string;\n model<M extends Db3ModelNames<TModels>>(modelName: M): Db3ModelHandle<Db3ModelRow<TModels, M>>;\n /** Ops across models in one request; each op names its `model`. */\n bulk(\n ops: Array<Db3BulkOp & { model: Db3ModelNames<TModels> }>,\n options?: { atomic?: boolean; requestId?: string }\n ): Promise<Db3BulkResult>;\n}\n\n/**\n * How a `ctx.db3` handle's calls are judged — #4806.\n *\n * `asUser` names the member every call is judged by: their grant on the\n * db3 and nothing else, with no app or function authority, and the room's\n * hook rules see them as `user.userId`. A sync-off db3 refuses every\n * member (403). Naming a member other than the invoking user needs a run\n * with no caller, one an app owner or admin invoked, or a function declaring\n * `users:actAsAny` (`SUBJECT_USER_FORBIDDEN` otherwise); a user who is not a member is\n * `SUBJECT_USER_NOT_FOUND`.\n *\n * ```ts\n * const mine = ctx.db3(input.db3Id, \"orders\", { asUser: ctx.user.userId });\n * await mine.model(\"Order\").query(); // only what this member may read\n * ```\n */\nexport interface Db3HandleOptions {\n asUser?: string;\n}\n\n/** A db3 opened with no type: the model API over open record shapes, and no `type`. */\nexport type Db3UntypedHandle = Omit<Db3Handle<Record<string, Record<string, unknown>>>, \"type\">;\n\n/**\n * One call through a granted integration — #3183.\n *\n * `path` is RELATIVE to the integration's `baseUrl`, and the host is the\n * integration's: the platform resolves and normalizes the path before checking\n * it against `allowedPaths`, so a protocol-relative path or a `..` segment is\n * refused rather than silently sending the request somewhere else.\n */\nexport interface IntegrationCallRequest {\n /** Must be in the integration's `allowedMethods`. Defaults to its own default. */\n method?: string;\n /** Relative to the integration's `baseUrl`. */\n path?: string;\n query?: Record<string, unknown>;\n headers?: Record<string, string>;\n body?: unknown;\n /** form-urlencoded body; not combinable with `body`. */\n form?: Record<string, unknown>;\n bodyMode?: \"json\" | \"raw\" | \"multipart\";\n}\n\n/** What the upstream answered, as the platform saw it. */\nexport interface IntegrationCallResult {\n status: number;\n headers: Record<string, string>;\n body: unknown;\n durationMs: number;\n traceId: string;\n /** Set when the platform or the upstream refused; absent on success. */\n errorCode?: string;\n}\n\n/** What a prompt run is given — the member execute route's own body. */\nexport interface PromptRunArgs {\n /**\n * The prompt's variables. A `kind = \"decisions\"` prompt takes\n * `{ state, criteria? }`: `state` is the value its questions are asked\n * about, and `criteria.<question>` supplies this run's options for each\n * choice question declared `criteriaSource = \"dynamic\"` — a table of option\n * key = description (a string or a JSON object), at least two entries (#3813).\n */\n variables?: Record<string, unknown>;\n /** Run against a different model for this call only. */\n modelOverride?: string;\n /** Pin a specific config OF THIS PROMPT; defaults to its active one. */\n configId?: string;\n}\n\n/**\n * The app's PROMPTS — EMPTY here and filled by the declaration\n * `primitive config push` writes into the config tree's `functions/` directory\n * (`primitive-prompt-types.d.ts`, from the tree's `prompts/*.toml`). A prompt\n * that declares an `outputSchema` carries `{ output: <Key>PromptOutput }`; one\n * that declares none carries `{}`, so reading `parsed.field` on it is a\n * compile error rather than a runtime `undefined`.\n */\nexport interface PromptSchemas {}\n\n/**\n * The keys whose declaration is an AGENT (`kind = \"agent\"`, #3798): entries\n * carrying `{ agent: … }` instead of an output. An agent runs turn by turn in\n * a session and never single-shot, so these are the keys `PromptKeys` leaves\n * out.\n */\nexport type AgentKeys = {\n [K in keyof PromptSchemas]: PromptSchemas[K] extends { agent: unknown } ? K : never;\n}[keyof PromptSchemas] &\n string;\n\n/**\n * The keys `ctx.prompts.run` accepts — every declared one that is not an\n * agent, or `string` before a push.\n */\nexport type PromptKeys = [keyof PromptSchemas] extends [never]\n ? string\n : Exclude<keyof PromptSchemas & string, AgentKeys>;\n\n/** One agent's session variables, typed from its `inputSchema` (#3798). */\nexport type AgentVariables<K extends AgentKeys> = PromptSchemas[K] extends {\n agent: { variables: infer V };\n}\n ? V\n : never;\n\n/**\n * The keys `ctx.agents.createSession` accepts — #3803: every declared agent,\n * or `string` before the tree has pushed any prompt (the `PromptKeys`\n * rule).\n */\nexport type SessionAgentKeys = [keyof PromptSchemas] extends [never]\n ? string\n : AgentKeys;\n\n/**\n * What `ctx.agents.createSession` takes — #3803. Typed by the agent's key:\n * `variables` is that agent's `inputSchema` (any object before a push),\n * and the platform validates it again against the schema as pushed.\n */\nexport interface AgentSessionCreateOptions<K extends SessionAgentKeys> {\n /** The key of an agent prompt (`kind = \"agent\"`). */\n agent: K;\n /** The session's variables; at most 16 KiB of JSON. */\n variables?: K extends AgentKeys ? AgentVariables<K> : Record<string, unknown>;\n /** Free text the app groups sessions by, 1 to 256 characters. */\n scope?: string;\n /** 1 to 255 characters; defaults to the agent's display name. */\n title?: string;\n /**\n * Initial participants, who send messages and hold a `read-write` grant\n * on the session's document — #3805. Existing users of this app, not the\n * caller; with `viewers`, at most 50.\n */\n participants?: string[];\n /**\n * Initial viewers, who read the session and hold a `reader` grant — #3805.\n * Existing users of this app, not the caller, in neither list twice.\n */\n viewers?: string[];\n /**\n * The member who owns the session; omitted, the invoking user. A run with\n * no caller must name one; naming another member follows the header's\n * subject rule. Initial members may not name the owner.\n */\n userId?: string;\n}\n\n/** What `ctx.agents.createSession` answers — #3803. */\nexport interface AgentSessionCreateResult {\n /** The session: what the app keeps and uses for everything but opening. */\n sessionId: string;\n /**\n * The session's conversation document, opened with the document client.\n * @deprecated Use `sessionId` with the session API (`ctx.agents`,\n * `ctx.api.agentSessions`); the field remains until a later breaking release.\n */\n documentId: string;\n}\n\n/** What `ctx.agents.getSession` answers — #3805. Never the document's rows. */\nexport interface AgentSessionInfo {\n sessionId: string;\n agentKey: string;\n /**\n * Open this with the document client to read the conversation.\n * @deprecated Use `sessionId` with the session API (`ctx.agents`,\n * `ctx.api.agentSessions`); the field remains until a later breaking release.\n */\n documentId: string;\n ownerUserId: string;\n /** ISO-8601. */\n createdAt: string;\n title: string | null;\n scope: string | null;\n /** ISO-8601; null when the session's listing row is missing. */\n lastActivityAt: string | null;\n /**\n * Whether the invoking user has activity in the session they have not\n * marked read (their client marks it); false for an admin with no role.\n */\n hasUnread: boolean;\n /** When the invoking user last marked the session read (ISO-8601), or null. */\n lastReadAt: string | null;\n /** The members, in the order they were added. */\n members: { viewers: string[]; participants: string[] };\n /** The standing on the session of the member the call acted as. */\n role: \"owner\" | \"participant\" | \"viewer\" | \"admin\";\n /**\n * The session's status, decided from the session object (never the\n * session row): the active turn's phase, else how the last turn ended.\n */\n status: AgentSessionStatus;\n /** The active turn, or null when none runs. */\n turn: AgentSessionTurnSummary | null;\n}\n\n/** A session's status: `idle` between turns, the active turn's phase, or how the last turn ended. */\nexport type AgentSessionStatus =\n | \"idle\"\n | \"thinking\"\n | \"running_tool\"\n | \"awaiting_answer\"\n | \"failed\"\n | \"expired\"\n | \"cancelled\";\n\n/** The active turn of a session, as `ctx.agents.getSession` answers it. */\nexport interface AgentSessionTurnSummary {\n turnId: string;\n /** The member whose messages started the turn. */\n initiatorUserId: string;\n /** ISO-8601; null until the turn has started. */\n startedAt: string | null;\n /** `model` while a model call runs, `tools` while server tools run, `paused` while a call waits on a person. */\n phase: \"model\" | \"tools\" | \"paused\" | \"draining\";\n /** Model rounds begun. */\n rounds: number;\n /** ISO-8601; until when the turn's runner holds it. */\n leaseUntil: string | null;\n /** Who may answer the turn's calls, as pinned at the turn's start. */\n answeredBy: string | null;\n /** The calls waiting on a person and until when, or null. */\n pause: { callIds: string[]; since: string; expiresAt: string } | null;\n /** A transition being made, or null. */\n pending: { kind: \"answer\" | \"end\" } | null;\n}\n\n/** One session in `ctx.agents.listSessions` — #3805. */\nexport interface AgentSessionListItem {\n sessionId: string;\n agentKey: string;\n scope: string | null;\n /**\n * The session's conversation document.\n * @deprecated Use `sessionId` with the session API (`ctx.agents`,\n * `ctx.api.agentSessions`); the field remains until a later breaking release.\n */\n documentId: string;\n ownerUserId: string;\n role: \"owner\" | \"participant\" | \"viewer\";\n title: string | null;\n /** ISO-8601. */\n lastActivityAt: string;\n createdAt: string | null;\n /** Whether the user has activity in the session they have not marked read. */\n hasUnread: boolean;\n /** When the user last marked the session read (ISO-8601), or null. */\n lastReadAt: string | null;\n /**\n * The session's status as of its last listed activity, or null for an\n * entry written before the status was listed. It may lag a status change\n * that came with no activity (a server tool's round); `getSession` reads\n * the current one.\n */\n status: AgentSessionStatus | null;\n}\n\n/** What `ctx.agents.listSessions` takes — #3805. */\nexport interface AgentSessionListOptions {\n /**\n * Whose sessions; omitted, the invoking user's. A run with no caller must\n * name one, and naming another follows the header's subject rule. A user\n * with no sessions here, member or not, answers an empty page.\n */\n userId?: string;\n /** Only this agent's sessions. */\n agent?: string;\n /** Only sessions created with exactly this scope. */\n scope?: string;\n /** Page size, at most 100 (default 50). */\n limit?: number;\n /** The `nextCursor` of the previous page. */\n cursor?: string;\n}\n\n/**\n * Which member `ctx.agents.getSession`, `recordEvent` and\n * `deleteSession` act as. Omitted, the invoking user; a run with no caller\n * must name one, and naming another follows the header's subject rule.\n */\nexport interface AgentSessionSubjectOptions {\n userId?: string;\n}\n\n/** A page of `ctx.agents.listSessions` — #3805. */\nexport interface AgentSessionListPage {\n items: AgentSessionListItem[];\n hasMore: boolean;\n nextCursor?: string;\n}\n\n/** What `ctx.agents.recordEvent` takes — #3807. */\nexport interface AgentSessionEvent {\n /** An event kind the session's agent declares. */\n kind: string;\n /** The payload, validated against the kind's schema; at most 64 KiB of JSON. */\n data: unknown;\n /** Your own id for the event, 1 to 128 characters: a repeat with the same content records nothing. */\n eventId?: string;\n /** A call of this session (`call_<ULID>`) the event is about. */\n refersTo?: string;\n}\n\n/** What `ctx.agents.recordEvent` answers — #3807. */\nexport interface AgentSessionEventResult {\n messageId: string;\n seq: number;\n /** Set when the `eventId` was already recorded with this content: the first event's ids. */\n duplicate?: boolean;\n}\n\n/** What `ctx.agents.deleteSession` answers: the session and the document deleted with it. */\nexport interface AgentSessionDeleteResult {\n deleted: true;\n sessionId: string;\n documentId: string;\n}\n\n/** One agent's client tools, by name: each one's `input` and `output` (#3798). */\nexport type AgentClientTools<K extends AgentKeys> = PromptSchemas[K] extends {\n agent: { clientTools: infer T };\n}\n ? T\n : never;\n\n/** One agent's event kinds, by name: each one's payload (#3798). */\nexport type AgentEvents<K extends AgentKeys> = PromptSchemas[K] extends {\n agent: { events: infer E };\n}\n ? E\n : never;\n\n/** One prompt's declared output type, or `unknown` where none is declared. */\nexport type PromptOutput<K extends string> = K extends keyof PromptSchemas\n ? PromptSchemas[K] extends { output: infer O }\n ? O\n : unknown\n : unknown;\n\n/**\n * Why a prompt's own answer was refused or incomplete — #3330, #4146. Never\n * set on a PROVIDER failure, which is what makes \"the model returned the wrong\n * shape\" distinguishable from \"the model failed\".\n *\n * `PROMPT_OUTPUT_TRUNCATED` is the answer cut off at the output token limit\n * (`truncated` is `true` beside it): a declared-JSON answer that stopped\n * before it was finished, whatever its shape, or a completion that spent the\n * whole limit and came back empty. Raise the config's `maxTokens` rather\n * than rewording the prompt.\n */\nexport type PromptOutputErrorCode =\n | \"PROMPT_OUTPUT_NOT_JSON\"\n | \"PROMPT_OUTPUT_SCHEMA_VIOLATION\"\n | \"PROMPT_OUTPUT_TRUNCATED\";\n\n/**\n * Every code the envelope's `errorCode` can carry — #3663, #3813.\n *\n * `PROMPT_UPSTREAM_TIMEOUT` and `PROMPT_UPSTREAM_REJECTED` are NOT about the\n * prompt's own answer: the provider ran out of time, or refused the request as\n * invalid (`upstreamStatus` 400 — a setting the model does not support, such\n * as a reasoning level, with the provider's message in `error`), so there was\n * no answer to refuse. They are the only provider failures that set\n * `errorCode`, which is what leaves \"the model returned the wrong shape\"\n * distinguishable from \"the model failed\" while still letting a caller retry\n * a timeout and fix the config for a refusal.\n *\n * `PROMPT_CRITERIA_INVALID` is the run that never reached a provider: a\n * decisions run's `variables.criteria` was refused before the call, so\n * nothing was billed (#3813).\n *\n * `PROMPT_STRICT_OUTPUT_SCHEMA_MISSING` never reached one either: the config\n * sets `strictOutput = true` and the prompt has no usable `outputSchema` to\n * send as the strict `json_schema` (#3801).\n */\nexport type PromptRunErrorCode =\n | PromptOutputErrorCode\n | \"PROMPT_UPSTREAM_TIMEOUT\"\n | \"PROMPT_UPSTREAM_REJECTED\"\n | \"PROMPT_CRITERIA_INVALID\"\n | \"PROMPT_STRICT_OUTPUT_SCHEMA_MISSING\";\n\n/** A prompt that declares an output shape, when the answer matched it. */\nexport interface PromptRunSuccess<TParsed> {\n success: true;\n output: string;\n /** The parsed, validated answer — no caller-side `JSON.parse` (#3330). */\n parsed: TParsed;\n error?: null;\n errorCode?: null;\n metrics?: Record<string, unknown>;\n configId: string;\n /**\n * `true` when the provider stopped at the output token limit\n * (`maxTokens`) before the answer was finished; absent otherwise. On\n * Gemini, reasoning tokens count against the same limit.\n */\n truncated?: true;\n}\n\n/**\n * The failure arm, whichever failed. `errorCode` is set for a SHAPE failure,\n * for a refused run (`PROMPT_CRITERIA_INVALID`, #3813), and for a provider\n * one only when the upstream TIMED OUT (#3663); `output` carries the text\n * either way, which is where the model's own value lives — a validation\n * `error` names paths and schema constraints only.\n */\nexport interface PromptRunFailure {\n success: false;\n output: string;\n error: string | null;\n errorCode?: PromptRunErrorCode | null;\n parsed?: undefined;\n metrics?: Record<string, unknown>;\n configId: string;\n /**\n * The upstream provider's HTTP status, when the call reached a provider and\n * it answered — #3663. This is what a retry decision is made on: a 504 or a\n * 503 is worth another attempt, a 400 on a refused payload is not.\n *\n * It does not depend on which provider the config named: Gemini and\n * OpenRouter report it identically. It is absent when no provider answer was\n * observed — an unset key, an oversized payload, a completion that came back\n * empty — so a number here is always the provider's own.\n */\n upstreamStatus?: number;\n /**\n * `true` when the provider stopped at the output token limit\n * (`maxTokens`) before the answer was finished; absent otherwise. On\n * Gemini, reasoning tokens count against the same limit.\n */\n truncated?: true;\n}\n\n/** The envelope for a key whose declaration says nothing about its output. */\nexport interface PromptRunOpenResult {\n success: boolean;\n output: string;\n /**\n * Present when the config that ran declares `outputFormat = \"json\"` and the\n * text parsed. Untyped: nothing declared its shape.\n */\n parsed?: unknown;\n error?: string | null;\n errorCode?: PromptRunErrorCode | null;\n metrics?: Record<string, unknown>;\n configId: string;\n /** The upstream provider's HTTP status on a provider failure — #3663. */\n upstreamStatus?: number;\n /**\n * `true` when the provider stopped at the output token limit\n * (`maxTokens`) before the answer was finished; absent otherwise. On\n * Gemini, reasoning tokens count against the same limit.\n */\n truncated?: true;\n}\n\n/**\n * The member execute envelope, plus what the prompt's own declaration adds.\n *\n * For a key whose `prompts/<key>.toml` declares an `outputSchema`, this is a\n * discriminated union: narrow on `success` and `parsed` is the declared type,\n * required. For every other key — and in a tree that has not pushed — it is\n * the open shape, with `parsed` optional and `unknown`.\n */\nexport type PromptRunResult<K extends string = string> = K extends keyof PromptSchemas\n ? PromptSchemas[K] extends { output: infer O }\n ? PromptRunSuccess<O> | PromptRunFailure\n : PromptRunOpenResult\n : PromptRunOpenResult;\n\n/** What a send delivered to. */\nexport interface SendResult {\n /** Unique live connections the frame was sent to. Zero is a success. */\n connections: number;\n /** True when the per-user connection ceiling stopped the fanout. */\n truncated: boolean;\n}\n\n/** Who a channel grant is for, and for how long — #3184. */\nexport interface ChannelAuthorizeOptions {\n /**\n * The member the grant names. Caller mode defaults to the invoking caller;\n * system mode has no caller and must say.\n */\n userId?: string;\n /** Default 300 s, clamped to the platform ceiling of 900 s. */\n ttlSeconds?: number;\n}\n\n/** The credential a client presents on the WebSocket it already has. */\nexport interface ChannelGrantResult {\n channel: string;\n /** The signed grant. Hand it to the client; it is not readable here. */\n grant: string;\n /** Epoch milliseconds. Expiry is the only revocation a channel has. */\n expiresAt: number;\n}\n\n/** Where to start and how big a page to take — #3280. */\nexport interface UserPageOptions {\n /** Page size. Capped by the route at 100. */\n limit?: number;\n /** The `nextCursor` of the page before this one. */\n cursor?: string;\n}\n\n/** One user on the roster, as the platform's own users route reports them. */\nexport interface UserPageItem {\n userId: string;\n email: string | null;\n name: string | null;\n avatarUrl: string | null;\n role: string;\n addedAt: string | null;\n status: string;\n disabledAt: string | null;\n [key: string]: unknown;\n}\n\n/** The decided paged envelope, the same shape every paged read answers. */\nexport interface UserPage {\n items: UserPageItem[];\n hasMore: boolean;\n /** Absent on the last page. */\n nextCursor?: string;\n}\n\n/** How a nested start is keyed and labelled — #3280. */\nexport interface FunctionStartOptions {\n /**\n * Idempotency key, scoped to the tree's root initiator and the resolved\n * context document: a repeat replays the run that already exists rather than\n * starting a second. At most 100 characters.\n */\n runKey?: string;\n /**\n * The document the child's run is keyed under. Defaults through the\n * inheritance rule: the parent run's context, else the root caller's root\n * document, else `fn:<the root function's id>`. At most 100 characters.\n */\n contextDocId?: string;\n /** Caller metadata, at most 1 KB encoded. */\n meta?: Record<string, unknown>;\n}\n\n/** The start envelope, the same one a workflow start answers with — #3280. */\nexport interface FunctionStartResult {\n /** Poll this on the platform's run-status route. */\n runId: string;\n runKey: string;\n instanceId: string;\n status: string;\n /**\n * True when `runKey` already named a run in this tree, which this envelope\n * describes. That is what makes a run key a singleton.\n */\n existing?: boolean;\n}\n\n/** A held named lock, as `ctx.locks.acquire` hands it back — #3930. */\nexport interface LockHandle {\n key: string;\n handleId: string;\n leaseExpiresAt: string;\n}\n\n/** How long to hold, and how long to wait — #3930. */\nexport interface LockAcquireOptions {\n /** The lease, in milliseconds (at most 24 h). Renew or release before it lapses. */\n ttlMs: number;\n /**\n * How long to wait for the key, in milliseconds, at most one hour. Under the\n * request runtime it must also fit the invocation's remaining budget.\n */\n timeoutMs: number;\n /**\n * Who this hold belongs to. Defaults to `ctx.runId` when the invocation\n * has a run, so a resumed slice re-takes its own hold with a fresh handle\n * rather than waiting on it.\n */\n owner?: string;\n}\n\n/**\n * The answer to a blocking acquire — #3930. Never a throw for \"not acquired\":\n * a refusal carries the last contention seen, and `rateLimited` says the\n * last attempt was refused by the acquire rate limit rather than by a holder.\n */\nexport type LockAcquireResult =\n | { acquired: true; handle: LockHandle }\n | {\n acquired: false;\n timedOut: true;\n rateLimited: boolean;\n heldBy: string | null;\n holderKind: string | null;\n owner: string | null;\n leaseExpiresAt: string | null;\n };\n\n/** The answer to `ctx.locks.release`. */\nexport type LockReleaseResult =\n | { released: true }\n | { released: false; reason: \"not_holder\" | \"not_held\" };\n\nexport interface FunctionContext {\n /** The HTTP caller, or null for a webhook or cron fire. */\n user: FunctionUser | null;\n trigger: FunctionTrigger;\n /**\n * The agent session this tool call belongs to, when an agent turn called\n * the function as a tool (`ctx.trigger.kind === \"tool\"`); otherwise\n * absent.\n *\n * Checking `ctx.trigger.kind` narrows `ctx.trigger` and not this\n * member, so call `assertTrigger(ctx, \"tool\")` first to read it without a\n * guard.\n */\n tool?: FunctionToolContext;\n /**\n * Which RUNTIME is hosting this code — #3482.\n *\n * Beside `trigger`, which says which DOOR fired, and they are different\n * questions: an HTTP call is whichever runtime the caller chose\n * (`invoke` or `start`), a cron fire is always a task and a webhook\n * delivery is always a request.\n *\n * To REFUSE a runtime rather than branch on it, call\n * `assertRuntime(\"task\")` — at module scope to refuse it outright, or in\n * the handler to refuse one call.\n */\n runtime: \"request\" | \"task\";\n /**\n * The RUN this invocation belongs to, or null — #3562.\n *\n * Set under the task runtime (every slice of the run, the first and every\n * resume) and for a webhook-fired request run, which writes a row. Null for\n * an HTTP `invoke`, which writes no run row at all.\n *\n * It is the deterministic OWNER a task run presents to re-take its own\n * lease: `ctx.api.locks.tryAcquire({ body: { key, ttlMs, owner: ctx.runId } })`\n * succeeds for the run that already holds the key, with a fresh handle.\n */\n runId: string | null;\n /**\n * The SLICE of the run this code is running in, or null — #3562.\n *\n * The same identifier `primitive functions runs` and the run-status\n * route's `slice.sliceId` report. A task run is a sequence of slices: it\n * changes when the run hibernates and wakes, which is how a handler can tell\n * a resume from a first pass.\n *\n * Null under the request runtime: a request invocation is not a slice.\n */\n sliceId: string | null;\n api: FunctionApi;\n /**\n * A typed handle over one database. The second argument is the database TYPE\n * key — the same key a `database:<type>/<model>:read|write` grant names —\n * and it is what selects the models this handle knows (#3182).\n */\n db<K extends DatabaseTypeKeys>(\n databaseId: string,\n databaseType: K\n ): DatabaseHandle<DatabaseModels<K>>;\n /**\n * A typed handle over one document's record models, typed from the\n * project's `models/models.toml` — `ctx.db`'s shape for documents. It\n * confers nothing: every call is a `documents.records.*` operation on the\n * same authority.\n */\n /**\n * A typed handle over one db3, typed from the pushed db3 types\n * (`primitive-db3-types.d.ts`):\n *\n * ```ts\n * const orders = ctx.db3(input.db3Id, \"orders\").model(\"Order\");\n * const { record } = await orders.save({ data: { total: 12 } });\n * await orders.increment(record.id, { total: 3 });\n * ```\n *\n * It confers nothing: every call is a `db3.records.*` operation on the\n * app's own authority, as `ctx.doc`'s are. A function that watches the\n * db3 it writes (`[[function.triggers.db3]]`) starts a run per flush of its\n * own writes; check `ctx.trigger.kind === \"db3\"` before writing back.\n *\n * A db3's lifecycle (create, get, delete, sync, type, app access, custody)\n * is `ctx.api.db3.*`, as `ctx.db`'s is `ctx.api.databases.*`.\n */\n db3<K extends Db3TypeKeys>(db3Id: string, type: K): Db3Handle<Db3Models<K>>;\n /**\n * The typed handle, with every call judged by the member `options.asUser`\n * names (`Db3HandleOptions`).\n */\n db3<K extends Db3TypeKeys>(db3Id: string, type: K, options: Db3HandleOptions): Db3Handle<Db3Models<K>>;\n /**\n * An untyped db3, from any tree: the same model API over open record\n * shapes, and no `type`.\n *\n * ```ts\n * const notes = ctx.db3(input.db3Id).model(\"Note\");\n * ```\n */\n db3(db3Id: string): Db3UntypedHandle;\n /** An untyped db3, with every call judged by the member `options.asUser` names. */\n db3(db3Id: string, type: undefined, options: Db3HandleOptions): Db3UntypedHandle;\n doc(documentId: string, options?: { documentFormat?: 1 | 2 | 3 }): DocumentHandle;\n /**\n * Outbound HTTP, through a granted integration and nowhere else (#3183).\n *\n * A function has no raw network access: every `fetch` to a host that is not\n * the platform answers `FUNCTION_EGRESS_DENIED`, grant or no grant. What an\n * `integration:<key>` grant buys is this call, which the MAIN WORKER makes on\n * the function's behalf — which is why the integration's `{{secrets.*}}`\n * credentials can be injected into the request without ever being visible to\n * the code that asked for it.\n */\n integrations: {\n call(\n integrationKey: string,\n request?: IntegrationCallRequest\n ): Promise<IntegrationCallResult>;\n };\n /**\n * Start another function as a TASK run from inside this one — #3280.\n *\n * The one nested door, and it is a START: code that wants a result composes\n * by IMPORTING the other function, so there is no synchronous nested\n * invocation to reach for.\n *\n * The callee's `access` gate is not consulted — this function's own gate was\n * the authorization — and every run in the tree is keyed by whoever started\n * it, so the member who invoked the root polls and terminates them all.\n * Nesting is bounded at four levels.\n */\n functions: {\n start(\n functionKey: string,\n input?: unknown,\n options?: FunctionStartOptions\n ): Promise<FunctionStartResult>;\n };\n /**\n * Run one of the app's prompts, with nothing to declare (#3183, #3279).\n *\n * The calling function's `authorize` is the authorization: it decided who\n * may invoke the function, and so who may run the prompt, which carries no\n * rule of its own. The provider request is bounded by the invocation's own\n * deadline.\n *\n * TYPED BY KEY (#3330). Where `prompts/<key>.toml` declares an\n * `outputSchema`, the platform parses the answer, validates it against that\n * schema and hands it back as `parsed`, typed — so the shape is written once\n * in TOML instead of restated as a `JSON.parse` at every call site. Where\n * only the config that ran declares `outputFormat = \"json\"`, `parsed` is\n * present but `unknown`. Where neither is declared the envelope is exactly\n * what it has always been.\n *\n * A shape the declaration refuses is `success: false` with an `errorCode`\n * (`PROMPT_OUTPUT_NOT_JSON` or `PROMPT_OUTPUT_SCHEMA_VIOLATION`) and the\n * text still in `output`; a PROVIDER failure has `error` and no\n * `errorCode`, so the two are told apart without guessing.\n *\n * Once a tree has pushed, a key it does not declare is a compile error.\n */\n prompts: {\n run<K extends PromptKeys>(\n promptKey: K,\n args?: PromptRunArgs\n ): Promise<PromptRunResult<K>>;\n };\n /**\n * Agent sessions (#3803, project `agents`), on the header's subject rule:\n * each call acts for `userId`, else the invoking user, and from any kind of\n * run — a run with no caller must name the member.\n *\n * `createSession` creates a session that member owns and answers\n * `{ sessionId, documentId }`. Variables failing the agent's\n * `inputSchema` reject with `AGENT_SESSION_VARIABLES_INVALID` and\n * `details.errors`. Once a tree has pushed, a key that is not an agent,\n * and variables the agent's schema refuses, are compile errors.\n * `participants` and `viewers` name initial members (#3805).\n *\n * `getSession` and `listSessions` (#3805) read the member's sessions —\n * the ones they own or are a member of — as that member, with no admin arm\n * whoever invoked the function: a session they are not in answers\n * `AGENT_SESSION_NOT_FOUND`, and function code never sees a session's\n * `object`, `turnContexts` or `lastTurn`.\n *\n * `deleteSession` deletes a session the member owns, with the same\n * outcome as the owner's delete from a client: the session, its document\n * and every member's listing go, and a repeat answers the same. A session\n * whose document is already gone can still be deleted. A participant or\n * viewer is refused `AGENT_SESSION_OWNER_ONLY`, anyone else\n * `AGENT_SESSION_NOT_FOUND`, with no admin arm. A `userId` that is\n * present but not a string (`null`, a number) is refused\n * `SUBJECT_USER_INVALID`, never read as the invoking user. Renaming and\n * changing members are the owner's, from a client.\n *\n * `recordEvent` (#3807) records an event as the member, who must be the\n * session's owner or a participant (`AGENT_SESSION_PARTICIPANT_ONLY` for a\n * viewer); the row is authored `app`. The kind must be one the agent\n * declares (`AGENT_EVENT_KIND_UNKNOWN`) and the data must match its schema\n * (`AGENT_EVENT_INVALID`). An event never starts a turn; the model reads\n * it in a later turn.\n */\n agents: {\n createSession<K extends SessionAgentKeys>(\n options: AgentSessionCreateOptions<K>\n ): Promise<AgentSessionCreateResult>;\n getSession(\n sessionId: string,\n options?: AgentSessionSubjectOptions\n ): Promise<AgentSessionInfo>;\n listSessions(options?: AgentSessionListOptions): Promise<AgentSessionListPage>;\n recordEvent(\n sessionId: string,\n event: AgentSessionEvent,\n options?: AgentSessionSubjectOptions\n ): Promise<AgentSessionEventResult>;\n deleteSession(\n sessionId: string,\n options?: AgentSessionSubjectOptions\n ): Promise<AgentSessionDeleteResult>;\n };\n /**\n * The value of one app secret, under a `secret:<NAME>` grant (#3183).\n *\n * Prefer `ctx.integrations.call` when the secret is a credential FOR an\n * integration: there the value is injected by the platform and never enters\n * the sandbox at all. This is for the cases an integration cannot express.\n *\n * Rejects with `FUNCTION_SECRET_NOT_FOUND` when the grant names a value\n * this environment has not been given — secrets are provisioned per\n * environment, out of band from the push.\n */\n secret(name: string): Promise<string>;\n /** The value of one app config var, under a `var:<NAME>` grant (#3183). */\n configVar(name: string): Promise<string>;\n /**\n * Realtime messages to this app's clients, under a `users:send` grant\n * (#3183).\n *\n * The recipient's client receives a `direct.message` frame carrying this\n * payload and the sending function's key. Presence is not guaranteed: a\n * member with no live socket answers `{ connections: 0 }` rather than an\n * error.\n */\n users: {\n /**\n * One page of the app's users — #3280.\n *\n * On the APP's system authority, whoever invoked the function: a member\n * who passes this function's gate reads whatever roster it chooses to\n * expose, so say who may in the function's own `access` expression.\n * `limit` is capped by the route at 100.\n */\n list(options?: UserPageOptions): Promise<UserPage>;\n /**\n * Every page of the app's users, in order — #3280.\n *\n * FOR A REQUEST FUNCTION AND A SINGLE-SLICE LOOP. A durable loop must take\n * its pages inside `step.do` with an EXPLICIT cursor: a memoized step does\n * not advance an iterator on resume, so an iteration across a sleep would\n * replay pages it had already taken.\n */\n iterate(options?: UserPageOptions): AsyncIterable<UserPage>;\n send(userId: string, payload: unknown): Promise<SendResult>;\n };\n /** The same frame to ONE connection, under a `connections:send` grant. */\n connections: {\n send(connectionId: string, payload: unknown): Promise<SendResult>;\n };\n /**\n * Realtime channels, under a `channel:<namespace>` grant that COVERS the\n * channel — #3184.\n *\n * `authorize` hands back a short-lived grant for ONE member to present on\n * the socket it already has; `publish` delivers a `channel.message` frame to\n * every connection that has joined and whose grant has not expired. Expiry is\n * the only revocation, so `expiresAt` comes back for the client to renew\n * ahead of — a renewal is another authorize and another subscribe.\n */\n channels: {\n authorize(\n channel: string,\n options?: ChannelAuthorizeOptions\n ): Promise<ChannelGrantResult>;\n publish(channel: string, payload: unknown): Promise<SendResult>;\n };\n /**\n * Named locks that WAIT — #3930. `ctx.api.locks.tryAcquire` is one attempt;\n * these wait for the key, up to `timeoutMs` (at most one hour).\n *\n * The owner defaults to `ctx.runId`, so a run never waits on its own hold:\n * a resumed slice, or a second call on a key the run already holds, re-takes\n * it at once with a fresh handle.\n *\n * Under the TASK runtime the wait is durable: each attempt is a step that\n * asks the platform to wait server-side for up to 30 s, so a wait costs one\n * platform call and one acquire slot per half-minute, no CPU, and the\n * slice's budget is refreshed at every attempt. It is not a suspension — the\n * engine does not hibernate a wait shorter than five minutes. Under the\n * REQUEST runtime the whole wait must fit the invocation's remaining budget,\n * or the call fails `FUNCTION_RUNTIME_REFUSED` before any attempt (a\n * webhook delivery has 5 s): hand longer waits to a task with\n * `ctx.functions.start`.\n */\n locks: {\n /**\n * Wait for `key`. Answers `acquired: true` with the handle, or\n * `acquired: false, timedOut: true` with the last contention seen.\n */\n acquire(key: string, options: LockAcquireOptions): Promise<LockAcquireResult>;\n /** Release a handle `acquire` handed back. */\n release(handle: LockHandle): Promise<LockReleaseResult>;\n /**\n * Acquire, run `fn`, and release in `finally` — on a return and on a\n * throw. Answers `fn`'s value; `fn`'s own error propagates after the\n * release. Throws an error named `LOCK_TIMEOUT` (`code` the same, the\n * contention in `details`) without running `fn` when the key is not\n * acquired within `timeoutMs`. A nested `withLock` on the same key in\n * one run re-enters, and its release frees the outer hold: use distinct\n * keys, or one wrapper.\n */\n withLock<T>(\n key: string,\n options: LockAcquireOptions,\n fn: (handle: LockHandle) => Promise<T>\n ): Promise<T>;\n };\n}\n\n/**\n * `FunctionContext` as `assertTrigger(ctx, kind)` leaves it: `trigger`\n * is the arm for `K`, `tool` is set for a tool call and `undefined` for\n * every other door, and `user` is the turn's initiator, never null, for the\n * three doors an agent turn opens (`tool`, `context` and `history`).\n *\n * Annotate a helper's parameter with it to take a context the caller has\n * already asserted:\n *\n * ```ts\n * async function lookup(ctx: FunctionContextFor<\"tool\">) {\n * return ctx.tool.variables.householdId;\n * }\n * ```\n */\nexport type FunctionContextFor<K extends FunctionTriggerKind> = FunctionContext & {\n trigger: Extract<FunctionTrigger, { kind: K }>;\n tool: K extends \"tool\" ? FunctionToolContext : undefined;\n user: K extends \"tool\" | \"context\" | \"history\" ? FunctionUser : FunctionUser | null;\n};\n\n/** How the wait between one step's retries grows. */\nexport type StepBackoff = \"constant\" | \"linear\" | \"exponential\";\n\n/**\n * The retry and timeout policy for ONE `step.do` — Cloudflare Workflows' own\n * step config.\n *\n * Under the TASK runner the platform forwards this object to Workflows\n * untouched, so these are its fields and its spellings: a duration is either a\n * number of milliseconds or a string Workflows parses (`\"10 seconds\"`,\n * `\"5 minutes\"`). Under the REQUEST runner `step.do` accepts a config and\n * ignores it — the body runs inline, and there is nothing to retry into.\n *\n * `stepPolicy.<family>` IS a `StepConfig`, so the platform's own defaults\n * hand straight to `step.do` (#3657). The shape is closed on purpose: a key\n * outside it — `retry` for `retries`, `timeoutMs` for `timeout` — is a\n * refusal at `config push` rather than an option the engine silently drops.\n */\nexport interface StepConfig {\n retries?: { limit: number; delay: string | number; backoff?: StepBackoff };\n timeout?: string | number;\n}\n\n/**\n * The step handle. `step` is the third argument under BOTH runners, so the\n * same body runs either way — which is what `mode = \"any\"` is for (#3454).\n *\n * Under the TASK runner it is Cloudflare Workflows' `WorkflowStep`, forwarded\n * untouched: `step.do` results are memoized and replayed, and `step.sleep`\n * hibernates.\n *\n * Under the REQUEST runner it is the platform's own, bounded by the request's\n * clock: `do` executes the body inline (there is no engine to memoize into,\n * and nothing is replayed); `sleep` and `sleepUntil` REALLY wait when the\n * remaining request budget covers the duration, and otherwise fail the\n * invocation with `errorCode: \"FUNCTION_RUNTIME_REFUSED\"` saying to start the\n * function as a task; `waitForEvent` fails the same way, because nothing can\n * deliver an event to an invocation that has to return now. The thrown error's\n * `name` is `STEP_NOT_AVAILABLE` in every case, so a body that catches it\n * keeps catching it.\n */\nexport interface FunctionStep {\n do<T>(name: string, body: () => T | Promise<T>): Promise<T>;\n do<T>(\n name: string,\n config: StepConfig,\n body: () => T | Promise<T>\n ): Promise<T>;\n sleep(name: string, duration: number | string): Promise<void>;\n sleepUntil(name: string, timestamp: Date | number): Promise<void>;\n waitForEvent<T = unknown>(\n name: string,\n options: Record<string, unknown>\n ): Promise<T>;\n}\n\nexport declare const SDK_STUB_VERSION: string;\n\n/**\n * Thrown by `assertRuntime` when this function is running under the other\n * runtime — #3482.\n *\n * The platform settles it as `status: \"failed\"` with\n * `errorCode: \"FUNCTION_RUNTIME_REFUSED\"`, on a request invocation's\n * envelope and on a task run's row and record alike.\n */\nexport declare class FunctionRuntimeError extends Error {\n name: \"FUNCTION_RUNTIME_REFUSED\";\n /** The runtime this invocation is actually running under. */\n runtime: \"request\" | \"task\";\n /** The runtime the function asked for. */\n required: \"request\" | \"task\";\n}\n\n/**\n * Refuse the runtime this function was not written for — #3482.\n *\n * A function is a function and the caller picks the runtime at each call, so\n * nothing in config says which one a function may run under. This is the lock,\n * and it lives in the one place that can always be right about the code:\n *\n * ```ts\n * import { assertRuntime } from \"primitive-functions\";\n *\n * // At module scope: this function is never runnable inside a request.\n * assertRuntime(\"task\");\n *\n * export default async function (input, ctx, step) {\n * await step.sleep(\"cool-off\", \"1 hour\");\n * return { ok: true };\n * }\n * ```\n *\n * Returns when the runtimes match; otherwise throws\n * {@link FunctionRuntimeError}, which the platform settles as\n * `status: \"failed\"` with `errorCode: \"FUNCTION_RUNTIME_REFUSED\"` and a\n * message naming both runtimes and the verb that takes the one required.\n * When `primitive config push` loads the module to check its export, no\n * runtime is running and every assertion returns.\n */\nexport declare function assertRuntime(required: \"request\" | \"task\"): void;\n\n/**\n * Refuse every door but the one this function was written for, and narrow\n * `ctx` to it.\n *\n * Make it the first line of a tool function: an agent turn calls it with\n * `ctx.tool` set, but the same function is also reachable over plain HTTP.\n * After the call, `ctx.trigger` is the named arm, `ctx.tool` needs no\n * guard, and `ctx.user` is the turn's initiator:\n *\n * ```ts\n * import { assertTrigger, defineFunction } from \"primitive-functions\";\n *\n * export default defineFunction(async (_input, ctx) => {\n * assertTrigger(ctx, \"tool\");\n * const { householdId } = ctx.tool.variables as { householdId: string };\n * await assertHouseholdMember(ctx.user.userId, householdId);\n * return { callId: ctx.trigger.callId };\n * });\n * ```\n *\n * Returns when `ctx.trigger.kind` is `kind`. Otherwise it throws an\n * `Error` naming both kinds, which the platform settles as\n * `status: \"failed\"` with `errorCode: \"FUNCTION_THREW\"`. A `kind` that is\n * not a trigger kind, or a first argument that is not a context, throws a\n * `TypeError`. It takes `ctx`, so it runs inside the handler, never at\n * module scope.\n */\nexport declare function assertTrigger<K extends FunctionTriggerKind>(\n ctx: FunctionContext,\n kind: K\n): asserts ctx is FunctionContextFor<K>;\n\n/**\n * The handler a function exports, typed for one declared key.\n *\n * `step` is the third argument under BOTH runners (#3186, #3454). A task run\n * gets the engine's live `WorkflowStep`; a request invocation gets the\n * platform's own, where `do` runs the body inline and a wait the request\n * budget cannot cover fails the invocation naming the task runner — so a\n * task-authored body can be exercised as a request, and the one place the two\n * genuinely differ says so rather than pretending.\n */\nexport type FunctionHandler<TInput, TOutput> = (\n input: TInput,\n ctx: FunctionContext,\n step: FunctionStep\n) => Promise<TOutput>;\n\n/** The codes a `deny` carries. */\nexport type AuthorizeCode = \"FORBIDDEN\" | \"NOT_FOUND\" | \"INVALID\";\n\n/**\n * What `allow(resolved)` returns. `resolved` is what the handler reads as\n * `ctx.auth`; `allow()` resolves `null`.\n */\nexport interface AllowDecision<T = null> {\n readonly decision: \"allow\";\n readonly resolved: T;\n}\n\n/** What `deny(code, message?, { expose? })` returns. */\nexport interface DenyDecision {\n readonly decision: \"deny\";\n readonly code: AuthorizeCode;\n /** The message, or `null` when none was given. */\n readonly message: string | null;\n /** Whether the deny asked for its code to be shown to the caller. */\n readonly expose: boolean;\n}\n\n/** Either decision. `T` is what an allow resolves. */\nexport type AuthorizeDecision<T = unknown> = AllowDecision<T> | DenyDecision;\n\n/** The caller `authorize` decides about. */\nexport interface FunctionAuthUser extends FunctionUser {\n /** The caller's role in the app, or `null` when it has none. */\n role: string | null;\n}\n\n/** An app role, as `requireRole` ranks it: owner > admin > member. */\nexport type AppRole = \"owner\" | \"admin\" | \"member\";\n\n/** A role on a group, ranked owner > manager > member. */\nexport type GroupRole = \"owner\" | \"manager\" | \"member\";\n\n/** A role on a collection, ranked owner > manager > editor > contributor > viewer. */\nexport type CollectionRole = \"owner\" | \"manager\" | \"editor\" | \"contributor\" | \"viewer\";\n\n/** The caller's permission on a document. */\nexport type DocumentPermission = \"owner\" | \"read-write\" | \"reader\";\n\n/** One group the caller belongs to, with the role they hold on it. */\nexport interface AuthMembership {\n groupType: string;\n groupId: string;\n role: GroupRole;\n}\n\n/** One database model, for reading inside `authorize`. */\nexport interface AuthDatabaseModelHandle<TRow> {\n /** The row with this id, or `null` when there is none. */\n get(recordId: string): Promise<TRow | null>;\n /** One page of rows, in the same envelope `ctx.db` answers. */\n query(body?: ModelScopedBody): Promise<{ items: TRow[]; hasMore: boolean; nextCursor?: string }>;\n}\n\n/** One database, typed by its type key the way `ctx.db` is, with reads only. */\nexport interface AuthDatabaseHandle<TModels> {\n model<M extends DatabaseModelNames<TModels>>(\n modelName: M\n ): AuthDatabaseModelHandle<DatabaseModelRow<TModels, M>>;\n}\n\n/** One document model, for reading inside `authorize`. */\nexport interface AuthDocumentModelHandle<TRow> {\n /** The record with this id, or `null` when there is none. */\n get(recordId: string): Promise<TRow | null>;\n /** One page of records, in the same envelope `ctx.doc` answers. */\n query(options?: DocumentQueryOptions): Promise<{ items: Array<TRow & { _related?: Record<string, any> }>; hasMore: boolean; nextCursor?: string }>;\n}\n\n/** One db3 model, for reading inside `authorize`. */\nexport interface AuthDb3ModelHandle<TRow> {\n /** The record with this id, or `null` when there is none. */\n get(recordId: string): Promise<TRow | null>;\n /** One page of records, in the same envelope `ctx.db3` answers. */\n query(options?: DocumentQueryOptions): Promise<{ items: Array<TRow & { _related?: Record<string, any> }>; hasMore: boolean; nextCursor?: string }>;\n}\n\n/** One db3, typed by its type the way `ctx.db3` is, with reads only. */\nexport interface AuthDb3Handle<TModels> {\n model<M extends Db3ModelNames<TModels>>(modelName: M): AuthDb3ModelHandle<Db3ModelRow<TModels, M>>;\n /** The caller's level on the db3, or `null`: none, not a db3 of this app, or its sync is off. One read. */\n permissions(): Promise<DocumentPermission | null>;\n}\n\n/** One document, for reading inside `authorize`; its models are typed the way `ctx.doc`'s are. */\nexport interface AuthDocumentHandle {\n /** The document, or `null` when this app has none with that id. */\n get(): Promise<Record<string, any> | null>;\n /** The caller's permission on the document, or `null` when they have none. */\n permissions(): Promise<DocumentPermission | null>;\n /** The document's tags, or `null` when this app has no such document. */\n tags(): Promise<string[] | null>;\n model<M extends DocumentModelNames>(modelName: M): AuthDocumentModelHandle<DocumentModelRow<M>>;\n}\n\n/**\n * What `authorize` is handed beside the input. It only reads: there is no\n * write, secret, integration or start here, and the platform refuses one\n * reached any other way.\n */\nexport interface FunctionAuthContext {\n /** The caller, or `null` when no user started this invocation. */\n readonly user: FunctionAuthUser | null;\n /** What started this invocation. */\n readonly trigger: FunctionTrigger;\n /** Whether the caller's app role is exactly `role`: `hasRole(\"admin\")` is false for an owner. */\n hasRole(role: string): boolean;\n /** Every group the caller belongs to, loaded whole. */\n memberships(): Promise<AuthMembership[]>;\n /** Whether the caller belongs to the group. */\n isMemberOf(groupId: string): Promise<boolean>;\n /** The ids of the groups the caller belongs to. */\n memberGroups(): Promise<string[]>;\n /** Whether the caller holds `role` or above on the group. */\n hasGroupRole(groupId: string, role: GroupRole): Promise<boolean>;\n readonly collections: {\n /** The caller's role on the collection, or `null` when they have none. */\n resolveRole(collectionId: string): Promise<CollectionRole | null>;\n };\n /** One document, read-only. */\n doc(documentId: string): AuthDocumentHandle;\n /** One database, read-only, typed by its type key. */\n db<K extends DatabaseTypeKeys>(\n databaseId: string,\n databaseType: K\n ): AuthDatabaseHandle<DatabaseModels<K>>;\n /** One db3, read-only, typed by its type. */\n db3<K extends Db3TypeKeys>(db3Id: string, type: K): AuthDb3Handle<Db3Models<K>>;\n /** An app config var's value. */\n configVar(name: string): Promise<string>;\n}\n\n/**\n * An `authorize` method: it decides from the input and the read-only\n * `auth` context, and what its `allow` resolves is `TAuth`.\n */\nexport type AuthorizeFn<TInput = any, TAuth = unknown> = (\n input: TInput,\n auth: FunctionAuthContext\n) => AuthorizeDecision<TAuth> | Promise<AuthorizeDecision<TAuth>>;\n\n// A conditional rather than the function type itself, on purpose: the\n// compiler sets aside a generic call that returns a function type while it\n// infers `defineFunction`'s type arguments, so `ctx.auth` would be fixed\n// before `authorize: requireMember(...)` was read. Deferred, the helper's\n// result is read first and types both the selector's input and `ctx.auth`.\n/**\n * What a helper that reads its input returns: an {@link AuthorizeFn} over\n * that input.\n */\nexport type AuthorizeHelper<TInput, TAuth> = [TInput] extends [unknown]\n ? AuthorizeFn<TInput, TAuth>\n : never;\n\n/**\n * Admit the caller. The value passed is what the handler reads as\n * `ctx.auth`, and it must be JSON-serializable.\n *\n * ```ts\n * import { allow, defineFunction, deny } from \"primitive-functions\";\n *\n * export default defineFunction({\n * authorize: async (input: { orgId: string }, auth) =>\n * auth.user ? allow({ orgId: input.orgId }) : deny(\"FORBIDDEN\"),\n * handler: async (input, ctx) => ({ orgId: ctx.auth.orgId }),\n * });\n * ```\n */\nexport declare function allow(): AllowDecision<null>;\nexport declare function allow<const T>(resolved: T): AllowDecision<T>;\n\n/**\n * Refuse the caller with one of the three codes. A code outside them, a\n * message that is not a string, or an `expose` that is not a boolean throws\n * a `TypeError` where the deny is written.\n */\nexport declare function deny(\n code: AuthorizeCode,\n message?: string,\n options?: { expose?: boolean }\n): DenyDecision;\n\n/**\n * Fail the invocation with your own code. It throws, so nothing after it\n * runs. The caller gets `status: \"failed\"` with `errorCode` set to\n * `code` and `error` set to `message` (or the code when no message is\n * given):\n *\n * ```ts\n * import { defineFunction, fail, requireSignedIn } from \"primitive-functions\";\n *\n * export default defineFunction({\n * authorize: requireSignedIn(),\n * handler: async (input: { quantity: number }) => {\n * if (input.quantity > 100) fail(\"ORDER_TOO_LARGE\", \"orders are capped at 100 units\");\n * return { accepted: input.quantity };\n * },\n * });\n * ```\n *\n * Any non-empty string is a code. Under the task runtime the run fails with\n * `errorCode: \"FUNCTION_THREW\"` and an `errorMessage` of\n * `FUNCTION_THREW: <code>: <message>`. Called inside `authorize`, it is a\n * throw, so the caller is denied. A code that is not a non-empty string, or a\n * message that is not a string, throws a `TypeError` instead.\n */\nexport declare function fail(code: string, message?: string): never;\n\n/**\n * An `authorize` that admits every caller the function's routes already\n * admit, with no check. It reads nothing and resolves `null`. To require a\n * signed-in caller, use {@link requireSignedIn}.\n */\nexport declare function allowAnyone(): AuthorizeFn<any, null>;\n\n/** An `authorize` that admits a signed-in caller, resolving `{ userId }`. */\nexport declare function requireSignedIn(): AuthorizeFn<any, { userId: string }>;\n\n/**\n * An `authorize` that admits a caller whose app role is `role` or above,\n * ranked owner > admin > member, so `requireRole(\"admin\")` admits an owner.\n * Resolves `{ userId, role }`.\n */\nexport declare function requireRole(\n role: AppRole\n): AuthorizeFn<any, { userId: string; role: AppRole }>;\n\n/**\n * An `authorize` that admits a member of the group `groupIdOf(input)`\n * names, at `role` or above when one is given. Resolves\n * `{ userId, groupId, role }` with the highest role the caller holds there.\n * An input that names no group id is denied `INVALID`.\n *\n * ```ts\n * import { defineFunction, requireMember } from \"primitive-functions\";\n *\n * export default defineFunction(\"team-report\", {\n * authorize: requireMember((input) => input.teamId, \"manager\"),\n * handler: async (input, ctx) => ({ team: ctx.auth.groupId, as: ctx.auth.role }),\n * });\n * ```\n */\nexport declare function requireMember<TInput = any>(\n groupIdOf: (input: TInput) => string,\n role?: GroupRole\n): AuthorizeHelper<TInput, { userId: string; groupId: string; role: GroupRole }>;\n\n/**\n * An `authorize` that admits a caller whose role on the collection\n * `collectionIdOf(input)` names is `minRole` or above, ranked owner >\n * manager > editor > contributor > viewer. Resolves\n * `{ userId, collectionId, role }`.\n */\nexport declare function requireCollectionRole<TInput = any>(\n collectionIdOf: (input: TInput) => string,\n minRole: CollectionRole\n): AuthorizeHelper<TInput, { userId: string; collectionId: string; role: CollectionRole }>;\n\n/**\n * An `authorize` that admits the owner of the document\n * `documentIdOf(input)` names, resolving `{ userId, documentId }`.\n */\nexport declare function requireDocumentOwner<TInput = any>(\n documentIdOf: (input: TInput) => string\n): AuthorizeHelper<TInput, { userId: string; documentId: string }>;\n\n/**\n * Which doors {@link allowCallers} admits. `users` decides on `http` only.\n * The agent doors (`tool`, `context`, `history`) are admitted only\n * through `agents`: `true` applies the `users` rule there too, and a\n * function is a rule of its own, which may resolve something other than the\n * `users` rule does.\n */\nexport interface CallerRules<TInput = any, TAuth = unknown, TAgentAuth = TAuth> {\n webhook?: boolean;\n cron?: boolean;\n manual?: boolean;\n /** A flush of a db3 of a type a `[[function.triggers.db3]]` entry watches. */\n db3?: boolean;\n /** The parent functions whose nested start is admitted, by key. */\n functions?: readonly string[];\n agents?: boolean | AuthorizeFn<TInput, TAgentAuth>;\n users?: AuthorizeFn<TInput, TAuth>;\n}\n\n/**\n * An `authorize` that admits by the door. `webhook`, `cron`,\n * `manual` and `db3` admit with `true` and resolve `null`, as does a nested start\n * from a parent `functions` lists. `http` takes the `users` rule's own\n * decision, and the agent doors take `agents`. A door with no rule is\n * denied, including one added later:\n *\n * ```ts\n * import { allowCallers, defineFunction, requireRole } from \"primitive-functions\";\n *\n * export default defineFunction({\n * authorize: allowCallers({ cron: true, manual: true, users: requireRole(\"admin\") }),\n * handler: async () => ({ swept: true }),\n * });\n * ```\n *\n * An unknown key, or a value of the wrong type, throws a `TypeError` when\n * the module loads.\n */\nexport declare function allowCallers<TInput = any, TAuth = never, TAgentAuth = never>(\n rules: CallerRules<TInput, TAuth, TAgentAuth>\n): AuthorizeHelper<TInput, TAuth | TAgentAuth | null>;\n\n/**\n * What the object form's handler reads beside `FunctionContext`: the value\n * `authorize` resolved when the invocation was admitted, and a way to ask\n * `authorize` again.\n */\nexport interface FunctionAuthorizedContext<TAuth> {\n /** What `authorize` resolved at admission. A task run keeps it on every resume. */\n auth: TAuth;\n /**\n * Run this version's `authorize` again against current state, for the\n * user it admitted, with this invocation's input and trigger. Resolves the\n * fresh value and leaves `ctx.auth` as it was; a deny throws the error\n * `fail(code, message)` throws, with the decision on it:\n *\n * ```ts\n * await step.sleep(\"cool-off\", \"1 hour\");\n * await ctx.reauthorize(); // throws FORBIDDEN if the member left the group\n * ```\n */\n reauthorize(): Promise<TAuth>;\n}\n\n/**\n * The object form's definition: an `authorize` method beside the handler.\n * `TAuth` is what `authorize`'s `allow` resolves, and the handler reads\n * it as `ctx.auth`.\n */\nexport interface FunctionDefinition<TInput, TOutput, TAuth> {\n authorize: AuthorizeFn<TInput, TAuth>;\n handler: (\n input: TInput,\n ctx: FunctionContext & FunctionAuthorizedContext<TAuth>,\n step: FunctionStep\n ) => TOutput | Promise<TOutput>;\n}\n\n/** What the object form returns: the handler, carrying its `authorize`. */\nexport type AuthorizedFunctionHandler<TInput, TOutput, TAuth> = FunctionHandler<\n TInput,\n TOutput\n> & {\n authorize: FunctionDefinition<TInput, TOutput, TAuth>[\"authorize\"];\n};\n\n/**\n * Declare a server function's handler, typed from its declaration.\n *\n * The KEYED form, `defineFunction(\"<key>\", handler)`, is typed from the\n * `FunctionSchemas` augmentation `primitive config push` writes beside the\n * sources: `input` is the key's declared input, the return is checked against\n * its declared output, and a key the tree does not declare is a compile error.\n * `config push` also refuses an entry whose key names another file's. In a\n * tree that has not pushed yet the key is any string and both types are `any`.\n *\n * The UNKEYED form is what it always was: author-declared generics. Both\n * styles reach the platform bootstrap identically — a plain default export\n * taking `(input, ctx, step)` runs exactly as a wrapped one does — so this is\n * a typing and intent marker, not a different calling convention.\n *\n * The OBJECT form, `defineFunction(key?, { authorize, handler })`, adds an\n * `authorize` method that decides who may run the handler; what its\n * `allow` resolves is the handler's `ctx.auth`. A definition with any\n * other key, or a member that is not a function, throws a `TypeError` when\n * the module loads.\n */\nexport declare function defineFunction<K extends FunctionKeys, TAuth = null>(\n key: K,\n definition: FunctionDefinition<FunctionInput<K>, FunctionOutput<K>, TAuth>\n): AuthorizedFunctionHandler<FunctionInput<K>, FunctionOutput<K>, TAuth> & {\n functionKey: K;\n};\nexport declare function defineFunction<\n TInput = unknown,\n TOutput = unknown,\n TAuth = unknown\n>(\n definition: FunctionDefinition<TInput, TOutput, TAuth>\n): AuthorizedFunctionHandler<TInput, TOutput, TAuth>;\n/**\n * A bare handler, keyed.\n *\n * @deprecated Define the object form, `defineFunction(key?, { authorize, handler })`:\n * a push that would create a new version of a bare handler is refused.\n */\nexport declare function defineFunction<K extends FunctionKeys>(\n key: K,\n handler: (\n input: FunctionInput<K>,\n ctx: FunctionContext,\n step: FunctionStep\n ) => FunctionOutput<K> | Promise<FunctionOutput<K>>\n): FunctionHandler<FunctionInput<K>, FunctionOutput<K>> & { functionKey: K };\n/**\n * A bare handler, unkeyed.\n *\n * @deprecated Define the object form, `defineFunction(key?, { authorize, handler })`:\n * a push that would create a new version of a bare handler is refused.\n */\nexport declare function defineFunction<TInput = unknown, TOutput = unknown>(\n handler: (\n input: TInput,\n ctx: FunctionContext,\n step: FunctionStep\n ) => TOutput | Promise<TOutput>\n): FunctionHandler<TInput, TOutput>;\n\n/**\n * One declared parameter of a registered query.\n *\n * `caller: true` (or `type: \"$caller\"`) is the intent's IMMUTABLE binding:\n * the platform injects the invocation's user and refuses a call that supplies\n * the parameter itself.\n */\n/** The scalar parameter types, and an array parameter's element types. */\nexport type QueryScalarParamType = \"string\" | \"number\" | \"boolean\" | \"any\";\n\nexport interface QueryParamSpec {\n type?: QueryScalarParamType | \"$caller\" | \"array\";\n /** For `type: \"array\"` — the element type; absent means any element. */\n items?: { type: QueryScalarParamType };\n caller?: boolean;\n optional?: boolean;\n default?: unknown;\n}\n\n/** A scalar parameter type's TypeScript type. */\nexport type QueryScalarValue<T> = T extends \"string\"\n ? string\n : T extends \"number\"\n ? number\n : T extends \"boolean\"\n ? boolean\n : T extends \"$caller\"\n ? string\n : any;\n\n/** The value `run` receives for one declared parameter. */\nexport type QueryParamValue<S> = S extends { caller: true }\n ? string\n : S extends { type: \"array\"; items: { type: infer I } }\n ? QueryScalarValue<I>[]\n : S extends { type: \"array\" }\n ? unknown[]\n : S extends { type: infer T }\n ? QueryScalarValue<T>\n : any;\n\ntype QueryOptionalKeys<P> = {\n [K in keyof P]: P[K] extends { optional: true } ? K : never;\n}[keyof P];\n\n/**\n * `run`'s `params`, typed from the declaration: scalars as their scalar,\n * `$caller` as a string, an array as `T[]`, an `optional: true` parameter\n * as an optional key (a parameter with a default is always present). An\n * undeclared name is a compile error.\n */\nexport type QueryParams<P> = {\n [K in Exclude<keyof P, QueryOptionalKeys<P>>]: QueryParamValue<P[K]>;\n} & {\n [K in QueryOptionalKeys<P>]?: QueryParamValue<P[K]>;\n};\n\n/** A registration's definition with its parameters DECLARED, so `run` is typed from them. */\nexport interface TypedQueryDefinition<TDb, TSpec extends Record<string, QueryParamSpec>, TResult> {\n models: string[];\n params?: TSpec;\n cache?: { ttlMs: number };\n run: (db: TDb, params: QueryParams<TSpec>) => TResult | Promise<TResult>;\n}\n\nexport interface QueryDefinition<TDb, TParams, TResult> {\n /** The models this query touches. Caching is off unless the run matches. */\n models: string[];\n params?: Record<string, QueryParamSpec>;\n /**\n * Cache the answer for `ttlMs` — capped by the platform, and applied ONLY\n * when the run is verified: every model the body touched was declared, and\n * no prepared operation was used. A write through the handle drops the\n * entries that read the written model.\n */\n cache?: { ttlMs: number };\n run: (db: TDb, params: TParams) => TResult | Promise<TResult>;\n}\n\n/**\n * Register a named query over a database handle (#3187).\n *\n * A registration helper, not a language: `run` is ordinary code over the same\n * typed handle, and what registration adds is a name, declared parameters\n * (validated, coerced and defaulted), the `$caller` binding, and a cache the\n * platform may use when it can verify what the run touched.\n *\n * Register at MODULE scope: a registration made inside the handler still works\n * for direct calls but is invisible to `config push`'s manifest.\n *\n * `run`'s `params` are TYPED from the declaration (the first overload,\n * inferred with a `const` type parameter): a scalar as its scalar, `$caller`\n * as a string, `{ type: \"array\", items: { type: \"string\" } }` as `string[]`,\n * an `optional: true` parameter as an optional key; an undeclared name inside\n * `run` is a compile error. A declared default is coerced to the declared\n * type at registration, so `run` receives what the declaration promises. The\n * second overload keeps an explicit `TParams`.\n */\nexport declare function defineQuery<\n const TSpec extends Record<string, QueryParamSpec>,\n TDb = DatabaseHandle<any>,\n TResult = any\n>(\n name: string,\n definition: TypedQueryDefinition<TDb, TSpec, TResult>\n): (db: TDb, params?: Record<string, unknown>) => Promise<TResult>;\nexport declare function defineQuery<\n TDb = DatabaseHandle<any>,\n TParams = Record<string, any>,\n TResult = any\n>(\n name: string,\n definition: QueryDefinition<TDb, TParams, TResult>\n): (db: TDb, params?: Record<string, unknown>) => Promise<TResult>;\n\n/** The same, for a registration that writes. A mutation is never cached. */\nexport declare function defineMutation<\n const TSpec extends Record<string, QueryParamSpec>,\n TDb = DatabaseHandle<any>,\n TResult = any\n>(\n name: string,\n definition: TypedQueryDefinition<TDb, TSpec, TResult>\n): (db: TDb, params?: Record<string, unknown>) => Promise<TResult>;\nexport declare function defineMutation<\n TDb = DatabaseHandle<any>,\n TParams = Record<string, any>,\n TResult = any\n>(\n name: string,\n definition: QueryDefinition<TDb, TParams, TResult>\n): (db: TDb, params?: Record<string, unknown>) => Promise<TResult>;\n\n/** The platform's cap on a registered query's cache TTL, in milliseconds. */\nexport declare const MAX_QUERY_CACHE_TTL_MS: number;\n\n/**\n * Map over items with BOUNDED concurrency (#3187). Results come back in the\n * input's order; the first rejection wins and nothing new is started after it.\n *\n * The bound matters inside a sandbox: an unbounded fan-out over a page of rows\n * spends the whole subrequest ceiling in one line.\n */\nexport declare function pMap<T, R>(\n items: Iterable<T>,\n mapper: (item: T, index: number) => R | Promise<R>,\n options?: { concurrency?: number }\n): Promise<R[]>;\n\n/** The default concurrency `pMap` applies when none is given. */\nexport declare const PMAP_DEFAULT_CONCURRENCY: number;\n\n/**\n * A time-ordered ULID.\n *\n * GENERATE IT INSIDE `step.do`. A durable run re-executes its handler on\n * every resume and memoizes only what a step returned, so an id minted at the\n * top of a handler is a different id after a sleep — and whatever it was\n * written into is orphaned.\n */\nexport declare function ulid(): string;\n\n/** One family's durable `step.do` configuration — a `StepConfig` with every field decided. */\nexport interface StepPolicy extends StepConfig {\n retries: { limit: number; delay: string; backoff: StepBackoff };\n timeout: string;\n}\n\n/**\n * The per-family step policies the DSL runners use, generated from their own\n * timeout module (#3187):\n *\n * await step.do(\"send-receipt\", stepPolicy.email, () =>\n * ctx.api.email.send({ body: { to, subject, htmlBody } }));\n *\n * `retries: 0` on email and the AI families is deliberate — a retried timeout\n * would send the same email twice or bill the same generation twice.\n */\nexport declare const stepPolicy: {\n email: StepPolicy;\n llm: StepPolicy;\n gemini: StepPolicy;\n database: StepPolicy;\n};\n\n// Every member the three runtime copies put on their own default export — the\n// platform's `sdk-core.ts`, the published stub and the CLI's collect stub —\n// and nothing else. A helper the module hands a default import but does not\n// declare here is one an author cannot call without the compiler refusing it\n// (#3482 CR3482-002); `tests/api/spec/function-profile.test.ts` holds the four\n// lists equal and compiles a default import against them.\ndeclare const _default: {\n SDK_STUB_VERSION: string;\n defineFunction: typeof defineFunction;\n allow: typeof allow;\n deny: typeof deny;\n fail: typeof fail;\n allowAnyone: typeof allowAnyone;\n allowCallers: typeof allowCallers;\n requireSignedIn: typeof requireSignedIn;\n requireRole: typeof requireRole;\n requireMember: typeof requireMember;\n requireCollectionRole: typeof requireCollectionRole;\n requireDocumentOwner: typeof requireDocumentOwner;\n defineQuery: typeof defineQuery;\n defineMutation: typeof defineMutation;\n pMap: typeof pMap;\n ulid: typeof ulid;\n assertRuntime: typeof assertRuntime;\n assertTrigger: typeof assertTrigger;\n FunctionRuntimeError: typeof FunctionRuntimeError;\n};\nexport default _default;\n";
12
+ export const SDK_TYPES_SOURCE = "// GENERATED by scripts/generate-function-profile.mjs from openapi.json.\n// DO NOT EDIT. Run `pnpm functions:profile` and commit the result; the\n// freshness guard in tests/api/spec/function-profile.test.ts fails when this\n// file and a fresh generation diverge.\n\n/**\n * Type surface of `primitive-functions` — what a server function's author writes\n * against (#3180). The published package's RUNTIME is a stub that throws from\n * every export on purpose: the platform substitutes its own copy at invoke\n * time, and reaching the stub means it did not.\n *\n * WHICH USER A CALL IS ABOUT. Every `ctx.api` and `ctx.agents` call that is\n * about one user says which user in `userId`. Omitted, it means the invoking\n * user (`ctx.user`); in a run with no caller (cron, a webhook, the system\n * door, a nested start under one of them) it must be named, or the call\n * rejects with `FUNCTION_SUBJECT_REQUIRED`. Naming a user other than the\n * invoking user — whether `userId` is optional or required on the call — is\n * allowed in a run with no caller or one an app owner or admin invoked, with\n * the role read at the call. An ordinary member's run may name another member\n * only when its function's TOML declares `users:readAny` (on a read: their\n * memberships, collections, documents, root document, inbox, devices and\n * agent sessions) or `users:actAsAny` (on a call that acts as them:\n * notifications read and devices, `ctx.agents` session calls,\n * `ctx.db3` `asUser`, their aliases); otherwise, and in every run an\n * agent drives (a tool, context or history run and anything it starts), it\n * rejects with `SUBJECT_USER_FORBIDDEN`. A named user who is not a member of\n * the app rejects with `SUBJECT_USER_NOT_FOUND`. Calls that hand something\n * to a user (`notifications.send`, `users.setProfile`, a channel grant)\n * and app-wide reads are outside this rule.\n */\n\n/**\n * The signed-in user who invoked the function over HTTP.\n *\n * Attribution, never authority (#3279): function code acts as the system\n * whoever called it, so this says WHO asked, and the rows the function writes\n * are attributed to them. A trigger fire has no caller and `ctx.user` is\n * null.\n */\nexport interface FunctionUser {\n userId: string;\n email: string | null;\n}\n\n/**\n * What started this invocation. Narrow on `kind`.\n *\n * The same union the runtime builds (`src/server-functions/trigger-descriptor.ts`),\n * held identical by `tests/api/spec/function-trigger-declarations-3281.test.ts`:\n * a field the fire path sets is declared here, and nothing is declared here\n * that the fire path does not set.\n */\nexport type FunctionTrigger =\n /**\n * An HTTP invocation: the caller is `ctx.user`.\n *\n * `runKey` is the key a `start` was coalesced by (#3562) — what you\n * passed as `runKey` to make the run a singleton — and null when the\n * start named none, or when the call was an `invoke`, which coalesces\n * nothing.\n */\n | { kind: \"http\"; runKey: string | null }\n /** A verified webhook delivery to the function's own key. */\n | {\n kind: \"webhook\";\n /** The webhook key, which is the function key. */\n webhookKey: string;\n /** The platform's webhook row the delivery log lives under. */\n webhookId: string;\n /** The provider's event id (`X-Webhook-Event-Id`), when it sent one. */\n externalEventId: string | null;\n }\n /** A cron entry firing, scheduled or from the `functions triggers fire` diagnostic. */\n | {\n kind: \"cron\";\n /** The `[[function.triggers.cron]]` entry's `name`. */\n name: string;\n /** The platform's cron row. */\n triggerId: string;\n /** ISO 8601. The instant the fire was scheduled for; a diagnostic fire's is \"now\". */\n scheduledFor: string;\n /** Present, and true, only on the diagnostic fire: nothing was scheduled. */\n manual?: true;\n }\n /**\n * Another function started this one with `ctx.functions.start` (#3280).\n *\n * `functionKey` names the PARENT, and `runId` its run — null when the\n * parent was a request invocation over HTTP, which writes no run row.\n * `runKey` is the key the parent's start named, or null (#3562).\n */\n | {\n kind: \"function\";\n functionKey: string;\n runId: string | null;\n runKey: string | null;\n }\n /**\n * An admin ran this function as the SYSTEM, from outside any trigger\n * (#3448) — `primitive functions invoke --as system`.\n *\n * `ctx.user` is null and the code runs with the app's system authority, as\n * it does for a cron or webhook fire. `userId` names the admin who asked:\n * attribution, never the principal the code runs as. `runKey` is the key\n * the admin's start named, or null (#3562).\n */\n | { kind: \"manual\"; userId: string; runKey: string | null }\n /**\n * An agent turn called this function as one of its tools.\n *\n * `ctx.user` is the turn's initiator, whose `access` gate the call\n * passed, and `ctx.tool` carries the session's ids, members and\n * variables, and the turn's context, timezone and locale. `callId` is the same on every attempt of the call, so use\n * it as an idempotency key. `toolName` is the declared tool name, which\n * may differ from the function's key.\n */\n | {\n kind: \"tool\";\n sessionId: string;\n turnId: string;\n callId: string;\n toolName: string;\n }\n /** An agent turn asked this function for its turn context. */\n | { kind: \"context\"; sessionId: string; turnId: string }\n /** An agent turn asked this function for the history to send the model. */\n | { kind: \"history\"; sessionId: string; turnId: string }\n /**\n * One flush of a db3 of a type a `[[function.triggers.db3]]` entry\n * watches: a client's socket batch, a records-route write or a partial\n * bulk that accepted at least one entry. `from` and `to` are the flush's\n * first and last log numbers. The run's input carries the changed records'\n * keys and change kinds, not their values: read what you need through\n * `ctx.db3(trigger.db3Id, trigger.type)`.\n *\n * A watcher that writes the db3 it watches starts another run per flush,\n * bounded only by its `ratePerMinute`; branch on\n * `ctx.trigger.kind === \"db3\"` to skip the writes a flush of your own\n * started.\n */\n | {\n kind: \"db3\";\n db3Id: string;\n type: string;\n triggerId: string;\n from: number;\n to: number;\n };\n\n/** The door names `ctx.trigger.kind` can hold. */\nexport type FunctionTriggerKind = FunctionTrigger[\"kind\"];\n\n/**\n * The agent session a tool call belongs to — `ctx.tool`, set only when\n * `ctx.trigger.kind === \"tool\"`.\n *\n * Variables and members describe the session; they grant nothing. Check what\n * `ctx.user` (the turn's initiator) may do before acting for them.\n */\nexport interface FunctionToolContext {\n readonly sessionId: string;\n readonly turnId: string;\n /** The call's id, the same on every attempt: an idempotency key. */\n readonly callId: string;\n /** The tool's declared name. */\n readonly toolName: string;\n /** The session's owner. */\n readonly ownerUserId: string;\n /** The session's members by role, besides the owner. */\n readonly members: {\n readonly viewerUserIds: string[];\n readonly participantUserIds: string[];\n };\n /** The session's variables, set when it was created. */\n readonly variables: Record<string, unknown>;\n /**\n * The turn's validated context: the object the member's send carried,\n * checked against the agent's `turnContext.schema`, or the return of the\n * agent's context function. The same values the system prompt rendered as\n * `turn.*`. Null when the turn carried none.\n */\n readonly context: Record<string, unknown> | null;\n /**\n * The IANA timezone the turn's send carried, such as\n * `\"Pacific/Auckland\"`; the prompt's `turn.timezone`. Null when it\n * carried none.\n */\n readonly timezone: string | null;\n /**\n * The BCP 47 locale the turn's send carried, such as `\"en-NZ\"`; the\n * prompt's `turn.locale`. Null when it carried none.\n */\n readonly locale: string | null;\n /**\n * Attach an app-only artifact to this call's row, replacing any earlier\n * one. The model never sees it; your app reads it from the call's row —\n * `artifact`, or, for one over 64 KiB of JSON or past the agent's\n * `maxRowBytes`, the blob on the session's document named by\n * `artifactBlobId`. At most 4 MiB of JSON: a larger value rejects with\n * `AGENT_ARTIFACT_TOO_LARGE`, and a call that already has its result with\n * `AGENT_CALL_NOT_RUNNING`.\n */\n attachArtifact(value: unknown): Promise<void>;\n}\n\n/** The result shape of an operation that answers in response headers. */\nexport interface HeaderResult {\n status: number;\n headers: Record<string, string>;\n}\n\n/**\n * A platform call that was refused. `errorCode` carries the gateway's own\n * codes (`FUNCTION_ROUTE_NOT_ALLOWED`, `FUNCTION_EGRESS_DENIED`, …) as well\n * as the route's.\n */\nexport interface PrimitivePlatformError extends Error {\n status: number;\n errorCode: string | null;\n /**\n * The route's structured `details`, or null when its refusal carries none\n * (#3803). `AGENT_SESSION_VARIABLES_INVALID` lists `errors` as\n * `{ path, message }`.\n */\n details: unknown;\n}\n\n/** Who holds a collection: the app, or one of its members (`user:<userId>`). */\nexport type Custodian = \"app\" | `user:${string}`;\n\n/**\n * The body of `ctx.api.collections.create`.\n *\n * ```ts\n * await ctx.api.collections.create({ body: { name: \"Plans\" } }); // held by the invoking member\n * await ctx.api.collections.create({ body: { name: \"Shared\", custodian: \"app\" } });\n * ```\n */\nexport interface CollectionCreateBody {\n /** The collection's display name. */\n name: string;\n /** Text describing the collection's purpose. */\n description?: string;\n /**\n * The collection's stored type.\n * @deprecated Collections have fixed roles; omit it.\n */\n collectionType?: string;\n /**\n * Who holds the collection: `\"app\"`, or `user:<userId>` for any member\n * of the app, who gets the `owner` role (`SUBJECT_USER_NOT_FOUND` for a\n * user who is not a member). Omitted, the invoking member holds it as\n * owner. A run with no caller (cron, a webhook) must name one\n * (`CUSTODIAN_REQUIRED`); a run an agent drives may name `\"app\"` or its\n * initiator but no other member (`SUBJECT_USER_FORBIDDEN`).\n */\n custodian?: Custodian;\n /** `memberList`: `members` (the default) lets every member list the members; `managers` limits it to the owner and managers. */\n settings?: { memberList?: \"members\" | \"managers\" };\n /** Members written with the collection, each with a role up to `manager` (the owner is the custodian). */\n initialMembers?: Array<{ userId: string; role: \"manager\" | \"editor\" | \"contributor\" | \"viewer\" }>;\n /** Resource metadata stamped with the collection: category name → that category's values. */\n initialMetadata?: Record<string, Record<string, unknown>>;\n}\n\n/**\n * The typed HTTP profile, generated from the platform's OpenAPI document. Its\n * namespaces mirror the operation ids: agentSessions, analytics, blobBuckets, channels, collections, configVars, connections, databaseTypeConfigs, databases, db3, documents, email, functions, groups, integrations, invitations, locks, notifications, prompts, resourceMetadata, secrets, users.\n * Methods take one options object carrying the operation's path parameters,\n * query parameters, request headers (under their wire names) and `body`.\n *\n * Generated from the same operations as the runtime profile, so a method that\n * type-checks is a method the platform publishes — and a missing path\n * parameter or a missing required header is a compile error rather than a\n * `TypeError` at invoke time. Every call runs with the app's own SYSTEM\n * authority (#3279): the invocation gate was the authorization. The two\n * namespaces the gateway does not admit are still declared: they exist, they\n * answer the gateway's structured denial, and hiding them would make a route's\n * availability look like a typo. Those are `databaseTypeConfigs` whole, and\n * `functions` except for `functions.start` — the nested-start door #3280\n * admits by name, which `ctx.functions.start` calls. `functions.invoke`\n * stays refused: same-run composition is an import.\n */\nexport interface FunctionApi {\n \"agentSessions\": {\n /** `agentSessions.addMember` — POST /agent-sessions/{sessionId}/members. Add a member to an agent session, or change their role */\n \"addMember\"(args: {\n \"sessionId\": string | number;\n body: {\n userId: string;\n role: \"viewer\" | \"participant\";\n };\n }): Promise<{\n members: {\n viewers: string[];\n participants: string[];\n };\n }>;\n /** `agentSessions.answer` — POST /agent-sessions/{sessionId}/calls/{callId}/answer. Answer a paused agent turn's call */\n \"answer\"(args: {\n \"sessionId\": string | number;\n \"callId\": string | number;\n body: {\n approval?: {\n approved: boolean;\n /** At most 1024 characters. */\n reason?: string;\n };\n /** A client tool's result: any JSON value, at most 64 KiB as JSON text. */\n output?: unknown;\n /** With `output` only: app data the model never sees, at most 4 MiB as JSON text. Over 64 KiB, or past the agent's `maxRowBytes` on the call's row, it is written to a blob on the session's document and the row carries `artifactBlobId`. */\n artifact?: unknown;\n error?: {\n /** At most 4096 characters. */\n message: string;\n };\n };\n }): Promise<{\n callId: string;\n state: string;\n }>;\n /** `agentSessions.attachArtifact` — POST /agent-sessions/{sessionId}/calls/{callId}/artifact. Attach an artifact to a running agent tool call (ctx.tool.attachArtifact) */\n \"attachArtifact\"(args: {\n \"sessionId\": string | number;\n \"callId\": string | number;\n body: {\n /** Any JSON value; at most 4 MiB as JSON text. */\n artifact: unknown;\n };\n }): Promise<{\n attached: boolean;\n }>;\n \"attachments\": {\n /** `agentSessions.attachments.downloadHeaders` — HEAD /agent-sessions/{sessionId}/attachments/{blobId}/download. Get an agent session attachment's download headers */\n \"downloadHeaders\"(args: {\n \"sessionId\": string | number;\n \"blobId\": string | number;\n \"disposition\"?: string | number | boolean;\n }): Promise<HeaderResult>;\n /** `agentSessions.attachments.downloadUrl` — GET /agent-sessions/{sessionId}/attachments/{blobId}/download. Download an agent session attachment */\n \"downloadUrl\"(args: {\n \"sessionId\": string | number;\n \"blobId\": string | number;\n \"disposition\"?: string | number | boolean;\n }): Promise<Uint8Array>;\n /** `agentSessions.attachments.upload` — PUT /agent-sessions/{sessionId}/attachments/{blobId}. Upload an agent session attachment */\n \"upload\"(args: {\n \"sessionId\": string | number;\n \"blobId\": string | number;\n \"X-Blob-Filename\": string | number;\n \"X-Blob-Size\": string | number;\n \"X-Blob-Sha256\": string | number;\n \"Content-Type\"?: string | number;\n body: ArrayBuffer | Uint8Array | string;\n }): Promise<{\n blobId: string;\n filename?: string;\n contentType?: string;\n numBytes?: number;\n sha256?: string;\n status?: string;\n createdAt?: string;\n /** 0 on the idempotent 200; the stored length on a 201. */\n bytesTransferred?: number;\n }>;\n };\n /** `agentSessions.cancel` — POST /agent-sessions/{sessionId}/cancel. Cancel an agent session's active turn */\n \"cancel\"(args: {\n \"sessionId\": string | number;\n body: {\n /** The active turn's id. */\n turnId: string;\n };\n }): Promise<{\n turnId: string;\n cancelled: boolean;\n nextTurnId: string | null;\n }>;\n /** `agentSessions.create` — POST /agent-sessions. Create an agent session (ctx.agents.createSession) */\n \"create\"(args: {\n body: {\n /** The key of an agent prompt (`kind = \"agent\"`) in this app. */\n agent: string;\n /** The session's variables, validated against the agent's `inputSchema`; at most 16 KiB of JSON. Absent reads as `{}`. */\n variables?: Record<string, unknown>;\n /** Free text an app groups sessions by; 1 to 256 characters. */\n scope?: string;\n /** 1 to 255 characters; defaults to the agent's display name. */\n title?: string;\n /** Initial participants (they send, answer and upload): existing users of this app, distinct, not the caller. Together with `viewers` at most 50 (#3805). */\n participants?: string[];\n /** Initial viewers (they read the session's db3): existing users of this app, distinct, in neither list twice, not the caller (#3805). */\n viewers?: string[];\n /** Whose session: the member who owns it. Omitted means the caller. An app owner or admin, or a server function run with no caller or one an app owner or admin invoked, may name another member; a run with no caller must name one (`FUNCTION_SUBJECT_REQUIRED`). An ordinary member's run may name another member only when its function declares `users:readAny` (on a read) or `users:actAsAny` (on a call that acts as them), and a run an agent drives never may (`SUBJECT_USER_FORBIDDEN`). */\n userId?: string;\n };\n }): Promise<{\n sessionId: string;\n }>;\n /** `agentSessions.delete` — DELETE /agent-sessions/{sessionId}. Delete an agent session (ctx.agents.deleteSession) */\n \"delete\"(args: {\n \"sessionId\": string | number;\n \"userId\"?: string | number;\n }): Promise<{\n deleted: boolean;\n sessionId: string;\n }>;\n /** `agentSessions.get` — GET /agent-sessions/{sessionId}. Get an agent session */\n \"get\"(args: {\n \"sessionId\": string | number;\n \"userId\"?: string | number;\n }): Promise<{\n sessionId: string;\n agentKey: string;\n ownerUserId: string;\n createdAt: string;\n title?: string | null;\n scope?: string | null;\n lastActivityAt?: string | null;\n /** Whether the caller has activity they have not marked read; false for an admin without a role. */\n hasUnread: boolean;\n /** When the caller last marked the session read; null for an admin without a role. */\n lastReadAt: string | null;\n members: {\n viewers: string[];\n participants: string[];\n };\n role: \"owner\" | \"participant\" | \"viewer\" | \"admin\";\n /** Decided from the session object: the active turn's phase, else how the last turn ended. */\n status?: \"idle\" | \"thinking\" | \"running_tool\" | \"awaiting_answer\" | \"failed\" | \"expired\" | \"cancelled\";\n /** The active turn, or null when none runs. */\n turn?: {\n turnId: string;\n initiatorUserId: string;\n startedAt: string | null;\n phase: \"model\" | \"tools\" | \"paused\" | \"draining\";\n rounds: number;\n leaseUntil?: string | null;\n answeredBy?: string | null;\n pause?: {\n callIds?: string[];\n since?: string;\n expiresAt?: string;\n } | null;\n pending?: {\n kind?: \"answer\" | \"end\";\n } | null;\n } | null;\n /** App owners and admins over REST only: the session object's state. Ids, phases and the pinned configuration; never a message's text, a part's input, output or artifact, or a step's usage. */\n object?: {\n pending?: Record<string, unknown>[];\n deletedAt?: string | null;\n initializing?: string | null;\n turn?: Record<string, unknown> | null;\n lastTurn?: Record<string, unknown> | null;\n queue?: {\n userId?: string;\n messageIds?: string[];\n }[];\n leaseUntil?: string | null;\n alarmAt?: string | null;\n calls?: Record<string, unknown>[];\n };\n /** App authority only: the last 20 turns' contexts, newest last — the context each turn rendered as `turn.*`, its timezone and locale. */\n turnContexts?: {\n turnId: string;\n startedAt: string;\n initiatorUserId: string;\n context: Record<string, unknown> | null;\n timezone: string | null;\n locale: string | null;\n }[];\n /** App authority only: the last turn that ended, as `object.lastTurn` projects it — its outcome, rendered system prompt, turn context and timing. */\n lastTurn?: Record<string, unknown> | null;\n }>;\n /** `agentSessions.list` — GET /agent-sessions. List one user's agent sessions */\n \"list\"(args?: {\n \"userId\"?: string | number;\n \"agent\"?: string | number | boolean;\n \"scope\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n items: {\n sessionId: string;\n agentKey: string;\n scope?: string | null;\n ownerUserId: string;\n role: \"owner\" | \"participant\" | \"viewer\";\n title?: string | null;\n lastActivityAt: string;\n createdAt?: string | null;\n hasUnread: boolean;\n lastReadAt?: string | null;\n /** The session's status as of its last listed activity; null for an entry written before the status was listed. A status change with no activity (a server tool's round) shows on the next activity; `get` reads the current one. */\n status?: \"idle\" | \"thinking\" | \"running_tool\" | \"awaiting_answer\" | \"failed\" | \"expired\" | \"cancelled\" | null;\n }[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /** `agentSessions.markRead` — POST /agent-sessions/{sessionId}/read. Mark an agent session read */\n \"markRead\"(args: {\n \"sessionId\": string | number;\n }): Promise<{\n sessionId: string;\n /** The caller's read marker, ISO-8601. */\n lastReadAt: string;\n }>;\n /** `agentSessions.recordEvent` — POST /agent-sessions/{sessionId}/events. Record an event in an agent session (ctx.agents.recordEvent) */\n \"recordEvent\"(args: {\n \"sessionId\": string | number;\n \"userId\"?: string | number;\n body: {\n /** An event kind the agent declares. */\n kind: string;\n /** The payload, validated against the kind's schema; at most 64 KiB. */\n data: unknown;\n /** The client's own id for the event, 1 to 128 characters. */\n eventId?: string;\n /** A call id of this session (`call_<ULID>`). */\n refersTo?: string;\n };\n }): Promise<{\n messageId: string;\n seq: number;\n duplicate: boolean;\n }>;\n /** `agentSessions.removeMember` — DELETE /agent-sessions/{sessionId}/members/{userId}. Remove a member from an agent session */\n \"removeMember\"(args: {\n \"sessionId\": string | number;\n \"userId\": string | number;\n }): Promise<{\n members: {\n viewers: string[];\n participants: string[];\n };\n }>;\n /** `agentSessions.rename` — PATCH /agent-sessions/{sessionId}. Rename an agent session */\n \"rename\"(args: {\n \"sessionId\": string | number;\n body: {\n /** 1 to 255 characters, not all whitespace. */\n title: string;\n };\n }): Promise<{\n sessionId: string;\n title: string;\n }>;\n /** `agentSessions.send` — POST /agent-sessions/{sessionId}/messages. Send a message to an agent session */\n \"send\"(args: {\n \"sessionId\": string | number;\n body: {\n /** Up to 32768 characters; may be empty only when files are sent. */\n text?: string;\n /** Up to 8 blobs of the session's db3. */\n files?: {\n blobId: string;\n }[];\n /** The client's own id for the message, 1 to 128 characters; stored on the row. */\n clientMessageId?: string;\n /** The turn context, at most 16 KiB of JSON, validated against the agent's `turnContext.schema` (a send without it is checked as `{}`). It renders as `turn.*` in the system prompt of this message's turn only and is never written to the document. Refused when the agent declares no turn context or fills it with a function. */\n context?: Record<string, unknown>;\n /** An IANA time zone name: `turn.timezone`, and `now`/`today` in that zone. */\n timezone?: string;\n /** A BCP 47 language tag, at most 35 characters: `turn.locale`. */\n locale?: string;\n };\n }): Promise<{\n messageId: string;\n seq: number;\n turnId: string | null;\n queued: boolean;\n duplicate: boolean;\n }>;\n };\n \"analytics\": {\n /** `analytics.cohortRetention` — GET /analytics/cohort-retention. Cohort retention metrics */\n \"cohortRetention\"(args?: {\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<{\n weeks: number[];\n rows: {\n signup_week: number;\n signup_week_label: string;\n cohort_size: number;\n retention: Array<number | null>;\n }[];\n averages: Array<number | null>;\n _timing: {\n total_ms: number;\n wae_queries: number[];\n };\n }>;\n /** `analytics.dailyActive` — GET /analytics/daily-active. Daily active user time series */\n \"dailyActive\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<{\n window_days: number;\n rows: {\n day_ts: number;\n day_label: string;\n active_users: number;\n }[];\n _timing: {\n total_ms: number;\n wae_queries: number[];\n };\n }>;\n /** `analytics.errorGroups` — GET /analytics/errors/groups. Group failure events by fingerprint with per-day count buckets */\n \"errorGroups\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n \"filter\"?: Record<string, Record<string, string | number | boolean | Array<string | number | boolean>>>;\n }): Promise<{\n window_days: number;\n rows: {\n fingerprint: string;\n normalized_title: string;\n source: string;\n status_class: string;\n total: number;\n daily: {\n day: string;\n count: number;\n }[];\n first_seen: string | null;\n last_seen: string | null;\n exemplar: {\n message?: string;\n action?: string;\n scope_key?: string;\n step_id?: string | null;\n run_id?: string | null;\n at?: string;\n } | null;\n }[];\n _timing: {\n total_ms: number;\n wae_queries: number[];\n };\n }>;\n /** `analytics.integrationUsage` — GET /analytics/integrations. Integration usage metrics */\n \"integrationUsage\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<{\n windowDays: number;\n integrations: {\n integrationKey: string;\n invocations: number;\n errorRate: number;\n medianDurationMs?: number;\n p10DurationMs?: number;\n p50DurationMs?: number;\n p95DurationMs?: number;\n }[];\n _timing: {\n total_ms: number;\n wae_queries: number[];\n };\n }>;\n /** `analytics.listEvents` — GET /analytics/events. List analytics events */\n \"listEvents\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"page\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n \"filter\"?: Record<string, Record<string, string | number | boolean | Array<string | number | boolean>>>;\n }): Promise<{\n page: number;\n page_size: number;\n total_rows: number;\n rows: {\n timestamp: string | null;\n user_ulid: string | null;\n user_name?: string | null;\n action: string | null;\n feature?: string | null;\n route?: string | null;\n country?: string | null;\n region_code?: string | null;\n region?: string | null;\n city?: string | null;\n colo?: string | null;\n plan?: string | null;\n connection_id?: string | null;\n device_type?: string | null;\n os_name?: string | null;\n os_version?: string | null;\n browser_name?: string | null;\n browser_version?: string | null;\n app_version?: string | null;\n /** The event's decoded context object. */\n context_json?: unknown;\n entity_key?: string | null;\n duration_ms?: number;\n input_tokens?: number;\n output_tokens?: number;\n total_tokens?: number;\n }[];\n _timing: {\n total_ms: number;\n wae_queries: number[];\n };\n }>;\n /** `analytics.listEventsGrouped` — GET /analytics/events/grouped. List analytics events grouped by dimension */\n \"listEventsGrouped\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"groupBy\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n \"filter\"?: Record<string, Record<string, string | number | boolean | Array<string | number | boolean>>>;\n }): Promise<{\n group_by: string;\n rows: {\n group_value: string;\n raw_group_value: string;\n events: number;\n unique_users: number;\n }[];\n _timing: {\n total_ms: number;\n wae_queries: number[];\n };\n }>;\n /** `analytics.overviewDau` — GET /analytics/overview/dau. Daily active users overview */\n \"overviewDau\"(args?: {\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<{\n value: number;\n previous: number;\n deltaPct?: number | null;\n _timing: {\n total_ms: number;\n wae_queries: number[];\n };\n }>;\n /** `analytics.overviewGrowth` — GET /analytics/overview/growth. User growth overview */\n \"overviewGrowth\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<{\n window_days: number;\n retained_users: number;\n new_users: number;\n reactivated_users: number;\n churned_users: number;\n current_active: number;\n previous_active: number;\n deltaPct?: number | null;\n _timing: {\n total_ms: number;\n wae_queries: number[];\n };\n }>;\n /** `analytics.overviewMau` — GET /analytics/overview/mau. Monthly active users overview */\n \"overviewMau\"(args?: {\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<{\n value: number;\n previous: number;\n deltaPct?: number | null;\n _timing: {\n total_ms: number;\n wae_queries: number[];\n };\n }>;\n /** `analytics.overviewWau` — GET /analytics/overview/wau. Weekly active users overview */\n \"overviewWau\"(args?: {\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<{\n value: number;\n previous: number;\n deltaPct?: number | null;\n _timing: {\n total_ms: number;\n wae_queries: number[];\n };\n }>;\n /** `analytics.rollingActive` — GET /analytics/rolling-active. Rolling active user time series */\n \"rollingActive\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<{\n window_days: number;\n rows: {\n day_ts: number;\n day_label: string;\n active_users: number;\n }[];\n _timing: {\n total_ms: number;\n wae_queries: number[];\n };\n }>;\n /** `analytics.searchUsers` — GET /analytics/users/search. Search app users for analytics */\n \"searchUsers\"(args?: {\n \"q\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"signupDay\"?: string | number | boolean;\n \"signupStartDay\"?: string | number | boolean;\n \"signupEndDay\"?: string | number | boolean;\n \"offset\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<{\n query: string;\n limit: number;\n offset: number;\n truncated: boolean;\n signupStartDay: string | null;\n signupEndDay: string | null;\n results: {\n userUlid: string;\n firstSeen?: string | null;\n lastSeen?: string | null;\n eventCount: number;\n email: string | null;\n name: string | null;\n signedUpAt: string | null;\n signupDay: string | null;\n }[];\n _timing: {\n total_ms: number;\n wae_queries: number[];\n };\n }>;\n /** `analytics.topPrompts` — GET /analytics/prompts/top. List the most-executed prompts */\n \"topPrompts\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<{\n windowDays: number;\n limit: number;\n prompts: {\n promptKey: string;\n executions: number;\n medianDurationMs?: number;\n p95DurationMs?: number;\n p10?: number;\n p50?: number;\n p95?: number;\n avgInputTokens?: number;\n avgOutputTokens?: number;\n totalTokens?: number;\n /** How many of this prompt's executions in the window reported a cost. Today only a decisions run does; a chat run reports none. Less than `executions` means the cost figures cover part of the window. */\n executionsWithCost?: number;\n /** What this prompt's costed executions spent in the window, in USD as the provider reported it, or `null` when no execution in the window reported a cost. Never 0 for an unpriced window: a run whose provider reported no price is cost-unknown, not free. */\n totalCost?: number | null;\n /** `totalCost` divided by `executionsWithCost` — the average over the executions that reported a cost, never over all of them, so it cannot read cheaper than the runs it describes. `null` when no execution in the window reported a cost. */\n avgCost?: number | null;\n }[];\n _timing: {\n total_ms: number;\n wae_queries: number[];\n };\n }>;\n /** `analytics.topUsers` — GET /analytics/users/top. List the most active users */\n \"topUsers\"(args?: {\n \"windowDays\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<{\n windowDays: number;\n limit: number;\n results: {\n userUlid: string;\n firstSeen?: string | null;\n firstSeenInWindow?: string | null;\n lastSeen?: string | null;\n eventCount: number;\n email: string | null;\n name: string | null;\n }[];\n _timing: {\n total_ms: number;\n wae_queries: number[];\n };\n }>;\n /** `analytics.userDetail` — GET /analytics/users/{userUlid}/detail. Detailed analytics for a single user */\n \"userDetail\"(args: {\n \"userUlid\": string | number;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<{\n user: {\n user_ulid: string;\n email: string | null;\n name: string | null;\n };\n stats: {\n first_seen: string | null;\n last_active: string | null;\n total_events: number;\n days_active: number;\n };\n events_by_action: {\n action: string;\n event_count: number;\n last_occurred?: string | null;\n }[];\n events_by_feature: {\n feature: string;\n event_count: number;\n pct: number;\n }[];\n _timing: {\n total_ms: number;\n wae_queries: number[];\n };\n }>;\n /** `analytics.userSnapshot` — GET /analytics/users/{userUlid}/snapshot. Activity snapshot for a single user */\n \"userSnapshot\"(args: {\n \"userUlid\": string | number;\n \"current_timestamp\"?: string | number | boolean;\n \"_bust\"?: string | number | boolean;\n }): Promise<{\n snapshot: {\n timestamp?: string | null;\n /** The snapshot's decoded context. */\n values?: unknown;\n } | null;\n _timing: {\n total_ms: number;\n wae_queries: number[];\n };\n }>;\n /** `analytics.writeForUser` — POST /analytics/write-for-user. Write an analytics event for a subject user under a grant */\n \"writeForUser\"(args: {\n body: {\n /** The subject the event is attributed to; must be a member of this app. */\n userId: string;\n /** The event's action name. */\n action: string;\n /** The feature bucket; defaults to `workflow`. */\n feature?: string;\n /** An optional route label. */\n route?: string;\n /** Author-supplied context. `appId` and `userId` are reserved and always the platform's own. */\n context?: Record<string, unknown>;\n /** Recorded as `timings.totalMs`. */\n durationMs?: number;\n /** Numeric metrics recorded with the event. */\n metrics?: Record<string, unknown>;\n };\n }): Promise<{\n eventsEmitted: number;\n /** Present when no analytics binding is configured; nothing was written. */\n warning?: string;\n }>;\n };\n \"blobBuckets\": {\n /** `blobBuckets.createBucket` — POST /blob-buckets. Create a blob bucket */\n \"createBucket\"(args: {\n body: {\n bucketKey?: unknown;\n description?: unknown;\n name?: unknown;\n preset?: unknown;\n ruleSetId?: unknown;\n ttlTier?: unknown;\n };\n }): Promise<{\n bucketId: string;\n appId: string;\n bucketKey: string;\n name: string;\n description?: string | null;\n ttlTier: string;\n preset: string | null;\n ruleSetId: string | null;\n createdBy?: string | null;\n createdAt?: string | null;\n modifiedAt?: string | null;\n }>;\n /** `blobBuckets.delete` — DELETE /blob-buckets/{bucketId}/blobs/{blobId}. Delete a blob */\n \"delete\"(args: {\n \"bucketId\": string | number;\n \"blobId\": string | number;\n }): Promise<{\n deleted: boolean;\n }>;\n /** `blobBuckets.deleteBatch` — POST /blob-buckets/{bucketId}/blobs/delete. Batch delete blobs from a bucket */\n \"deleteBatch\"(args: {\n \"bucketId\": string | number;\n body: {\n blobIds: string[];\n };\n }): Promise<{\n deleted: number;\n blobIds: string[];\n bucketId: string;\n }>;\n /** `blobBuckets.deleteBucket` — DELETE /blob-buckets/{bucketId}. Delete a blob bucket */\n \"deleteBucket\"(args: {\n \"bucketId\": string | number;\n }): Promise<{\n deleted: boolean;\n }>;\n /** `blobBuckets.download` — GET /blob-buckets/{bucketId}/blobs/{blobId}. Download a blob (anonymous allowed for public buckets) */\n \"download\"(args: {\n \"bucketId\": string | number;\n \"blobId\": string | number;\n \"disposition\"?: string | number | boolean;\n }): Promise<Uint8Array>;\n /** `blobBuckets.downloadSigned` — GET /blob-buckets/{bucketId}/blobs/{blobId}/signed. Download a blob via a signed URL token */\n \"downloadSigned\"(args: {\n \"bucketId\": string | number;\n \"blobId\": string | number;\n \"token\"?: string | number | boolean;\n }): Promise<Uint8Array>;\n /** `blobBuckets.getBucket` — GET /blob-buckets/{bucketId}. Get a blob bucket by id */\n \"getBucket\"(args: {\n \"bucketId\": string | number;\n }): Promise<{\n bucketId: string;\n appId: string;\n bucketKey: string;\n name: string;\n description?: string | null;\n ttlTier: string;\n preset: string | null;\n ruleSetId: string | null;\n createdBy?: string | null;\n createdAt?: string | null;\n modifiedAt?: string | null;\n }>;\n /** `blobBuckets.getMetadata` — GET /blob-buckets/{bucketId}/blobs/{blobId}/metadata. Get blob metadata (anonymous allowed for public buckets) */\n \"getMetadata\"(args: {\n \"bucketId\": string | number;\n \"blobId\": string | number;\n }): Promise<{\n blobId: string | null;\n bucketId: string;\n filename: string | null;\n contentType: string | null;\n numBytes: number;\n sha256?: string | null;\n tags?: string[];\n createdBy?: string | null;\n uploaded?: string | null;\n etag?: string | null;\n }>;\n /** `blobBuckets.getSignedUrl` — POST /blob-buckets/{bucketId}/blobs/{blobId}/signed-url. Create a signed download URL for a blob */\n \"getSignedUrl\"(args: {\n \"bucketId\": string | number;\n \"blobId\": string | number;\n body?: {\n expiresInSeconds?: number;\n };\n }): Promise<{\n url: string;\n token: string;\n expiresAt: number;\n expiresInSeconds: number;\n }>;\n /** `blobBuckets.list` — GET /blob-buckets/{bucketId}/blobs. List blobs in a bucket (anonymous allowed for public buckets) */\n \"list\"(args: {\n \"bucketId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n items: {\n blobId: string | null;\n bucketId: string;\n filename: string | null;\n contentType: string | null;\n numBytes: number;\n sha256?: string | null;\n tags?: string[];\n createdBy?: string | null;\n uploaded?: string | null;\n etag?: string | null;\n }[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /** `blobBuckets.listBuckets` — GET /blob-buckets. List blob buckets */\n \"listBuckets\"(args?: Record<string, never>): Promise<{\n items: {\n bucketId: string;\n appId: string;\n bucketKey: string;\n name: string;\n description?: string | null;\n ttlTier: string;\n preset: string | null;\n ruleSetId: string | null;\n createdBy?: string | null;\n createdAt?: string | null;\n modifiedAt?: string | null;\n }[];\n }>;\n /** `blobBuckets.updateBucket` — PATCH /blob-buckets/{bucketId}. Update a blob bucket */\n \"updateBucket\"(args: {\n \"bucketId\": string | number;\n body: {\n description?: unknown;\n expectedModifiedAt?: unknown;\n name?: unknown;\n preset?: unknown;\n ruleSetId?: unknown;\n };\n }): Promise<{\n bucketId: string;\n appId: string;\n bucketKey: string;\n name: string;\n description?: string | null;\n ttlTier: string;\n preset: string | null;\n ruleSetId: string | null;\n createdBy?: string | null;\n createdAt?: string | null;\n modifiedAt?: string | null;\n }>;\n /** `blobBuckets.upload` — POST /blob-buckets/{bucketId}/blobs. Upload a blob to a bucket */\n \"upload\"(args: {\n \"bucketId\": string | number;\n \"X-Blob-Filename\": string | number;\n \"X-Blob-Tags\"?: string | number;\n \"Content-Type\"?: string | number;\n body: ArrayBuffer | Uint8Array | string;\n }): Promise<{\n blobId: string;\n bucketId: string;\n filename: string;\n contentType: string;\n numBytes: number;\n sha256?: string | null;\n tags?: string[];\n createdBy?: string | null;\n }>;\n };\n \"channels\": {\n /** `channels.authorize` — POST /channels/{channel}/grants. Issue a channel grant under a server function's grant */\n \"authorize\"(args: {\n \"channel\": string | number;\n body: {\n /** The member this grant is for. Caller mode defaults to the invoking caller; system mode must name one. */\n userId?: string;\n /** How long the grant lives, in seconds. Defaults to 300 and is clamped to 900 — `expiresAt` states what it got. */\n ttlSeconds?: number;\n };\n }): Promise<{\n channel?: string;\n grant?: string;\n /** Epoch milliseconds, from the token's own claim. */\n expiresAt?: number;\n }>;\n /** `channels.publish` — POST /channels/{channel}/publish. Publish a message to a channel under a server function's grant */\n \"publish\"(args: {\n \"channel\": string | number;\n body: {\n /** The message body, delivered verbatim as the frame's `payload`. */\n payload?: Record<string, unknown>;\n };\n }): Promise<{\n connections?: number;\n truncated?: boolean;\n }>;\n };\n \"collections\": {\n /** `collections.addDocument` — POST /collections/{collectionId}/documents. Add a document to a collection */\n \"addDocument\"(args: {\n \"collectionId\": string | number;\n body: {\n documentId: string;\n };\n }): Promise<{\n collectionId: string;\n documentId: string;\n addedBy?: string | null;\n }>;\n /** `collections.addMember` — POST /collections/{collectionId}/members. Add a member to a collection */\n \"addMember\"(args: {\n \"collectionId\": string | number;\n body: {\n userId: string;\n role?: \"owner\" | \"manager\" | \"editor\" | \"contributor\" | \"viewer\";\n /** Deprecated (removal: #4718): send `role`. `reader` is viewer, `read-write` is editor. @deprecated */\n permission?: \"reader\" | \"read-write\";\n sendEmail?: boolean;\n collectionUrl?: string;\n note?: string;\n } | {\n email: string;\n role?: \"owner\" | \"manager\" | \"editor\" | \"contributor\" | \"viewer\";\n /** Deprecated (removal: #4718): send `role`. `reader` is viewer, `read-write` is editor. @deprecated */\n permission?: \"reader\" | \"read-write\";\n sendEmail?: boolean;\n collectionUrl?: string;\n note?: string;\n } | {\n groupId: string;\n /** Deprecated (removal: #4718): groups are addressed by `groupId` alone; a sent type is looked up first. @deprecated */\n groupType?: string;\n role?: \"manager\" | \"editor\" | \"contributor\" | \"viewer\";\n /** Deprecated (removal: #4718): send `role`. `reader` is viewer, `read-write` is editor. @deprecated */\n permission?: \"reader\" | \"read-write\";\n };\n }): Promise<{\n status: \"added\" | \"already_member\" | \"pending_signup\";\n userId?: string;\n principal?: string;\n groupId?: string;\n /** Deprecated (removal: #4718): groups are addressed by `groupId` alone. @deprecated */\n groupType?: string;\n role?: \"owner\" | \"manager\" | \"editor\" | \"contributor\" | \"viewer\";\n /** Deprecated (removal: #4718): read `role`. `reader` for viewer and contributor, `read-write` for editor, manager and owner. @deprecated */\n permission?: string;\n addedAt?: string | null;\n /** Deprecated (removal: #4718): kept for clients built before collection roles; read `role`. @deprecated */\n addedBy?: string | null;\n userName?: string;\n userEmail?: string;\n email?: string;\n appInvitationCreated?: boolean;\n deferredId?: string;\n expiresAt?: string | null;\n collectionId?: string;\n invitationId?: string | null;\n inviteToken?: string | null;\n }>;\n /** `collections.create` — POST /collections. Create a collection */\n \"create\"(args: {\n body: CollectionCreateBody;\n }): Promise<{\n collectionId: string;\n appId: string;\n name: string;\n description?: string | null;\n /** Deprecated (removal: #4718): read `role` and `settings`. The stored type, or `default`, while the type's rule set still governs the collection; `default` once fixed roles do. @deprecated */\n collectionType: string;\n documentCount?: number;\n /** Who created the collection: the caller, never the custodian it named. */\n createdBy?: string | null;\n createdAt?: string | null;\n modifiedAt?: string | null;\n /** `user:<userId>` or `app`; null on a collection created before custody. */\n custodian?: string | null;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n }>;\n /** `collections.delete` — DELETE /collections/{collectionId}. Delete a collection */\n \"delete\"(args: {\n \"collectionId\": string | number;\n }): Promise<{\n success: boolean;\n }>;\n /** `collections.get` — GET /collections/{collectionId}. Get a collection by id */\n \"get\"(args: {\n \"collectionId\": string | number;\n }): Promise<{\n collectionId: string;\n appId: string;\n name: string;\n description?: string | null;\n /** Deprecated (removal: #4718): read `role` and `settings`. The stored type, or `default`, while the type's rule set still governs the collection; `default` once fixed roles do. @deprecated */\n collectionType: string;\n documentCount?: number;\n /** Who created the collection: the caller, never the custodian it named. */\n createdBy?: string | null;\n createdAt?: string | null;\n modifiedAt?: string | null;\n /** `user:<userId>` or `app`; null on a collection created before custody. */\n custodian?: string | null;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n }>;\n /**\n * `collections.getAccess` — GET /collections/{collectionId}/access. DEPRECATED — Get a collection's access summary; use GET /collections/{collectionId}/members (removal: #4718)\n * @deprecated Use GET /collections/{collectionId}/members (removal: #4718)\n */\n \"getAccess\"(args: {\n \"collectionId\": string | number;\n }): Promise<{\n groups: {\n collectionId: string;\n /** Deprecated (removal: #4718): groups are addressed by `groupId` alone. @deprecated */\n groupType: string;\n groupId: string;\n /** Deprecated (removal: #4718): read `role`. `reader` for viewer and contributor, `read-write` for editor, manager and owner. @deprecated */\n permission: string;\n role?: \"owner\" | \"manager\" | \"editor\" | \"contributor\" | \"viewer\";\n grantedAt?: string | null;\n grantedBy?: string | null;\n }[];\n members: {\n userId: string;\n /** Deprecated (removal: #4718): read `role`. `reader` for viewer and contributor, `read-write` for editor, manager and owner. @deprecated */\n permission: string;\n role?: \"owner\" | \"manager\" | \"editor\" | \"contributor\" | \"viewer\";\n addedAt?: string | null;\n /** Deprecated (removal: #4718): kept for clients built before collection roles; read `role`. @deprecated */\n addedBy?: string | null;\n }[];\n }>;\n /**\n * `collections.grantGroupPermission` — POST /collections/{collectionId}/group-permissions. DEPRECATED — Grant a group permission on a collection; use POST /collections/{collectionId}/members with groupId and role (removal: #4718)\n * @deprecated Use POST /collections/{collectionId}/members with groupId and role (removal: #4718)\n */\n \"grantGroupPermission\"(args: {\n \"collectionId\": string | number;\n body: {\n /** Deprecated (removal: #4718): groups are addressed by `groupId` alone; a sent type is looked up first. @deprecated */\n groupType?: string;\n groupId: string;\n role?: \"manager\" | \"editor\" | \"contributor\" | \"viewer\";\n /** Deprecated (removal: #4718): send `role`. `reader` is viewer, `read-write` is editor. @deprecated */\n permission?: \"reader\" | \"read-write\";\n };\n }): Promise<{\n collectionId: string;\n /** Deprecated (removal: #4718): groups are addressed by `groupId` alone. @deprecated */\n groupType: string;\n groupId: string;\n /** Deprecated (removal: #4718): read `role`. `reader` for viewer and contributor, `read-write` for editor, manager and owner. @deprecated */\n permission: string;\n role?: \"owner\" | \"manager\" | \"editor\" | \"contributor\" | \"viewer\";\n grantedAt?: string | null;\n grantedBy?: string | null;\n }>;\n /** `collections.list` — GET /collections. List collections */\n \"list\"(args?: {\n \"userId\"?: string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n items: {\n collectionId: string;\n appId: string;\n name: string;\n description?: string | null;\n /** Deprecated (removal: #4718): read `role` and `settings`. The stored type, or `default`, while the type's rule set still governs the collection; `default` once fixed roles do. @deprecated */\n collectionType: string;\n documentCount?: number;\n createdBy?: string | null;\n createdAt?: string | null;\n modifiedAt?: string | null;\n custodian?: string | null;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n /** The listed user's role on the collection, held directly. */\n role?: \"owner\" | \"manager\" | \"editor\" | \"contributor\" | \"viewer\";\n /** Deprecated (removal: #4718): read `role`. `reader` for viewer and contributor, `read-write` for editor, manager and owner. @deprecated */\n permission: \"reader\" | \"read-write\";\n }[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /** `collections.listByCustodian` — GET /holdings/collections. List the collections one custodian holds, from a server function */\n \"listByCustodian\"(args?: {\n \"custodian\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n items: {\n collectionId: string;\n appId: string;\n name: string;\n description?: string | null;\n /** Deprecated (removal: #4718): read `role` and `settings`. The stored type, or `default`, while the type's rule set still governs the collection; `default` once fixed roles do. @deprecated */\n collectionType: string;\n documentCount?: number;\n /** Who created the collection: the caller, never the custodian it named. */\n createdBy?: string | null;\n createdAt?: string | null;\n modifiedAt?: string | null;\n /** `user:<userId>` or `app`; null on a collection created before custody. */\n custodian?: string | null;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n }[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /** `collections.listCollectionsForDocument` — GET /documents/{documentId}/collections. List collections a document belongs to (reverse lookup) */\n \"listCollectionsForDocument\"(args: {\n \"documentId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n items: {\n collectionId: string;\n documentId: string;\n name?: string;\n addedAt?: string;\n addedBy?: string;\n }[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /** `collections.listDb3` — GET /collections/{collectionId}/db3. List db3s in a collection */\n \"listDb3\"(args: {\n \"collectionId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n items: {\n id: string;\n title: string | null;\n createdAt: string;\n modifiedAt: string;\n /** The user the db3 was created for, or `sys:<appId>` for a db3 the app created */\n createdBy: string;\n /** Who holds the db3: `user:<userId>` or `app` */\n custodian: string | null;\n sync: boolean;\n /** The db3's type; null while it has none */\n type: string | null;\n /** The caller's level on the db3 */\n permission: string | null;\n collectionId: string;\n addedAt: string | null;\n addedBy: string | null;\n }[];\n hasMore: boolean;\n /** Pass as `cursor` for the next page; absent on the last page */\n nextCursor?: string;\n }>;\n /** `collections.listDocuments` — GET /collections/{collectionId}/documents. List documents in a collection */\n \"listDocuments\"(args: {\n \"collectionId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n items: {\n documentId: string;\n title?: string | null;\n createdBy?: string | null;\n createdAt?: string | null;\n lastModified?: string | null;\n permission: string | null;\n grantedAt?: string | null;\n accessSource?: string;\n linkAccess?: string;\n tags?: string[];\n thumbnailBlobId?: string;\n /** The document's stored metadata. */\n metadata?: Record<string, unknown>;\n documentFormat?: string;\n collectionId?: string;\n addedAt?: string | null;\n addedBy?: string | null;\n }[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /** `collections.listForUser` — GET /users/{userId}/collections. List the collections an app user is a direct member of */\n \"listForUser\"(args: {\n \"userId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n items: {\n collectionId: string;\n appId: string;\n name: string;\n description?: string | null;\n /** Deprecated (removal: #4718): read `role` and `settings`. The stored type, or `default`, while the type's rule set still governs the collection; `default` once fixed roles do. @deprecated */\n collectionType: string;\n documentCount?: number;\n createdBy?: string | null;\n createdAt?: string | null;\n modifiedAt?: string | null;\n custodian?: string | null;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n /** The listed user's role on the collection, held directly. */\n role?: \"owner\" | \"manager\" | \"editor\" | \"contributor\" | \"viewer\";\n /** Deprecated (removal: #4718): read `role`. `reader` for viewer and contributor, `read-write` for editor, manager and owner. @deprecated */\n permission: \"reader\" | \"read-write\";\n }[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /** `collections.listMembers` — GET /collections/{collectionId}/members. List a collection's members */\n \"listMembers\"(args: {\n \"collectionId\": string | number;\n }): Promise<{\n items: {\n /** The member's address: a user id, or `group:<groupId>`. */\n principal: string;\n /** A user member's id. */\n userId?: string;\n /** A group member's id. */\n groupId?: string;\n /** Deprecated (removal: #4718): groups are addressed by `groupId` alone. @deprecated */\n groupType?: string;\n role: \"owner\" | \"manager\" | \"editor\" | \"contributor\" | \"viewer\";\n /** Deprecated (removal: #4718): read `role`. `reader` for viewer and contributor, `read-write` for editor, manager and owner. @deprecated */\n permission: string;\n addedAt?: string | null;\n /** Deprecated (removal: #4718): kept for clients built before collection roles; read `role`. @deprecated */\n addedBy?: string | null;\n }[];\n /** Always false: the list is complete. */\n hasMore: boolean;\n }>;\n /** `collections.listPendingInvitations` — GET /collections/{collectionId}/pending-invitations. List a collection's pending invitations */\n \"listPendingInvitations\"(args: {\n \"collectionId\": string | number;\n }): Promise<{\n items: {\n email: string;\n role?: \"owner\" | \"manager\" | \"editor\" | \"contributor\" | \"viewer\";\n /** Deprecated (removal: #4718): read `role`. @deprecated */\n permission: \"reader\" | \"read-write\";\n invitationId: string;\n createdAt?: string | null;\n expiresAt?: string | null;\n addedBy?: string | null;\n }[];\n }>;\n /** `collections.removeDocument` — DELETE /collections/{collectionId}/documents/{documentId}. Remove a document from a collection */\n \"removeDocument\"(args: {\n \"collectionId\": string | number;\n \"documentId\": string | number;\n }): Promise<{\n success: boolean;\n }>;\n /** `collections.removeMember` — DELETE /collections/{collectionId}/members/{principal}. Remove a member from a collection */\n \"removeMember\"(args: {\n \"collectionId\": string | number;\n \"principal\": string | number;\n }): Promise<{\n success: boolean;\n }>;\n /** `collections.resolveRole` — GET /collections/{collectionId}/role. Resolve a user's role on a collection */\n \"resolveRole\"(args: {\n \"collectionId\": string | number;\n \"userId\"?: string | number;\n }): Promise<{\n role: \"owner\" | \"manager\" | \"editor\" | \"contributor\" | \"viewer\" | null;\n /** `\"direct\"` for the user's own row, or the group that grants the role. */\n source?: \"direct\" | {\n groupId: string;\n };\n }>;\n /**\n * `collections.revokeGroupPermission` — DELETE /collections/{collectionId}/group-permissions/{groupType}/{groupId}. DEPRECATED — Revoke a group permission on a collection, by type; use DELETE /collections/{collectionId}/members/group:{groupId} (removal: #4718)\n * @deprecated Use DELETE /collections/{collectionId}/members/group:{groupId} (removal: #4718)\n */\n \"revokeGroupPermission\"(args: {\n \"collectionId\": string | number;\n \"groupType\": string | number;\n \"groupId\": string | number;\n }): Promise<{\n success: boolean;\n }>;\n /** `collections.setMemberRole` — PATCH /collections/{collectionId}/members/{principal}. Change a collection member's role */\n \"setMemberRole\"(args: {\n \"collectionId\": string | number;\n \"principal\": string | number;\n body: {\n role: \"owner\" | \"manager\" | \"editor\" | \"contributor\" | \"viewer\";\n };\n }): Promise<{\n /** The member's address: a user id, or `group:<groupId>`. */\n principal: string;\n /** A user member's id. */\n userId?: string;\n /** A group member's id. */\n groupId?: string;\n /** Deprecated (removal: #4718): groups are addressed by `groupId` alone. @deprecated */\n groupType?: string;\n role: \"owner\" | \"manager\" | \"editor\" | \"contributor\" | \"viewer\";\n /** Deprecated (removal: #4718): read `role`. `reader` for viewer and contributor, `read-write` for editor, manager and owner. @deprecated */\n permission: string;\n addedAt?: string | null;\n /** Deprecated (removal: #4718): kept for clients built before collection roles; read `role`. @deprecated */\n addedBy?: string | null;\n }>;\n /** `collections.transfer` — POST /collections/{collectionId}/transfer. Transfer a collection to another user or to the app */\n \"transfer\"(args: {\n \"collectionId\": string | number;\n body: {\n /** `\"user:<userId>\"` (a member of the app; a disabled member counts) or `\"app\"`. */\n to: string;\n };\n }): Promise<{\n collectionId: string;\n appId: string;\n name: string;\n description?: string | null;\n /** Deprecated (removal: #4718): read `role` and `settings`. The stored type, or `default`, while the type's rule set still governs the collection; `default` once fixed roles do. @deprecated */\n collectionType: string;\n documentCount?: number;\n /** Who created the collection: the caller, never the custodian it named. */\n createdBy?: string | null;\n createdAt?: string | null;\n modifiedAt?: string | null;\n /** `user:<userId>` or `app`; null on a collection created before custody. */\n custodian?: string | null;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n }>;\n /** `collections.update` — PATCH /collections/{collectionId}. Update a collection */\n \"update\"(args: {\n \"collectionId\": string | number;\n body: {\n name?: string;\n description?: string;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n };\n }): Promise<{\n collectionId: string;\n appId: string;\n name: string;\n description?: string | null;\n /** Deprecated (removal: #4718): read `role` and `settings`. The stored type, or `default`, while the type's rule set still governs the collection; `default` once fixed roles do. @deprecated */\n collectionType: string;\n documentCount?: number;\n /** Who created the collection: the caller, never the custodian it named. */\n createdBy?: string | null;\n createdAt?: string | null;\n modifiedAt?: string | null;\n /** `user:<userId>` or `app`; null on a collection created before custody. */\n custodian?: string | null;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n }>;\n };\n \"configVars\": {\n /** `configVars.get` — GET /config-vars/{name}. Read an app config var under a server function's grants */\n \"get\"(args: {\n \"name\": string | number;\n }): Promise<{\n name?: string;\n value?: string;\n }>;\n };\n \"connections\": {\n /** `connections.send` — POST /connections/{connectionId}/send. Send a realtime message to one connection of this app */\n \"send\"(args: {\n \"connectionId\": string | number;\n body: {\n /** The message body, delivered verbatim as the frame's `payload`. */\n payload?: Record<string, unknown>;\n };\n }): Promise<any>;\n };\n \"databaseTypeConfigs\": {\n /** `databaseTypeConfigs.create` — POST /databases/types. Create a database type */\n \"create\"(args: {\n \"dryRun\"?: string | number | boolean;\n body: {\n autoPopulatedFields?: unknown;\n databaseType?: unknown;\n metadataManifest?: unknown;\n ruleSetId?: unknown;\n schema?: unknown;\n timestamps?: unknown;\n triggers?: unknown;\n };\n }): Promise<{\n appId: string;\n databaseType: string;\n ruleSetId?: string | null;\n triggers?: Record<string, unknown> | null;\n autoPopulatedFields?: Record<string, unknown> | null;\n timestamps?: Record<string, unknown> | null;\n /** Raw TOML; clients parse it themselves (round-2 decision). */\n schema?: string | null;\n metadataManifest?: Record<string, unknown> | null;\n createdAt?: string;\n modifiedAt?: string;\n createdBy?: string;\n warnings?: string[];\n /** A schema edit that newly declares a field unique while databases of the type exist: the fields their indexes lack, and how to back-provision them. */\n staleInstanceWarning?: string | {\n code?: \"EXISTING_INSTANCES_NEED_REINDEX\";\n message?: string;\n fields?: string[];\n remedy?: string;\n };\n /** A schema edit that changes the indexes of a type with databases: the run that back-provisions them (`status: running`), or why it did not start (`not_started`, `error`). */\n reindexFanout?: {\n status: \"running\" | \"not_started\";\n runId?: string;\n workflowKey?: string;\n instanceCount?: number;\n /** The reindex-status path that follows the run. */\n statusUrl?: string;\n error?: string;\n };\n /** Present on a `?dryRun=true` answer. */\n ok?: boolean;\n dryRun?: boolean;\n } | {\n ok: boolean;\n dryRun: boolean;\n databaseType: string;\n }>;\n /** `databaseTypeConfigs.delete` — DELETE /databases/types/{databaseType}. Delete a database type */\n \"delete\"(args: {\n \"databaseType\": string | number;\n }): Promise<{\n success: boolean;\n deletedOperations?: number;\n deletedSubscriptions?: number;\n }>;\n /** `databaseTypeConfigs.get` — GET /databases/types/{databaseType}. Get a database type */\n \"get\"(args: {\n \"databaseType\": string | number;\n }): Promise<{\n appId: string;\n databaseType: string;\n ruleSetId?: string | null;\n triggers?: Record<string, unknown> | null;\n autoPopulatedFields?: Record<string, unknown> | null;\n timestamps?: Record<string, unknown> | null;\n /** Raw TOML; clients parse it themselves (round-2 decision). */\n schema?: string | null;\n metadataManifest?: Record<string, unknown> | null;\n createdAt?: string;\n modifiedAt?: string;\n createdBy?: string;\n warnings?: string[];\n /** A schema edit that newly declares a field unique while databases of the type exist: the fields their indexes lack, and how to back-provision them. */\n staleInstanceWarning?: string | {\n code?: \"EXISTING_INSTANCES_NEED_REINDEX\";\n message?: string;\n fields?: string[];\n remedy?: string;\n };\n /** A schema edit that changes the indexes of a type with databases: the run that back-provisions them (`status: running`), or why it did not start (`not_started`, `error`). */\n reindexFanout?: {\n status: \"running\" | \"not_started\";\n runId?: string;\n workflowKey?: string;\n instanceCount?: number;\n /** The reindex-status path that follows the run. */\n statusUrl?: string;\n error?: string;\n };\n /** Present on a `?dryRun=true` answer. */\n ok?: boolean;\n dryRun?: boolean;\n }>;\n /** `databaseTypeConfigs.getReindexStatus` — GET /databases/types/{databaseType}/reindex-status. Status of the index back-provision fan-out for a type */\n \"getReindexStatus\"(args: {\n \"databaseType\": string | number;\n \"runId\"?: string | number | boolean;\n }): Promise<{\n runId?: string;\n workflowKey?: string;\n databaseType: string;\n status?: string;\n total?: number;\n completed?: number;\n failed?: number;\n failures?: Record<string, unknown>[];\n /** When the run started; null when the run did not record it. */\n requestedAt?: string | null;\n /** When the run ended; null while it runs. */\n finishedAt?: string | null;\n }>;\n /** `databaseTypeConfigs.list` — GET /databases/types. List database types */\n \"list\"(args?: Record<string, never>): Promise<{\n appId: string;\n databaseType: string;\n ruleSetId?: string | null;\n triggers?: Record<string, unknown> | null;\n autoPopulatedFields?: Record<string, unknown> | null;\n timestamps?: Record<string, unknown> | null;\n /** Raw TOML; clients parse it themselves (round-2 decision). */\n schema?: string | null;\n metadataManifest?: Record<string, unknown> | null;\n createdAt?: string;\n modifiedAt?: string;\n createdBy?: string;\n warnings?: string[];\n /** A schema edit that newly declares a field unique while databases of the type exist: the fields their indexes lack, and how to back-provision them. */\n staleInstanceWarning?: string | {\n code?: \"EXISTING_INSTANCES_NEED_REINDEX\";\n message?: string;\n fields?: string[];\n remedy?: string;\n };\n /** A schema edit that changes the indexes of a type with databases: the run that back-provisions them (`status: running`), or why it did not start (`not_started`, `error`). */\n reindexFanout?: {\n status: \"running\" | \"not_started\";\n runId?: string;\n workflowKey?: string;\n instanceCount?: number;\n /** The reindex-status path that follows the run. */\n statusUrl?: string;\n error?: string;\n };\n /** Present on a `?dryRun=true` answer. */\n ok?: boolean;\n dryRun?: boolean;\n }[]>;\n /** `databaseTypeConfigs.scaffoldSchema` — POST /databases/types/{databaseType}/schema:scaffold. Scaffold a starter schema for a database type */\n \"scaffoldSchema\"(args: {\n \"databaseType\": string | number;\n }): Promise<{\n schema: string;\n }>;\n /** `databaseTypeConfigs.update` — PATCH /databases/types/{databaseType}. Update a database type */\n \"update\"(args: {\n \"databaseType\": string | number;\n \"dryRun\"?: string | number | boolean;\n body: {\n autoPopulatedFields?: unknown;\n expectedModifiedAt?: unknown;\n metadataManifest?: unknown;\n ruleSetId?: unknown;\n schema?: unknown;\n timestamps?: unknown;\n triggers?: unknown;\n };\n }): Promise<{\n appId: string;\n databaseType: string;\n ruleSetId?: string | null;\n triggers?: Record<string, unknown> | null;\n autoPopulatedFields?: Record<string, unknown> | null;\n timestamps?: Record<string, unknown> | null;\n /** Raw TOML; clients parse it themselves (round-2 decision). */\n schema?: string | null;\n metadataManifest?: Record<string, unknown> | null;\n createdAt?: string;\n modifiedAt?: string;\n createdBy?: string;\n warnings?: string[];\n /** A schema edit that newly declares a field unique while databases of the type exist: the fields their indexes lack, and how to back-provision them. */\n staleInstanceWarning?: string | {\n code?: \"EXISTING_INSTANCES_NEED_REINDEX\";\n message?: string;\n fields?: string[];\n remedy?: string;\n };\n /** A schema edit that changes the indexes of a type with databases: the run that back-provisions them (`status: running`), or why it did not start (`not_started`, `error`). */\n reindexFanout?: {\n status: \"running\" | \"not_started\";\n runId?: string;\n workflowKey?: string;\n instanceCount?: number;\n /** The reindex-status path that follows the run. */\n statusUrl?: string;\n error?: string;\n };\n /** Present on a `?dryRun=true` answer. */\n ok?: boolean;\n dryRun?: boolean;\n /** The push of the new revision to every db3 of the type; null when no db3 names it */\n db3Push?: {\n runId?: string;\n /** `running`, or `not_started` when the push could not start (the row is written either way) */\n status?: string;\n /** Where `push-status` reads the run */\n statusPath?: string;\n error?: string;\n } | null;\n }>;\n };\n \"databases\": {\n /** `databases.addManager` — PUT /databases/{databaseId}/permissions. Set a user's database permission */\n \"addManager\"(args: {\n \"databaseId\": string | number;\n body: {\n userId: string;\n permission: \"manager\" | \"owner\";\n };\n }): Promise<{\n databaseId: string;\n userId: string;\n permission: string;\n grantedAt?: string;\n grantedBy?: string;\n /** On the list: the grantee's name, when the user is found. */\n userName?: string;\n /** On the list: the grantee's email, when the user is found. */\n userEmail?: string;\n }>;\n /** `databases.create` — POST /databases. Create a database */\n \"create\"(args: {\n body: {\n /** Up to 500 characters. */\n title: string;\n /** Required. A type config is auto-created when none exists. */\n databaseType: string;\n /** Resource metadata written with the database, keyed by category (`{ <category>: { <key>: <value> } }`); each entry is validated against its category's schema. */\n initialMetadata?: Record<string, unknown>;\n };\n }): Promise<{\n databaseId: string;\n title: string;\n databaseType?: string | null;\n permission?: string;\n createdBy?: string;\n createdAt?: string;\n modifiedAt?: string;\n }>;\n /** `databases.delete` — DELETE /databases/{databaseId}. Delete a database */\n \"delete\"(args: {\n \"databaseId\": string | number;\n }): Promise<{\n success: boolean;\n }>;\n /** `databases.get` — GET /databases/{databaseId}. Get a database by id */\n \"get\"(args: {\n \"databaseId\": string | number;\n }): Promise<{\n databaseId: string;\n title: string;\n databaseType?: string | null;\n permission?: string;\n createdBy?: string;\n createdAt?: string;\n modifiedAt?: string;\n }>;\n /** `databases.grantGroupPermission` — POST /databases/{databaseId}/group-permissions. Grant a group permission on a database */\n \"grantGroupPermission\"(args: {\n \"databaseId\": string | number;\n body: {\n /** Deprecated (removal: #4718): groups are named by `groupId` alone. Given, the group is looked up by type first. @deprecated */\n groupType?: string;\n groupId: string;\n permission: \"manager\" | \"owner\";\n };\n }): Promise<{\n databaseId: string;\n groupType: string;\n groupId: string;\n permission: string;\n grantedAt?: string;\n grantedBy?: string;\n }>;\n /** `databases.list` — GET /databases. List databases */\n \"list\"(args?: Record<string, never>): Promise<{\n items: {\n databaseId: string;\n title: string;\n databaseType?: string | null;\n permission?: string;\n createdBy?: string;\n createdAt?: string;\n modifiedAt?: string;\n }[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /** `databases.listGroupPermissions` — GET /databases/{databaseId}/group-permissions. List a database's group permissions */\n \"listGroupPermissions\"(args: {\n \"databaseId\": string | number;\n }): Promise<{\n databaseId: string;\n groupType: string;\n groupId: string;\n permission: string;\n grantedAt?: string;\n grantedBy?: string;\n }[]>;\n /** `databases.listPermissions` — GET /databases/{databaseId}/permissions. List a database's user permissions */\n \"listPermissions\"(args: {\n \"databaseId\": string | number;\n }): Promise<{\n databaseId: string;\n userId: string;\n permission: string;\n grantedAt?: string;\n grantedBy?: string;\n /** On the list: the grantee's name, when the user is found. */\n userName?: string;\n /** On the list: the grantee's email, when the user is found. */\n userEmail?: string;\n }[]>;\n \"records\": {\n /** `databases.records.addToSet` — POST /databases/{databaseId}/records/stringset/add. Database records: stringset/add (app admin or owner) */\n \"addToSet\"(args: {\n \"databaseId\": string | number;\n body: {\n modelName: string;\n id: string;\n /** StringSet field name → the members to write. */\n sets: Record<string, unknown>;\n /** A conditional-write predicate; a mismatch fails the write with 409. */\n condition?: Record<string, unknown>;\n };\n }): Promise<{\n success: boolean;\n }>;\n /** `databases.records.aggregate` — POST /databases/{databaseId}/records/aggregate. Database records: aggregate (app admin or owner) */\n \"aggregate\"(args: {\n \"databaseId\": string | number;\n body: {\n modelName: string;\n /** Aggregation options: `operations`, `groupBy`, `filter`, `sort`, `limit`. */\n options: Record<string, unknown>;\n };\n }): Promise<{\n /** One row per group, in the order SQL returned them: `{ group, count, <op>_<field> }`, every requested operation present under its key (`count`, `<op>_<field>`) even when it is the only one. A grouped aggregate that matches no record is `[]`; an ungrouped one is exactly one row with an empty `group`. Two `groupBy` levels that would take the same key in `group` are refused with a 400, `Ambiguous aggregation group keys: '<key>' names more than one groupBy level`. */\n result: {\n /** One entry per `groupBy` level, keyed by the field name (or `has_<field>_<contains>` for a StringSet membership level, or `<field>_<period>` for a period level), holding the value as stored: `null` for a missing field, numbers as numbers. Empty for an ungrouped aggregate. */\n group: Record<string, unknown>;\n /** The group's record count, present when `count` is requested. */\n count?: number;\n [key: string]: unknown;\n }[];\n }>;\n /** `databases.records.batch` — POST /databases/{databaseId}/records/batch. Database records: batch (app admin or owner) */\n \"batch\"(args: {\n \"databaseId\": string | number;\n body: {\n operations: {\n op: \"save\" | \"patch\" | \"delete\" | \"increment\" | \"addToSet\" | \"removeFromSet\";\n modelName: string;\n id?: string;\n /** The record's fields, for save/patch. */\n data?: Record<string, unknown>;\n /** StringSet field name → the members to write. */\n stringSets?: Record<string, unknown>;\n /** Field → delta, for `increment`. */\n fields?: Record<string, unknown>;\n ifNotExists?: boolean;\n /** A conditional-write predicate; a mismatch fails the write with 409. */\n condition?: Record<string, unknown>;\n upsertOn?: string;\n /** Per-call auto-timestamp directives. `create` stamps only on insert, `update` on every write; an explicit value in `data` always wins. The database type's own `timestamps` directive is merged in server-side, so a type that declares one stamps this write whether or not the caller sends anything here. */\n autoStamps?: {\n create?: string[];\n update?: string[];\n };\n }[];\n /** All-or-nothing (#1478). Default false: each operation's outcome is recorded independently and successful siblings commit. */\n atomic?: boolean;\n };\n }): Promise<{\n results: {\n success: boolean;\n id: string;\n error?: string;\n /** The natural HTTP status of a failure (#1478). */\n status?: number;\n code?: \"NOT_FOUND\" | \"HOOK_DENIED\" | \"CONDITION_NOT_MET\" | \"ALREADY_EXISTS\" | \"UNIQUE_VIOLATION\" | \"VALIDATION_ERROR\";\n /** The post-increment values, for increment. */\n values?: Record<string, unknown>;\n /** Server-applied field values (#1476). */\n appliedFields?: Record<string, unknown>;\n }[];\n }>;\n /** `databases.records.count` — POST /databases/{databaseId}/records/count. Database records: count (app admin or owner) */\n \"count\"(args: {\n \"databaseId\": string | number;\n body: {\n modelName: string;\n /** A dynamo-bao style filter; `{}` matches every record of the model. */\n filter?: Record<string, unknown>;\n };\n }): Promise<{\n count: number;\n }>;\n /** `databases.records.delete` — POST /databases/{databaseId}/records/delete. Database records: delete (app admin or owner) */\n \"delete\"(args: {\n \"databaseId\": string | number;\n body: {\n modelName: string;\n id: string;\n /** A conditional-write predicate; a mismatch fails the write with 409. */\n condition?: Record<string, unknown>;\n };\n }): Promise<{\n success: boolean;\n }>;\n /** `databases.records.describe` — GET /databases/{databaseId}/records/describe. Database records: describe (app admin or owner) */\n \"describe\"(args: {\n \"databaseId\": string | number;\n \"modelName\"?: string | number | boolean;\n }): Promise<{\n modelName: string;\n fields: {\n model_name: string;\n field_name: string;\n inferred_type?: string;\n first_seen_at?: string;\n }[];\n }>;\n /** `databases.records.dropIndex` — POST /databases/{databaseId}/records/index/drop. Database records: index/drop (app admin or owner) */\n \"dropIndex\"(args: {\n \"databaseId\": string | number;\n body: {\n modelName: string;\n fieldName: string;\n };\n }): Promise<{\n success: boolean;\n modelName: string;\n fieldName: string;\n }>;\n /** `databases.records.dropUniqueConstraint` — POST /databases/{databaseId}/records/unique-constraint/drop. Database records: unique-constraint/drop (app admin or owner) */\n \"dropUniqueConstraint\"(args: {\n \"databaseId\": string | number;\n body: {\n modelName: string;\n constraintName: string;\n };\n }): Promise<{\n success: boolean;\n modelName: string;\n constraintName: string;\n }>;\n /** `databases.records.increment` — POST /databases/{databaseId}/records/increment. Database records: increment (app admin or owner) */\n \"increment\"(args: {\n \"databaseId\": string | number;\n body: {\n modelName: string;\n id: string;\n /** Field name → the delta to apply. */\n fields: Record<string, unknown>;\n /** A conditional-write predicate; a mismatch fails the write with 409. */\n condition?: Record<string, unknown>;\n };\n }): Promise<{\n success: boolean;\n id: string;\n /** Field name → the value after the increment. */\n values: Record<string, unknown>;\n }>;\n /** `databases.records.listIndexes` — GET /databases/{databaseId}/records/indexes. Database records: indexes (app admin or owner) */\n \"listIndexes\"(args: {\n \"databaseId\": string | number;\n \"modelName\"?: string | number | boolean;\n }): Promise<{\n indexes: {\n model_name: string;\n field_name: string;\n field_type?: string;\n is_unique?: number;\n created_at?: string;\n }[];\n }>;\n /** `databases.records.listUniqueConstraints` — GET /databases/{databaseId}/records/unique-constraints. Database records: unique-constraints (app admin or owner) */\n \"listUniqueConstraints\"(args: {\n \"databaseId\": string | number;\n \"modelName\"?: string | number | boolean;\n }): Promise<{\n constraints: {\n model_name: string;\n constraint_name: string;\n fields?: string[];\n created_at?: string;\n }[];\n }>;\n /** `databases.records.models` — GET /databases/{databaseId}/records/models. Database records: models (app admin or owner) */\n \"models\"(args: {\n \"databaseId\": string | number;\n \"modelName\"?: string | number | boolean;\n }): Promise<{\n models: string[];\n }>;\n /** `databases.records.patch` — POST /databases/{databaseId}/records/patch. Database records: patch (app admin or owner) */\n \"patch\"(args: {\n \"databaseId\": string | number;\n body: {\n modelName: string;\n id: string;\n /** The fields to merge. */\n data: Record<string, unknown>;\n /** StringSet field name → the members to write. */\n stringSets?: Record<string, unknown>;\n /** A conditional-write predicate; a mismatch fails the write with 409. */\n condition?: Record<string, unknown>;\n /** A patch is always an update, so only the `update` list applies. */\n autoStamps?: {\n create?: string[];\n update?: string[];\n };\n };\n }): Promise<{\n success: boolean;\n id: string;\n /** Server-applied field values (#1476). */\n appliedFields?: Record<string, unknown>;\n }>;\n /** `databases.records.query` — POST /databases/{databaseId}/records/query. Database records: query (app admin or owner) */\n \"query\"(args: {\n \"databaseId\": string | number;\n body: {\n modelName: string;\n /** A dynamo-bao style filter; `{}` matches every record of the model. */\n filter?: Record<string, unknown>;\n /** Query options: `limit`, `startKey`, `sort`, `select`, `direction`. */\n options?: Record<string, unknown>;\n };\n }): Promise<{ items: any[]; hasMore: boolean; nextCursor?: string; prevCursor?: string }>;\n /** `databases.records.registerIndex` — POST /databases/{databaseId}/records/index/register. Database records: index/register (app admin or owner) */\n \"registerIndex\"(args: {\n \"databaseId\": string | number;\n body: {\n modelName: string;\n fieldName: string;\n fieldType: string;\n unique?: boolean;\n };\n }): Promise<{\n success: boolean;\n modelName: string;\n fieldName: string;\n }>;\n /** `databases.records.registerUniqueConstraint` — POST /databases/{databaseId}/records/unique-constraint/register. Database records: unique-constraint/register (app admin or owner) */\n \"registerUniqueConstraint\"(args: {\n \"databaseId\": string | number;\n body: {\n modelName: string;\n constraintName: string;\n fields: string[];\n };\n }): Promise<{\n success: boolean;\n modelName: string;\n constraintName: string;\n }>;\n /** `databases.records.removeFromSet` — POST /databases/{databaseId}/records/stringset/remove. Database records: stringset/remove (app admin or owner) */\n \"removeFromSet\"(args: {\n \"databaseId\": string | number;\n body: {\n modelName: string;\n id: string;\n /** StringSet field name → the members to write. */\n sets: Record<string, unknown>;\n /** A conditional-write predicate; a mismatch fails the write with 409. */\n condition?: Record<string, unknown>;\n };\n }): Promise<{\n success: boolean;\n }>;\n /** `databases.records.save` — POST /databases/{databaseId}/records/save. Database records: save (app admin or owner) */\n \"save\"(args: {\n \"databaseId\": string | number;\n body: {\n modelName: string;\n /** Generated when omitted. */\n id?: string;\n /** The record's fields. */\n data: Record<string, unknown>;\n /** StringSet field name → the members to write. */\n stringSets?: Record<string, unknown>;\n ifNotExists?: boolean;\n /** A conditional-write predicate; a mismatch fails the write with 409. */\n condition?: Record<string, unknown>;\n upsertOn?: string;\n /** Per-call auto-timestamp directives. `create` stamps only on insert, `update` on every write; an explicit value in `data` always wins. The database type's own `timestamps` directive is merged in server-side, so a type that declares one stamps this write whether or not the caller sends anything here. */\n autoStamps?: {\n create?: string[];\n update?: string[];\n };\n };\n }): Promise<{\n success: boolean;\n id: string;\n /** Server-applied field values (#1476); present only when non-empty. */\n appliedFields?: Record<string, unknown>;\n }>;\n /** `databases.records.syncIndexes` — POST /databases/{databaseId}/records/indexes/sync. Database records: indexes/sync (app admin or owner) */\n \"syncIndexes\"(args: {\n \"databaseId\": string | number;\n body: {\n models: {\n modelName: string;\n indexes?: {\n fieldName: string;\n fieldType?: string;\n unique?: boolean;\n }[];\n uniqueConstraints?: {\n name: string;\n fields: string[];\n }[];\n }[];\n };\n }): Promise<{\n registered: number;\n }>;\n };\n /** `databases.reindex` — POST /databases/{databaseId}/reindex. Reindex a database */\n \"reindex\"(args: {\n \"databaseId\": string | number;\n }): Promise<{\n ok: boolean;\n registered: number;\n skipped?: boolean;\n reason?: string;\n databaseType?: string | null;\n }>;\n /** `databases.revokeGroupPermission` — DELETE /databases/{databaseId}/group-permissions/{groupId}. Revoke a group permission on a database */\n \"revokeGroupPermission\"(args: {\n \"databaseId\": string | number;\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<{\n success: boolean;\n }>;\n /**\n * `databases.revokeGroupPermissionByType` — DELETE /databases/{databaseId}/group-permissions/{groupType}/{groupId}. DEPRECATED — Revoke a group permission on a database, by type; use DELETE /databases/{databaseId}/group-permissions/{groupId} (removal: #4718)\n * @deprecated Use DELETE /databases/{databaseId}/group-permissions/{groupId} (removal: #4718)\n */\n \"revokeGroupPermissionByType\"(args: {\n \"databaseId\": string | number;\n \"groupType\": string | number;\n \"groupId\": string | number;\n }): Promise<{\n success: boolean;\n }>;\n /** `databases.revokePermission` — DELETE /databases/{databaseId}/permissions/{userId}. Remove a user's database permission */\n \"revokePermission\"(args: {\n \"databaseId\": string | number;\n \"userId\": string | number;\n }): Promise<{\n success: boolean;\n }>;\n /** `databases.transferOwnership` — POST /databases/{databaseId}/permissions/transfer. Transfer database ownership */\n \"transferOwnership\"(args: {\n \"databaseId\": string | number;\n body: {\n newOwnerId: string;\n };\n }): Promise<{\n success: boolean;\n message?: string;\n previousOwnerId?: string;\n newOwnerId?: string;\n }>;\n /** `databases.update` — PATCH /databases/{databaseId}. Update a database */\n \"update\"(args: {\n \"databaseId\": string | number;\n body: {\n title?: string;\n /** Must name a configured type; null clears it. */\n databaseType?: string | null;\n };\n }): Promise<{\n databaseId: string;\n title: string;\n databaseType?: string | null;\n permission?: string;\n createdBy?: string;\n createdAt?: string;\n modifiedAt?: string;\n }>;\n };\n \"db3\": {\n /** `db3.abortIngest` — POST /db3/{db3Id}/ingest/{sessionId}/abort. Abort a db3 bulk load */\n \"abortIngest\"(args: {\n \"db3Id\": string | number;\n \"sessionId\": string | number;\n body: Record<string, unknown>;\n }): Promise<{\n sessionId: string;\n documentId: string;\n /** uploading | committed | validating | staging | applying | finalizing | registering | complete | failed | aborted */\n state: string;\n createdBy?: string;\n createdAt?: string;\n updatedAt?: string;\n completedAt?: string | null;\n chunks?: number;\n rows?: number;\n bytes?: number;\n /** Decompressed bytes across the stored chunks; null when unknown (a session that completed before timings were recorded has had its chunk descriptors swept) */\n rawBytes?: number | null;\n /** When the current state began */\n stateEnteredAt?: string | null;\n /** Where the session's time went. On Workers the clock advances only across I/O: a synchronous stage (copyMs, applyMs, decodeMs, swapMs, registerMs) reads 0 there, and an I/O stage (readMs, sealMs, manifestMs) is an OBSERVATION INTERVAL ending at that boundary which includes the synchronous work before it, not an isolated cost. State windows and intervals are exact, because every tick begins in a fresh alarm invocation. */\n timings?: {\n /** The state at which this session's timing history begins; uploading for a session opened after timings were recorded */\n since?: string | null;\n ticks?: number;\n /** Stage costs summed over the session's ticks, ms Stage totals are WALL milliseconds, bracketed on Workers when the room settles the clock at both ends of the bracket; the ledger clock still does not move inside a transaction, so an unbracketed tick reads 0. They are not CPU time. */\n totals?: {\n manifestMs?: number;\n readMs?: number;\n decodeMs?: number;\n copyMs?: number;\n applyMs?: number;\n reconcileMs?: number;\n swapMs?: number;\n sealMs?: number;\n registerMs?: number;\n /** Clock at tick end minus clock at tick start, summed; a lower bound on Workers, where a pure-SQL tick reads 0 */\n totalMs?: number;\n /** How many of this session ticks had their stage timers bracketed by a clock settle at both ends. A tick that was not bracketed reads 0 for every synchronous stage, exactly as before. */\n bracketedTicks?: number;\n /** How many applied rows the `apply` counters describe: the denominator of a per-row figure. Below the session's applied rows when some ticks' counters were not recorded. */\n countedRows?: number;\n /** What each stage SQL did, without asking a clock. Keyed by the nine stage names: manifest, read, decode, copy, apply, reconcile, swap, seal, register. */\n counters?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n /** The same figures split by the table each statement named: records, members (string-set index), claims (unique index), log, bookkeeping, other. This is what separates the records fold from string-set maintenance from unique claims inside one stage. */\n byTarget?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n }>;\n }>;\n };\n /** Per-state { ms, ticks, intervalMs }. intervalMs is the start-to-start interval of the ticks that STARTED in this state, which includes their execution, the room's post-tick work and the 1,000 ms re-arm delay. The transition tick's own cost lands in the next state's window. */\n states?: Record<string, {\n ms?: number;\n ticks?: number;\n intervalMs?: number;\n }>;\n /** The longest interval seen, attributed to the state of the tick that started it */\n longestInterval?: {\n intervalMs?: number;\n state?: string;\n } | null;\n };\n /** Rates over the pipeline window (committed through the swap). Null unless the session reached registering AND its timing history begins at uploading — a session whose window was not measured reports no rate rather than an invented one. */\n throughput?: {\n pipelineMs?: number;\n rowsPerSecond?: number;\n storedBytesPerSecond?: number;\n /** Null when the decompressed total is unknown */\n rawBytesPerSecond?: number | null;\n } | null;\n progress?: {\n rowsCopied?: number;\n chunksApplied?: number;\n rowsApplied?: number;\n recordsReconciled?: number;\n oldRowsRemoved?: number;\n };\n copyStartedAt?: string | null;\n discontinuityEpoch?: number | null;\n buildId?: string | null;\n failure?: {\n code?: string;\n reason?: string;\n rows?: {\n model?: string;\n id?: string;\n }[];\n } | null;\n expiresAt?: string;\n /** A record-log (format 3) load: `open` or `commit`; null for format 2 */\n reserveEpoch?: string | null;\n /** A record-log (format 3) load: `merge` or `refresh`; null for format 2 */\n mode?: string | null;\n /** Rows the load refused, each kept with its code */\n refusedRows?: number;\n /** The first 20 refused rows; the full list pages from GET …/documents/{id}/room?refused= */\n refusedSample?: {\n model?: string;\n id?: string;\n code?: string;\n }[];\n /** A record-log (format 3) load once committed with its epoch reserved: the epoch its rows carry, the log number at the reservation (k), and the log numbers of its first and last entries */\n load?: {\n epoch?: number;\n k?: number;\n firstLsn?: number | null;\n lastLsn?: number | null;\n } | null;\n }>;\n /** `db3.addTag` — POST /db3/{db3Id}/tags. Add a tag to a db3 */\n \"addTag\"(args: {\n \"db3Id\": string | number;\n body: {\n tag: string;\n };\n }): Promise<{\n documentId: string;\n tags: string[];\n }>;\n \"aliases\": {\n /** `db3.aliases.listForDocument` — GET /db3/{db3Id}/aliases. List aliases bound to a db3 */\n \"listForDocument\"(args: {\n \"db3Id\": string | number;\n }): Promise<{\n scope: \"app\" | \"user\";\n aliasKey: string;\n documentId: string;\n userId?: string | null;\n createdAt?: string;\n updatedAt?: string;\n }[]>;\n };\n /** `db3.approveAccessRequest` — POST /db3/{db3Id}/access-requests/{requestId}/approve. Approve a db3 access request */\n \"approveAccessRequest\"(args: {\n \"db3Id\": string | number;\n \"requestId\": string | number;\n body?: {\n /** Approve at this level instead of the requested one. */\n permission?: \"read-write\" | \"reader\";\n /** Link included in the approval notification. */\n documentUrl?: string;\n /** Not read by the handler; use `permission`. */\n role?: string;\n };\n }): Promise<{\n success: boolean;\n message?: string;\n request: {\n requestId: string;\n documentId: string;\n requesterId: string;\n status: string;\n requestedPermission?: string;\n message?: string;\n createdAt?: string;\n resolvedBy?: string;\n resolvedAt?: string;\n grantedPermission?: string;\n };\n }>;\n \"blobs\": {\n /** `db3.blobs.delete` — DELETE /db3/{db3Id}/blobs/{blobId}. Delete a db3 blob */\n \"delete\"(args: {\n \"db3Id\": string | number;\n \"blobId\": string | number;\n }): Promise<{\n deleted: boolean;\n }>;\n /** `db3.blobs.downloadHeaders` — HEAD /db3/{db3Id}/blobs/{blobId}/download. Get db3 blob download headers (ETag/304 support) */\n \"downloadHeaders\"(args: {\n \"db3Id\": string | number;\n \"blobId\": string | number;\n }): Promise<HeaderResult>;\n /** `db3.blobs.downloadUrl` — GET /db3/{db3Id}/blobs/{blobId}/download. Download a db3 blob's bytes */\n \"downloadUrl\"(args: {\n \"db3Id\": string | number;\n \"blobId\": string | number;\n \"disposition\"?: string | number | boolean;\n }): Promise<Uint8Array>;\n /** `db3.blobs.get` — GET /db3/{db3Id}/blobs/{blobId}. Get a db3 blob's metadata */\n \"get\"(args: {\n \"db3Id\": string | number;\n \"blobId\": string | number;\n }): Promise<{\n blobId: string;\n filename?: string;\n contentType?: string;\n numBytes?: number;\n sha256?: string;\n status?: string;\n createdAt?: string;\n /** 0 on the idempotent 200; the stored length on a 201. */\n bytesTransferred?: number;\n }>;\n /** `db3.blobs.list` — GET /db3/{db3Id}/blobs. List blobs attached to a db3 */\n \"list\"(args: {\n \"db3Id\": string | number;\n }): Promise<{\n items: {\n blobId: string;\n filename?: string;\n contentType?: string;\n numBytes?: number;\n sha256?: string;\n status?: string;\n createdAt?: string;\n /** 0 on the idempotent 200; the stored length on a 201. */\n bytesTransferred?: number;\n }[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /** `db3.blobs.upload` — PUT /db3/{db3Id}/blobs/{blobId}. Upload a db3 blob with a client-specified id (immutable + idempotent) */\n \"upload\"(args: {\n \"db3Id\": string | number;\n \"blobId\": string | number;\n \"X-Blob-Filename\": string | number;\n \"X-Blob-Size\": string | number;\n \"X-Blob-Sha256\": string | number;\n \"Content-Type\"?: string | number;\n body: ArrayBuffer | Uint8Array | string;\n }): Promise<{\n blobId: string;\n filename?: string;\n contentType?: string;\n numBytes?: number;\n sha256?: string;\n status?: string;\n createdAt?: string;\n /** 0 on the idempotent 200; the stored length on a 201. */\n bytesTransferred?: number;\n }>;\n };\n /** `db3.clearLinkAccess` — DELETE /db3/{db3Id}/link-access. Turn off the db3's link access */\n \"clearLinkAccess\"(args: {\n \"db3Id\": string | number;\n }): Promise<{\n documentId: string;\n /** `reader`, `read-write`, or null when link access is off. */\n linkAccess: string | null;\n linkAccessUpdatedBy?: string;\n linkAccessUpdatedAt?: string;\n }>;\n /** `db3.commitIngest` — POST /db3/{db3Id}/ingest/{sessionId}/commit. Commit a db3 bulk load: its rows apply in the background */\n \"commitIngest\"(args: {\n \"db3Id\": string | number;\n \"sessionId\": string | number;\n body: Record<string, unknown>;\n }): Promise<{\n sessionId: string;\n documentId: string;\n /** uploading | committed | validating | staging | applying | finalizing | registering | complete | failed | aborted */\n state: string;\n createdBy?: string;\n createdAt?: string;\n updatedAt?: string;\n completedAt?: string | null;\n chunks?: number;\n rows?: number;\n bytes?: number;\n /** Decompressed bytes across the stored chunks; null when unknown (a session that completed before timings were recorded has had its chunk descriptors swept) */\n rawBytes?: number | null;\n /** When the current state began */\n stateEnteredAt?: string | null;\n /** Where the session's time went. On Workers the clock advances only across I/O: a synchronous stage (copyMs, applyMs, decodeMs, swapMs, registerMs) reads 0 there, and an I/O stage (readMs, sealMs, manifestMs) is an OBSERVATION INTERVAL ending at that boundary which includes the synchronous work before it, not an isolated cost. State windows and intervals are exact, because every tick begins in a fresh alarm invocation. */\n timings?: {\n /** The state at which this session's timing history begins; uploading for a session opened after timings were recorded */\n since?: string | null;\n ticks?: number;\n /** Stage costs summed over the session's ticks, ms Stage totals are WALL milliseconds, bracketed on Workers when the room settles the clock at both ends of the bracket; the ledger clock still does not move inside a transaction, so an unbracketed tick reads 0. They are not CPU time. */\n totals?: {\n manifestMs?: number;\n readMs?: number;\n decodeMs?: number;\n copyMs?: number;\n applyMs?: number;\n reconcileMs?: number;\n swapMs?: number;\n sealMs?: number;\n registerMs?: number;\n /** Clock at tick end minus clock at tick start, summed; a lower bound on Workers, where a pure-SQL tick reads 0 */\n totalMs?: number;\n /** How many of this session ticks had their stage timers bracketed by a clock settle at both ends. A tick that was not bracketed reads 0 for every synchronous stage, exactly as before. */\n bracketedTicks?: number;\n /** How many applied rows the `apply` counters describe: the denominator of a per-row figure. Below the session's applied rows when some ticks' counters were not recorded. */\n countedRows?: number;\n /** What each stage SQL did, without asking a clock. Keyed by the nine stage names: manifest, read, decode, copy, apply, reconcile, swap, seal, register. */\n counters?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n /** The same figures split by the table each statement named: records, members (string-set index), claims (unique index), log, bookkeeping, other. This is what separates the records fold from string-set maintenance from unique claims inside one stage. */\n byTarget?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n }>;\n }>;\n };\n /** Per-state { ms, ticks, intervalMs }. intervalMs is the start-to-start interval of the ticks that STARTED in this state, which includes their execution, the room's post-tick work and the 1,000 ms re-arm delay. The transition tick's own cost lands in the next state's window. */\n states?: Record<string, {\n ms?: number;\n ticks?: number;\n intervalMs?: number;\n }>;\n /** The longest interval seen, attributed to the state of the tick that started it */\n longestInterval?: {\n intervalMs?: number;\n state?: string;\n } | null;\n };\n /** Rates over the pipeline window (committed through the swap). Null unless the session reached registering AND its timing history begins at uploading — a session whose window was not measured reports no rate rather than an invented one. */\n throughput?: {\n pipelineMs?: number;\n rowsPerSecond?: number;\n storedBytesPerSecond?: number;\n /** Null when the decompressed total is unknown */\n rawBytesPerSecond?: number | null;\n } | null;\n progress?: {\n rowsCopied?: number;\n chunksApplied?: number;\n rowsApplied?: number;\n recordsReconciled?: number;\n oldRowsRemoved?: number;\n };\n copyStartedAt?: string | null;\n discontinuityEpoch?: number | null;\n buildId?: string | null;\n failure?: {\n code?: string;\n reason?: string;\n rows?: {\n model?: string;\n id?: string;\n }[];\n } | null;\n expiresAt?: string;\n /** A record-log (format 3) load: `open` or `commit`; null for format 2 */\n reserveEpoch?: string | null;\n /** A record-log (format 3) load: `merge` or `refresh`; null for format 2 */\n mode?: string | null;\n /** Rows the load refused, each kept with its code */\n refusedRows?: number;\n /** The first 20 refused rows; the full list pages from GET …/documents/{id}/room?refused= */\n refusedSample?: {\n model?: string;\n id?: string;\n code?: string;\n }[];\n /** A record-log (format 3) load once committed with its epoch reserved: the epoch its rows carry, the log number at the reservation (k), and the log numbers of its first and last entries */\n load?: {\n epoch?: number;\n k?: number;\n firstLsn?: number | null;\n lastLsn?: number | null;\n } | null;\n }>;\n /** `db3.create` — POST /db3. Create a db3 */\n \"create\"(args: {\n body: {\n /** At most 255 characters. */\n title: string;\n /** At most ten, each at most 48 characters. */\n tags?: string[];\n /** Caller-defined metadata, at most 4 KB as JSON. */\n metadata?: Record<string, unknown>;\n /** A db3 type of this app: its current revision is installed before the db3 answers, so the first write already meets it. */\n type?: string;\n /** `false` creates the db3 with sync off: no client opens it over a socket. Needs an app owner or admin, or a server function declaring `db3:setSync`. Omitted or `true`, the db3 is synced. */\n sync?: boolean;\n /** Who holds the db3: `app` or `user:<userId>`, a member of the app. Only an app owner or admin, or a server function, names one (a function names `app` only while it declares `db3:transfer`). Omitted, the caller holds it (a server function's caller; the app for a console admin). */\n custodian?: string;\n /** Keep this id instead of minting one: a ULID (26 uppercase Crockford base32 characters, the first 0 to 7) whose timestamp is no later than now plus a day, and that no document of this app holds. An app owner or admin sends one for any custodian (moving a db3 between apps); a member sends one for a db3 they hold, with no `custodian` named (a client creating a db3 offline). A server function never sends one. */\n id?: string;\n };\n }): Promise<{\n id: string;\n title: string | null;\n createdAt: string;\n modifiedAt: string;\n /** The user the db3 was created for, or `sys:<appId>` for a db3 the app created */\n createdBy: string;\n /** Who holds the db3: `user:<userId>` or `app` */\n custodian: string | null;\n sync: boolean;\n /** The db3's type; null while it has none */\n type: string | null;\n tags: string[];\n metadata?: Record<string, unknown>;\n }>;\n /** `db3.createIngest` — POST /db3/{db3Id}/ingest. Open a bulk-load session on a db3 */\n \"createIngest\"(args: {\n \"db3Id\": string | number;\n body: {\n /** A record-log (format 3) document's load: when the load's epoch is reserved — at session create (`open`, the default) or at commit. A write made after the reservation by a client that has seen it wins against the load's rows. */\n reserveEpoch?: \"open\" | \"commit\";\n /** A record-log (format 3) document's load: `merge` (the default) applies the rows; `refresh` also deletes every record of the models the load covers that no row names. */\n mode?: \"merge\" | \"refresh\";\n /** A refresh only: models to empty beside those the chunks carry, including when the session has no chunk. */\n models?: string[];\n };\n }): Promise<{\n sessionId: string;\n documentId: string;\n /** uploading | committed | validating | staging | applying | finalizing | registering | complete | failed | aborted */\n state: string;\n createdBy?: string;\n createdAt?: string;\n updatedAt?: string;\n completedAt?: string | null;\n chunks?: number;\n rows?: number;\n bytes?: number;\n /** Decompressed bytes across the stored chunks; null when unknown (a session that completed before timings were recorded has had its chunk descriptors swept) */\n rawBytes?: number | null;\n /** When the current state began */\n stateEnteredAt?: string | null;\n /** Where the session's time went. On Workers the clock advances only across I/O: a synchronous stage (copyMs, applyMs, decodeMs, swapMs, registerMs) reads 0 there, and an I/O stage (readMs, sealMs, manifestMs) is an OBSERVATION INTERVAL ending at that boundary which includes the synchronous work before it, not an isolated cost. State windows and intervals are exact, because every tick begins in a fresh alarm invocation. */\n timings?: {\n /** The state at which this session's timing history begins; uploading for a session opened after timings were recorded */\n since?: string | null;\n ticks?: number;\n /** Stage costs summed over the session's ticks, ms Stage totals are WALL milliseconds, bracketed on Workers when the room settles the clock at both ends of the bracket; the ledger clock still does not move inside a transaction, so an unbracketed tick reads 0. They are not CPU time. */\n totals?: {\n manifestMs?: number;\n readMs?: number;\n decodeMs?: number;\n copyMs?: number;\n applyMs?: number;\n reconcileMs?: number;\n swapMs?: number;\n sealMs?: number;\n registerMs?: number;\n /** Clock at tick end minus clock at tick start, summed; a lower bound on Workers, where a pure-SQL tick reads 0 */\n totalMs?: number;\n /** How many of this session ticks had their stage timers bracketed by a clock settle at both ends. A tick that was not bracketed reads 0 for every synchronous stage, exactly as before. */\n bracketedTicks?: number;\n /** How many applied rows the `apply` counters describe: the denominator of a per-row figure. Below the session's applied rows when some ticks' counters were not recorded. */\n countedRows?: number;\n /** What each stage SQL did, without asking a clock. Keyed by the nine stage names: manifest, read, decode, copy, apply, reconcile, swap, seal, register. */\n counters?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n /** The same figures split by the table each statement named: records, members (string-set index), claims (unique index), log, bookkeeping, other. This is what separates the records fold from string-set maintenance from unique claims inside one stage. */\n byTarget?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n }>;\n }>;\n };\n /** Per-state { ms, ticks, intervalMs }. intervalMs is the start-to-start interval of the ticks that STARTED in this state, which includes their execution, the room's post-tick work and the 1,000 ms re-arm delay. The transition tick's own cost lands in the next state's window. */\n states?: Record<string, {\n ms?: number;\n ticks?: number;\n intervalMs?: number;\n }>;\n /** The longest interval seen, attributed to the state of the tick that started it */\n longestInterval?: {\n intervalMs?: number;\n state?: string;\n } | null;\n };\n /** Rates over the pipeline window (committed through the swap). Null unless the session reached registering AND its timing history begins at uploading — a session whose window was not measured reports no rate rather than an invented one. */\n throughput?: {\n pipelineMs?: number;\n rowsPerSecond?: number;\n storedBytesPerSecond?: number;\n /** Null when the decompressed total is unknown */\n rawBytesPerSecond?: number | null;\n } | null;\n progress?: {\n rowsCopied?: number;\n chunksApplied?: number;\n rowsApplied?: number;\n recordsReconciled?: number;\n oldRowsRemoved?: number;\n };\n copyStartedAt?: string | null;\n discontinuityEpoch?: number | null;\n buildId?: string | null;\n failure?: {\n code?: string;\n reason?: string;\n rows?: {\n model?: string;\n id?: string;\n }[];\n } | null;\n expiresAt?: string;\n /** A record-log (format 3) load: `open` or `commit`; null for format 2 */\n reserveEpoch?: string | null;\n /** A record-log (format 3) load: `merge` or `refresh`; null for format 2 */\n mode?: string | null;\n /** Rows the load refused, each kept with its code */\n refusedRows?: number;\n /** The first 20 refused rows; the full list pages from GET …/documents/{id}/room?refused= */\n refusedSample?: {\n model?: string;\n id?: string;\n code?: string;\n }[];\n /** A record-log (format 3) load once committed with its epoch reserved: the epoch its rows carry, the log number at the reservation (k), and the log numbers of its first and last entries */\n load?: {\n epoch?: number;\n k?: number;\n firstLsn?: number | null;\n lastLsn?: number | null;\n } | null;\n }>;\n /** `db3.delete` — DELETE /db3/{db3Id}. Delete a db3 */\n \"delete\"(args: {\n \"db3Id\": string | number;\n }): Promise<{\n success: boolean;\n message?: string;\n }>;\n /** `db3.denyAccessRequest` — POST /db3/{db3Id}/access-requests/{requestId}/deny. Deny a db3 access request */\n \"denyAccessRequest\"(args: {\n \"db3Id\": string | number;\n \"requestId\": string | number;\n body?: {\n /** An https URL included in the denial notification; a non-https value is refused. */\n documentUrl?: string;\n };\n }): Promise<{\n success: boolean;\n message?: string;\n request: {\n requestId: string;\n documentId: string;\n requesterId: string;\n status: string;\n requestedPermission?: string;\n message?: string;\n createdAt?: string;\n resolvedBy?: string;\n resolvedAt?: string;\n grantedPermission?: string;\n };\n }>;\n /** `db3.exportChain` — GET /db3/{db3Id}/export/chain. Export a db3's chain: its current segment, signed for download */\n \"exportChain\"(args: {\n \"db3Id\": string | number;\n }): Promise<{\n ok: boolean;\n appId?: string;\n documentId?: string;\n documentFormat?: number;\n /** A record-log document: the log position the current segment exports the rows at */\n lsn?: number;\n /** A record-log document: the log position the segment's corrections were read at */\n completedLsn?: number | null;\n /** A record-log document: its current segment, signed for download */\n segment?: {\n segmentId?: string;\n rows?: number;\n chunks?: number;\n corrections?: number;\n completedAt?: number | null;\n /** Null when the deployment cannot sign artifact downloads */\n download?: {\n /** The signed artifact path */\n path?: string;\n /** Epoch milliseconds */\n expiresAt?: number;\n } | null;\n basedOn?: {\n segmentId?: string;\n lsn?: number;\n } | null;\n reused?: number;\n written?: number;\n rowsRead?: number;\n };\n }>;\n /** `db3.get` — GET /db3/{db3Id}. Get a db3 */\n \"get\"(args: {\n \"db3Id\": string | number;\n }): Promise<{\n id: string;\n title: string | null;\n createdAt: string;\n modifiedAt: string;\n /** The user the db3 was created for, or `sys:<appId>` for a db3 the app created */\n createdBy: string;\n /** Who holds the db3: `user:<userId>` or `app` */\n custodian: string | null;\n sync: boolean;\n /** The db3's type; null while it has none */\n type: string | null;\n tags: string[];\n /** The caller's level; absent for the app-admin arm */\n permission?: string;\n /** How the caller holds it: `owner`, `grant` (a direct grant), `group`, `link`, `app` (the db3's app access), or `resource` (a member of the resource that holds the db3, such as an agent session) */\n accessSource?: string;\n grantedAt?: string;\n }>;\n /** `db3.getAppAccess` — GET /db3/{db3Id}/app-access. Read a db3's app access */\n \"getAppAccess\"(args: {\n \"db3Id\": string | number;\n }): Promise<{\n id: string;\n /** The level every user of the app holds on the db3, or null when it is not granted to them */\n level: \"reader\" | \"read-write\" | null;\n }>;\n /** `db3.getIngest` — GET /db3/{db3Id}/ingest/{sessionId}. Get one db3 bulk-load session */\n \"getIngest\"(args: {\n \"db3Id\": string | number;\n \"sessionId\": string | number;\n }): Promise<{\n sessionId: string;\n documentId: string;\n /** uploading | committed | validating | staging | applying | finalizing | registering | complete | failed | aborted */\n state: string;\n createdBy?: string;\n createdAt?: string;\n updatedAt?: string;\n completedAt?: string | null;\n chunks?: number;\n rows?: number;\n bytes?: number;\n /** Decompressed bytes across the stored chunks; null when unknown (a session that completed before timings were recorded has had its chunk descriptors swept) */\n rawBytes?: number | null;\n /** When the current state began */\n stateEnteredAt?: string | null;\n /** Where the session's time went. On Workers the clock advances only across I/O: a synchronous stage (copyMs, applyMs, decodeMs, swapMs, registerMs) reads 0 there, and an I/O stage (readMs, sealMs, manifestMs) is an OBSERVATION INTERVAL ending at that boundary which includes the synchronous work before it, not an isolated cost. State windows and intervals are exact, because every tick begins in a fresh alarm invocation. */\n timings?: {\n /** The state at which this session's timing history begins; uploading for a session opened after timings were recorded */\n since?: string | null;\n ticks?: number;\n /** Stage costs summed over the session's ticks, ms Stage totals are WALL milliseconds, bracketed on Workers when the room settles the clock at both ends of the bracket; the ledger clock still does not move inside a transaction, so an unbracketed tick reads 0. They are not CPU time. */\n totals?: {\n manifestMs?: number;\n readMs?: number;\n decodeMs?: number;\n copyMs?: number;\n applyMs?: number;\n reconcileMs?: number;\n swapMs?: number;\n sealMs?: number;\n registerMs?: number;\n /** Clock at tick end minus clock at tick start, summed; a lower bound on Workers, where a pure-SQL tick reads 0 */\n totalMs?: number;\n /** How many of this session ticks had their stage timers bracketed by a clock settle at both ends. A tick that was not bracketed reads 0 for every synchronous stage, exactly as before. */\n bracketedTicks?: number;\n /** How many applied rows the `apply` counters describe: the denominator of a per-row figure. Below the session's applied rows when some ticks' counters were not recorded. */\n countedRows?: number;\n /** What each stage SQL did, without asking a clock. Keyed by the nine stage names: manifest, read, decode, copy, apply, reconcile, swap, seal, register. */\n counters?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n /** The same figures split by the table each statement named: records, members (string-set index), claims (unique index), log, bookkeeping, other. This is what separates the records fold from string-set maintenance from unique claims inside one stage. */\n byTarget?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n }>;\n }>;\n };\n /** Per-state { ms, ticks, intervalMs }. intervalMs is the start-to-start interval of the ticks that STARTED in this state, which includes their execution, the room's post-tick work and the 1,000 ms re-arm delay. The transition tick's own cost lands in the next state's window. */\n states?: Record<string, {\n ms?: number;\n ticks?: number;\n intervalMs?: number;\n }>;\n /** The longest interval seen, attributed to the state of the tick that started it */\n longestInterval?: {\n intervalMs?: number;\n state?: string;\n } | null;\n };\n /** Rates over the pipeline window (committed through the swap). Null unless the session reached registering AND its timing history begins at uploading — a session whose window was not measured reports no rate rather than an invented one. */\n throughput?: {\n pipelineMs?: number;\n rowsPerSecond?: number;\n storedBytesPerSecond?: number;\n /** Null when the decompressed total is unknown */\n rawBytesPerSecond?: number | null;\n } | null;\n progress?: {\n rowsCopied?: number;\n chunksApplied?: number;\n rowsApplied?: number;\n recordsReconciled?: number;\n oldRowsRemoved?: number;\n };\n copyStartedAt?: string | null;\n discontinuityEpoch?: number | null;\n buildId?: string | null;\n failure?: {\n code?: string;\n reason?: string;\n rows?: {\n model?: string;\n id?: string;\n }[];\n } | null;\n expiresAt?: string;\n /** A record-log (format 3) load: `open` or `commit`; null for format 2 */\n reserveEpoch?: string | null;\n /** A record-log (format 3) load: `merge` or `refresh`; null for format 2 */\n mode?: string | null;\n /** Rows the load refused, each kept with its code */\n refusedRows?: number;\n /** The first 20 refused rows; the full list pages from GET …/documents/{id}/room?refused= */\n refusedSample?: {\n model?: string;\n id?: string;\n code?: string;\n }[];\n /** A record-log (format 3) load once committed with its epoch reserved: the epoch its rows carry, the log number at the reservation (k), and the log numbers of its first and last entries */\n load?: {\n epoch?: number;\n k?: number;\n firstLsn?: number | null;\n lastLsn?: number | null;\n } | null;\n }>;\n /** `db3.getLinkAccess` — GET /db3/{db3Id}/link-access. Get the db3's \"anyone with the link\" access level */\n \"getLinkAccess\"(args: {\n \"db3Id\": string | number;\n }): Promise<{\n documentId: string;\n /** `reader`, `read-write`, or null when link access is off. */\n linkAccess: string | null;\n linkAccessUpdatedBy?: string;\n linkAccessUpdatedAt?: string;\n }>;\n /** `db3.getOrCreateWithAlias` — POST /db3/get-or-create-with-alias. Get the db3 bound to an alias, creating it if absent */\n \"getOrCreateWithAlias\"(args: {\n body: {\n /** The alias to bind. `scope` must be `user` — app-scoped aliases were removed (#1168) — and `userId` defaults to the caller, which only an app admin may override. */\n alias: {\n scope: \"user\";\n aliasKey: string;\n userId?: string;\n };\n title?: string;\n /** Applied only when the alias is created here. */\n tags?: string[];\n /** Not read by the handler; use `alias.scope`. Sending it is refused with 400 `VALIDATION_FAILED` (#3757). */\n scope?: string;\n /** Not read by the handler; use `alias.aliasKey`. Sending it is refused with 400 `VALIDATION_FAILED` (#3757). */\n aliasKey?: string;\n /** Not read by the handler. Sending it is refused with 400 `VALIDATION_FAILED` (#3757). */\n name?: string;\n /** Caller-defined metadata blob applied only when the alias is created here (#3757). */\n metadata?: Record<string, unknown>;\n /** A db3 type of this app. Creating, its current revision is installed before the db3 answers; on an alias that already names a db3, a db3 of another type (or of none) is refused `DB3_TYPE_MISMATCH`. */\n type?: string;\n /** The alias user's level on a db3 this call creates (default `owner`). `reader` or `read-write` writes no owner row and one row for the alias user at that level, so a `reader` never holds write access; it needs an app owner or admin, a console admin, or a function declaring `db3:setOwnerRow`. Ignored when the alias already names a db3. */\n permission?: \"owner\" | \"read-write\" | \"reader\";\n };\n }): Promise<{\n id: string;\n alias: {\n scope: \"app\" | \"user\";\n aliasKey: string;\n documentId: string;\n userId?: string | null;\n createdAt?: string;\n updatedAt?: string;\n };\n created: boolean;\n }>;\n /** `db3.getPermissions` — GET /db3/{db3Id}/permissions. List a db3's user permissions */\n \"getPermissions\"(args: {\n \"db3Id\": string | number;\n }): Promise<{\n userId: string;\n email?: string;\n name?: string;\n avatarUrl?: string;\n permission: string;\n grantedAt?: string;\n }[]>;\n /** `db3.getSchema` — GET /db3/{db3Id}/schema. Introspect a db3's model schema */\n \"getSchema\"(args: {\n \"db3Id\": string | number;\n }): Promise<{\n ok: boolean;\n documentId?: string;\n appId?: string;\n /** Discovered model metadata, keyed by model name. */\n schema?: Record<string, unknown>;\n modelNames?: string[];\n modelCount?: number;\n /** Every model the authoritative table holds a row of, on a large document; `[]` otherwise. Not the same list as `modelNames`, which is what the document DECLARES (#3433). */\n tableModels?: string[];\n /** 3 for a record-log document, whose writes and bulk loads take models and fields it does not declare; absent for formats 1 and 2. */\n documentFormat?: number;\n }>;\n /** `db3.getSnapshot` — GET /db3/{db3Id}/snapshots/{buildId}. Get one of a db3's segment exports */\n \"getSnapshot\"(args: {\n \"db3Id\": string | number;\n \"buildId\": string | number;\n }): Promise<{\n ok: boolean;\n segmentId: string;\n state: \"exporting\" | \"complete\" | \"failed\" | \"superseded\";\n /** The log position the segment exports the rows at */\n lsn: number;\n /** The log position the corrections were read at, once they were */\n completedLsn: number | null;\n /** The epochs in force when the export began */\n epochs: {\n current?: number;\n next?: number;\n high?: number;\n floor?: number;\n };\n rows: number;\n /** How many chunks the segment holds */\n chunks: number;\n /** Rows in the corrections chunk; null until the corrections are read */\n corrections: number | null;\n bytes: number;\n /** Epoch milliseconds */\n startedAt: number;\n /** Epoch milliseconds */\n completedAt: number | null;\n failure: {\n code?: string;\n reason?: string;\n } | null;\n /** The segment this one reuses chunks from; null for a full export */\n basedOn: {\n segmentId?: string;\n lsn?: number;\n } | null;\n /** What started the export; null on a segment recorded before triggers were */\n trigger: \"daily\" | \"explicit\" | \"change\" | \"demand\" | \"sync-on\" | null;\n /** Chunks reused from `basedOn` */\n reused: number;\n /** Chunks written */\n written: number;\n /** Rows read out of the table */\n rowsRead: number;\n } | {\n buildId: string;\n epoch: number;\n state: \"building\" | \"verifying\" | \"complete\" | \"failed\" | \"abandoned\";\n source: \"builder\" | \"import\" | \"ingest\";\n manifestVersion: number;\n startedAt: number;\n completedAt: number | null;\n rows: number;\n bytes: number;\n /** How many chunks the build holds */\n chunks: number;\n /** The build this one reused chunks from; null when it walked the whole document */\n baseBuildId: string | null;\n /** How many of those chunks came from that build */\n chunksReused: number;\n /** Rows read out of the table while building */\n rowsWalked: number;\n /** The bulk-load session this base was built for; null on every other build */\n ingestSessionId: string | null;\n /** The checks run before the build was registered */\n verification: {\n state?: \"pending\" | \"passed\" | \"failed\";\n checkedAt?: number;\n chunksChecked?: number;\n chunksReused?: number;\n mode?: \"build\" | \"install\";\n code?: string;\n reason?: string;\n } | null;\n failure: {\n code?: string;\n reason?: string;\n at?: number;\n chunk?: {\n model?: string;\n ordinal?: number;\n };\n } | null;\n /** Where the build's time went, summed over its ticks (ms) */\n timings: {\n ticks?: number;\n totals?: {\n readMs?: number;\n encodeMs?: number;\n compressMs?: number;\n hashMs?: number;\n uploadMs?: number;\n verifyReadMs?: number;\n verifyDigestMs?: number;\n verifyCoverageMs?: number;\n manifestMs?: number;\n };\n };\n }>;\n /** `db3.getStats` — GET /db3/{db3Id}/stats. Get a db3's stats */\n \"getStats\"(args: {\n \"db3Id\": string | number;\n }): Promise<{\n documentId: string;\n recordCount: number;\n modelCount: number;\n blobCount: number;\n /** Size of the document's data in bytes, measured as sizeBasis says. For a large document, the stored JSON of every record; sealing an epoch or building a snapshot does not change it. */\n sizeBytes: number;\n /** True when sizeBytes is an estimate (an ordinary document); false for a large document's record bytes. */\n sizeBytesApproximate: boolean;\n /** What sizeBytes measures: `records` (a large document's stored record JSON) or `document` (an ordinary document's approximate size). */\n sizeBasis: \"records\" | \"document\";\n lastModifiedAt?: string | null;\n }>;\n /** `db3.getSync` — GET /db3/{db3Id}/sync. Read whether a db3 is synced */\n \"getSync\"(args: {\n \"db3Id\": string | number;\n }): Promise<{\n id: string;\n /** Whether clients open the db3 over a socket (`true`, the default) or only its records routes reach it */\n sync: boolean;\n }>;\n /** `db3.getType` — GET /db3/{db3Id}/type. Read a db3's type */\n \"getType\"(args: {\n \"db3Id\": string | number;\n }): Promise<{\n id: string;\n type: string | null;\n revision: {\n /** The type row's `modifiedAt`, in epoch milliseconds: a later push is a greater generation */\n generation: number;\n /** The SHA-256 of the type's declarations and hook rules */\n hash: string;\n } | null;\n installed: {\n name?: string;\n revision?: {\n /** The type row's `modifiedAt`, in epoch milliseconds: a later push is a greater generation */\n generation: number;\n /** The SHA-256 of the type's declarations and hook rules */\n hash: string;\n };\n installedAt?: number;\n } | null;\n }>;\n /** `db3.grantGroupPermission` — POST /db3/{db3Id}/group-permissions. Grant a group permission on a db3 */\n \"grantGroupPermission\"(args: {\n \"db3Id\": string | number;\n body: {\n /** Deprecated (removal: #4718): groups are named by `groupId` alone. Given, the group is looked up by type first; the `_`-prefixed platform types are refused here. @deprecated */\n groupType?: string;\n groupId: string;\n permission: \"read-write\" | \"reader\";\n /** Not read by the handler; use `permission`. */\n role?: string;\n };\n }): Promise<{\n documentId: string;\n groupType: string;\n groupId: string;\n permission: string;\n grantedAt?: string;\n grantedBy?: string;\n }>;\n \"indexes\": {\n /** `db3.indexes.drop` — DELETE /db3/{db3Id}/indexes/{name}. Drop a db3's registered index */\n \"drop\"(args: {\n \"db3Id\": string | number;\n \"name\": string | number;\n }): Promise<{\n ok: boolean;\n name: string;\n }>;\n /** `db3.indexes.list` — GET /db3/{db3Id}/indexes. List a db3's indexes */\n \"list\"(args: {\n \"db3Id\": string | number;\n }): Promise<{\n indexes: {\n /** The index's name: `idx_records_<model>_<field>` for a field's shared index, `idx_uc_<model>_<constraint>` for a declared compound constraint's, `idx_named_<model>_<name>` for one registered with a name; a `_<n>` suffix when two models' names would collide. */\n name: string;\n model: string;\n /** The fields, in index order. */\n fields: string[];\n /** Whether a write that would give two live records the same key is refused (a null or absent value is never part of a key). */\n unique: boolean;\n /** Why the index exists: a declaration that marks the fields `indexed` or `unique` (or a compound constraint), and a registration through these routes. The index is dropped when the last origin goes. */\n origins: {\n kind: \"declaration\" | \"named\";\n unique: boolean;\n }[];\n }[];\n }>;\n /** `db3.indexes.register` — POST /db3/{db3Id}/indexes. Register an index on a db3 */\n \"register\"(args: {\n \"db3Id\": string | number;\n body: {\n model: string;\n field?: string;\n fields?: string[];\n unique?: boolean;\n name?: string;\n };\n }): Promise<{\n index: {\n /** The index's name: `idx_records_<model>_<field>` for a field's shared index, `idx_uc_<model>_<constraint>` for a declared compound constraint's, `idx_named_<model>_<name>` for one registered with a name; a `_<n>` suffix when two models' names would collide. */\n name: string;\n model: string;\n /** The fields, in index order. */\n fields: string[];\n /** Whether a write that would give two live records the same key is refused (a null or absent value is never part of a key). */\n unique: boolean;\n /** Why the index exists: a declaration that marks the fields `indexed` or `unique` (or a compound constraint), and a registration through these routes. The index is dropped when the last origin goes. */\n origins: {\n kind: \"declaration\" | \"named\";\n unique: boolean;\n }[];\n };\n }>;\n };\n /** `db3.listAccessRequests` — GET /db3/{db3Id}/access-requests. List access requests for a db3 */\n \"listAccessRequests\"(args: {\n \"db3Id\": string | number;\n }): Promise<{\n requestId: string;\n documentId: string;\n requesterId: string;\n status: string;\n requestedPermission?: string;\n message?: string;\n createdAt?: string;\n resolvedBy?: string;\n resolvedAt?: string;\n grantedPermission?: string;\n }[]>;\n /** `db3.listGroupPermissions` — GET /db3/{db3Id}/group-permissions. List a db3's group permissions */\n \"listGroupPermissions\"(args: {\n \"db3Id\": string | number;\n }): Promise<{\n documentId: string;\n groupType: string;\n groupId: string;\n permission: string;\n grantedAt?: string;\n grantedBy?: string;\n }[]>;\n /** `db3.listIngests` — GET /db3/{db3Id}/ingest. List a db3's bulk-load sessions, newest first */\n \"listIngests\"(args: {\n \"db3Id\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n items: {\n sessionId: string;\n documentId: string;\n /** uploading | committed | validating | staging | applying | finalizing | registering | complete | failed | aborted */\n state: string;\n createdBy?: string;\n createdAt?: string;\n updatedAt?: string;\n completedAt?: string | null;\n chunks?: number;\n rows?: number;\n bytes?: number;\n /** Decompressed bytes across the stored chunks; null when unknown (a session that completed before timings were recorded has had its chunk descriptors swept) */\n rawBytes?: number | null;\n /** When the current state began */\n stateEnteredAt?: string | null;\n /** Where the session's time went. On Workers the clock advances only across I/O: a synchronous stage (copyMs, applyMs, decodeMs, swapMs, registerMs) reads 0 there, and an I/O stage (readMs, sealMs, manifestMs) is an OBSERVATION INTERVAL ending at that boundary which includes the synchronous work before it, not an isolated cost. State windows and intervals are exact, because every tick begins in a fresh alarm invocation. */\n timings?: {\n /** The state at which this session's timing history begins; uploading for a session opened after timings were recorded */\n since?: string | null;\n ticks?: number;\n /** Stage costs summed over the session's ticks, ms Stage totals are WALL milliseconds, bracketed on Workers when the room settles the clock at both ends of the bracket; the ledger clock still does not move inside a transaction, so an unbracketed tick reads 0. They are not CPU time. */\n totals?: {\n manifestMs?: number;\n readMs?: number;\n decodeMs?: number;\n copyMs?: number;\n applyMs?: number;\n reconcileMs?: number;\n swapMs?: number;\n sealMs?: number;\n registerMs?: number;\n /** Clock at tick end minus clock at tick start, summed; a lower bound on Workers, where a pure-SQL tick reads 0 */\n totalMs?: number;\n /** How many of this session ticks had their stage timers bracketed by a clock settle at both ends. A tick that was not bracketed reads 0 for every synchronous stage, exactly as before. */\n bracketedTicks?: number;\n /** How many applied rows the `apply` counters describe: the denominator of a per-row figure. Below the session's applied rows when some ticks' counters were not recorded. */\n countedRows?: number;\n /** What each stage SQL did, without asking a clock. Keyed by the nine stage names: manifest, read, decode, copy, apply, reconcile, swap, seal, register. */\n counters?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n /** The same figures split by the table each statement named: records, members (string-set index), claims (unique index), log, bookkeeping, other. This is what separates the records fold from string-set maintenance from unique claims inside one stage. */\n byTarget?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n }>;\n }>;\n };\n /** Per-state { ms, ticks, intervalMs }. intervalMs is the start-to-start interval of the ticks that STARTED in this state, which includes their execution, the room's post-tick work and the 1,000 ms re-arm delay. The transition tick's own cost lands in the next state's window. */\n states?: Record<string, {\n ms?: number;\n ticks?: number;\n intervalMs?: number;\n }>;\n /** The longest interval seen, attributed to the state of the tick that started it */\n longestInterval?: {\n intervalMs?: number;\n state?: string;\n } | null;\n };\n /** Rates over the pipeline window (committed through the swap). Null unless the session reached registering AND its timing history begins at uploading — a session whose window was not measured reports no rate rather than an invented one. */\n throughput?: {\n pipelineMs?: number;\n rowsPerSecond?: number;\n storedBytesPerSecond?: number;\n /** Null when the decompressed total is unknown */\n rawBytesPerSecond?: number | null;\n } | null;\n progress?: {\n rowsCopied?: number;\n chunksApplied?: number;\n rowsApplied?: number;\n recordsReconciled?: number;\n oldRowsRemoved?: number;\n };\n copyStartedAt?: string | null;\n discontinuityEpoch?: number | null;\n buildId?: string | null;\n failure?: {\n code?: string;\n reason?: string;\n rows?: {\n model?: string;\n id?: string;\n }[];\n } | null;\n expiresAt?: string;\n /** A record-log (format 3) load: `open` or `commit`; null for format 2 */\n reserveEpoch?: string | null;\n /** A record-log (format 3) load: `merge` or `refresh`; null for format 2 */\n mode?: string | null;\n /** Rows the load refused, each kept with its code */\n refusedRows?: number;\n /** The first 20 refused rows; the full list pages from GET …/documents/{id}/room?refused= */\n refusedSample?: {\n model?: string;\n id?: string;\n code?: string;\n }[];\n /** A record-log (format 3) load once committed with its epoch reserved: the epoch its rows carry, the log number at the reservation (k), and the log numbers of its first and last entries */\n load?: {\n epoch?: number;\n k?: number;\n firstLsn?: number | null;\n lastLsn?: number | null;\n } | null;\n }[];\n hasMore: boolean;\n nextCursor?: string;\n }>;\n /** `db3.listPendingInvitations` — GET /db3/{db3Id}/pending-invitations. List a db3's pending (deferred) invitations */\n \"listPendingInvitations\"(args: {\n \"db3Id\": string | number;\n }): Promise<{\n items: {\n invitationId: string;\n email: string;\n permission: string;\n invitedAt?: string;\n invitedBy?: string;\n expiresAt?: string;\n accepted?: boolean;\n /** When the deferred grant was made. */\n createdAt?: string;\n /** The user id that made the deferred grant. */\n grantedBy?: string;\n }[];\n }>;\n /** `db3.listSnapshots` — GET /db3/{db3Id}/snapshots. List a db3's segment exports, newest first */\n \"listSnapshots\"(args: {\n \"db3Id\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n ok?: boolean;\n items: Array<{\n segmentId: string;\n state: \"exporting\" | \"complete\" | \"failed\" | \"superseded\";\n /** The log position the segment exports the rows at */\n lsn: number;\n /** The log position the corrections were read at, once they were */\n completedLsn: number | null;\n /** The epochs in force when the export began */\n epochs: {\n current?: number;\n next?: number;\n high?: number;\n floor?: number;\n };\n rows: number;\n /** How many chunks the segment holds */\n chunks: number;\n /** Rows in the corrections chunk; null until the corrections are read */\n corrections: number | null;\n bytes: number;\n /** Epoch milliseconds */\n startedAt: number;\n /** Epoch milliseconds */\n completedAt: number | null;\n failure: {\n code?: string;\n reason?: string;\n } | null;\n /** The segment this one reuses chunks from; null for a full export */\n basedOn: {\n segmentId?: string;\n lsn?: number;\n } | null;\n /** What started the export; null on a segment recorded before triggers were */\n trigger: \"daily\" | \"explicit\" | \"change\" | \"demand\" | \"sync-on\" | null;\n /** Chunks reused from `basedOn` */\n reused: number;\n /** Chunks written */\n written: number;\n /** Rows read out of the table */\n rowsRead: number;\n } | {\n buildId: string;\n epoch: number;\n state: \"building\" | \"verifying\" | \"complete\" | \"failed\" | \"abandoned\";\n source: \"builder\" | \"import\" | \"ingest\";\n manifestVersion: number;\n startedAt: number;\n completedAt: number | null;\n rows: number;\n bytes: number;\n /** How many chunks the build holds */\n chunks: number;\n /** The build this one reused chunks from; null when it walked the whole document */\n baseBuildId: string | null;\n /** How many of those chunks came from that build */\n chunksReused: number;\n /** Rows read out of the table while building */\n rowsWalked: number;\n /** The bulk-load session this base was built for; null on every other build */\n ingestSessionId: string | null;\n /** The checks run before the build was registered */\n verification: {\n state?: \"pending\" | \"passed\" | \"failed\";\n checkedAt?: number;\n chunksChecked?: number;\n chunksReused?: number;\n mode?: \"build\" | \"install\";\n code?: string;\n reason?: string;\n } | null;\n failure: {\n code?: string;\n reason?: string;\n at?: number;\n chunk?: {\n model?: string;\n ordinal?: number;\n };\n } | null;\n /** Where the build's time went, summed over its ticks (ms) */\n timings: {\n ticks?: number;\n totals?: {\n readMs?: number;\n encodeMs?: number;\n compressMs?: number;\n hashMs?: number;\n uploadMs?: number;\n verifyReadMs?: number;\n verifyDigestMs?: number;\n verifyCoverageMs?: number;\n manifestMs?: number;\n };\n };\n }>;\n hasMore: boolean;\n nextCursor?: string;\n }>;\n \"records\": {\n /** `db3.records.aggregate` — POST /db3/{db3Id}/records/{model}/aggregate. Aggregate records in a db3 model */\n \"aggregate\"(args: {\n \"db3Id\": string | number;\n \"model\": string | number;\n \"userId\"?: string | number;\n body: {\n options: {\n /** One or more aggregate operations. `count` takes no field; `sum`/`avg`/`min`/`max` each require one. */\n operations: {\n type: \"count\" | \"sum\" | \"avg\" | \"min\" | \"max\";\n field?: string;\n }[];\n /** Levels to group by: field names, period levels `{ field, period }` and, on a db3, membership levels `{ field, contains }`. On a db3 a field name naming a StringSet field is a facet. A format-1 document refuses StringSet facet and membership grouping with a 400. */\n groupBy?: Array<string | {\n field: string;\n period: \"month\" | \"quarter\" | \"year\";\n } | {\n field: string;\n contains: string;\n }>;\n /** Query filter restricting the aggregated set. */\n filter?: Record<string, unknown>;\n /** The groups' order (a db3 only; a format-1 document refuses it): `field` is `count`, an operation key (`sum_amount`), a group key (`has_tags_x`, `due_month`) or a field name. */\n sort?: {\n field: string;\n direction: 1 | -1;\n };\n /** The most groups answered (a db3 only; a format-1 document refuses it). Above 10,000 is a 400, never clamped. */\n limit?: number;\n };\n };\n }): Promise<{\n /** One row per group, in the order SQL returned them: `{ group, count, <op>_<field> }`, every requested operation present under its key (`count`, `<op>_<field>`) even when it is the only one. A grouped aggregate that matches no record is `[]`; an ungrouped one is exactly one row with an empty `group`. Two `groupBy` levels that would take the same key in `group` are refused with a 400, `Ambiguous aggregation group keys: '<key>' names more than one groupBy level`. */\n result: {\n /** One entry per `groupBy` level, keyed by the field name (or `has_<field>_<contains>` for a StringSet membership level, or `<field>_<period>` for a period level), holding the value as stored: `null` for a missing field, numbers as numbers. Empty for an ungrouped aggregate. */\n group: Record<string, unknown>;\n /** The group's record count, present when `count` is requested. */\n count?: number;\n [key: string]: unknown;\n }[];\n }>;\n /** `db3.records.bulk` — POST /db3/{db3Id}/records/bulk. Apply an atomic multi-model record blob to a db3 (create/patch/delete/upsert) */\n \"bulk\"(args: {\n \"db3Id\": string | number;\n \"userId\"?: string | number;\n body: {\n /** Ordered ops, applied in one transaction (max 500, all-or-nothing). */\n operations: Array<{\n model: string;\n action: \"create\";\n /** A 26-char uppercase Crockford ULID, minted by the server when omitted. */\n id?: string;\n /** Record fields. Required, and must have at least one field. */\n data: Record<string, unknown>;\n /** Field-equality precondition; a mismatch fails the whole blob with 409. */\n precondition?: Record<string, unknown>;\n /** Optional 26-char uppercase Crockford ULID naming this operation. On a record-log document a retry carrying an id the document already holds is answered from its first outcome and not applied again. */\n requestId?: string;\n /** A guard in the query filter grammar on the record the op addresses (an upsert's holder). A failing one is 409 `DB3_CONDITION_NOT_MET`; a missing record meets no condition. */\n condition?: Record<string, unknown>;\n } | {\n model: string;\n action: \"patch\";\n /** The id of an existing record. */\n id: string;\n /** Record fields. Required, and must have at least one field. */\n data: Record<string, unknown>;\n /** Field-equality precondition; a mismatch fails the whole blob with 409. */\n precondition?: Record<string, unknown>;\n /** Optional 26-char uppercase Crockford ULID naming this operation. On a record-log document a retry carrying an id the document already holds is answered from its first outcome and not applied again. */\n requestId?: string;\n /** A guard in the query filter grammar on the record the op addresses (an upsert's holder). A failing one is 409 `DB3_CONDITION_NOT_MET`; a missing record meets no condition. */\n condition?: Record<string, unknown>;\n } | {\n model: string;\n action: \"delete\";\n /** The id of an existing record. */\n id: string;\n /** Field-equality precondition; a mismatch fails the whole blob with 409. */\n precondition?: Record<string, unknown>;\n /** Optional 26-char uppercase Crockford ULID naming this operation. On a record-log document a retry carrying an id the document already holds is answered from its first outcome and not applied again. */\n requestId?: string;\n /** A guard in the query filter grammar on the record the op addresses (an upsert's holder). A failing one is 409 `DB3_CONDITION_NOT_MET`; a missing record meets no condition. */\n condition?: Record<string, unknown>;\n } | {\n model: string;\n action: \"upsert\";\n /** Name of a unique constraint the model declares (a compound `unique_constraints` name, or `<model>_<field>_unique` for a `unique` field). Must not include `id`. */\n constraint: string;\n /** Optional 26-char uppercase Crockford ULID, used only when the op creates the record; the server mints one when absent. */\n id?: string;\n /** Record fields, carrying every field of the constraint and no `id`. Merged into the record holding that key, or used to create one. */\n data: Record<string, unknown>;\n /** Field-equality precondition on the resolved record; a mismatch or no record fails the whole blob with 409. */\n precondition?: Record<string, unknown>;\n /** Optional 26-char uppercase Crockford ULID naming this operation. On a record-log document a retry carrying an id the document already holds is answered from its first outcome and not applied again. */\n requestId?: string;\n /** A guard in the query filter grammar on the record the op addresses (an upsert's holder). A failing one is 409 `DB3_CONDITION_NOT_MET`; a missing record meets no condition. */\n condition?: Record<string, unknown>;\n } | {\n model: string;\n action: \"increment\";\n /** The id of an existing record. */\n id: string;\n /** Each field's delta, a finite number. A missing or non-numeric field starts at 0; two increments of one field both count. */\n fields: Record<string, number>;\n /** A guard in the query filter grammar on the record, judged before the deltas. A failing one is 409 `DB3_CONDITION_NOT_MET`. */\n condition?: Record<string, unknown>;\n /** Optional 26-char uppercase Crockford ULID naming this operation. A retry carrying an id the db3 already holds is answered from its first outcome and not applied again. */\n requestId?: string;\n }>;\n /** On a db3: `false` applies each op on its own, committing those that pass and answering a result per op; omitted or `true`, all or nothing. */\n atomic?: boolean;\n /** On a db3: an optional 26-char uppercase Crockford ULID naming this whole request. It is echoed in the answer, and a retry carrying it is answered with the first answer byte for byte. */\n requestId?: string;\n };\n }): Promise<{\n applied?: number;\n /** The records the bulk created, each `{ model, id }`, in input order; on a db3 an entry its hook rules wrote into also carries `appliedFields`, the fields written with their values. */\n added?: {\n model: string;\n id: string;\n /** On a db3: every field its hook rules wrote into the record, with the value written; absent when they wrote none. */\n appliedFields?: Record<string, unknown>;\n }[];\n /** The records the bulk patched, each `{ model, id }`, in input order; on a db3 an entry its hook rules wrote into also carries `appliedFields`. */\n updated?: {\n model: string;\n id: string;\n /** On a db3: every field its hook rules wrote into the record, with the value written; absent when they wrote none. */\n appliedFields?: Record<string, unknown>;\n }[];\n deleted?: number;\n /** `false` when the db3 applied each op on its own; the counts and lists name the passing ops. */\n atomic?: boolean;\n /** With `atomic: false`: one result per op, in order. A passing op has `ok: true`, its `kind` and the record `id`; a refused one `ok: false` with its `code`, `status` and `error` (e.g. `DB3_CONDITION_NOT_MET` 409, `DB3_RECORD_NOT_FOUND` 404, `DB3_RECORD_EXISTS` 409). */\n results?: {\n index: number;\n model: string;\n id?: string;\n ok: boolean;\n /** What the op did; `incremented` for a db3 `increment`. */\n kind?: \"added\" | \"updated\" | \"upserted\" | \"deleted\" | \"incremented\";\n created?: boolean;\n removed?: boolean;\n /** For an `incremented` op: each incremented field's new value. */\n values?: Record<string, number>;\n /** For a passing op on a db3: every field its hook rules wrote, with the value written; absent when they wrote none. */\n appliedFields?: Record<string, unknown>;\n code?: string;\n status?: number;\n error?: string;\n /** For an op refused `DB3_TRIGGER_REFUSED`: the refusing trigger's own code. */\n reason?: string;\n requestId?: string;\n }[];\n /** The request's own id, echoed. */\n requestId?: string;\n /** One entry per upsert op, in input order: the op's index, the record id, and whether the op created it. */\n upserted?: {\n index?: number;\n model?: string;\n id?: string;\n created?: boolean;\n /** On a db3: every field its hook rules wrote into the record, with the value written; absent when they wrote none. */\n appliedFields?: Record<string, unknown>;\n }[];\n /** On a db3, only when the blob carried an `increment`: one entry per passing increment op, in input order, with the fields' new values. */\n incremented?: {\n index?: number;\n model?: string;\n id?: string;\n values?: Record<string, number>;\n }[];\n }>;\n /** `db3.records.count` — GET /db3/{db3Id}/records/{model}/count. Count records in a db3 model */\n \"count\"(args: {\n \"db3Id\": string | number;\n \"model\": string | number;\n \"userId\"?: string | number;\n \"filter\"?: Record<string, unknown> | string;\n }): Promise<{\n count: number;\n }>;\n /** `db3.records.delete` — DELETE /db3/{db3Id}/records/{model}/{recordId}. Delete a record from a db3 model */\n \"delete\"(args: {\n \"db3Id\": string | number;\n \"model\": string | number;\n \"recordId\": string | number;\n \"requestId\"?: string | number | boolean;\n \"condition\"?: string | number | boolean;\n \"userId\"?: string | number;\n }): Promise<{\n deleted: boolean;\n }>;\n /** `db3.records.increment` — POST /db3/{db3Id}/records/{model}/{recordId}/increment. Increment numeric fields of a record in a db3 model */\n \"increment\"(args: {\n \"db3Id\": string | number;\n \"model\": string | number;\n \"recordId\": string | number;\n \"userId\"?: string | number;\n body: {\n /** Each field's delta, a finite number; a missing or non-numeric field starts at 0. `id` and reserved names are refused. */\n fields: Record<string, number>;\n options?: {\n /** A guard in the query filter grammar on the record, judged before the deltas; a failing one is 409 `DB3_CONDITION_NOT_MET`. */\n condition?: Record<string, unknown>;\n };\n /** Optional 26-char uppercase Crockford ULID naming this write; a retry carrying it is answered with the first answer. */\n requestId?: string;\n };\n }): Promise<{\n /** The record after the increment. */\n record: Record<string, unknown>;\n /** Each incremented field's new value. */\n values: Record<string, number>;\n }>;\n /** `db3.records.patch` — PATCH /db3/{db3Id}/records/{model}/{recordId}. Merge fields into an existing record in a db3 model */\n \"patch\"(args: {\n \"db3Id\": string | number;\n \"model\": string | number;\n \"recordId\": string | number;\n \"userId\"?: string | number;\n body: {\n /** The fields to merge into the record. */\n data: Record<string, unknown>;\n /** Per-write options forwarded to the document facade. */\n options?: {\n /** On a db3: a guard in the query filter grammar (the `filter` a query takes, e.g. `{ status: \"open\", n: { $lt: 5 } }`). The write applies only when the record is live and matches it; otherwise it is refused 409 `DB3_CONDITION_NOT_MET` and nothing is written. A missing record meets no condition. An invalid one is 400 `DOCUMENT_ENTRY_INVALID`. */\n condition?: Record<string, unknown>;\n /** Save only: apply only when no record has this id; otherwise 409 `CONDITION_NOT_MET`. */\n ifNotExists?: boolean;\n /** Save only: land on the live record holding the same key instead of creating one. On a db3 it names a unique constraint of the model (`<model>_<field>_unique`, a compound constraint's name or a registered unique index's) or a field; elsewhere a field. */\n upsertOn?: string;\n /** Field-equality map the live record must hold; a mismatch or a missing record is 409 `CONDITION_NOT_MET`. */\n precondition?: Record<string, unknown>;\n };\n /** Optional 26-char uppercase Crockford ULID naming this write. On a record-log document a retry carrying an id the document already holds is answered from its first outcome and not applied again. */\n requestId?: string;\n };\n }): Promise<{\n /** The saved record, with the model's own fields. */\n record: Record<string, unknown>;\n /** On a db3: every field its hook rules wrote (timestamps, auto-populated fields, triggers), with the value written, whether or not it equals the value sent; absent when they wrote none. */\n appliedFields?: Record<string, unknown>;\n }>;\n /** `db3.records.query` — GET /db3/{db3Id}/records/{model}. Query records in a db3 model */\n \"query\"(args: {\n \"db3Id\": string | number;\n \"model\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"userId\"?: string | number;\n \"filter\"?: Record<string, unknown> | string;\n \"sort\"?: Record<string, unknown> | string;\n \"include\"?: unknown[] | string;\n }): Promise<{\n items: Record<string, unknown>[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /** `db3.records.save` — POST /db3/{db3Id}/records/{model}. Create or replace a record in a db3 model */\n \"save\"(args: {\n \"db3Id\": string | number;\n \"model\": string | number;\n \"userId\"?: string | number;\n body: {\n /** The record's id, minted by the server when omitted (a ULID). Must not contain the reserved key separator. */\n id?: string;\n /** The record's fields. */\n data: Record<string, unknown>;\n /** Per-write options forwarded to the document facade. */\n options?: {\n /** On a db3: a guard in the query filter grammar (the `filter` a query takes, e.g. `{ status: \"open\", n: { $lt: 5 } }`). The write applies only when the record is live and matches it; otherwise it is refused 409 `DB3_CONDITION_NOT_MET` and nothing is written. A missing record meets no condition. An invalid one is 400 `DOCUMENT_ENTRY_INVALID`. */\n condition?: Record<string, unknown>;\n /** Save only: apply only when no record has this id; otherwise 409 `CONDITION_NOT_MET`. */\n ifNotExists?: boolean;\n /** Save only: land on the live record holding the same key instead of creating one. On a db3 it names a unique constraint of the model (`<model>_<field>_unique`, a compound constraint's name or a registered unique index's) or a field; elsewhere a field. */\n upsertOn?: string;\n /** Field-equality map the live record must hold; a mismatch or a missing record is 409 `CONDITION_NOT_MET`. */\n precondition?: Record<string, unknown>;\n };\n /** Optional 26-char uppercase Crockford ULID naming this write. On a record-log document a retry carrying an id the document already holds is answered from its first outcome and not applied again. */\n requestId?: string;\n };\n }): Promise<{\n /** The saved record, with the model's own fields. */\n record: Record<string, unknown>;\n /** On a db3: every field its hook rules wrote (timestamps, auto-populated fields, triggers), with the value written, whether or not it equals the value sent; absent when they wrote none. */\n appliedFields?: Record<string, unknown>;\n }>;\n };\n /** `db3.removePermissionByEmail` — DELETE /db3/{db3Id}/permissions. Revoke a user's permission on a db3 by email (?email=) */\n \"removePermissionByEmail\"(args: {\n \"db3Id\": string | number;\n \"email\"?: string | number | boolean;\n }): Promise<{\n success: boolean;\n message?: string;\n status?: string;\n email?: string;\n deferredCount?: number;\n }>;\n /** `db3.removePermissionByUserId` — DELETE /db3/{db3Id}/permissions/{userId}. Revoke a user's permission on a db3 by user id */\n \"removePermissionByUserId\"(args: {\n \"db3Id\": string | number;\n \"userId\": string | number;\n }): Promise<{\n success: boolean;\n message?: string;\n }>;\n /** `db3.removeTag` — DELETE /db3/{db3Id}/tags/{tag}. Remove a tag from a db3 */\n \"removeTag\"(args: {\n \"db3Id\": string | number;\n \"tag\": string | number;\n }): Promise<{\n documentId: string;\n tags: string[];\n }>;\n /** `db3.requestAccess` — POST /db3/{db3Id}/access-requests. Request access to a db3 */\n \"requestAccess\"(args: {\n \"db3Id\": string | number;\n body: {\n /** The level being asked for. */\n permission: \"read-write\" | \"reader\";\n /** Note shown to the reviewer. */\n message?: string;\n /** Link included in the reviewer's email. */\n documentUrl?: string;\n /** Where the reviewer lands to act on the request. */\n reviewUrl?: string;\n /** Email the reviewer. */\n sendEmail?: boolean;\n /** Not read by the handler; use `permission`. */\n role?: string;\n };\n }): Promise<{\n success: boolean;\n message?: string;\n request: {\n requestId: string;\n documentId: string;\n requesterId: string;\n status: string;\n requestedPermission?: string;\n message?: string;\n createdAt?: string;\n resolvedBy?: string;\n resolvedAt?: string;\n grantedPermission?: string;\n };\n document?: {\n documentId?: string;\n title?: string | null;\n tags?: string[];\n createdAt?: string;\n lastModified?: string;\n createdBy?: string;\n };\n }>;\n /** `db3.requestSnapshot` — POST /db3/{db3Id}/snapshots. Start a segment export of a db3 now */\n \"requestSnapshot\"(args: {\n \"db3Id\": string | number;\n body: Record<string, unknown>;\n }): Promise<{\n sealed: boolean;\n reason: string;\n coveringBuildId?: string | null;\n }>;\n /** `db3.revokeGroupPermission` — DELETE /db3/{db3Id}/group-permissions/{groupId}. Revoke a group permission on a db3 */\n \"revokeGroupPermission\"(args: {\n \"db3Id\": string | number;\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<{\n success: boolean;\n }>;\n /** `db3.room` — GET /db3/{db3Id}/room. Inspect a db3's room */\n \"room\"(args: {\n \"db3Id\": string | number;\n \"refused\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n ok: boolean;\n appId: string;\n documentId: string;\n documentFormat: number;\n /** With refused: the session's refused rows, oldest first. */\n refused?: {\n sessionId?: string;\n items?: {\n model?: string;\n id?: string;\n code?: string;\n constraint?: string;\n conflicting?: {\n model?: string;\n id?: string;\n };\n }[];\n hasMore?: boolean;\n nextCursor?: string;\n };\n /** The record room's state; null for formats 1 and 2. */\n room: {\n lsn?: number;\n /** current, next, high, floor, rotatedAt, entriesSinceRotation. */\n epochs?: Record<string, unknown>;\n cursorFloor?: number;\n /** count, connected. */\n writers?: Record<string, unknown>;\n subscribers?: number;\n /** entries, writers. */\n held?: Record<string, unknown>;\n /** compact, full: the writers' own acknowledgements of accepted entries since the room last woke, sent without changes (to a writer that declared compact acknowledgements, for an entry the room applied as written) and with them. */\n acks?: Record<string, unknown>;\n /** The bulk load in progress, or null. */\n load?: Record<string, unknown> | null;\n /** The bulk loads the room still keeps, oldest first. */\n loads?: Record<string, unknown>[];\n /** The current segment, as `GET …/snapshots/{segmentId}` describes it, or null. */\n segment?: Record<string, unknown> | null;\n /** The segment export in progress, or null. */\n segmentExport?: Record<string, unknown> | null;\n /** The automatic segments' spacing: lastStartedAt, nextAllowedAt. */\n segmentAuto?: Record<string, unknown>;\n /** The pending change check for an automatic segment (at, reason), or null. */\n segmentCheck?: Record<string, unknown> | null;\n /** Where the last change check that found no segment due counted to, or null. */\n segmentCheckedLsn?: number | null;\n /** The last checkpoint, or null. */\n checkpoint?: Record<string, unknown> | null;\n /** Whether the room admits sockets (the db3's sync). */\n sync?: boolean;\n /** The sync flip holding the room's lease, or null. */\n syncFlip?: Record<string, unknown> | null;\n /** What the hook rules hold: timestamps, autoPopulatedFields, triggers (per model). */\n hooks?: Record<string, unknown>;\n /** The db3's type and the revision it installed, or null. */\n type?: Record<string, unknown> | null;\n /** True when the room has nothing left for its alarm to do: no entry in the window, nothing left to prune and no subscriber. A quiet room holds no alarm; its next write wakes it. */\n quiet?: boolean;\n /** When the room's alarm next runs (the daily checkpoint or the epoch's maximum age), in milliseconds; null while the room is quiet. */\n nextAlarmAt?: number | null;\n /** databaseSize. */\n storage?: Record<string, unknown>;\n } | null;\n }>;\n /** `db3.setAppAccess` — PUT /db3/{db3Id}/app-access. Grant a db3 to every user of the app */\n \"setAppAccess\"(args: {\n \"db3Id\": string | number;\n body: {\n /** `reader` or `read-write` grants the db3 to every user of the app; `null` removes the grant */\n level: \"reader\" | \"read-write\" | null;\n };\n }): Promise<{\n id: string;\n /** The level every user of the app holds on the db3, or null when it is not granted to them */\n level: \"reader\" | \"read-write\" | null;\n changed: boolean;\n }>;\n /** `db3.setLinkAccess` — PUT /db3/{db3Id}/link-access. Set the db3's \"anyone with the link\" access level */\n \"setLinkAccess\"(args: {\n \"db3Id\": string | number;\n body: {\n level: \"reader\" | \"read-write\";\n };\n }): Promise<{\n documentId: string;\n /** `reader`, `read-write`, or null when link access is off. */\n linkAccess: string | null;\n linkAccessUpdatedBy?: string;\n linkAccessUpdatedAt?: string;\n }>;\n /** `db3.setOwnerRow` — PUT /db3/{db3Id}/owner-row. Remove or restore a db3's owner row */\n \"setOwnerRow\"(args: {\n \"db3Id\": string | number;\n body: {\n /** Whether the custodian holds the owner row */\n present: boolean;\n };\n }): Promise<{\n id: string;\n /** `user:<userId>`: the db3's custodian, unchanged */\n custodian: string;\n /** Whether the custodian holds the owner row now */\n ownerRow: boolean;\n changed: boolean;\n }>;\n /** `db3.setSync` — PUT /db3/{db3Id}/sync. Turn a db3's sync on or off */\n \"setSync\"(args: {\n \"db3Id\": string | number;\n body: {\n sync: boolean;\n };\n }): Promise<{\n id: string;\n /** Whether clients open the db3 over a socket (`true`, the default) or only its records routes reach it */\n sync: boolean;\n changed: boolean;\n }>;\n /** `db3.setType` — PUT /db3/{db3Id}/type. Attach a type to a db3 */\n \"setType\"(args: {\n \"db3Id\": string | number;\n body: {\n /** The db3 type's name */\n type: string;\n };\n }): Promise<{\n id: string;\n type: string;\n revision: {\n /** The type row's `modifiedAt`, in epoch milliseconds: a later push is a greater generation */\n generation: number;\n /** The SHA-256 of the type's declarations and hook rules */\n hash: string;\n };\n outcome: \"committed\" | \"unchanged\";\n }>;\n /** `db3.transfer` — POST /db3/{db3Id}/transfer. Transfer a db3 to another user or to the app */\n \"transfer\"(args: {\n \"db3Id\": string | number;\n body: {\n /** `\"user:<userId>\"` (a member of the app; a disabled member counts) or `\"app\"`. */\n to: string;\n };\n }): Promise<{\n id: string;\n title: string | null;\n createdAt: string;\n modifiedAt: string;\n /** The user the db3 was created for, or `sys:<appId>` for a db3 the app created */\n createdBy: string;\n /** Who holds the db3: `user:<userId>` or `app` */\n custodian: string | null;\n sync: boolean;\n /** The db3's type; null while it has none */\n type: string | null;\n }>;\n /** `db3.updatePermissions` — PUT /db3/{db3Id}/permissions. Grant or update a user's permission on a db3 */\n \"updatePermissions\"(args: {\n \"db3Id\": string | number;\n body: {\n userId?: string;\n email?: string;\n /** Required on the single-grant arm. */\n permission?: \"read-write\" | \"reader\";\n /** The multi-grant arm: each entry needs `userId` or `email` and a `permission`. */\n permissions?: {\n userId?: string;\n email?: string;\n permission: \"read-write\" | \"reader\";\n }[];\n /** Email the grantee. Requires `documentUrl`. */\n sendEmail?: boolean;\n /** Link used in the email; required when `sendEmail` is true. */\n documentUrl?: string;\n /** Optional message in the email; max 500 characters. */\n note?: string;\n /** Not read by the handler; use `permission`. */\n role?: string;\n };\n }): Promise<{\n success: boolean;\n message?: string;\n /** Present on the multi-update arm: one entry per resolved grantee, plus the deferred (unresolved email) entries. */\n results?: {\n status?: string;\n userId?: string;\n email?: string;\n permission?: string;\n /** A `pending_signup` entry: whether this call created the app invitation. */\n appInvitationCreated?: boolean;\n /** A `pending_signup` entry: the app invitation's id. */\n invitationId?: string;\n /** A `pending_signup` entry: the app invitation's accept token. */\n inviteToken?: string | null;\n }[];\n }>;\n /** `db3.uploadIngestChunk` — POST /db3/{db3Id}/ingest/{sessionId}/chunks. Upload one chunk of a db3 bulk load */\n \"uploadIngestChunk\"(args: {\n \"db3Id\": string | number;\n \"sessionId\": string | number;\n body: FormData | ArrayBuffer | Uint8Array | string;\n }): Promise<{\n ok: boolean;\n bytes?: number;\n ordinal?: number;\n }>;\n /** `db3.validateAccess` — POST /db3/{db3Id}/validate-access. Resolve effective access to a db3, for the caller or a named user */\n \"validateAccess\"(args: {\n \"db3Id\": string | number;\n body?: {\n /** Resolve this user's effective access instead of the caller's. Must be a non-empty string naming a member of this app. */\n userId?: string;\n };\n }): Promise<{\n success: boolean;\n hasAccess: boolean;\n /** Absent when `hasAccess` is false. */\n permission?: string;\n /** How the access was obtained. Present whenever `hasAccess` is true. */\n accessSource?: \"owner\" | \"grant\" | \"group\" | \"link\" | \"app\";\n /** The SUBJECT's app role, present only in the `userId` form. Reported beside the grant, never folded into `permission`: the tag routes are the only routes that admit `appRole` of `admin` or `owner` without a grant, while `PUT documents/{documentId}` and the other content writes require a real grant from everybody. `GET documents/{documentId}` does bypass the grant, but for a CONSOLE administrator's token, not for an app role — an `admin` here is refused that read without a grant, so a reader must not be admitted on `appRole`. */\n appRole?: \"owner\" | \"admin\" | \"member\";\n invitationAccepted?: boolean;\n upgradedFromPermission?: string;\n }>;\n };\n \"documents\": {\n /** `documents.abortIngest` — POST /documents/{documentId}/ingest/{sessionId}/abort. Abort a bulk-load session before its swap */\n \"abortIngest\"(args: {\n \"documentId\": string | number;\n \"sessionId\": string | number;\n body: Record<string, unknown>;\n }): Promise<{\n sessionId: string;\n documentId: string;\n /** uploading | committed | validating | staging | applying | finalizing | registering | complete | failed | aborted */\n state: string;\n createdBy?: string;\n createdAt?: string;\n updatedAt?: string;\n completedAt?: string | null;\n chunks?: number;\n rows?: number;\n bytes?: number;\n /** Decompressed bytes across the stored chunks; null when unknown (a session that completed before timings were recorded has had its chunk descriptors swept) */\n rawBytes?: number | null;\n /** When the current state began */\n stateEnteredAt?: string | null;\n /** Where the session's time went. On Workers the clock advances only across I/O: a synchronous stage (copyMs, applyMs, decodeMs, swapMs, registerMs) reads 0 there, and an I/O stage (readMs, sealMs, manifestMs) is an OBSERVATION INTERVAL ending at that boundary which includes the synchronous work before it, not an isolated cost. State windows and intervals are exact, because every tick begins in a fresh alarm invocation. */\n timings?: {\n /** The state at which this session's timing history begins; uploading for a session opened after timings were recorded */\n since?: string | null;\n ticks?: number;\n /** Stage costs summed over the session's ticks, ms Stage totals are WALL milliseconds, bracketed on Workers when the room settles the clock at both ends of the bracket; the ledger clock still does not move inside a transaction, so an unbracketed tick reads 0. They are not CPU time. */\n totals?: {\n manifestMs?: number;\n readMs?: number;\n decodeMs?: number;\n copyMs?: number;\n applyMs?: number;\n reconcileMs?: number;\n swapMs?: number;\n sealMs?: number;\n registerMs?: number;\n /** Clock at tick end minus clock at tick start, summed; a lower bound on Workers, where a pure-SQL tick reads 0 */\n totalMs?: number;\n /** How many of this session ticks had their stage timers bracketed by a clock settle at both ends. A tick that was not bracketed reads 0 for every synchronous stage, exactly as before. */\n bracketedTicks?: number;\n /** How many applied rows the `apply` counters describe: the denominator of a per-row figure. Below the session's applied rows when some ticks' counters were not recorded. */\n countedRows?: number;\n /** What each stage SQL did, without asking a clock. Keyed by the nine stage names: manifest, read, decode, copy, apply, reconcile, swap, seal, register. */\n counters?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n /** The same figures split by the table each statement named: records, members (string-set index), claims (unique index), log, bookkeeping, other. This is what separates the records fold from string-set maintenance from unique claims inside one stage. */\n byTarget?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n }>;\n }>;\n };\n /** Per-state { ms, ticks, intervalMs }. intervalMs is the start-to-start interval of the ticks that STARTED in this state, which includes their execution, the room's post-tick work and the 1,000 ms re-arm delay. The transition tick's own cost lands in the next state's window. */\n states?: Record<string, {\n ms?: number;\n ticks?: number;\n intervalMs?: number;\n }>;\n /** The longest interval seen, attributed to the state of the tick that started it */\n longestInterval?: {\n intervalMs?: number;\n state?: string;\n } | null;\n };\n /** Rates over the pipeline window (committed through the swap). Null unless the session reached registering AND its timing history begins at uploading — a session whose window was not measured reports no rate rather than an invented one. */\n throughput?: {\n pipelineMs?: number;\n rowsPerSecond?: number;\n storedBytesPerSecond?: number;\n /** Null when the decompressed total is unknown */\n rawBytesPerSecond?: number | null;\n } | null;\n progress?: {\n rowsCopied?: number;\n chunksApplied?: number;\n rowsApplied?: number;\n recordsReconciled?: number;\n oldRowsRemoved?: number;\n };\n copyStartedAt?: string | null;\n discontinuityEpoch?: number | null;\n buildId?: string | null;\n failure?: {\n code?: string;\n reason?: string;\n rows?: {\n model?: string;\n id?: string;\n }[];\n } | null;\n expiresAt?: string;\n /** A record-log (format 3) load: `open` or `commit`; null for format 2 */\n reserveEpoch?: string | null;\n /** A record-log (format 3) load: `merge` or `refresh`; null for format 2 */\n mode?: string | null;\n /** Rows the load refused, each kept with its code */\n refusedRows?: number;\n /** The first 20 refused rows; the full list pages from GET …/documents/{id}/room?refused= */\n refusedSample?: {\n model?: string;\n id?: string;\n code?: string;\n }[];\n /** A record-log (format 3) load once committed with its epoch reserved: the epoch its rows carry, the log number at the reservation (k), and the log numbers of its first and last entries */\n load?: {\n epoch?: number;\n k?: number;\n firstLsn?: number | null;\n lastLsn?: number | null;\n } | null;\n }>;\n /** `documents.addTag` — POST /documents/{documentId}/tags. Add a tag to a document */\n \"addTag\"(args: {\n \"documentId\": string | number;\n body: {\n tag: string;\n };\n }): Promise<{\n documentId: string;\n tags: string[];\n }>;\n \"aliases\": {\n /** `documents.aliases.delete` — DELETE /document-aliases/{scope}/{aliasKey}. Delete a (scope, aliasKey) document alias binding */\n \"delete\"(args: {\n \"scope\": string | number;\n \"aliasKey\": string | number;\n \"userId\"?: string | number;\n }): Promise<{\n success: boolean;\n }>;\n /** `documents.aliases.listForDocument` — GET /documents/{documentId}/aliases. List aliases bound to a document */\n \"listForDocument\"(args: {\n \"documentId\": string | number;\n }): Promise<{\n scope: \"app\" | \"user\";\n aliasKey: string;\n documentId: string;\n userId?: string | null;\n createdAt?: string;\n updatedAt?: string;\n }[]>;\n /** `documents.aliases.resolve` — GET /document-aliases/{scope}/{aliasKey}. Resolve the document bound to a (scope, aliasKey) alias */\n \"resolve\"(args: {\n \"scope\": string | number;\n \"aliasKey\": string | number;\n \"userId\"?: string | number;\n }): Promise<{\n scope: \"app\" | \"user\";\n aliasKey: string;\n documentId: string;\n userId?: string | null;\n createdAt?: string;\n updatedAt?: string;\n }>;\n /** `documents.aliases.set` — PUT /document-aliases/{scope}/{aliasKey}. Bind a (scope, aliasKey) alias to a document */\n \"set\"(args: {\n \"scope\": string | number;\n \"aliasKey\": string | number;\n body: {\n documentId: string;\n };\n }): Promise<{\n scope: \"app\" | \"user\";\n aliasKey: string;\n documentId: string;\n userId?: string | null;\n createdAt?: string;\n updatedAt?: string;\n }>;\n };\n /** `documents.approveAccessRequest` — POST /documents/{documentId}/access-requests/{requestId}/approve. Approve a document access request */\n \"approveAccessRequest\"(args: {\n \"documentId\": string | number;\n \"requestId\": string | number;\n body?: {\n /** Approve at this level instead of the requested one. */\n permission?: \"read-write\" | \"reader\";\n /** Link included in the approval notification. */\n documentUrl?: string;\n /** Not read by the handler; use `permission`. */\n role?: string;\n };\n }): Promise<{\n success: boolean;\n message?: string;\n request: {\n requestId: string;\n documentId: string;\n requesterId: string;\n status: string;\n requestedPermission?: string;\n message?: string;\n createdAt?: string;\n resolvedBy?: string;\n resolvedAt?: string;\n grantedPermission?: string;\n };\n }>;\n \"blobs\": {\n /** `documents.blobs.delete` — DELETE /documents/{documentId}/blobs/{blobId}. Delete a document blob */\n \"delete\"(args: {\n \"documentId\": string | number;\n \"blobId\": string | number;\n }): Promise<{\n deleted: boolean;\n }>;\n /** `documents.blobs.downloadHeaders` — HEAD /documents/{documentId}/blobs/{blobId}/download. Get document blob download headers (ETag/304 support) */\n \"downloadHeaders\"(args: {\n \"documentId\": string | number;\n \"blobId\": string | number;\n }): Promise<HeaderResult>;\n /** `documents.blobs.downloadUrl` — GET /documents/{documentId}/blobs/{blobId}/download. Download a document blob's bytes */\n \"downloadUrl\"(args: {\n \"documentId\": string | number;\n \"blobId\": string | number;\n \"disposition\"?: string | number | boolean;\n }): Promise<Uint8Array>;\n /** `documents.blobs.get` — GET /documents/{documentId}/blobs/{blobId}. Get a document blob's metadata */\n \"get\"(args: {\n \"documentId\": string | number;\n \"blobId\": string | number;\n }): Promise<{\n blobId: string;\n filename?: string;\n contentType?: string;\n numBytes?: number;\n sha256?: string;\n status?: string;\n createdAt?: string;\n /** 0 on the idempotent 200; the stored length on a 201. */\n bytesTransferred?: number;\n }>;\n /** `documents.blobs.list` — GET /documents/{documentId}/blobs. List blobs attached to a document */\n \"list\"(args: {\n \"documentId\": string | number;\n }): Promise<{\n items: {\n blobId: string;\n filename?: string;\n contentType?: string;\n numBytes?: number;\n sha256?: string;\n status?: string;\n createdAt?: string;\n /** 0 on the idempotent 200; the stored length on a 201. */\n bytesTransferred?: number;\n }[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /** `documents.blobs.upload` — PUT /documents/{documentId}/blobs/{blobId}. Upload a document blob with a client-specified id (immutable + idempotent) */\n \"upload\"(args: {\n \"documentId\": string | number;\n \"blobId\": string | number;\n \"X-Blob-Filename\": string | number;\n \"X-Blob-Size\": string | number;\n \"X-Blob-Sha256\": string | number;\n \"Content-Type\"?: string | number;\n body: ArrayBuffer | Uint8Array | string;\n }): Promise<{\n blobId: string;\n filename?: string;\n contentType?: string;\n numBytes?: number;\n sha256?: string;\n status?: string;\n createdAt?: string;\n /** 0 on the idempotent 200; the stored length on a 201. */\n bytesTransferred?: number;\n }>;\n };\n /** `documents.clearLinkAccess` — DELETE /documents/{documentId}/link-access. Turn off the document's link access */\n \"clearLinkAccess\"(args: {\n \"documentId\": string | number;\n }): Promise<{\n documentId: string;\n /** `reader`, `read-write`, or null when link access is off. */\n linkAccess: string | null;\n linkAccessUpdatedBy?: string;\n linkAccessUpdatedAt?: string;\n }>;\n /** `documents.commitIngest` — POST /documents/{documentId}/ingest/{sessionId}/commit. Commit a bulk-load session: freeze its manifest and apply it */\n \"commitIngest\"(args: {\n \"documentId\": string | number;\n \"sessionId\": string | number;\n body: Record<string, unknown>;\n }): Promise<{\n sessionId: string;\n documentId: string;\n /** uploading | committed | validating | staging | applying | finalizing | registering | complete | failed | aborted */\n state: string;\n createdBy?: string;\n createdAt?: string;\n updatedAt?: string;\n completedAt?: string | null;\n chunks?: number;\n rows?: number;\n bytes?: number;\n /** Decompressed bytes across the stored chunks; null when unknown (a session that completed before timings were recorded has had its chunk descriptors swept) */\n rawBytes?: number | null;\n /** When the current state began */\n stateEnteredAt?: string | null;\n /** Where the session's time went. On Workers the clock advances only across I/O: a synchronous stage (copyMs, applyMs, decodeMs, swapMs, registerMs) reads 0 there, and an I/O stage (readMs, sealMs, manifestMs) is an OBSERVATION INTERVAL ending at that boundary which includes the synchronous work before it, not an isolated cost. State windows and intervals are exact, because every tick begins in a fresh alarm invocation. */\n timings?: {\n /** The state at which this session's timing history begins; uploading for a session opened after timings were recorded */\n since?: string | null;\n ticks?: number;\n /** Stage costs summed over the session's ticks, ms Stage totals are WALL milliseconds, bracketed on Workers when the room settles the clock at both ends of the bracket; the ledger clock still does not move inside a transaction, so an unbracketed tick reads 0. They are not CPU time. */\n totals?: {\n manifestMs?: number;\n readMs?: number;\n decodeMs?: number;\n copyMs?: number;\n applyMs?: number;\n reconcileMs?: number;\n swapMs?: number;\n sealMs?: number;\n registerMs?: number;\n /** Clock at tick end minus clock at tick start, summed; a lower bound on Workers, where a pure-SQL tick reads 0 */\n totalMs?: number;\n /** How many of this session ticks had their stage timers bracketed by a clock settle at both ends. A tick that was not bracketed reads 0 for every synchronous stage, exactly as before. */\n bracketedTicks?: number;\n /** How many applied rows the `apply` counters describe: the denominator of a per-row figure. Below the session's applied rows when some ticks' counters were not recorded. */\n countedRows?: number;\n /** What each stage SQL did, without asking a clock. Keyed by the nine stage names: manifest, read, decode, copy, apply, reconcile, swap, seal, register. */\n counters?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n /** The same figures split by the table each statement named: records, members (string-set index), claims (unique index), log, bookkeeping, other. This is what separates the records fold from string-set maintenance from unique claims inside one stage. */\n byTarget?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n }>;\n }>;\n };\n /** Per-state { ms, ticks, intervalMs }. intervalMs is the start-to-start interval of the ticks that STARTED in this state, which includes their execution, the room's post-tick work and the 1,000 ms re-arm delay. The transition tick's own cost lands in the next state's window. */\n states?: Record<string, {\n ms?: number;\n ticks?: number;\n intervalMs?: number;\n }>;\n /** The longest interval seen, attributed to the state of the tick that started it */\n longestInterval?: {\n intervalMs?: number;\n state?: string;\n } | null;\n };\n /** Rates over the pipeline window (committed through the swap). Null unless the session reached registering AND its timing history begins at uploading — a session whose window was not measured reports no rate rather than an invented one. */\n throughput?: {\n pipelineMs?: number;\n rowsPerSecond?: number;\n storedBytesPerSecond?: number;\n /** Null when the decompressed total is unknown */\n rawBytesPerSecond?: number | null;\n } | null;\n progress?: {\n rowsCopied?: number;\n chunksApplied?: number;\n rowsApplied?: number;\n recordsReconciled?: number;\n oldRowsRemoved?: number;\n };\n copyStartedAt?: string | null;\n discontinuityEpoch?: number | null;\n buildId?: string | null;\n failure?: {\n code?: string;\n reason?: string;\n rows?: {\n model?: string;\n id?: string;\n }[];\n } | null;\n expiresAt?: string;\n /** A record-log (format 3) load: `open` or `commit`; null for format 2 */\n reserveEpoch?: string | null;\n /** A record-log (format 3) load: `merge` or `refresh`; null for format 2 */\n mode?: string | null;\n /** Rows the load refused, each kept with its code */\n refusedRows?: number;\n /** The first 20 refused rows; the full list pages from GET …/documents/{id}/room?refused= */\n refusedSample?: {\n model?: string;\n id?: string;\n code?: string;\n }[];\n /** A record-log (format 3) load once committed with its epoch reserved: the epoch its rows carry, the log number at the reservation (k), and the log numbers of its first and last entries */\n load?: {\n epoch?: number;\n k?: number;\n firstLsn?: number | null;\n lastLsn?: number | null;\n } | null;\n }>;\n /** `documents.create` — POST /documents. Create a new document */\n \"create\"(args: {\n body: {\n /** Not read by the handler — send `title` instead. Sending it is refused with 400 `VALIDATION_FAILED` (#3757). */\n name?: string;\n /** Not read by the handler. Sending it is refused with 400 `VALIDATION_FAILED` (#3757). */\n parentId?: string;\n title?: string;\n /** Adopt a caller-chosen id instead of a generated one. */\n documentId?: string;\n tags?: string[];\n /** Honored for an app admin only; ignored otherwise. */\n createdBy?: string;\n metadata?: Record<string, unknown>;\n /** Large-document opt-in (#2816); chosen at creation, never migrated. */\n documentFormat?: number;\n /** Read in order to be refused: a Blob requires its document, so create the document first, upload the blob, then `PUT /documents/{documentId}`. Answers 400 `THUMBNAIL_REQUIRES_EXISTING_DOC`. */\n thumbnailBlobId?: string;\n };\n }): Promise<{\n documentId: string;\n title?: string | null;\n createdBy?: string;\n createdAt?: string;\n modifiedAt?: string;\n tags?: string[];\n /** Caller-defined metadata blob, when set. */\n metadata?: Record<string, unknown>;\n /** Echoed only for a large document (#2816). */\n documentFormat?: number;\n }>;\n /** `documents.createIngest` — POST /documents/{documentId}/ingest. Open a bulk-load session on a large document */\n \"createIngest\"(args: {\n \"documentId\": string | number;\n body: {\n /** A record-log (format 3) document's load: when the load's epoch is reserved — at session create (`open`, the default) or at commit. A write made after the reservation by a client that has seen it wins against the load's rows. */\n reserveEpoch?: \"open\" | \"commit\";\n /** A record-log (format 3) document's load: `merge` (the default) applies the rows; `refresh` also deletes every record of the models the load covers that no row names. */\n mode?: \"merge\" | \"refresh\";\n /** A refresh only: models to empty beside those the chunks carry, including when the session has no chunk. */\n models?: string[];\n };\n }): Promise<{\n sessionId: string;\n documentId: string;\n /** uploading | committed | validating | staging | applying | finalizing | registering | complete | failed | aborted */\n state: string;\n createdBy?: string;\n createdAt?: string;\n updatedAt?: string;\n completedAt?: string | null;\n chunks?: number;\n rows?: number;\n bytes?: number;\n /** Decompressed bytes across the stored chunks; null when unknown (a session that completed before timings were recorded has had its chunk descriptors swept) */\n rawBytes?: number | null;\n /** When the current state began */\n stateEnteredAt?: string | null;\n /** Where the session's time went. On Workers the clock advances only across I/O: a synchronous stage (copyMs, applyMs, decodeMs, swapMs, registerMs) reads 0 there, and an I/O stage (readMs, sealMs, manifestMs) is an OBSERVATION INTERVAL ending at that boundary which includes the synchronous work before it, not an isolated cost. State windows and intervals are exact, because every tick begins in a fresh alarm invocation. */\n timings?: {\n /** The state at which this session's timing history begins; uploading for a session opened after timings were recorded */\n since?: string | null;\n ticks?: number;\n /** Stage costs summed over the session's ticks, ms Stage totals are WALL milliseconds, bracketed on Workers when the room settles the clock at both ends of the bracket; the ledger clock still does not move inside a transaction, so an unbracketed tick reads 0. They are not CPU time. */\n totals?: {\n manifestMs?: number;\n readMs?: number;\n decodeMs?: number;\n copyMs?: number;\n applyMs?: number;\n reconcileMs?: number;\n swapMs?: number;\n sealMs?: number;\n registerMs?: number;\n /** Clock at tick end minus clock at tick start, summed; a lower bound on Workers, where a pure-SQL tick reads 0 */\n totalMs?: number;\n /** How many of this session ticks had their stage timers bracketed by a clock settle at both ends. A tick that was not bracketed reads 0 for every synchronous stage, exactly as before. */\n bracketedTicks?: number;\n /** How many applied rows the `apply` counters describe: the denominator of a per-row figure. Below the session's applied rows when some ticks' counters were not recorded. */\n countedRows?: number;\n /** What each stage SQL did, without asking a clock. Keyed by the nine stage names: manifest, read, decode, copy, apply, reconcile, swap, seal, register. */\n counters?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n /** The same figures split by the table each statement named: records, members (string-set index), claims (unique index), log, bookkeeping, other. This is what separates the records fold from string-set maintenance from unique claims inside one stage. */\n byTarget?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n }>;\n }>;\n };\n /** Per-state { ms, ticks, intervalMs }. intervalMs is the start-to-start interval of the ticks that STARTED in this state, which includes their execution, the room's post-tick work and the 1,000 ms re-arm delay. The transition tick's own cost lands in the next state's window. */\n states?: Record<string, {\n ms?: number;\n ticks?: number;\n intervalMs?: number;\n }>;\n /** The longest interval seen, attributed to the state of the tick that started it */\n longestInterval?: {\n intervalMs?: number;\n state?: string;\n } | null;\n };\n /** Rates over the pipeline window (committed through the swap). Null unless the session reached registering AND its timing history begins at uploading — a session whose window was not measured reports no rate rather than an invented one. */\n throughput?: {\n pipelineMs?: number;\n rowsPerSecond?: number;\n storedBytesPerSecond?: number;\n /** Null when the decompressed total is unknown */\n rawBytesPerSecond?: number | null;\n } | null;\n progress?: {\n rowsCopied?: number;\n chunksApplied?: number;\n rowsApplied?: number;\n recordsReconciled?: number;\n oldRowsRemoved?: number;\n };\n copyStartedAt?: string | null;\n discontinuityEpoch?: number | null;\n buildId?: string | null;\n failure?: {\n code?: string;\n reason?: string;\n rows?: {\n model?: string;\n id?: string;\n }[];\n } | null;\n expiresAt?: string;\n /** A record-log (format 3) load: `open` or `commit`; null for format 2 */\n reserveEpoch?: string | null;\n /** A record-log (format 3) load: `merge` or `refresh`; null for format 2 */\n mode?: string | null;\n /** Rows the load refused, each kept with its code */\n refusedRows?: number;\n /** The first 20 refused rows; the full list pages from GET …/documents/{id}/room?refused= */\n refusedSample?: {\n model?: string;\n id?: string;\n code?: string;\n }[];\n /** A record-log (format 3) load once committed with its epoch reserved: the epoch its rows carry, the log number at the reservation (k), and the log numbers of its first and last entries */\n load?: {\n epoch?: number;\n k?: number;\n firstLsn?: number | null;\n lastLsn?: number | null;\n } | null;\n }>;\n /** `documents.createWithAlias` — POST /documents/create-with-alias. Create a document and bind it to an alias */\n \"createWithAlias\"(args: {\n body: {\n /** The alias to bind. `scope` must be `user` — app-scoped aliases were removed (#1168) — and `userId` defaults to the caller, which only an app admin may override. */\n alias: {\n scope: \"user\";\n aliasKey: string;\n userId?: string;\n };\n title?: string;\n /** Not read by the handler; use `alias.scope`. Sending it is refused with 400 `VALIDATION_FAILED` (#3757). */\n scope?: string;\n /** Not read by the handler; use `alias.aliasKey`. Sending it is refused with 400 `VALIDATION_FAILED` (#3757). */\n aliasKey?: string;\n /** Not read by the handler. Sending it is refused with 400 `VALIDATION_FAILED` (#3757). */\n name?: string;\n /** Applied at creation, under the same limits `POST /documents` applies (#3757). */\n tags?: string[];\n /** Caller-defined metadata blob applied at creation, under the same size limit `POST /documents` applies (#3757). */\n metadata?: Record<string, unknown>;\n /** Large-document opt-in (#3654); chosen at creation, never migrated. Same rule as `POST /documents`. */\n documentFormat?: number;\n };\n }): Promise<{\n documentId: string;\n title?: string | null;\n createdBy?: string;\n createdAt?: string;\n modifiedAt?: string;\n /** Echoed when the call applied tags (#3757). */\n tags?: string[];\n /** Caller-defined metadata blob, when set. */\n metadata?: Record<string, unknown>;\n /** Echoed only for a large document (#3654). */\n documentFormat?: number;\n alias: {\n scope: \"app\" | \"user\";\n aliasKey: string;\n documentId: string;\n userId?: string | null;\n createdAt?: string;\n updatedAt?: string;\n };\n /** `false` when an existing binding was returned; absent on a create. */\n created?: boolean;\n }>;\n /** `documents.debugDumpUpdates` — POST /documents/{documentId}/debug/dump-updates. Dump a document's raw CRDT update log (debug) */\n \"debugDumpUpdates\"(args: {\n \"documentId\": string | number;\n \"limit\"?: string | number | boolean;\n \"offset\"?: string | number | boolean;\n \"includeData\"?: string | number | boolean;\n \"includeR2Data\"?: string | number | boolean;\n body?: {\n limit?: number | string;\n offset?: number | string;\n includeData?: boolean | string;\n includeR2Data?: boolean | string;\n };\n }): Promise<{\n ok: boolean;\n appId: string;\n documentId: string;\n /** The room's own answer, passed through verbatim. */\n outcome?: Record<string, unknown>;\n }>;\n /** `documents.debugMerge` — POST /documents/{documentId}/debug/merge. Force-merge a document's pending updates (debug) */\n \"debugMerge\"(args: {\n \"documentId\": string | number;\n body?: {\n /** Anything other than `merge-to-r2` means `merge`. */\n mode?: \"merge\" | \"merge-to-r2\";\n traceRunId?: string;\n traceTestName?: string;\n };\n }): Promise<{\n ok: boolean;\n appId: string;\n documentId: string;\n /** The room's own answer, passed through verbatim. */\n outcome?: Record<string, unknown>;\n }>;\n /** `documents.debugMergeBlock` — POST /documents/{documentId}/debug/merge-block. Merge a specific update block of a document (debug) */\n \"debugMergeBlock\"(args: {\n \"documentId\": string | number;\n body?: {\n /** Ignored unless it parses as a finite number. */\n blockSize?: number;\n traceRunId?: string;\n traceTestName?: string;\n };\n }): Promise<{\n ok: boolean;\n appId: string;\n documentId: string;\n /** The room's own answer, passed through verbatim. */\n outcome?: Record<string, unknown>;\n }>;\n /** `documents.debugRestore` — POST /documents/debug/restore. Restore a document from a prior state snapshot (debug) */\n \"debugRestore\"(args: {\n body: {\n /** Not read by the handler. */\n documentId?: string;\n /** Not read by the handler. */\n state?: string;\n /** A `debug/dump-updates` payload; `rows` carries the updates. */\n dumpData?: Record<string, unknown>;\n options?: {\n /** Required unless `appendToExisting` is set. */\n title?: string;\n appendToExisting?: boolean;\n documentId?: string;\n overwrite?: boolean;\n allowCrossApp?: boolean;\n };\n };\n }): Promise<{\n ok: boolean;\n documentId: string;\n updatesApplied?: number;\n originalDocumentId?: string | null;\n /** The room's own restore answer. */\n restoreOutcome?: Record<string, unknown>;\n /** Absent when appending to an existing document. */\n title?: string | null;\n createdBy?: string;\n wasOverwritten?: boolean;\n }>;\n /** `documents.debugStats` — GET /documents/{documentId}/debug/stats. Get document storage/update stats (debug) */\n \"debugStats\"(args: {\n \"documentId\": string | number;\n }): Promise<{\n ok: boolean;\n appId: string;\n documentId: string;\n /** The room's own stats payload. */\n stats?: Record<string, unknown>;\n /** The room's own state payload. */\n state?: Record<string, unknown>;\n }>;\n /** `documents.delete` — DELETE /documents/{documentId}. Delete a document */\n \"delete\"(args: {\n \"documentId\": string | number;\n }): Promise<{\n success: boolean;\n message?: string;\n }>;\n /** `documents.denyAccessRequest` — POST /documents/{documentId}/access-requests/{requestId}/deny. Deny a document access request */\n \"denyAccessRequest\"(args: {\n \"documentId\": string | number;\n \"requestId\": string | number;\n body?: {\n /** An https URL included in the denial notification; a non-https value is refused. */\n documentUrl?: string;\n };\n }): Promise<{\n success: boolean;\n message?: string;\n request: {\n requestId: string;\n documentId: string;\n requesterId: string;\n status: string;\n requestedPermission?: string;\n message?: string;\n createdAt?: string;\n resolvedBy?: string;\n resolvedAt?: string;\n grantedPermission?: string;\n };\n }>;\n /** `documents.exportChain` — GET /documents/{documentId}/export/chain. Export chain of a large document (snapshot + sealed overlays + open epoch) */\n \"exportChain\"(args: {\n \"documentId\": string | number;\n }): Promise<{\n ok: boolean;\n appId?: string;\n documentId?: string;\n documentFormat?: number;\n /** A record-log document: the log position the current segment exports the rows at */\n lsn?: number;\n /** A record-log document: the log position the segment's corrections were read at */\n completedLsn?: number | null;\n /** A record-log document: its current segment, signed for download */\n segment?: {\n segmentId?: string;\n rows?: number;\n chunks?: number;\n corrections?: number;\n completedAt?: number | null;\n /** Null when the deployment cannot sign artifact downloads */\n download?: {\n /** The signed artifact path */\n path?: string;\n /** Epoch milliseconds */\n expiresAt?: number;\n } | null;\n basedOn?: {\n segmentId?: string;\n lsn?: number;\n } | null;\n reused?: number;\n written?: number;\n rowsRead?: number;\n };\n }>;\n /** `documents.exportState` — GET /documents/{documentId}/export/state. Export a document's encoded CRDT state */\n \"exportState\"(args: {\n \"documentId\": string | number;\n }): Promise<{\n ok: boolean;\n documentId?: string;\n appId?: string;\n /** Base64 of `Y.encodeStateAsUpdate`. */\n state: string;\n byteLength?: number;\n }>;\n /** `documents.get` — GET /documents/{documentId}. Get a single document by id */\n \"get\"(args: {\n \"documentId\": string | number;\n }): Promise<{\n documentId: string;\n title?: string | null;\n createdBy?: string;\n createdAt?: string;\n lastModified?: string;\n modifiedAt?: string;\n appId?: string;\n isAdmin?: boolean;\n permission?: string;\n accessSource?: string;\n grantedAt?: string;\n linkAccess?: \"reader\" | \"read-write\";\n tags?: string[];\n thumbnailBlobId?: string;\n /** Caller-defined metadata blob. */\n metadata?: Record<string, unknown>;\n /** Present only for a large document (#2816). */\n documentFormat?: number;\n invitationAccepted?: boolean;\n upgradedFromPermission?: string;\n collectionId?: string;\n addedAt?: string;\n addedBy?: string;\n }>;\n /**\n * `documents.getImportChainStatus` — GET /documents/{documentId}/import/chain. DEPRECATED — how far a large document's chain import has got\n * @deprecated No document accepts a chain import any more; load rows into a database with `primitive db3 ingest` or `client.db3.ingests` instead.\n */\n \"getImportChainStatus\"(args: {\n \"documentId\": string | number;\n }): Promise<{\n ok: boolean;\n /** null when no install has been started. */\n install: {\n installId?: string;\n state?: string;\n chunks?: number;\n overlays?: number;\n rows?: number;\n error?: string | null;\n } | null;\n }>;\n /** `documents.getIngest` — GET /documents/{documentId}/ingest/{sessionId}. One bulk-load session's status */\n \"getIngest\"(args: {\n \"documentId\": string | number;\n \"sessionId\": string | number;\n }): Promise<{\n sessionId: string;\n documentId: string;\n /** uploading | committed | validating | staging | applying | finalizing | registering | complete | failed | aborted */\n state: string;\n createdBy?: string;\n createdAt?: string;\n updatedAt?: string;\n completedAt?: string | null;\n chunks?: number;\n rows?: number;\n bytes?: number;\n /** Decompressed bytes across the stored chunks; null when unknown (a session that completed before timings were recorded has had its chunk descriptors swept) */\n rawBytes?: number | null;\n /** When the current state began */\n stateEnteredAt?: string | null;\n /** Where the session's time went. On Workers the clock advances only across I/O: a synchronous stage (copyMs, applyMs, decodeMs, swapMs, registerMs) reads 0 there, and an I/O stage (readMs, sealMs, manifestMs) is an OBSERVATION INTERVAL ending at that boundary which includes the synchronous work before it, not an isolated cost. State windows and intervals are exact, because every tick begins in a fresh alarm invocation. */\n timings?: {\n /** The state at which this session's timing history begins; uploading for a session opened after timings were recorded */\n since?: string | null;\n ticks?: number;\n /** Stage costs summed over the session's ticks, ms Stage totals are WALL milliseconds, bracketed on Workers when the room settles the clock at both ends of the bracket; the ledger clock still does not move inside a transaction, so an unbracketed tick reads 0. They are not CPU time. */\n totals?: {\n manifestMs?: number;\n readMs?: number;\n decodeMs?: number;\n copyMs?: number;\n applyMs?: number;\n reconcileMs?: number;\n swapMs?: number;\n sealMs?: number;\n registerMs?: number;\n /** Clock at tick end minus clock at tick start, summed; a lower bound on Workers, where a pure-SQL tick reads 0 */\n totalMs?: number;\n /** How many of this session ticks had their stage timers bracketed by a clock settle at both ends. A tick that was not bracketed reads 0 for every synchronous stage, exactly as before. */\n bracketedTicks?: number;\n /** How many applied rows the `apply` counters describe: the denominator of a per-row figure. Below the session's applied rows when some ticks' counters were not recorded. */\n countedRows?: number;\n /** What each stage SQL did, without asking a clock. Keyed by the nine stage names: manifest, read, decode, copy, apply, reconcile, swap, seal, register. */\n counters?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n /** The same figures split by the table each statement named: records, members (string-set index), claims (unique index), log, bookkeeping, other. This is what separates the records fold from string-set maintenance from unique claims inside one stage. */\n byTarget?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n }>;\n }>;\n };\n /** Per-state { ms, ticks, intervalMs }. intervalMs is the start-to-start interval of the ticks that STARTED in this state, which includes their execution, the room's post-tick work and the 1,000 ms re-arm delay. The transition tick's own cost lands in the next state's window. */\n states?: Record<string, {\n ms?: number;\n ticks?: number;\n intervalMs?: number;\n }>;\n /** The longest interval seen, attributed to the state of the tick that started it */\n longestInterval?: {\n intervalMs?: number;\n state?: string;\n } | null;\n };\n /** Rates over the pipeline window (committed through the swap). Null unless the session reached registering AND its timing history begins at uploading — a session whose window was not measured reports no rate rather than an invented one. */\n throughput?: {\n pipelineMs?: number;\n rowsPerSecond?: number;\n storedBytesPerSecond?: number;\n /** Null when the decompressed total is unknown */\n rawBytesPerSecond?: number | null;\n } | null;\n progress?: {\n rowsCopied?: number;\n chunksApplied?: number;\n rowsApplied?: number;\n recordsReconciled?: number;\n oldRowsRemoved?: number;\n };\n copyStartedAt?: string | null;\n discontinuityEpoch?: number | null;\n buildId?: string | null;\n failure?: {\n code?: string;\n reason?: string;\n rows?: {\n model?: string;\n id?: string;\n }[];\n } | null;\n expiresAt?: string;\n /** A record-log (format 3) load: `open` or `commit`; null for format 2 */\n reserveEpoch?: string | null;\n /** A record-log (format 3) load: `merge` or `refresh`; null for format 2 */\n mode?: string | null;\n /** Rows the load refused, each kept with its code */\n refusedRows?: number;\n /** The first 20 refused rows; the full list pages from GET …/documents/{id}/room?refused= */\n refusedSample?: {\n model?: string;\n id?: string;\n code?: string;\n }[];\n /** A record-log (format 3) load once committed with its epoch reserved: the epoch its rows carry, the log number at the reservation (k), and the log numbers of its first and last entries */\n load?: {\n epoch?: number;\n k?: number;\n firstLsn?: number | null;\n lastLsn?: number | null;\n } | null;\n }>;\n /** `documents.getLinkAccess` — GET /documents/{documentId}/link-access. Get the document's \"anyone with the link\" access level */\n \"getLinkAccess\"(args: {\n \"documentId\": string | number;\n }): Promise<{\n documentId: string;\n /** `reader`, `read-write`, or null when link access is off. */\n linkAccess: string | null;\n linkAccessUpdatedBy?: string;\n linkAccessUpdatedAt?: string;\n }>;\n /** `documents.getOrCreateWithAlias` — POST /documents/get-or-create-with-alias. Get the document bound to an alias, creating it if absent (idempotent) */\n \"getOrCreateWithAlias\"(args: {\n body: {\n /** The alias to bind. `scope` must be `user` — app-scoped aliases were removed (#1168) — and `userId` defaults to the caller, which only an app admin may override. */\n alias: {\n scope: \"user\";\n aliasKey: string;\n userId?: string;\n };\n title?: string;\n /** Applied only when the alias is created here. */\n tags?: string[];\n /** Not read by the handler; use `alias.scope`. Sending it is refused with 400 `VALIDATION_FAILED` (#3757). */\n scope?: string;\n /** Not read by the handler; use `alias.aliasKey`. Sending it is refused with 400 `VALIDATION_FAILED` (#3757). */\n aliasKey?: string;\n /** Not read by the handler. Sending it is refused with 400 `VALIDATION_FAILED` (#3757). */\n name?: string;\n /** Caller-defined metadata blob applied only when the alias is created here (#3757). */\n metadata?: Record<string, unknown>;\n /** Large-document opt-in (#3757); applied when this call creates the document, and otherwise read as an expectation about the document the alias already names — a stored format that differs answers 409, one that agrees is echoed. Chosen at creation, never migrated. */\n documentFormat?: number;\n };\n }): Promise<{\n documentId: string;\n title?: string | null;\n createdBy?: string;\n createdAt?: string;\n modifiedAt?: string;\n /** Echoed when the call applied tags (#3757). */\n tags?: string[];\n /** Caller-defined metadata blob, when set. */\n metadata?: Record<string, unknown>;\n /** Echoed only for a large document (#3654). */\n documentFormat?: number;\n alias: {\n scope: \"app\" | \"user\";\n aliasKey: string;\n documentId: string;\n userId?: string | null;\n createdAt?: string;\n updatedAt?: string;\n };\n /** `false` when an existing binding was returned; absent on a create. */\n created?: boolean;\n }>;\n /** `documents.getPermissions` — GET /documents/{documentId}/permissions. List a document's user permissions */\n \"getPermissions\"(args: {\n \"documentId\": string | number;\n }): Promise<{\n userId: string;\n email?: string;\n name?: string;\n avatarUrl?: string;\n permission: string;\n grantedAt?: string;\n }[]>;\n /** `documents.getSchema` — GET /documents/{documentId}/schema. Introspect a document's model schema */\n \"getSchema\"(args: {\n \"documentId\": string | number;\n }): Promise<{\n ok: boolean;\n documentId?: string;\n appId?: string;\n /** Discovered model metadata, keyed by model name. */\n schema?: Record<string, unknown>;\n modelNames?: string[];\n modelCount?: number;\n /** Every model the authoritative table holds a row of, on a large document; `[]` otherwise. Not the same list as `modelNames`, which is what the document DECLARES (#3433). */\n tableModels?: string[];\n /** 3 for a record-log document, whose writes and bulk loads take models and fields it does not declare; absent for formats 1 and 2. */\n documentFormat?: number;\n }>;\n /** `documents.getSnapshot` — GET /documents/{documentId}/snapshots/{buildId}. One snapshot build with its verification result */\n \"getSnapshot\"(args: {\n \"documentId\": string | number;\n \"buildId\": string | number;\n }): Promise<{\n ok: boolean;\n segmentId: string;\n state: \"exporting\" | \"complete\" | \"failed\" | \"superseded\";\n /** The log position the segment exports the rows at */\n lsn: number;\n /** The log position the corrections were read at, once they were */\n completedLsn: number | null;\n /** The epochs in force when the export began */\n epochs: {\n current?: number;\n next?: number;\n high?: number;\n floor?: number;\n };\n rows: number;\n /** How many chunks the segment holds */\n chunks: number;\n /** Rows in the corrections chunk; null until the corrections are read */\n corrections: number | null;\n bytes: number;\n /** Epoch milliseconds */\n startedAt: number;\n /** Epoch milliseconds */\n completedAt: number | null;\n failure: {\n code?: string;\n reason?: string;\n } | null;\n /** The segment this one reuses chunks from; null for a full export */\n basedOn: {\n segmentId?: string;\n lsn?: number;\n } | null;\n /** What started the export; null on a segment recorded before triggers were */\n trigger: \"daily\" | \"explicit\" | \"change\" | \"demand\" | \"sync-on\" | null;\n /** Chunks reused from `basedOn` */\n reused: number;\n /** Chunks written */\n written: number;\n /** Rows read out of the table */\n rowsRead: number;\n } | {\n buildId: string;\n epoch: number;\n state: \"building\" | \"verifying\" | \"complete\" | \"failed\" | \"abandoned\";\n source: \"builder\" | \"import\" | \"ingest\";\n manifestVersion: number;\n startedAt: number;\n completedAt: number | null;\n rows: number;\n bytes: number;\n /** How many chunks the build holds */\n chunks: number;\n /** The build this one reused chunks from; null when it walked the whole document */\n baseBuildId: string | null;\n /** How many of those chunks came from that build */\n chunksReused: number;\n /** Rows read out of the table while building */\n rowsWalked: number;\n /** The bulk-load session this base was built for; null on every other build */\n ingestSessionId: string | null;\n /** The checks run before the build was registered */\n verification: {\n state?: \"pending\" | \"passed\" | \"failed\";\n checkedAt?: number;\n chunksChecked?: number;\n chunksReused?: number;\n mode?: \"build\" | \"install\";\n code?: string;\n reason?: string;\n } | null;\n failure: {\n code?: string;\n reason?: string;\n at?: number;\n chunk?: {\n model?: string;\n ordinal?: number;\n };\n } | null;\n /** Where the build's time went, summed over its ticks (ms) */\n timings: {\n ticks?: number;\n totals?: {\n readMs?: number;\n encodeMs?: number;\n compressMs?: number;\n hashMs?: number;\n uploadMs?: number;\n verifyReadMs?: number;\n verifyDigestMs?: number;\n verifyCoverageMs?: number;\n manifestMs?: number;\n };\n };\n }>;\n /** `documents.getStats` — GET /documents/{documentId}/stats. Document statistics (record/model/blob counts, approximate size) */\n \"getStats\"(args: {\n \"documentId\": string | number;\n }): Promise<{\n documentId: string;\n recordCount: number;\n modelCount: number;\n blobCount: number;\n /** Size of the document's data in bytes, measured as sizeBasis says. For a large document, the stored JSON of every record; sealing an epoch or building a snapshot does not change it. */\n sizeBytes: number;\n /** True when sizeBytes is an estimate (an ordinary document); false for a large document's record bytes. */\n sizeBytesApproximate: boolean;\n /** What sizeBytes measures: `records` (a large document's stored record JSON) or `document` (an ordinary document's approximate size). */\n sizeBasis: \"records\" | \"document\";\n lastModifiedAt?: string | null;\n }>;\n /** `documents.grantGroupPermission` — POST /documents/{documentId}/group-permissions. Grant a group permission on a document */\n \"grantGroupPermission\"(args: {\n \"documentId\": string | number;\n body: {\n /** Deprecated (removal: #4718): groups are named by `groupId` alone. Given, the group is looked up by type first; the `_`-prefixed platform types are refused here. @deprecated */\n groupType?: string;\n groupId: string;\n permission: \"read-write\" | \"reader\";\n /** Not read by the handler; use `permission`. */\n role?: string;\n };\n }): Promise<{\n documentId: string;\n groupType: string;\n groupId: string;\n permission: string;\n grantedAt?: string;\n grantedBy?: string;\n }>;\n /**\n * `documents.importChain` — POST /documents/{documentId}/import/chain. DEPRECATED — install an uploaded chain into a large document\n * @deprecated No document accepts a chain import any more; load rows into a database with `primitive db3 ingest` or `client.db3.ingests` instead.\n */\n \"importChain\"(args: {\n \"documentId\": string | number;\n body: {\n installId?: string;\n base?: Record<string, unknown>;\n overlays?: number[];\n currentEpoch: number;\n };\n }): Promise<{\n ok: boolean;\n installId: string;\n base?: Record<string, unknown> | null;\n overlays?: number[];\n currentEpoch?: number;\n }>;\n /**\n * `documents.importChainArtifact` — POST /documents/{documentId}/import/chain/artifact. DEPRECATED — upload one artifact of a large document's import chain\n * @deprecated No document accepts a chain import any more; load rows into a database with `primitive db3 ingest` or `client.db3.ingests` instead.\n */\n \"importChainArtifact\"(args: {\n \"documentId\": string | number;\n \"kind\"?: string | number | boolean;\n \"epoch\"?: string | number | boolean;\n \"buildId\"?: string | number | boolean;\n \"model\"?: string | number | boolean;\n \"index\"?: string | number | boolean;\n body: ArrayBuffer | Uint8Array | string;\n }): Promise<{\n ok: boolean;\n bytes?: number;\n }>;\n /** `documents.importState` — POST /documents/{documentId}/import/state. Import encoded CRDT state into a document */\n \"importState\"(args: {\n \"documentId\": string | number;\n body: {\n state: string;\n };\n }): Promise<{\n ok: boolean;\n documentId?: string;\n appId?: string;\n importedBytes?: number;\n mergedBytes?: number;\n }>;\n /** `documents.listAccessRequests` — GET /documents/{documentId}/access-requests. List access requests for a document */\n \"listAccessRequests\"(args: {\n \"documentId\": string | number;\n }): Promise<{\n requestId: string;\n documentId: string;\n requesterId: string;\n status: string;\n requestedPermission?: string;\n message?: string;\n createdAt?: string;\n resolvedBy?: string;\n resolvedAt?: string;\n grantedPermission?: string;\n }[]>;\n /** `documents.listGroupPermissions` — GET /documents/{documentId}/group-permissions. List a document's group permissions */\n \"listGroupPermissions\"(args: {\n \"documentId\": string | number;\n }): Promise<{\n documentId: string;\n groupType: string;\n groupId: string;\n permission: string;\n grantedAt?: string;\n grantedBy?: string;\n }[]>;\n /** `documents.listIngests` — GET /documents/{documentId}/ingest. List a large document's bulk-load sessions, newest first */\n \"listIngests\"(args: {\n \"documentId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n items: {\n sessionId: string;\n documentId: string;\n /** uploading | committed | validating | staging | applying | finalizing | registering | complete | failed | aborted */\n state: string;\n createdBy?: string;\n createdAt?: string;\n updatedAt?: string;\n completedAt?: string | null;\n chunks?: number;\n rows?: number;\n bytes?: number;\n /** Decompressed bytes across the stored chunks; null when unknown (a session that completed before timings were recorded has had its chunk descriptors swept) */\n rawBytes?: number | null;\n /** When the current state began */\n stateEnteredAt?: string | null;\n /** Where the session's time went. On Workers the clock advances only across I/O: a synchronous stage (copyMs, applyMs, decodeMs, swapMs, registerMs) reads 0 there, and an I/O stage (readMs, sealMs, manifestMs) is an OBSERVATION INTERVAL ending at that boundary which includes the synchronous work before it, not an isolated cost. State windows and intervals are exact, because every tick begins in a fresh alarm invocation. */\n timings?: {\n /** The state at which this session's timing history begins; uploading for a session opened after timings were recorded */\n since?: string | null;\n ticks?: number;\n /** Stage costs summed over the session's ticks, ms Stage totals are WALL milliseconds, bracketed on Workers when the room settles the clock at both ends of the bracket; the ledger clock still does not move inside a transaction, so an unbracketed tick reads 0. They are not CPU time. */\n totals?: {\n manifestMs?: number;\n readMs?: number;\n decodeMs?: number;\n copyMs?: number;\n applyMs?: number;\n reconcileMs?: number;\n swapMs?: number;\n sealMs?: number;\n registerMs?: number;\n /** Clock at tick end minus clock at tick start, summed; a lower bound on Workers, where a pure-SQL tick reads 0 */\n totalMs?: number;\n /** How many of this session ticks had their stage timers bracketed by a clock settle at both ends. A tick that was not bracketed reads 0 for every synchronous stage, exactly as before. */\n bracketedTicks?: number;\n /** How many applied rows the `apply` counters describe: the denominator of a per-row figure. Below the session's applied rows when some ticks' counters were not recorded. */\n countedRows?: number;\n /** What each stage SQL did, without asking a clock. Keyed by the nine stage names: manifest, read, decode, copy, apply, reconcile, swap, seal, register. */\n counters?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n /** The same figures split by the table each statement named: records, members (string-set index), claims (unique index), log, bookkeeping, other. This is what separates the records fold from string-set maintenance from unique claims inside one stage. */\n byTarget?: Record<string, {\n /** Statements executed. Exact on every host. */\n statements?: number;\n /** Rows read, from the SQL cursor's own billing counter. null where the host has no such counter — never a substituted zero, and never the number of rows returned. */\n rowsRead?: number | null;\n /** Rows written, from the SQL cursor's own billing counter. null where the host has no such counter. */\n rowsWritten?: number | null;\n /** Rows the statements answered with, which is a third figure: an aggregate returns one row after reading many, and a write returns none after writing many. */\n rowsReturned?: number;\n /** Per-statement wall milliseconds. null on Workers, where a per-statement Date.now delta is 0 by construction. */\n ms?: number | null;\n }>;\n }>;\n };\n /** Per-state { ms, ticks, intervalMs }. intervalMs is the start-to-start interval of the ticks that STARTED in this state, which includes their execution, the room's post-tick work and the 1,000 ms re-arm delay. The transition tick's own cost lands in the next state's window. */\n states?: Record<string, {\n ms?: number;\n ticks?: number;\n intervalMs?: number;\n }>;\n /** The longest interval seen, attributed to the state of the tick that started it */\n longestInterval?: {\n intervalMs?: number;\n state?: string;\n } | null;\n };\n /** Rates over the pipeline window (committed through the swap). Null unless the session reached registering AND its timing history begins at uploading — a session whose window was not measured reports no rate rather than an invented one. */\n throughput?: {\n pipelineMs?: number;\n rowsPerSecond?: number;\n storedBytesPerSecond?: number;\n /** Null when the decompressed total is unknown */\n rawBytesPerSecond?: number | null;\n } | null;\n progress?: {\n rowsCopied?: number;\n chunksApplied?: number;\n rowsApplied?: number;\n recordsReconciled?: number;\n oldRowsRemoved?: number;\n };\n copyStartedAt?: string | null;\n discontinuityEpoch?: number | null;\n buildId?: string | null;\n failure?: {\n code?: string;\n reason?: string;\n rows?: {\n model?: string;\n id?: string;\n }[];\n } | null;\n expiresAt?: string;\n /** A record-log (format 3) load: `open` or `commit`; null for format 2 */\n reserveEpoch?: string | null;\n /** A record-log (format 3) load: `merge` or `refresh`; null for format 2 */\n mode?: string | null;\n /** Rows the load refused, each kept with its code */\n refusedRows?: number;\n /** The first 20 refused rows; the full list pages from GET …/documents/{id}/room?refused= */\n refusedSample?: {\n model?: string;\n id?: string;\n code?: string;\n }[];\n /** A record-log (format 3) load once committed with its epoch reserved: the epoch its rows carry, the log number at the reservation (k), and the log numbers of its first and last entries */\n load?: {\n epoch?: number;\n k?: number;\n firstLsn?: number | null;\n lastLsn?: number | null;\n } | null;\n }[];\n hasMore: boolean;\n nextCursor?: string;\n }>;\n /** `documents.listOwnedByUser` — GET /users/{userId}/owned-documents. List the documents an app user owns */\n \"listOwnedByUser\"(args: {\n \"userId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"tag\"?: string | number | boolean;\n \"includeRoot\"?: string | number | boolean;\n \"forward\"?: string | number | boolean;\n }): Promise<{\n items: {\n documentId: string;\n title?: string | null;\n createdBy?: string;\n createdAt?: string;\n lastModified?: string;\n modifiedAt?: string;\n appId?: string;\n isAdmin?: boolean;\n permission: string;\n accessSource?: string;\n grantedAt?: string;\n linkAccess?: \"reader\" | \"read-write\";\n tags?: string[];\n thumbnailBlobId?: string;\n /** Caller-defined metadata blob. */\n metadata?: Record<string, unknown>;\n /** Present only for a large document (#2816). */\n documentFormat?: number;\n invitationAccepted?: boolean;\n upgradedFromPermission?: string;\n collectionId?: string;\n addedAt?: string;\n addedBy?: string;\n /** Shared rows only: who granted the permission. */\n grantedBy?: string | null;\n /** Shared rows only: always `permission`, a direct grant. */\n source?: \"permission\";\n }[];\n hasMore: boolean;\n nextCursor?: string;\n }>;\n /** `documents.listPendingInvitations` — GET /documents/{documentId}/pending-invitations. List a document's pending (deferred) invitations */\n \"listPendingInvitations\"(args: {\n \"documentId\": string | number;\n }): Promise<{\n items: {\n invitationId: string;\n email: string;\n permission: string;\n invitedAt?: string;\n invitedBy?: string;\n expiresAt?: string;\n accepted?: boolean;\n /** When the deferred grant was made. */\n createdAt?: string;\n /** The user id that made the deferred grant. */\n grantedBy?: string;\n }[];\n }>;\n /** `documents.listSharedWithUser` — GET /users/{userId}/shared-documents. List the documents directly shared with an app user */\n \"listSharedWithUser\"(args: {\n \"userId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"tag\"?: string | number | boolean;\n }): Promise<{\n items: {\n documentId: string;\n title?: string | null;\n createdBy?: string;\n createdAt?: string;\n lastModified?: string;\n modifiedAt?: string;\n appId?: string;\n isAdmin?: boolean;\n permission: string;\n accessSource?: string;\n grantedAt?: string;\n linkAccess?: \"reader\" | \"read-write\";\n tags?: string[];\n thumbnailBlobId?: string;\n /** Caller-defined metadata blob. */\n metadata?: Record<string, unknown>;\n /** Present only for a large document (#2816). */\n documentFormat?: number;\n invitationAccepted?: boolean;\n upgradedFromPermission?: string;\n collectionId?: string;\n addedAt?: string;\n addedBy?: string;\n /** Shared rows only: who granted the permission. */\n grantedBy?: string | null;\n /** Shared rows only: always `permission`, a direct grant. */\n source?: \"permission\";\n }[];\n hasMore: boolean;\n nextCursor?: string;\n }>;\n /** `documents.listSnapshots` — GET /documents/{documentId}/snapshots. List a large document's snapshot builds, newest first */\n \"listSnapshots\"(args: {\n \"documentId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n ok?: boolean;\n items: Array<{\n segmentId: string;\n state: \"exporting\" | \"complete\" | \"failed\" | \"superseded\";\n /** The log position the segment exports the rows at */\n lsn: number;\n /** The log position the corrections were read at, once they were */\n completedLsn: number | null;\n /** The epochs in force when the export began */\n epochs: {\n current?: number;\n next?: number;\n high?: number;\n floor?: number;\n };\n rows: number;\n /** How many chunks the segment holds */\n chunks: number;\n /** Rows in the corrections chunk; null until the corrections are read */\n corrections: number | null;\n bytes: number;\n /** Epoch milliseconds */\n startedAt: number;\n /** Epoch milliseconds */\n completedAt: number | null;\n failure: {\n code?: string;\n reason?: string;\n } | null;\n /** The segment this one reuses chunks from; null for a full export */\n basedOn: {\n segmentId?: string;\n lsn?: number;\n } | null;\n /** What started the export; null on a segment recorded before triggers were */\n trigger: \"daily\" | \"explicit\" | \"change\" | \"demand\" | \"sync-on\" | null;\n /** Chunks reused from `basedOn` */\n reused: number;\n /** Chunks written */\n written: number;\n /** Rows read out of the table */\n rowsRead: number;\n } | {\n buildId: string;\n epoch: number;\n state: \"building\" | \"verifying\" | \"complete\" | \"failed\" | \"abandoned\";\n source: \"builder\" | \"import\" | \"ingest\";\n manifestVersion: number;\n startedAt: number;\n completedAt: number | null;\n rows: number;\n bytes: number;\n /** How many chunks the build holds */\n chunks: number;\n /** The build this one reused chunks from; null when it walked the whole document */\n baseBuildId: string | null;\n /** How many of those chunks came from that build */\n chunksReused: number;\n /** Rows read out of the table while building */\n rowsWalked: number;\n /** The bulk-load session this base was built for; null on every other build */\n ingestSessionId: string | null;\n /** The checks run before the build was registered */\n verification: {\n state?: \"pending\" | \"passed\" | \"failed\";\n checkedAt?: number;\n chunksChecked?: number;\n chunksReused?: number;\n mode?: \"build\" | \"install\";\n code?: string;\n reason?: string;\n } | null;\n failure: {\n code?: string;\n reason?: string;\n at?: number;\n chunk?: {\n model?: string;\n ordinal?: number;\n };\n } | null;\n /** Where the build's time went, summed over its ticks (ms) */\n timings: {\n ticks?: number;\n totals?: {\n readMs?: number;\n encodeMs?: number;\n compressMs?: number;\n hashMs?: number;\n uploadMs?: number;\n verifyReadMs?: number;\n verifyDigestMs?: number;\n verifyCoverageMs?: number;\n manifestMs?: number;\n };\n };\n }>;\n hasMore: boolean;\n nextCursor?: string;\n }>;\n /** `documents.open` — POST /documents/open. Open a document for collaboration (resolves access + alias) */\n \"open\"(args: {\n body: {\n documentId?: string;\n alias?: {\n scope?: \"app\" | \"user\";\n aliasKey: string;\n /** `user` scope only; defaults to the calling user. */\n userId?: string;\n };\n /** Not read by the handler — use `alias.scope`. */\n scope?: string;\n /** Not read by the handler — use `alias.aliasKey`. */\n aliasKey?: string;\n };\n }): Promise<{\n documentId: string;\n title?: string | null;\n createdBy?: string;\n createdAt?: string;\n lastModified?: string;\n modifiedAt?: string;\n appId?: string;\n isAdmin?: boolean;\n permission?: string;\n accessSource?: string;\n grantedAt?: string;\n linkAccess?: \"reader\" | \"read-write\";\n tags?: string[];\n thumbnailBlobId?: string;\n /** Caller-defined metadata blob. */\n metadata?: Record<string, unknown>;\n /** Present only for a large document (#2816). */\n documentFormat?: number;\n invitationAccepted?: boolean;\n upgradedFromPermission?: string;\n collectionId?: string;\n addedAt?: string;\n addedBy?: string;\n }>;\n \"records\": {\n /** `documents.records.aggregate` — POST /documents/{documentId}/records/{model}/aggregate. Aggregate records in a document model (count/sum/avg/min/max, optional grouping) */\n \"aggregate\"(args: {\n \"documentId\": string | number;\n \"model\": string | number;\n \"documentFormat\"?: string | number | boolean;\n body: {\n options: {\n /** One or more aggregate operations. `count` takes no field; `sum`/`avg`/`min`/`max` each require one. */\n operations: {\n type: \"count\" | \"sum\" | \"avg\" | \"min\" | \"max\";\n field?: string;\n }[];\n /** Levels to group by: field names, period levels `{ field, period }` and, on a db3, membership levels `{ field, contains }`. On a db3 a field name naming a StringSet field is a facet. A format-1 document refuses StringSet facet and membership grouping with a 400. */\n groupBy?: Array<string | {\n field: string;\n period: \"month\" | \"quarter\" | \"year\";\n } | {\n field: string;\n contains: string;\n }>;\n /** Query filter restricting the aggregated set. */\n filter?: Record<string, unknown>;\n /** The groups' order (a db3 only; a format-1 document refuses it): `field` is `count`, an operation key (`sum_amount`), a group key (`has_tags_x`, `due_month`) or a field name. */\n sort?: {\n field: string;\n direction: 1 | -1;\n };\n /** The most groups answered (a db3 only; a format-1 document refuses it). Above 10,000 is a 400, never clamped. */\n limit?: number;\n };\n };\n }): Promise<{\n /** One row per group, in the order SQL returned them: `{ group, count, <op>_<field> }`, every requested operation present under its key (`count`, `<op>_<field>`) even when it is the only one. A grouped aggregate that matches no record is `[]`; an ungrouped one is exactly one row with an empty `group`. Two `groupBy` levels that would take the same key in `group` are refused with a 400, `Ambiguous aggregation group keys: '<key>' names more than one groupBy level`. */\n result: {\n /** One entry per `groupBy` level, keyed by the field name (or `has_<field>_<contains>` for a StringSet membership level, or `<field>_<period>` for a period level), holding the value as stored: `null` for a missing field, numbers as numbers. Empty for an ungrouped aggregate. */\n group: Record<string, unknown>;\n /** The group's record count, present when `count` is requested. */\n count?: number;\n [key: string]: unknown;\n }[];\n }>;\n /** `documents.records.bulk` — POST /documents/{documentId}/records/bulk. Apply an atomic multi-model record blob to a document (create/patch/delete/upsert) */\n \"bulk\"(args: {\n \"documentId\": string | number;\n \"documentFormat\"?: string | number | boolean;\n body: {\n /** Ordered ops, applied in one transaction (max 500, all-or-nothing). */\n operations: Array<{\n model: string;\n action: \"create\";\n /** A 26-char uppercase Crockford ULID the caller mints. */\n id: string;\n /** Record fields. Required, and must have at least one field. */\n data: Record<string, unknown>;\n /** Field-equality precondition; a mismatch fails the whole blob with 409. */\n precondition?: Record<string, unknown>;\n /** Optional 26-char uppercase Crockford ULID naming this operation. On a record-log document a retry carrying an id the document already holds is answered from its first outcome and not applied again. */\n requestId?: string;\n } | {\n model: string;\n action: \"patch\";\n /** The id of an existing record. */\n id: string;\n /** Record fields. Required, and must have at least one field. */\n data: Record<string, unknown>;\n /** Field-equality precondition; a mismatch fails the whole blob with 409. */\n precondition?: Record<string, unknown>;\n /** Optional 26-char uppercase Crockford ULID naming this operation. On a record-log document a retry carrying an id the document already holds is answered from its first outcome and not applied again. */\n requestId?: string;\n } | {\n model: string;\n action: \"delete\";\n /** The id of an existing record. */\n id: string;\n /** Field-equality precondition; a mismatch fails the whole blob with 409. */\n precondition?: Record<string, unknown>;\n /** Optional 26-char uppercase Crockford ULID naming this operation. On a record-log document a retry carrying an id the document already holds is answered from its first outcome and not applied again. */\n requestId?: string;\n } | {\n model: string;\n action: \"upsert\";\n /** Name of a unique constraint the model declares (a compound `unique_constraints` name, or `<model>_<field>_unique` for a `unique` field). Must not include `id`. */\n constraint: string;\n /** Optional 26-char uppercase Crockford ULID, used only when the op creates the record; the server mints one when absent. */\n id?: string;\n /** Record fields, carrying every field of the constraint and no `id`. Merged into the record holding that key, or used to create one. */\n data: Record<string, unknown>;\n /** Field-equality precondition on the resolved record; a mismatch or no record fails the whole blob with 409. */\n precondition?: Record<string, unknown>;\n /** Optional 26-char uppercase Crockford ULID naming this operation. On a record-log document a retry carrying an id the document already holds is answered from its first outcome and not applied again. */\n requestId?: string;\n }>;\n /** On a db3: `false` applies each op on its own, committing those that pass and answering a result per op; omitted or `true`, all or nothing. */\n atomic?: boolean;\n /** On a db3: an optional 26-char uppercase Crockford ULID naming this whole request. It is echoed in the answer, and a retry carrying it is answered with the first answer byte for byte. */\n requestId?: string;\n };\n }): Promise<{\n applied?: number;\n /** The records the bulk created, each `{ model, id }`, in input order; on a db3 an entry its hook rules wrote into also carries `appliedFields`, the fields written with their values. */\n added?: {\n model: string;\n id: string;\n /** On a db3: every field its hook rules wrote into the record, with the value written; absent when they wrote none. */\n appliedFields?: Record<string, unknown>;\n }[];\n /** The records the bulk patched, each `{ model, id }`, in input order; on a db3 an entry its hook rules wrote into also carries `appliedFields`. */\n updated?: {\n model: string;\n id: string;\n /** On a db3: every field its hook rules wrote into the record, with the value written; absent when they wrote none. */\n appliedFields?: Record<string, unknown>;\n }[];\n deleted?: number;\n /** `false` when the db3 applied each op on its own; the counts and lists name the passing ops. */\n atomic?: boolean;\n /** With `atomic: false`: one result per op, in order. A passing op has `ok: true`, its `kind` and the record `id`; a refused one `ok: false` with its `code`, `status` and `error` (e.g. `DB3_CONDITION_NOT_MET` 409, `DB3_RECORD_NOT_FOUND` 404, `DB3_RECORD_EXISTS` 409). */\n results?: {\n index: number;\n model: string;\n id?: string;\n ok: boolean;\n /** What the op did; `incremented` for a db3 `increment`. */\n kind?: \"added\" | \"updated\" | \"upserted\" | \"deleted\" | \"incremented\";\n created?: boolean;\n removed?: boolean;\n /** For an `incremented` op: each incremented field's new value. */\n values?: Record<string, number>;\n /** For a passing op on a db3: every field its hook rules wrote, with the value written; absent when they wrote none. */\n appliedFields?: Record<string, unknown>;\n code?: string;\n status?: number;\n error?: string;\n /** For an op refused `DB3_TRIGGER_REFUSED`: the refusing trigger's own code. */\n reason?: string;\n requestId?: string;\n }[];\n /** The request's own id, echoed. */\n requestId?: string;\n /** One entry per upsert op, in input order: the op's index, the record id, and whether the op created it. */\n upserted?: {\n index?: number;\n model?: string;\n id?: string;\n created?: boolean;\n /** On a db3: every field its hook rules wrote into the record, with the value written; absent when they wrote none. */\n appliedFields?: Record<string, unknown>;\n }[];\n /** On a db3, only when the blob carried an `increment`: one entry per passing increment op, in input order, with the fields' new values. */\n incremented?: {\n index?: number;\n model?: string;\n id?: string;\n values?: Record<string, number>;\n }[];\n }>;\n /** `documents.records.count` — GET /documents/{documentId}/records/{model}/count. Count records in a document model */\n \"count\"(args: {\n \"documentId\": string | number;\n \"model\": string | number;\n \"documentFormat\"?: string | number | boolean;\n \"filter\"?: Record<string, unknown> | string;\n }): Promise<{\n count: number;\n }>;\n /** `documents.records.delete` — DELETE /documents/{documentId}/records/{model}/{recordId}. Delete a record from a document model */\n \"delete\"(args: {\n \"documentId\": string | number;\n \"model\": string | number;\n \"recordId\": string | number;\n \"documentFormat\"?: string | number | boolean;\n \"requestId\"?: string | number | boolean;\n \"condition\"?: string | number | boolean;\n }): Promise<{\n deleted: boolean;\n }>;\n /** `documents.records.patch` — PATCH /documents/{documentId}/records/{model}/{recordId}. Merge fields into an existing record in a document model */\n \"patch\"(args: {\n \"documentId\": string | number;\n \"model\": string | number;\n \"recordId\": string | number;\n \"documentFormat\"?: string | number | boolean;\n body: {\n /** The fields to merge into the record. */\n data: Record<string, unknown>;\n /** Per-write options forwarded to the document facade. */\n options?: {\n /** On a db3: a guard in the query filter grammar (the `filter` a query takes, e.g. `{ status: \"open\", n: { $lt: 5 } }`). The write applies only when the record is live and matches it; otherwise it is refused 409 `DB3_CONDITION_NOT_MET` and nothing is written. A missing record meets no condition. An invalid one is 400 `DOCUMENT_ENTRY_INVALID`. */\n condition?: Record<string, unknown>;\n /** Save only: apply only when no record has this id; otherwise 409 `CONDITION_NOT_MET`. */\n ifNotExists?: boolean;\n /** Save only: land on the live record holding the same key instead of creating one. On a db3 it names a unique constraint of the model (`<model>_<field>_unique`, a compound constraint's name or a registered unique index's) or a field; elsewhere a field. */\n upsertOn?: string;\n /** Field-equality map the live record must hold; a mismatch or a missing record is 409 `CONDITION_NOT_MET`. */\n precondition?: Record<string, unknown>;\n };\n /** Optional 26-char uppercase Crockford ULID naming this write. On a record-log document a retry carrying an id the document already holds is answered from its first outcome and not applied again. */\n requestId?: string;\n };\n }): Promise<{\n /** The saved record, with the model's own fields. */\n record: Record<string, unknown>;\n /** On a db3: every field its hook rules wrote (timestamps, auto-populated fields, triggers), with the value written, whether or not it equals the value sent; absent when they wrote none. */\n appliedFields?: Record<string, unknown>;\n }>;\n /** `documents.records.query` — GET /documents/{documentId}/records/{model}. Query records in a document model */\n \"query\"(args: {\n \"documentId\": string | number;\n \"model\": string | number;\n \"documentFormat\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"filter\"?: Record<string, unknown> | string;\n \"sort\"?: Record<string, unknown> | string;\n \"include\"?: unknown[] | string;\n }): Promise<{\n items: Record<string, unknown>[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /** `documents.records.save` — POST /documents/{documentId}/records/{model}. Create or replace a record in a document model */\n \"save\"(args: {\n \"documentId\": string | number;\n \"model\": string | number;\n \"documentFormat\"?: string | number | boolean;\n body: {\n /** The record's id. Must not contain the reserved key separator. */\n id: string;\n /** The record's fields. */\n data: Record<string, unknown>;\n /** Per-write options forwarded to the document facade. */\n options?: {\n /** On a db3: a guard in the query filter grammar (the `filter` a query takes, e.g. `{ status: \"open\", n: { $lt: 5 } }`). The write applies only when the record is live and matches it; otherwise it is refused 409 `DB3_CONDITION_NOT_MET` and nothing is written. A missing record meets no condition. An invalid one is 400 `DOCUMENT_ENTRY_INVALID`. */\n condition?: Record<string, unknown>;\n /** Save only: apply only when no record has this id; otherwise 409 `CONDITION_NOT_MET`. */\n ifNotExists?: boolean;\n /** Save only: land on the live record holding the same key instead of creating one. On a db3 it names a unique constraint of the model (`<model>_<field>_unique`, a compound constraint's name or a registered unique index's) or a field; elsewhere a field. */\n upsertOn?: string;\n /** Field-equality map the live record must hold; a mismatch or a missing record is 409 `CONDITION_NOT_MET`. */\n precondition?: Record<string, unknown>;\n };\n /** Optional 26-char uppercase Crockford ULID naming this write. On a record-log document a retry carrying an id the document already holds is answered from its first outcome and not applied again. */\n requestId?: string;\n };\n }): Promise<{\n /** The saved record, with the model's own fields. */\n record: Record<string, unknown>;\n /** On a db3: every field its hook rules wrote (timestamps, auto-populated fields, triggers), with the value written, whether or not it equals the value sent; absent when they wrote none. */\n appliedFields?: Record<string, unknown>;\n }>;\n };\n /** `documents.removePermissionByEmail` — DELETE /documents/{documentId}/permissions. Revoke a user's permission on a document by email (?email=) */\n \"removePermissionByEmail\"(args: {\n \"documentId\": string | number;\n \"email\"?: string | number | boolean;\n }): Promise<{\n success: boolean;\n message?: string;\n status?: string;\n email?: string;\n deferredCount?: number;\n }>;\n /** `documents.removePermissionByUserId` — DELETE /documents/{documentId}/permissions/{userId}. Revoke a user's permission on a document by user id */\n \"removePermissionByUserId\"(args: {\n \"documentId\": string | number;\n \"userId\": string | number;\n }): Promise<{\n success: boolean;\n message?: string;\n }>;\n /** `documents.removeTag` — DELETE /documents/{documentId}/tags/{tag}. Remove a tag from a document */\n \"removeTag\"(args: {\n \"documentId\": string | number;\n \"tag\": string | number;\n }): Promise<{\n documentId: string;\n tags: string[];\n }>;\n /** `documents.requestAccess` — POST /documents/{documentId}/access-requests. Request access to a document */\n \"requestAccess\"(args: {\n \"documentId\": string | number;\n body: {\n /** The level being asked for. */\n permission: \"read-write\" | \"reader\";\n /** Note shown to the reviewer. */\n message?: string;\n /** Link included in the reviewer's email. */\n documentUrl?: string;\n /** Where the reviewer lands to act on the request. */\n reviewUrl?: string;\n /** Email the reviewer. */\n sendEmail?: boolean;\n /** Not read by the handler; use `permission`. */\n role?: string;\n };\n }): Promise<{\n success: boolean;\n message?: string;\n request: {\n requestId: string;\n documentId: string;\n requesterId: string;\n status: string;\n requestedPermission?: string;\n message?: string;\n createdAt?: string;\n resolvedBy?: string;\n resolvedAt?: string;\n grantedPermission?: string;\n };\n document?: {\n documentId?: string;\n title?: string | null;\n tags?: string[];\n createdAt?: string;\n lastModified?: string;\n createdBy?: string;\n };\n }>;\n /** `documents.requestSnapshot` — POST /documents/{documentId}/snapshots. Snapshot a large document now: seal the open epoch and build a base */\n \"requestSnapshot\"(args: {\n \"documentId\": string | number;\n body: Record<string, unknown>;\n }): Promise<{\n sealed: boolean;\n reason: string;\n coveringBuildId?: string | null;\n }>;\n /** `documents.revokeGroupPermission` — DELETE /documents/{documentId}/group-permissions/{groupId}. Revoke a group permission on a document */\n \"revokeGroupPermission\"(args: {\n \"documentId\": string | number;\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<{\n success: boolean;\n }>;\n /**\n * `documents.revokeGroupPermissionByType` — DELETE /documents/{documentId}/group-permissions/{groupType}/{groupId}. DEPRECATED — Revoke a group permission on a document, by type; use DELETE /documents/{documentId}/group-permissions/{groupId} (removal: #4718)\n * @deprecated Use DELETE /documents/{documentId}/group-permissions/{groupId} (removal: #4718)\n */\n \"revokeGroupPermissionByType\"(args: {\n \"documentId\": string | number;\n \"groupType\": string | number;\n \"groupId\": string | number;\n }): Promise<{\n success: boolean;\n }>;\n /** `documents.room` — GET /documents/{documentId}/room. Inspect a record-log document's room */\n \"room\"(args: {\n \"documentId\": string | number;\n \"refused\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n ok: boolean;\n appId: string;\n documentId: string;\n documentFormat: number;\n /** With refused: the session's refused rows, oldest first. */\n refused?: {\n sessionId?: string;\n items?: {\n model?: string;\n id?: string;\n code?: string;\n constraint?: string;\n conflicting?: {\n model?: string;\n id?: string;\n };\n }[];\n hasMore?: boolean;\n nextCursor?: string;\n };\n /** The record room's state; null for formats 1 and 2. */\n room: {\n lsn?: number;\n /** current, next, high, floor, rotatedAt, entriesSinceRotation. */\n epochs?: Record<string, unknown>;\n cursorFloor?: number;\n /** count, connected. */\n writers?: Record<string, unknown>;\n subscribers?: number;\n /** entries, writers. */\n held?: Record<string, unknown>;\n /** compact, full: the writers' own acknowledgements of accepted entries since the room last woke, sent without changes (to a writer that declared compact acknowledgements, for an entry the room applied as written) and with them. */\n acks?: Record<string, unknown>;\n /** The bulk load in progress, or null. */\n load?: Record<string, unknown> | null;\n /** The bulk loads the room still keeps, oldest first. */\n loads?: Record<string, unknown>[];\n /** The current segment, as `GET …/snapshots/{segmentId}` describes it, or null. */\n segment?: Record<string, unknown> | null;\n /** The segment export in progress, or null. */\n segmentExport?: Record<string, unknown> | null;\n /** The automatic segments' spacing: lastStartedAt, nextAllowedAt. */\n segmentAuto?: Record<string, unknown>;\n /** The pending change check for an automatic segment (at, reason), or null. */\n segmentCheck?: Record<string, unknown> | null;\n /** Where the last change check that found no segment due counted to, or null. */\n segmentCheckedLsn?: number | null;\n /** The last checkpoint, or null. */\n checkpoint?: Record<string, unknown> | null;\n /** Whether the room admits sockets (the db3's sync). */\n sync?: boolean;\n /** The sync flip holding the room's lease, or null. */\n syncFlip?: Record<string, unknown> | null;\n /** What the hook rules hold: timestamps, autoPopulatedFields, triggers (per model). */\n hooks?: Record<string, unknown>;\n /** The db3's type and the revision it installed, or null. */\n type?: Record<string, unknown> | null;\n /** True when the room has nothing left for its alarm to do: no entry in the window, nothing left to prune and no subscriber. A quiet room holds no alarm; its next write wakes it. */\n quiet?: boolean;\n /** When the room's alarm next runs (the daily checkpoint or the epoch's maximum age), in milliseconds; null while the room is quiet. */\n nextAlarmAt?: number | null;\n /** databaseSize. */\n storage?: Record<string, unknown>;\n } | null;\n }>;\n /** `documents.setLinkAccess` — PUT /documents/{documentId}/link-access. Set the document's \"anyone with the link\" access level */\n \"setLinkAccess\"(args: {\n \"documentId\": string | number;\n body: {\n level: \"reader\" | \"read-write\";\n };\n }): Promise<{\n documentId: string;\n /** `reader`, `read-write`, or null when link access is off. */\n linkAccess: string | null;\n linkAccessUpdatedBy?: string;\n linkAccessUpdatedAt?: string;\n }>;\n /** `documents.transferOwnership` — POST /documents/{documentId}/permissions/transfer. Transfer ownership of a document to another user */\n \"transferOwnership\"(args: {\n \"documentId\": string | number;\n body: {\n /** The user the ownership moves to. */\n newOwnerId: string;\n /** Not read by the handler; use `newOwnerId`. */\n userId?: string;\n /** Not read by the handler; use `newOwnerId`. */\n email?: string;\n };\n }): Promise<{\n success: boolean;\n message?: string;\n previousOwnerId?: string;\n newOwnerId?: string;\n }>;\n /** `documents.update` — PUT /documents/{documentId}. Update a document's metadata */\n \"update\"(args: {\n \"documentId\": string | number;\n body: {\n /** Not read by the handler — send `title` instead. */\n name?: string;\n /** Not read by the handler. */\n parentId?: string;\n title?: string;\n /** A blob already attached to this document; refused on create. */\n thumbnailBlobId?: string;\n metadata?: Record<string, unknown>;\n };\n }): Promise<{\n documentId: string;\n title?: string | null;\n createdBy?: string;\n createdAt?: string;\n lastModified?: string;\n modifiedAt?: string;\n appId?: string;\n isAdmin?: boolean;\n permission?: string;\n accessSource?: string;\n grantedAt?: string;\n linkAccess?: \"reader\" | \"read-write\";\n tags?: string[];\n thumbnailBlobId?: string;\n /** Caller-defined metadata blob. */\n metadata?: Record<string, unknown>;\n /** Present only for a large document (#2816). */\n documentFormat?: number;\n invitationAccepted?: boolean;\n upgradedFromPermission?: string;\n collectionId?: string;\n addedAt?: string;\n addedBy?: string;\n }>;\n /** `documents.updatePermissions` — PUT /documents/{documentId}/permissions. Grant or update a user's permission on a document */\n \"updatePermissions\"(args: {\n \"documentId\": string | number;\n body: {\n userId?: string;\n email?: string;\n /** Required on the single-grant arm. */\n permission?: \"read-write\" | \"reader\";\n /** The multi-grant arm: each entry needs `userId` or `email` and a `permission`. */\n permissions?: {\n userId?: string;\n email?: string;\n permission: \"read-write\" | \"reader\";\n }[];\n /** Email the grantee. Requires `documentUrl`. */\n sendEmail?: boolean;\n /** Link used in the email; required when `sendEmail` is true. */\n documentUrl?: string;\n /** Optional message in the email; max 500 characters. */\n note?: string;\n /** Not read by the handler; use `permission`. */\n role?: string;\n };\n }): Promise<{\n success: boolean;\n message?: string;\n /** Present on the multi-update arm: one entry per resolved grantee, plus the deferred (unresolved email) entries. */\n results?: {\n status?: string;\n userId?: string;\n email?: string;\n permission?: string;\n /** A `pending_signup` entry: whether this call created the app invitation. */\n appInvitationCreated?: boolean;\n /** A `pending_signup` entry: the app invitation's id. */\n invitationId?: string;\n /** A `pending_signup` entry: the app invitation's accept token. */\n inviteToken?: string | null;\n }[];\n }>;\n /** `documents.uploadIngestChunk` — POST /documents/{documentId}/ingest/{sessionId}/chunks. Upload one chunk of a bulk-load session's artifact */\n \"uploadIngestChunk\"(args: {\n \"documentId\": string | number;\n \"sessionId\": string | number;\n body: FormData | ArrayBuffer | Uint8Array | string;\n }): Promise<{\n ok: boolean;\n bytes?: number;\n ordinal?: number;\n }>;\n /** `documents.validateAccess` — POST /documents/{documentId}/validate-access. Resolve effective access to a document, for the caller or a named user */\n \"validateAccess\"(args: {\n \"documentId\": string | number;\n body?: {\n /** Resolve this user's effective access instead of the caller's. Must be a non-empty string naming a member of this app. */\n userId?: string;\n };\n }): Promise<{\n success: boolean;\n hasAccess: boolean;\n /** Absent when `hasAccess` is false. */\n permission?: string;\n /** How the access was obtained. Present whenever `hasAccess` is true. */\n accessSource?: \"owner\" | \"grant\" | \"group\" | \"link\" | \"app\";\n /** The SUBJECT's app role, present only in the `userId` form. Reported beside the grant, never folded into `permission`: the tag routes are the only routes that admit `appRole` of `admin` or `owner` without a grant, while `PUT documents/{documentId}` and the other content writes require a real grant from everybody. `GET documents/{documentId}` does bypass the grant, but for a CONSOLE administrator's token, not for an app role — an `admin` here is refused that read without a grant, so a reader must not be admitted on `appRole`. */\n appRole?: \"owner\" | \"admin\" | \"member\";\n invitationAccepted?: boolean;\n upgradedFromPermission?: string;\n }>;\n };\n \"email\": {\n /** `email.send` — POST /emails/send. Send an application email under a server function's grant */\n \"send\"(args: {\n body: {\n /** The recipient's email address. */\n to?: string;\n /** A member of this app, whose address is resolved server-side. */\n toUserId?: string;\n /** A registered template type — the app's override, or a built-in. */\n templateType?: string;\n /** Required in inline mode; overrides the template's subject in template mode. */\n subject?: string;\n /** Inline mode's HTML body. */\n htmlBody?: string;\n /** Inline mode's text body. */\n textBody?: string;\n /** Values interpolated into the subject and bodies. */\n variables?: Record<string, unknown>;\n };\n }): Promise<{\n success: boolean;\n /** The provider's id for the message. */\n messageId?: string;\n to: string;\n /** The template that rendered, or `(inline)`. */\n templateType: string;\n /** The rendered subject. */\n subject: string;\n }>;\n };\n \"functions\": {\n /** `functions.getStatus` — GET /functions/runs/{runId}/status. Get the status of a function run by run id */\n \"getStatus\"(args: {\n \"runId\": string | number;\n }): Promise<{\n /** The reconciled run status, and what came out of the run. */\n status: {\n /** The canonical vocabulary (#2348): `queued`, `running`, `apply_pending`, `apply_claimed`, `completed`, `failed`, `terminated`, `skipped`, `missing`. A plain string rather than an `enum` so a server-added state is never a spec violation. */\n status: string;\n /** The run's output, when it produced one. Any JSON value. For a task run it is recorded on the run itself as the run settles, so it is answered for the life of the run row whether or not the engine still holds the instance. */\n output?: unknown;\n /** Why the run failed. An object for every failed durable run, `null` on a read that has not failed, and a string on the older shape. Read `message`: a platform refusal leads its message with its code, and `name` is the error's own name rather than that code. */\n error?: null | string | {\n /** The error's name, NOT the platform's error code. `WorkflowError` when the platform built the object itself; a function run's thrown error's own name (`Error` for a plain throw) when Cloudflare recorded it; absent when the engine kept only the message. */\n name?: string;\n /** What went wrong. A platform refusal leads with its code — `FUNCTION_OUTPUT_INVALID`, `OUTPUT_TOO_LARGE`, `OUTPUT_NOT_SERIALIZABLE` — so this is where the code is. An engine-level failure is the exception: its message is the engine's own text and its code is in `code`. */\n message: string;\n /** #3564 — the platform's classification of this failure, from the closed `RUN_ERROR_CODES` set, on a FUNCTION run that carries one. The same value the run block's `errorCode` carries; absent on every DSL run, and on a FUNCTION run the platform did not classify. #3662 — a failed FUNCTION run that was neither a platform refusal nor an engine failure is the handler throwing, so it carries `FUNCTION_THREW` rather than nothing. The `ENGINE_*` family says the run died in the engine rather than in application code, which is what makes it worth branching on: `ENGINE_ISOLATE_EVICTED`, `ENGINE_CODE_UPDATED`, `ENGINE_SLICE_DEADLINE`, `ENGINE_STORAGE_ERROR`, `ENGINE_INTERNAL_ERROR`, `ENGINE_INSTANCE_LOST`, `ENGINE_START_FAILED`. The rest are the function's own: `FUNCTION_THREW`, `FUNCTION_NO_HANDLER`, `FUNCTION_TIMEOUT`, `FUNCTION_INPUT_INVALID`, `FUNCTION_OUTPUT_INVALID`, `FUNCTION_RUNTIME_REFUSED`, `FUNCTION_DELETED`, `FUNCTION_STALLED`, `OUTPUT_NOT_SERIALIZABLE`, `OUTPUT_TOO_LARGE`. */\n code?: string;\n };\n /** Why the run did not run, when `status` is `skipped`. */\n skipReason?: string;\n };\n /** The persisted run record. */\n run: Record<string, unknown>;\n /** The task slice's record (#3381), present only for a task run that has one. */\n slice?: Record<string, unknown>;\n }>;\n /** `functions.getStatusByRunKey` — GET /functions/{functionKey}/instances/{runKey}/status. Get the status of a function run by run key */\n \"getStatusByRunKey\"(args: {\n \"functionKey\": string | number;\n \"runKey\": string | number;\n \"contextDocId\"?: string | number | boolean;\n }): Promise<{\n /** The reconciled run status, and what came out of the run. */\n status: {\n /** The canonical vocabulary (#2348): `queued`, `running`, `apply_pending`, `apply_claimed`, `completed`, `failed`, `terminated`, `skipped`, `missing`. A plain string rather than an `enum` so a server-added state is never a spec violation. */\n status: string;\n /** The run's output, when it produced one. Any JSON value. For a task run it is recorded on the run itself as the run settles, so it is answered for the life of the run row whether or not the engine still holds the instance. */\n output?: unknown;\n /** Why the run failed. An object for every failed durable run, `null` on a read that has not failed, and a string on the older shape. Read `message`: a platform refusal leads its message with its code, and `name` is the error's own name rather than that code. */\n error?: null | string | {\n /** The error's name, NOT the platform's error code. `WorkflowError` when the platform built the object itself; a function run's thrown error's own name (`Error` for a plain throw) when Cloudflare recorded it; absent when the engine kept only the message. */\n name?: string;\n /** What went wrong. A platform refusal leads with its code — `FUNCTION_OUTPUT_INVALID`, `OUTPUT_TOO_LARGE`, `OUTPUT_NOT_SERIALIZABLE` — so this is where the code is. An engine-level failure is the exception: its message is the engine's own text and its code is in `code`. */\n message: string;\n /** #3564 — the platform's classification of this failure, from the closed `RUN_ERROR_CODES` set, on a FUNCTION run that carries one. The same value the run block's `errorCode` carries; absent on every DSL run, and on a FUNCTION run the platform did not classify. #3662 — a failed FUNCTION run that was neither a platform refusal nor an engine failure is the handler throwing, so it carries `FUNCTION_THREW` rather than nothing. The `ENGINE_*` family says the run died in the engine rather than in application code, which is what makes it worth branching on: `ENGINE_ISOLATE_EVICTED`, `ENGINE_CODE_UPDATED`, `ENGINE_SLICE_DEADLINE`, `ENGINE_STORAGE_ERROR`, `ENGINE_INTERNAL_ERROR`, `ENGINE_INSTANCE_LOST`, `ENGINE_START_FAILED`. The rest are the function's own: `FUNCTION_THREW`, `FUNCTION_NO_HANDLER`, `FUNCTION_TIMEOUT`, `FUNCTION_INPUT_INVALID`, `FUNCTION_OUTPUT_INVALID`, `FUNCTION_RUNTIME_REFUSED`, `FUNCTION_DELETED`, `FUNCTION_STALLED`, `OUTPUT_NOT_SERIALIZABLE`, `OUTPUT_TOO_LARGE`. */\n code?: string;\n };\n /** Why the run did not run, when `status` is `skipped`. */\n skipReason?: string;\n };\n /** The persisted run record. */\n run: Record<string, unknown>;\n /** The task slice's record (#3381), present only for a task run that has one. */\n slice?: Record<string, unknown>;\n }>;\n /** `functions.invoke` — POST /functions/{functionKey}. Invoke a server function and answer its result */\n \"invoke\"(args: {\n \"functionKey\": string | number;\n body?: {\n /** The value passed to the handler as its `input`. */\n rootInput?: Record<string, unknown>;\n /** Accepted and ignored — a request invocation writes no run row to deduplicate against. */\n runKey?: string;\n contextDocId?: string;\n /** Caller-supplied metadata, at most 1 KB encoded. */\n meta?: Record<string, unknown>;\n /** Wall-clock budget for the invocation. Defaults to 5000 and clamps silently to the platform ceiling of 30000. */\n timeoutMs?: number;\n };\n }): Promise<{\n status?: string;\n /** Present when `status` is `completed`. */\n output?: Record<string, unknown>;\n error?: string;\n errorCode?: string;\n /** The invocation-log record this answer belongs to (#3448), minted before the run so the record and the answer share it. Hand it to `functions logs --invocation`. Present exactly when the platform recorded the invocation; a gate refusal carries none. */\n invocationId?: string;\n /** The resolved platform ceilings the sandbox ran under — `[function.limits]` clamped element-wise to the platform's own values. Present on every request outcome the sandbox produced (`completed`, and a `failed` the handler itself caused); absent from a refusal that never reached the sandbox, which has no run to describe. */\n limits?: {\n cpuMs?: number;\n subRequests?: number;\n ratePerMinute?: number;\n };\n }>;\n /** `functions.invokeAsSystem` — POST /functions/{functionKey}/invoke-as-system. Invoke a server function as the system, with no caller */\n \"invokeAsSystem\"(args: {\n \"functionKey\": string | number;\n body?: {\n /** The value passed to the handler as its `input`. */\n rootInput?: Record<string, unknown>;\n runKey?: string;\n /** Accepted and ignored on the request runtime. */\n contextDocId?: string;\n meta?: Record<string, unknown>;\n timeoutMs?: number;\n };\n }): Promise<{\n status?: string;\n output?: Record<string, unknown>;\n error?: string;\n errorCode?: string;\n invocationId?: string;\n limits?: Record<string, unknown>;\n }>;\n /** `functions.listRunSteps` — GET /functions/runs/{runId}/steps. List a function run's steps, oldest first */\n \"listRunSteps\"(args: {\n \"runId\": string | number;\n }): Promise<{\n items: Record<string, unknown>[];\n }>;\n /** `functions.listRuns` — GET /functions/runs. List the caller's own function runs */\n \"listRuns\"(args?: {\n \"functionKey\"?: string | number | boolean;\n \"contextDocId\"?: string | number | boolean;\n \"status\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"forward\"?: string | number | boolean;\n }): Promise<{\n items: Record<string, unknown>[];\n hasMore: boolean;\n nextCursor?: string;\n /** Index rows examined, on a read without `contextDocId`. A `nextCursor` with fewer than `limit` items means the walk stopped on its budget rather than at the end. */\n scanned?: number;\n }>;\n /** `functions.logs` — GET /functions/{functionKey}/logs. List a server function's invocation logs, newest first */\n \"logs\"(args: {\n \"functionKey\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"runId\"?: string | number | boolean;\n }): Promise<{\n items: Record<string, unknown>[];\n hasMore: boolean;\n nextCursor?: string;\n }>;\n /** `functions.start` — POST /functions/{functionKey}/start. Start a server function as a task run */\n \"start\"(args: {\n \"functionKey\": string | number;\n body?: {\n /** The value passed to the callee as its `input`. */\n rootInput?: Record<string, unknown>;\n /** Idempotency key, scoped to the tree's root initiator and the resolved `contextDocId`: a repeat replays the existing run rather than starting a second. At most 100 characters. */\n runKey?: string;\n /** The document the run is keyed under. Defaults through the inheritance rule above. At most 100 characters. */\n contextDocId?: string;\n /** Caller-supplied metadata, at most 1 KB encoded. The platform's `parent` and `nestDepth` are written over it. */\n meta?: Record<string, unknown>;\n };\n }): Promise<{\n runId?: string;\n runKey?: string;\n instanceId?: string;\n status?: string;\n /** Why the existing run did not run, when its `status` is `skipped`; else null. */\n skipReason?: string | null;\n existing?: boolean;\n }>;\n /** `functions.startAsSystem` — POST /functions/{functionKey}/start-as-system. Start a server function as a task run, as the system */\n \"startAsSystem\"(args: {\n \"functionKey\": string | number;\n body?: {\n /** The value passed to the handler as its `input`. */\n rootInput?: Record<string, unknown>;\n runKey?: string;\n /** The run's context document. Absent, the synthetic `fn:<functionId>` — there is no app user to take a root document from. */\n contextDocId?: string;\n meta?: Record<string, unknown>;\n timeoutMs?: number;\n };\n }): Promise<{\n runId?: string;\n runKey?: string;\n instanceId?: string;\n status?: string;\n /** Why the existing run did not run, when its `status` is `skipped`; else null. */\n skipReason?: string | null;\n existing?: boolean;\n }>;\n /** `functions.terminate` — POST /functions/{functionKey}/instances/{runKey}/terminate. Terminate a function run */\n \"terminate\"(args: {\n \"functionKey\": string | number;\n \"runKey\": string | number;\n \"contextDocId\"?: string | number | boolean;\n }): Promise<{\n /** The reconciled run status, and what came out of the run. */\n status: {\n /** The canonical vocabulary (#2348): `queued`, `running`, `apply_pending`, `apply_claimed`, `completed`, `failed`, `terminated`, `skipped`, `missing`. A plain string rather than an `enum` so a server-added state is never a spec violation. */\n status: string;\n /** The run's output, when it produced one. Any JSON value. For a task run it is recorded on the run itself as the run settles, so it is answered for the life of the run row whether or not the engine still holds the instance. */\n output?: unknown;\n /** Why the run failed. An object for every failed durable run, `null` on a read that has not failed, and a string on the older shape. Read `message`: a platform refusal leads its message with its code, and `name` is the error's own name rather than that code. */\n error?: null | string | {\n /** The error's name, NOT the platform's error code. `WorkflowError` when the platform built the object itself; a function run's thrown error's own name (`Error` for a plain throw) when Cloudflare recorded it; absent when the engine kept only the message. */\n name?: string;\n /** What went wrong. A platform refusal leads with its code — `FUNCTION_OUTPUT_INVALID`, `OUTPUT_TOO_LARGE`, `OUTPUT_NOT_SERIALIZABLE` — so this is where the code is. An engine-level failure is the exception: its message is the engine's own text and its code is in `code`. */\n message: string;\n /** #3564 — the platform's classification of this failure, from the closed `RUN_ERROR_CODES` set, on a FUNCTION run that carries one. The same value the run block's `errorCode` carries; absent on every DSL run, and on a FUNCTION run the platform did not classify. #3662 — a failed FUNCTION run that was neither a platform refusal nor an engine failure is the handler throwing, so it carries `FUNCTION_THREW` rather than nothing. The `ENGINE_*` family says the run died in the engine rather than in application code, which is what makes it worth branching on: `ENGINE_ISOLATE_EVICTED`, `ENGINE_CODE_UPDATED`, `ENGINE_SLICE_DEADLINE`, `ENGINE_STORAGE_ERROR`, `ENGINE_INTERNAL_ERROR`, `ENGINE_INSTANCE_LOST`, `ENGINE_START_FAILED`. The rest are the function's own: `FUNCTION_THREW`, `FUNCTION_NO_HANDLER`, `FUNCTION_TIMEOUT`, `FUNCTION_INPUT_INVALID`, `FUNCTION_OUTPUT_INVALID`, `FUNCTION_RUNTIME_REFUSED`, `FUNCTION_DELETED`, `FUNCTION_STALLED`, `OUTPUT_NOT_SERIALIZABLE`, `OUTPUT_TOO_LARGE`. */\n code?: string;\n };\n /** Why the run did not run, when `status` is `skipped`. */\n skipReason?: string;\n };\n /** The persisted run record. */\n run: Record<string, unknown>;\n /** The task slice's record (#3381), present only for a task run that has one. */\n slice?: Record<string, unknown>;\n }>;\n };\n \"groups\": {\n /** `groups.addMember` — POST /groups/{groupId}/members. Add a member to a group */\n \"addMember\"(args: {\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n body: {\n userId: string;\n role?: \"owner\" | \"manager\" | \"member\";\n requireExistingUser?: boolean;\n } | {\n email: string;\n role?: \"owner\" | \"manager\" | \"member\";\n requireExistingUser?: boolean;\n };\n }): Promise<{\n status: \"added\" | \"already_member\" | \"pending_signup\";\n userId?: string;\n userName?: string;\n userEmail?: string;\n role?: string;\n addedAt?: string | null;\n addedBy?: string | null;\n email?: string;\n appInvitationCreated?: boolean;\n deferredId?: string;\n expiresAt?: string | null;\n groupType?: string;\n groupId?: string;\n invitationId?: string | null;\n inviteToken?: string | null;\n }>;\n /**\n * `groups.addMemberByType` — POST /groups/{groupType}/{groupId}/members. DEPRECATED — Add a member to a group, by type; use POST /groups/{groupId}/members (removal: #4718)\n * @deprecated Use POST /groups/{groupId}/members (removal: #4718)\n */\n \"addMemberByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n body: {\n userId: string;\n requireExistingUser?: boolean;\n } | {\n email: string;\n requireExistingUser?: boolean;\n };\n }): Promise<{\n status: \"added\" | \"already_member\" | \"pending_signup\";\n userId?: string;\n userName?: string;\n userEmail?: string;\n role?: string;\n addedAt?: string | null;\n addedBy?: string | null;\n email?: string;\n appInvitationCreated?: boolean;\n deferredId?: string;\n expiresAt?: string | null;\n groupType?: string;\n groupId?: string;\n invitationId?: string | null;\n inviteToken?: string | null;\n }>;\n /** `groups.create` — POST /groups. Create a group */\n \"create\"(args: {\n body: {\n /** Deprecated (removal: #4718): groups are addressed by `groupId` alone. Checked and ignored: a new group is stored as type `group`. @deprecated */\n groupType?: string;\n name: string;\n description?: string;\n /** `app` or `user:<userId>`. Named only by a server function or the admin API. */\n custodian?: string;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n /** Members written with the group, each `manager` or `member` (the default). Named only by a server function or the admin API. */\n initialMembers?: {\n userId: string;\n role?: \"manager\" | \"member\";\n }[];\n /** Metadata written with the group. */\n initialMetadata?: Record<string, unknown>;\n };\n }): Promise<{\n appId: string;\n /** Deprecated (removal: #4718): groups are addressed by `groupId` alone. */\n groupType: string;\n groupId: string;\n name: string;\n description?: string | null;\n memberCount?: number;\n /** `user:<userId>` or `app`; null on a group created before custody. */\n custodian?: string | null;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n createdAt?: string | null;\n createdBy?: string | null;\n modifiedAt?: string | null;\n }>;\n /** `groups.delete` — DELETE /groups/{groupId}. Delete a group */\n \"delete\"(args: {\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<{\n success: boolean;\n }>;\n /**\n * `groups.deleteByType` — DELETE /groups/{groupType}/{groupId}. DEPRECATED — Delete a group, by type; use DELETE /groups/{groupId} (removal: #4718)\n * @deprecated Use DELETE /groups/{groupId} (removal: #4718)\n */\n \"deleteByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n }): Promise<{\n success: boolean;\n }>;\n /** `groups.get` — GET /groups/{groupId}. Get a group */\n \"get\"(args: {\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<{\n appId: string;\n /** Deprecated (removal: #4718): groups are addressed by `groupId` alone. */\n groupType: string;\n groupId: string;\n name: string;\n description?: string | null;\n memberCount?: number;\n /** `user:<userId>` or `app`; null on a group created before custody. */\n custodian?: string | null;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n createdAt?: string | null;\n createdBy?: string | null;\n modifiedAt?: string | null;\n }>;\n /**\n * `groups.getByType` — GET /groups/{groupType}/{groupId}. DEPRECATED — Get a group, by type; use GET /groups/{groupId} (removal: #4718)\n * @deprecated Use GET /groups/{groupId} (removal: #4718)\n */\n \"getByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n }): Promise<{\n appId: string;\n /** Deprecated (removal: #4718): groups are addressed by `groupId` alone. */\n groupType: string;\n groupId: string;\n name: string;\n description?: string | null;\n memberCount?: number;\n /** `user:<userId>` or `app`; null on a group created before custody. */\n custodian?: string | null;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n createdAt?: string | null;\n createdBy?: string | null;\n modifiedAt?: string | null;\n }>;\n /** `groups.list` — GET /groups. List groups */\n \"list\"(args?: {\n \"type\"?: string | number | boolean;\n \"includeSystem\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n items: {\n appId: string;\n /** Deprecated (removal: #4718): groups are addressed by `groupId` alone. */\n groupType: string;\n groupId: string;\n name: string;\n description?: string | null;\n memberCount?: number;\n /** `user:<userId>` or `app`; null on a group created before custody. */\n custodian?: string | null;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n createdAt?: string | null;\n createdBy?: string | null;\n modifiedAt?: string | null;\n }[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /** `groups.listByCustodian` — GET /holdings/groups. List the groups one custodian holds, from a server function */\n \"listByCustodian\"(args?: {\n \"custodian\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n items: {\n appId: string;\n /** Deprecated (removal: #4718): groups are addressed by `groupId` alone. */\n groupType: string;\n groupId: string;\n name: string;\n description?: string | null;\n memberCount?: number;\n /** `user:<userId>` or `app`; null on a group created before custody. */\n custodian?: string | null;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n createdAt?: string | null;\n createdBy?: string | null;\n modifiedAt?: string | null;\n }[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /** `groups.listDatabases` — GET /groups/{groupId}/databases. List databases shared with a group */\n \"listDatabases\"(args: {\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<{\n databaseId: string;\n title?: string | null;\n databaseType: string | null;\n createdBy?: string | null;\n createdAt?: string | null;\n modifiedAt?: string | null;\n permission: string;\n grantedAt?: string | null;\n }[]>;\n /**\n * `groups.listDatabasesByType` — GET /groups/{groupType}/{groupId}/databases. DEPRECATED — List databases shared with a group, by type; use GET /groups/{groupId}/databases (removal: #4718)\n * @deprecated Use GET /groups/{groupId}/databases (removal: #4718)\n */\n \"listDatabasesByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n }): Promise<{\n databaseId: string;\n title?: string | null;\n databaseType: string | null;\n createdBy?: string | null;\n createdAt?: string | null;\n modifiedAt?: string | null;\n permission: string;\n grantedAt?: string | null;\n }[]>;\n /** `groups.listDb3` — GET /groups/{groupId}/db3. List db3s shared with a group */\n \"listDb3\"(args: {\n \"groupId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"groupType\"?: string | number | boolean;\n }): Promise<{\n items: {\n id: string;\n title: string | null;\n createdAt: string;\n modifiedAt: string;\n /** The user the db3 was created for, or `sys:<appId>` for a db3 the app created */\n createdBy: string;\n /** Who holds the db3: `user:<userId>` or `app` */\n custodian: string | null;\n sync: boolean;\n /** The db3's type; null while it has none */\n type: string | null;\n /** The level the group holds on the db3 */\n permission: string | null;\n grantedAt: string | null;\n }[];\n hasMore: boolean;\n /** Pass as `cursor` for the next page; absent on the last page */\n nextCursor?: string;\n }>;\n /**\n * `groups.listDb3ByType` — GET /groups/{groupType}/{groupId}/db3. DEPRECATED — List db3s shared with a group, by type; use GET /groups/{groupId}/db3 (removal: #4718)\n * @deprecated Use GET /groups/{groupId}/db3 (removal: #4718)\n */\n \"listDb3ByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n items: {\n id: string;\n title: string | null;\n createdAt: string;\n modifiedAt: string;\n /** The user the db3 was created for, or `sys:<appId>` for a db3 the app created */\n createdBy: string;\n /** Who holds the db3: `user:<userId>` or `app` */\n custodian: string | null;\n sync: boolean;\n /** The db3's type; null while it has none */\n type: string | null;\n /** The level the group holds on the db3 */\n permission: string | null;\n grantedAt: string | null;\n }[];\n hasMore: boolean;\n /** Pass as `cursor` for the next page; absent on the last page */\n nextCursor?: string;\n }>;\n /** `groups.listDocuments` — GET /groups/{groupId}/documents. List documents shared with a group */\n \"listDocuments\"(args: {\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<{\n documentId: string;\n title?: string | null;\n createdBy?: string | null;\n createdAt?: string | null;\n lastModified?: string | null;\n permission: string | null;\n grantedAt?: string | null;\n accessSource?: string;\n linkAccess?: string;\n tags?: string[];\n thumbnailBlobId?: string;\n /** The document's stored metadata. */\n metadata?: Record<string, unknown>;\n documentFormat?: string;\n collectionId?: string;\n addedAt?: string | null;\n addedBy?: string | null;\n }[]>;\n /**\n * `groups.listDocumentsByType` — GET /groups/{groupType}/{groupId}/documents. DEPRECATED — List documents shared with a group, by type; use GET /groups/{groupId}/documents (removal: #4718)\n * @deprecated Use GET /groups/{groupId}/documents (removal: #4718)\n */\n \"listDocumentsByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n }): Promise<{\n documentId: string;\n title?: string | null;\n createdBy?: string | null;\n createdAt?: string | null;\n lastModified?: string | null;\n permission: string | null;\n grantedAt?: string | null;\n accessSource?: string;\n linkAccess?: string;\n tags?: string[];\n thumbnailBlobId?: string;\n /** The document's stored metadata. */\n metadata?: Record<string, unknown>;\n documentFormat?: string;\n collectionId?: string;\n addedAt?: string | null;\n addedBy?: string | null;\n }[]>;\n /** `groups.listMembers` — GET /groups/{groupId}/members. List a group's members */\n \"listMembers\"(args: {\n \"groupId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"include\"?: string | number | boolean;\n \"groupType\"?: string | number | boolean;\n }): Promise<{\n items: {\n userId: string;\n /** `owner`, `manager` or `member` on a public group. */\n role?: string | null;\n addedAt?: string | null;\n addedBy?: string | null;\n userName?: string;\n userEmail?: string;\n avatarUrl?: string | null;\n }[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /**\n * `groups.listMembersByType` — GET /groups/{groupType}/{groupId}/members. DEPRECATED — List a group's members, by type; use GET /groups/{groupId}/members (removal: #4718)\n * @deprecated Use GET /groups/{groupId}/members (removal: #4718)\n */\n \"listMembersByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n \"include\"?: string | number | boolean;\n }): Promise<{\n items: {\n userId: string;\n /** `owner`, `manager` or `member` on a public group. */\n role?: string | null;\n addedAt?: string | null;\n addedBy?: string | null;\n userName?: string;\n userEmail?: string;\n avatarUrl?: string | null;\n }[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /** `groups.listPendingInvitations` — GET /groups/{groupId}/pending-invitations. List a group's pending invitations */\n \"listPendingInvitations\"(args: {\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<{\n items: {\n email: string;\n role: string;\n invitationId: string;\n deferredId: string;\n createdAt?: string | null;\n expiresAt?: string | null;\n addedBy?: string | null;\n }[];\n }>;\n /**\n * `groups.listPendingInvitationsByType` — GET /groups/{groupType}/{groupId}/pending-invitations. DEPRECATED — List a group's pending invitations, by type; use GET /groups/{groupId}/pending-invitations (removal: #4718)\n * @deprecated Use GET /groups/{groupId}/pending-invitations (removal: #4718)\n */\n \"listPendingInvitationsByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n }): Promise<{\n items: {\n email: string;\n role: string;\n invitationId: string;\n deferredId: string;\n createdAt?: string | null;\n expiresAt?: string | null;\n addedBy?: string | null;\n }[];\n }>;\n /** `groups.listUserMemberships` — GET /users/{userId}/memberships. List a user's group memberships */\n \"listUserMemberships\"(args: {\n \"userId\": string | number;\n \"includeSystem\"?: string | number | boolean;\n \"type\"?: string | number | boolean;\n }): Promise<{\n groupType: string;\n groupId: string;\n name?: string | null;\n /** `owner`, `manager` or `member` on a public group. */\n role?: string | null;\n addedAt?: string | null;\n addedBy?: string | null;\n description?: string;\n }[]>;\n /** `groups.removeMember` — DELETE /groups/{groupId}/members/{userId}. Remove a specific member from a group */\n \"removeMember\"(args: {\n \"groupId\": string | number;\n \"userId\": string | number;\n \"groupType\"?: string | number | boolean;\n }): Promise<{\n success: boolean;\n }>;\n /** `groups.removeMemberByEmail` — DELETE /groups/{groupId}/members. Remove a group member or pending invitation by email */\n \"removeMemberByEmail\"(args: {\n \"groupId\": string | number;\n \"email\"?: string | number | boolean;\n \"groupType\"?: string | number | boolean;\n }): Promise<{\n success: boolean;\n status?: \"pending_cancelled\";\n email?: string;\n deferredCount?: number;\n }>;\n /**\n * `groups.removeMemberByEmailByType` — DELETE /groups/{groupType}/{groupId}/members. DEPRECATED — Remove a group member or pending invitation by email, by type; use DELETE /groups/{groupId}/members (removal: #4718)\n * @deprecated Use DELETE /groups/{groupId}/members (removal: #4718)\n */\n \"removeMemberByEmailByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n \"email\"?: string | number | boolean;\n }): Promise<{\n success: boolean;\n status?: \"pending_cancelled\";\n email?: string;\n deferredCount?: number;\n }>;\n /**\n * `groups.removeMemberByType` — DELETE /groups/{groupType}/{groupId}/members/{userId}. DEPRECATED — Remove a specific member from a group, by type; use DELETE /groups/{groupId}/members/{userId} (removal: #4718)\n * @deprecated Use DELETE /groups/{groupId}/members/{userId} (removal: #4718)\n */\n \"removeMemberByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n \"userId\": string | number;\n }): Promise<{\n success: boolean;\n }>;\n /** `groups.setMemberRole` — PATCH /groups/{groupId}/members/{userId}. Change a member's role */\n \"setMemberRole\"(args: {\n \"groupId\": string | number;\n \"userId\": string | number;\n \"groupType\"?: string | number | boolean;\n body: {\n role: \"owner\" | \"manager\" | \"member\";\n };\n }): Promise<{\n userId: string;\n role: string;\n addedAt?: string | null;\n addedBy?: string | null;\n }>;\n /** `groups.transfer` — POST /groups/{groupId}/transfer. Transfer a group to another user or to the app */\n \"transfer\"(args: {\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n body: {\n /** `\"user:<userId>\"` (a member of the app; a disabled member counts) or `\"app\"`. */\n to: string;\n };\n }): Promise<{\n appId: string;\n /** Deprecated (removal: #4718): groups are addressed by `groupId` alone. */\n groupType: string;\n groupId: string;\n name: string;\n description?: string | null;\n memberCount?: number;\n /** `user:<userId>` or `app`; null on a group created before custody. */\n custodian?: string | null;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n createdAt?: string | null;\n createdBy?: string | null;\n modifiedAt?: string | null;\n }>;\n /** `groups.update` — PATCH /groups/{groupId}. Update a group */\n \"update\"(args: {\n \"groupId\": string | number;\n \"groupType\"?: string | number | boolean;\n body: {\n name?: string;\n description?: string;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n };\n }): Promise<{\n appId: string;\n /** Deprecated (removal: #4718): groups are addressed by `groupId` alone. */\n groupType: string;\n groupId: string;\n name: string;\n description?: string | null;\n memberCount?: number;\n /** `user:<userId>` or `app`; null on a group created before custody. */\n custodian?: string | null;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n createdAt?: string | null;\n createdBy?: string | null;\n modifiedAt?: string | null;\n }>;\n /**\n * `groups.updateByType` — PATCH /groups/{groupType}/{groupId}. DEPRECATED — Update a group, by type; use PATCH /groups/{groupId} (removal: #4718)\n * @deprecated Use PATCH /groups/{groupId} (removal: #4718)\n */\n \"updateByType\"(args: {\n \"groupType\": string | number;\n \"groupId\": string | number;\n body: {\n name?: string;\n description?: string;\n };\n }): Promise<{\n appId: string;\n /** Deprecated (removal: #4718): groups are addressed by `groupId` alone. */\n groupType: string;\n groupId: string;\n name: string;\n description?: string | null;\n memberCount?: number;\n /** `user:<userId>` or `app`; null on a group created before custody. */\n custodian?: string | null;\n /** `memberList`: `members` (the default) lets every member list the members and pending invitations; `managers` limits it to the owner and managers. */\n settings?: {\n memberList?: \"members\" | \"managers\";\n };\n createdAt?: string | null;\n createdBy?: string | null;\n modifiedAt?: string | null;\n }>;\n };\n \"integrations\": {\n /** `integrations.call` — POST /integrations/{integrationKey}/call. Call an integration under a server function's grants */\n \"call\"(args: {\n \"integrationKey\": string | number;\n body?: {\n /** Must be in the integration's `allowedMethods`, or the call answers `DISALLOWED_METHOD`. */\n method?: string;\n /** Relative to the integration's `baseUrl`. Resolved and normalized before the allowlist is applied, so a protocol-relative path or a dot segment cannot change the origin or escape `allowedPaths`. */\n path?: string;\n /** Query parameters to forward. */\n query?: Record<string, unknown>;\n /** Headers to forward, subject to the integration's `forwardHeaders`. */\n headers?: Record<string, unknown>;\n /** JSON request body. */\n body?: Record<string, unknown>;\n /** form-urlencoded body; mutually exclusive with `body`. */\n form?: Record<string, unknown>;\n /** \"json\" | \"raw\" | \"multipart\". */\n bodyMode?: string;\n };\n }): Promise<{\n status?: number;\n /** Upstream response headers. */\n headers?: Record<string, unknown>;\n /** Upstream response body. */\n body?: Record<string, unknown>;\n traceId?: string;\n durationMs?: number;\n errorCode?: string;\n }>;\n /** `integrations.list` — GET /integrations. List integrations configured for the app */\n \"list\"(args?: Record<string, never>): Promise<any>;\n };\n \"invitations\": {\n /** `invitations.accept` — POST /invitations/accept. Accept an app invitation */\n \"accept\"(args: {\n body: {\n inviteToken: string;\n };\n }): Promise<{\n status: \"accepted\";\n invitationId: string;\n grantsResolved: {\n groups: number;\n documents: number;\n };\n }>;\n /** `invitations.create` — POST /invitations. Create an app invitation */\n \"create\"(args: {\n body: {\n /** Who to invite. Stored trimmed and lowercased. */\n email: string;\n /** The role the invitee gets at sign-up. Defaults to `member`; a server function may invite only at `member`. */\n role?: \"member\" | \"admin\";\n /** When the invitation expires (ISO 8601). Defaults to seven days. */\n expiresAt?: string;\n source?: string;\n note?: string;\n /** Send the platform's invitation email from the caller. Needs the app's `baseUrl`. */\n sendEmail?: boolean;\n };\n }): Promise<{\n invitationId: string;\n email: string;\n role: string;\n invitedBy: string;\n invitedAt: string;\n expiresAt: string;\n accepted: boolean;\n appId: string;\n source: string | null;\n note: string | null;\n inviteToken: string | null;\n }>;\n /** `invitations.delete` — DELETE /invitations/{invitationId}. Delete an app invitation */\n \"delete\"(args: {\n \"invitationId\": string | number;\n }): Promise<{\n success: boolean;\n message: string;\n }>;\n /** `invitations.get` — GET /invitations/{invitationId}. Get an app invitation by id */\n \"get\"(args: {\n \"invitationId\": string | number;\n }): Promise<{\n invitationId: string;\n email: string;\n role: string;\n invitedBy: string;\n invitedAt: string;\n expiresAt: string | null;\n accepted: boolean;\n acceptedAt: string | null;\n source: string | null;\n note: string | null;\n inviteToken: string | null;\n status: \"pending\" | \"expired\" | \"accepted\";\n }>;\n /** `invitations.list` — GET /invitations. List app invitations */\n \"list\"(args?: {\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n items: {\n invitationId: string;\n email: string;\n role: string;\n invitedBy: string;\n invitedAt: string;\n expiresAt: string | null;\n accepted: boolean;\n acceptedAt: string | null;\n source: string | null;\n note: string | null;\n }[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /** `invitations.quota` — GET /invitations/quota. Get the current user's invitation quota */\n \"quota\"(args?: Record<string, never>): Promise<{\n used: number;\n limit: number;\n remaining: number;\n unlimited: boolean;\n }>;\n };\n \"locks\": {\n /** `locks.forceRelease` — POST /locks/force-release. Free a held named lock with no handle (operator's door) */\n \"forceRelease\"(args: {\n body: {\n key: string;\n };\n }): Promise<{\n released: boolean;\n reason?: \"not_held\";\n }>;\n /** `locks.list` — GET /locks. List all currently-held named locks in the app */\n \"list\"(args?: Record<string, never>): Promise<{\n locks: {\n key: string;\n heldBy: string | null;\n holderKind: string | null;\n holderRunId: string | null;\n owner: string | null;\n acquiredAt: string | null;\n leaseExpiresAt: string | null;\n }[];\n }>;\n /** `locks.release` — POST /locks/release. Release a held named lock (requires the acquire handle) */\n \"release\"(args: {\n body: {\n key: string;\n /** `handleId` is the whole capability — it is the only field `LocksController.release` reads, and `ctx.api.locks.release` sends `{ handleId }` alone. The acquire handle's other fields are accepted and ignored. */\n handle: {\n key?: string;\n handleId: string;\n leaseExpiresAt?: string;\n };\n };\n }): Promise<{\n released: boolean;\n reason?: \"not_holder\" | \"not_held\";\n }>;\n /** `locks.renew` — POST /locks/renew. Extend the lease on a held named lock */\n \"renew\"(args: {\n body: {\n key: string;\n /** `handleId` is the whole capability — it is the only field `LocksController.renew` reads, and `ctx.api.locks.renew` sends `{ handleId }` alone. The acquire handle's other fields are accepted and ignored. */\n handle: {\n key?: string;\n handleId: string;\n leaseExpiresAt?: string;\n };\n ttlMs: number;\n };\n }): Promise<{\n renewed: boolean;\n leaseExpiresAt?: string;\n reason?: \"lease_lost\";\n }>;\n /** `locks.status` — POST /locks/status. Report the current holder of a named lock */\n \"status\"(args: {\n body: {\n key: string;\n };\n }): Promise<{\n held: boolean;\n heldBy?: string | null;\n holderKind?: string | null;\n holderRunId?: string | null;\n owner?: string | null;\n acquiredAt?: string | null;\n leaseExpiresAt?: string | null;\n }>;\n /** `locks.tryAcquire` — POST /locks/acquire. Attempt to acquire a named lock (one attempt, or with waitMs a bounded server-side wait) */\n \"tryAcquire\"(args: {\n body: {\n key: string;\n ttlMs: number;\n owner?: string | null;\n /** Milliseconds, 0 or more. While another holder has the key, wait server-side up to this long for it to free, then answer as for one attempt (capped at 30 s, and at a function dispatch's remaining budget). One acquire attempt against the rate limit per call, however long it waits. */\n waitMs?: number;\n };\n }): Promise<{\n acquired: true;\n handle: {\n key: string;\n handleId: string;\n leaseExpiresAt: string;\n };\n } | {\n acquired: false;\n heldBy: string | null;\n holderKind: string | null;\n owner: string | null;\n leaseExpiresAt: string | null;\n retryAfterMs: number;\n }>;\n };\n \"notifications\": {\n /** `notifications.list` — GET /notifications. List the caller's in-app notification inbox (newest first) */\n \"list\"(args?: {\n \"userId\"?: string | number;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n items: {\n notificationId: string;\n title: string;\n body: string;\n iconUrl?: string;\n deepLink?: string;\n read: boolean;\n readAt?: string;\n expiresAt?: string;\n sourceRef?: string;\n createdAt: string;\n }[];\n unreadCount: number;\n hasMore: boolean;\n nextCursor?: string;\n }>;\n /** `notifications.listDevices` — GET /me/push-tokens. List the caller's registered push devices */\n \"listDevices\"(args?: {\n \"userId\"?: string | number;\n }): Promise<{\n items: {\n tokenId: string;\n tokenSuffix?: string;\n platform: string;\n environment: string;\n bundleId?: string;\n deviceName?: string;\n appVersion?: string;\n lastSeenAt?: string;\n createdAt?: string;\n }[];\n }>;\n /** `notifications.markAllRead` — POST /notifications/read-all. Mark all of the caller's notifications as read */\n \"markAllRead\"(args?: {\n \"userId\"?: string | number;\n }): Promise<{\n updated: number;\n }>;\n /** `notifications.markRead` — PATCH /notifications/{notificationId}/read. Mark one of the caller's notifications as read */\n \"markRead\"(args: {\n \"notificationId\": string | number;\n \"userId\"?: string | number;\n }): Promise<{\n notificationId: string;\n title: string;\n body: string;\n iconUrl?: string;\n deepLink?: string;\n read: boolean;\n readAt?: string;\n expiresAt?: string;\n sourceRef?: string;\n createdAt: string;\n }>;\n /** `notifications.registerDevice` — POST /me/push-tokens. Register (upsert) the caller's device push token */\n \"registerDevice\"(args: {\n \"userId\"?: string | number;\n body: {\n token: string;\n platform: \"ios\" | \"macos\" | \"android\";\n environment: \"sandbox\" | \"production\";\n bundleId?: string;\n deviceName?: string;\n appVersion?: string;\n };\n }): Promise<{\n tokenId: string;\n tokenSuffix?: string;\n platform: string;\n environment: string;\n bundleId?: string;\n deviceName?: string;\n appVersion?: string;\n lastSeenAt?: string;\n createdAt?: string;\n }>;\n /** `notifications.send` — POST /notifications/send. Send a notification to an app user (durable in-app inbox row + live WS frame) */\n \"send\"(args: {\n body: {\n title: string;\n body: string;\n target: {\n userId: string;\n };\n channels?: string[];\n iconUrl?: string;\n deepLink?: string;\n expiresAt?: string;\n sourceRef?: string;\n idempotencyKey?: string;\n };\n }): Promise<{\n results: {\n channel: string;\n status: \"delivered\" | \"failed\" | \"skipped\" | \"invalidated\";\n notificationId?: string;\n delivered?: number;\n failed?: number;\n invalidated?: number;\n skipReason?: string;\n httpStatus?: number;\n error?: string;\n retryable?: boolean;\n }[];\n deduplicated?: boolean;\n deduplicatedChannels?: string[];\n }>;\n /** `notifications.unreadCount` — GET /notifications/unread-count. Count the caller's unread notifications */\n \"unreadCount\"(args?: {\n \"userId\"?: string | number;\n }): Promise<{\n unreadCount: number;\n }>;\n /** `notifications.unregisterDevice` — DELETE /me/push-tokens/{token}. Unregister one of the caller's device push tokens */\n \"unregisterDevice\"(args: {\n \"token\": string | number;\n \"userId\"?: string | number;\n }): Promise<{\n deleted: boolean;\n }>;\n };\n \"prompts\": {\n /** `prompts.run` — POST /prompts/{promptKey}/run. Run a prompt under a server function's grants */\n \"run\"(args: {\n \"promptKey\": string | number;\n body?: {\n /** Template variables for the prompt, or `{ state, criteria? }` for a decisions prompt: `criteria.<question>` supplies the options of each `criteriaSource = \"dynamic\"` choice question for this run. */\n variables?: Record<string, unknown>;\n /** Run against a different model for this call only. */\n modelOverride?: string;\n /** Pin a specific config of THIS prompt; defaults to its active one. */\n configId?: string;\n };\n }): Promise<{\n success?: boolean;\n output?: string;\n error?: string;\n /** Duration and token counts, plus `cost` — the price of the call in USD as the provider reported it, absent when it reports none (#3626). */\n metrics?: Record<string, unknown>;\n configId?: string;\n /** The parsed JSON value of the answer — an object, an array or a scalar, whichever the declaration produced. Present only when the prompt declares an `outputSchema` (against which it was validated) or the config that ran declares `outputFormat = \"json\"` (unvalidated), and only on success. A `kind = \"decisions\"` prompt always answers JSON, so `parsed` is its typed answers object with no declaration needed (#3626). */\n parsed?: Record<string, unknown> | unknown[] | string | number | boolean | null;\n /** `PROMPT_OUTPUT_NOT_JSON` when a declared-JSON prompt answered text that does not parse, or holds a number JSON cannot represent, `PROMPT_OUTPUT_SCHEMA_VIOLATION` when it parsed and the declared `outputSchema` refuses it (`error` names the failing paths and carries no value from the output), or `PROMPT_UPSTREAM_TIMEOUT` when the provider itself ran out of time (#3663), or `PROMPT_UPSTREAM_REJECTED` when the provider refused the request as invalid (`upstreamStatus: 400`): a setting the model does not support, such as a reasoning level; `error` carries the provider's message, and the remedy is the config, not a retry (#4147), or `PROMPT_CRITERIA_INVALID` when a decisions run's `variables.criteria` was refused before the provider call (`error` names the question and the rule, #3813), or `PROMPT_STRICT_OUTPUT_SCHEMA_MISSING` when the config that ran sets `strictOutput = true` and the prompt has no usable `outputSchema` to send, refused before the provider call (#3801), or `PROMPT_OUTPUT_TRUNCATED` when the provider stopped at the output token limit: a declared-JSON answer cut off before it was finished (never judged on its shape), or a completion that spent the whole limit and came back empty; raise the config's `maxTokens` (#4146). Absent on success and on every other provider failure. */\n errorCode?: string;\n /** `true` when the provider stopped at the output token limit (`maxTokens`) before the answer was finished, on either arm; absent otherwise, never `false`. On Gemini, reasoning tokens count against the same limit (#4146). */\n truncated?: boolean;\n /** The upstream provider's HTTP status (#3663). Provider-agnostic: Gemini and OpenRouter configs report it identically, so a caller never has to know which provider the config named. Present only on a provider failure that reached a provider and got an answer — a status this platform decided on its own (an unset provider key, an oversized payload, a completion that came back empty) carries none — so a caller can decide whether to retry without parsing the message: 408, 429, 502, 503 and 504 are worth another attempt — 408 and 504 are the upstream timeouts — and a 400 on a refused payload is not. */\n upstreamStatus?: number;\n }>;\n };\n \"resourceMetadata\": {\n /** `resourceMetadata.delete` — DELETE /resources/{resourceType}/{resourceId}/metadata/{category}. Delete a resource's metadata for a category (idempotent) */\n \"delete\"(args: {\n \"resourceType\": string | number;\n \"resourceId\": string | number;\n \"category\": string | number;\n }): Promise<{\n resourceType: string;\n resourceId: string;\n category: string;\n /** The stored metadata object. */\n data?: Record<string, unknown>;\n deleted: boolean;\n }>;\n /** `resourceMetadata.get` — GET /resources/{resourceType}/{resourceId}/metadata/{category}. Read a resource's metadata for a category */\n \"get\"(args: {\n \"resourceType\": string | number;\n \"resourceId\": string | number;\n \"category\": string | number;\n }): Promise<{\n resourceType: string;\n resourceId: string;\n category: string;\n /** The stored metadata object. */\n data: Record<string, unknown>;\n schemaVersion?: number | null;\n exists: boolean;\n }>;\n /** `resourceMetadata.getBatch` — POST /resources/metadata/batch. Batch-read resource metadata (partial success) */\n \"getBatch\"(args: {\n \"debug\"?: string | number | boolean;\n body: {\n requests: {\n resourceType: string;\n resourceId: string;\n categories: string[];\n }[];\n };\n }): Promise<{\n results: {\n resourceType: string;\n resourceId: string;\n ok: boolean;\n /** Per-category outcome, keyed by category: `{ ok: true, data, schemaVersion, exists }` or `{ ok: false, status, code, message }`. */\n categories?: Record<string, unknown>;\n status?: number;\n code?: string;\n message?: string;\n }[];\n _debug?: {\n dynamoQueries?: number;\n };\n }>;\n /** `resourceMetadata.list` — GET /resources/{resourceType}/{resourceId}/metadata. List all metadata categories on a resource */\n \"list\"(args: {\n \"resourceType\": string | number;\n \"resourceId\": string | number;\n }): Promise<{\n resourceType: string;\n resourceId: string;\n categories: {\n category: string;\n data: Record<string, unknown>;\n schemaVersion: number | null;\n }[];\n }>;\n /** `resourceMetadata.resolve` — POST /metadata/resolve. Resolve a resource by a category's unique metadata value */\n \"resolve\"(args: {\n body: {\n resourceType: string;\n category: string;\n key: string;\n /** The unique value to resolve. It is the operation's whole lookup input, and `ResourceMetadataResolveParams` requires it; a non-string or absent value is never indexed, so the service answers the miss shape rather than an error. */\n value: string;\n };\n }): Promise<{\n resourceId: string | null;\n resourceType?: string;\n }>;\n /** `resourceMetadata.set` — PUT /resources/{resourceType}/{resourceId}/metadata/{category}. Write a resource's metadata for a category */\n \"set\"(args: {\n \"resourceType\": string | number;\n \"resourceId\": string | number;\n \"category\": string | number;\n body: {\n data?: Record<string, unknown>;\n };\n }): Promise<{\n resourceType: string;\n resourceId: string;\n category: string;\n /** The stored metadata object. */\n data: Record<string, unknown>;\n schemaVersion?: number | null;\n size?: number;\n }>;\n };\n \"secrets\": {\n /** `secrets.get` — GET /secrets/{name}. Read an app secret under a server function's grants */\n \"get\"(args: {\n \"name\": string | number;\n }): Promise<{\n name?: string;\n value?: string;\n }>;\n };\n \"users\": {\n /** `users.getBasic` — GET /users/{userId}/basic. Get a user's basic public profile */\n \"getBasic\"(args: {\n \"userId\": string | number;\n }): Promise<{\n userId: string;\n email?: string | null;\n name?: string | null;\n avatarUrl?: string | null;\n appRole: string | null;\n appId: string;\n addedAt?: string | null;\n }>;\n /** `users.getProfiles` — POST /users/profiles. Look up user profiles in bulk */\n \"getProfiles\"(args: {\n body: {\n userIds: string[];\n };\n }): Promise<{\n profiles: {\n userId: string;\n email?: string | null;\n name?: string | null;\n avatarUrl?: string | null;\n }[];\n }>;\n /** `users.getRootDocument` — GET /users/{userId}/root-document. Get an app user's root document id */\n \"getRootDocument\"(args: {\n \"userId\": string | number;\n }): Promise<{\n userId: string;\n rootDocId: string | null;\n }>;\n /** `users.list` — GET /users. List app users */\n \"list\"(args?: {\n \"email\"?: string | number | boolean;\n \"userId\"?: string | number;\n \"name\"?: string | number | boolean;\n \"limit\"?: string | number | boolean;\n \"cursor\"?: string | number | boolean;\n }): Promise<{\n items: {\n userId: string;\n email?: string | null;\n name?: string | null;\n avatarUrl?: string | null;\n role: string | null;\n addedAt: string | null;\n status: string;\n disabledAt?: string;\n }[];\n hasMore: boolean;\n nextCursor?: string;\n prevCursor?: string;\n }>;\n /** `users.lookup` — GET /users/lookup. Look up a user by identifier */\n \"lookup\"(args?: {\n \"email\"?: string | number | boolean;\n }): Promise<{\n exists: boolean;\n user?: {\n userId: string;\n name?: string | null;\n email: string;\n };\n }>;\n /**\n * `users.remove` — DELETE /users/{userId}. DEPRECATED — remove a user from the app; use the admin API's PUT apps/:appId/users/:userId/disable (`primitive users disable`)\n * @deprecated Use the admin API's PUT apps/:appId/users/:userId/disable (`primitive users disable`)\n */\n \"remove\"(args: {\n \"userId\": string | number;\n }): Promise<{\n success: boolean;\n message: string;\n }>;\n /** `users.send` — POST /users/{userId}/send. Send a realtime message to a member of this app */\n \"send\"(args: {\n \"userId\": string | number;\n body: {\n /** The message body, delivered verbatim as the frame's `payload`. */\n payload?: Record<string, unknown>;\n };\n }): Promise<{\n connections?: number;\n truncated?: boolean;\n }>;\n /** `users.setProfile` — PATCH /users/{userId}/profile. Set a user's display name and avatar */\n \"setProfile\"(args: {\n \"userId\": string | number;\n body: {\n /** Display name; trimmed, non-empty and at most 200 characters */\n name?: string;\n /** External avatar URL, `http:` or `https:` only; `null` or an empty string clears the avatar */\n avatarUrl?: string | null;\n };\n }): Promise<{\n userId: string;\n email: string;\n name: string | null;\n avatarUrl: string | null;\n }>;\n /** `users.setRole` — PUT /users/{userId}/role. Set a user's app role */\n \"setRole\"(args: {\n \"userId\": string | number;\n body: {\n role: \"member\" | \"admin\" | \"owner\";\n };\n }): Promise<{\n userId: string;\n role: string;\n updatedAt: string;\n }>;\n };\n}\n\n/**\n * The app's database types, model by model — EMPTY here and filled by the\n * declaration `primitive config push` writes into the config tree's\n * `functions/` directory (#3182). A tree that has pushed once therefore types\n * `ctx.db` against its own schemas; one that has not gets the open form and\n * still compiles.\n */\nexport interface DatabaseSchemas {}\n\n/**\n * The type keys `ctx.db` accepts.\n *\n * Every key the augmentation declares, and NOTHING else, once a tree has\n * pushed: naming a type the app does not have is a compile error. Before that\n * — an unaugmented tree, a function written before the first push —\n * `DatabaseSchemas` is empty and `keyof` it is `never`, which would make the\n * argument unwritable rather than open. So the empty case widens to `string`\n * and the handle is untyped instead of unusable.\n */\nexport type DatabaseTypeKeys = [keyof DatabaseSchemas] extends [never]\n ? string\n : keyof DatabaseSchemas & string;\n\n/** A model's row shape, or an open record for a type with no schema. */\nexport type DatabaseModels<K extends string> = K extends keyof DatabaseSchemas\n ? DatabaseSchemas[K]\n : Record<string, Record<string, unknown>>;\n\n/**\n * The app's functions, key by key — EMPTY here and filled by the declaration\n * `primitive config push` writes into the config tree's `functions/`\n * directory (`primitive-function-types.d.ts`): each key's declared input and\n * output types, from its `inputSchema` and `outputSchema`. It is what types\n * `defineFunction(\"<key>\", handler)`.\n */\nexport interface FunctionSchemas {}\n\n/**\n * The keys `defineFunction(key, handler)` accepts: every key the augmentation\n * declares once a tree has pushed, so a key the tree does not declare is a\n * compile error — and `string` before that, the `DatabaseTypeKeys` rule, so an\n * unaugmented tree keeps compiling.\n */\nexport type FunctionKeys = [keyof FunctionSchemas] extends [never]\n ? string\n : keyof FunctionSchemas & string;\n\n/** A declared function's input type, or `any` when nothing is declared. */\nexport type FunctionInput<K extends string> = K extends keyof FunctionSchemas\n ? FunctionSchemas[K] extends { input: infer I }\n ? I\n : any\n : any;\n\n/** A declared function's output type, or `any` when nothing is declared. */\nexport type FunctionOutput<K extends string> = K extends keyof FunctionSchemas\n ? FunctionSchemas[K] extends { output: infer O }\n ? O\n : any\n : any;\n\n/**\n * The model names one database type addresses — its own, or any name at all\n * for a type that declares no schema (the DO is schemaless, so a grant on such\n * a type is legal and there is simply nothing to narrow to).\n */\nexport type DatabaseModelNames<TModels> = [keyof TModels] extends [never]\n ? string\n : keyof TModels & string;\n\n/**\n * A row as the platform HANDS IT BACK: whatever the schema declared, plus the\n * record identity the platform owns (#3450).\n *\n * Every stored record has an `id`. A save that arrives without one is given a\n * ULID, a projection always keeps it, and `delete` and `patch` take nothing\n * else — so a function that queries a model and then moves one of its rows\n * needs the id of the row it just read. A schema is free to say nothing about\n * that field, and most do; the identity is the platform's, not the schema's,\n * so it is added here rather than rendered into each declaration.\n *\n * A declared `id` is REPLACED, never intersected: one declared optional would\n * stay optional on a read row it is always present on, and one declared with\n * some other type would intersect to `never` and be unusable. The platform\n * stamps a string whatever the schema says.\n *\n * An `any` row stays `any` — `DatabaseHandle<any>` is `defineQuery`'s default\n * handle, and turning its rows into an object with one known member would\n * narrow code that was deliberately left open.\n *\n * Writes are untouched: every one of them takes `Partial<TRow>`, so a row a\n * function BUILDS still needs no id.\n */\nexport type PlatformRow<TRow> = 0 extends 1 & TRow\n ? TRow\n : Omit<TRow, \"id\"> & { id: string };\n\n/** One model's row shape, open when the type declares no schema. */\nexport type DatabaseModelRow<TModels, M extends string> =\n M extends keyof TModels\n ? PlatformRow<TModels[M]>\n : Record<string, unknown> & { id: string };\n\n/**\n * One model of one database, scoped: the `modelName` every records call needs\n * is bound once, so a call names an operation and its own arguments.\n *\n * Filters and options are ordinary objects. Inline filter typing arrives with\n * unified schemas — the intent's decision, not an omission — so what is typed\n * today is the model name and the row shape a read hands back.\n */\nexport type ModelScopedBody<TBody = Record<string, unknown>> = TBody & {\n /**\n * Bound by the handle. Reserved so a body cannot look like a second way to\n * choose a model: the runtime assigns the handle's own model last, and a row\n * type that said otherwise would be a lie about what came back.\n */\n modelName?: never;\n};\n\n/**\n * One write inside a model-scoped batch. Every batch verb is a write, so a\n * batch on a model needs that model's write grant whatever the ops are.\n */\nexport type ModelBatchOperation<TRow> = {\n op: \"save\" | \"patch\" | \"delete\" | \"increment\" | \"addToSet\" | \"removeFromSet\";\n id?: string;\n data?: Partial<TRow>;\n /** Bound by the handle, for the same reason every other call's is. */\n modelName?: never;\n [key: string]: unknown;\n};\n\nexport interface DatabaseModelHandle<TRow> {\n /**\n * One page of this model's rows, in the decided envelope — `{ items,\n * hasMore, nextCursor? }` (#3287), the same shape `ctx.doc(...)`,\n * `ctx.users.list` and the client library answer. The route's own wire\n * shape is unchanged; the SDK is where the one name lives, so shared paging\n * code can be written once.\n */\n query(body?: ModelScopedBody): Promise<{ items: TRow[]; hasMore: boolean; nextCursor?: string }>;\n count(body?: ModelScopedBody): Promise<any>;\n aggregate(body: ModelScopedBody): Promise<any>;\n save(body: ModelScopedBody<{ id?: string; data: Partial<TRow>; [key: string]: unknown }>): Promise<any>;\n /**\n * Change some fields of ONE row — `databases.records.patch`, with this\n * handle's model bound (#3450).\n *\n * The record id is positional and the body may not carry another, for the\n * same reason it may not name another model: the runtime assigns both LAST,\n * so a body that appeared to choose either would be a lie about which row\n * moved. `condition`, `stringSets` and the rest of the operation's own keys\n * pass through untouched.\n */\n patch(\n recordId: string,\n body: ModelScopedBody<{ data: Partial<TRow>; id?: never; [key: string]: unknown }>\n ): Promise<any>;\n /**\n * Remove ONE row by the id a read handed back — `databases.records.delete`,\n * with this handle's model bound (#3450). An optional `condition` makes it\n * conditional, and travels untouched.\n */\n delete(\n recordId: string,\n body?: ModelScopedBody<{ condition?: Record<string, unknown>; id?: never }>\n ): Promise<any>;\n /** Several writes to THIS model in one request; the binding is per item. */\n batch(body: {\n operations: Array<ModelBatchOperation<TRow>>;\n atomic?: boolean;\n }): Promise<any>;\n}\n\n/** One database, typed by the database TYPE key its grant names. */\nexport interface DatabaseHandle<TModels> {\n /** The database this handle addresses — part of every query cache key. */\n databaseId: string;\n /** The type key this handle was opened with. */\n databaseType: string;\n model<M extends DatabaseModelNames<TModels>>(\n modelName: M\n ): DatabaseModelHandle<DatabaseModelRow<TModels, M>>;\n /**\n * A batch may also SPAN models, and then it names each one itself — the\n * model-scoped form above is the typed way to write the common case.\n */\n batch(body: {\n operations: Array<Record<string, unknown>>;\n atomic?: boolean;\n }): Promise<any>;\n}\n\n/**\n * The app's DOCUMENT models — EMPTY here and filled by the declaration\n * `primitive config push` writes into the config tree's `functions/` directory\n * (`primitive-document-types.d.ts`, from the project's `models/models.toml`).\n * A project with no document schema gets the open form and still compiles.\n */\nexport interface DocumentSchemas {}\n\n/** The model names `ctx.doc(id).model()` accepts — every declared one, or `string` before a push. */\nexport type DocumentModelNames = [keyof DocumentSchemas] extends [never]\n ? string\n : keyof DocumentSchemas & string;\n\n/**\n * A document model's row shape, or an open record for an undeclared schema —\n * carrying the platform's record identity either way (#3450), by the same rule\n * and for the same reason as a database row: the records DO is one\n * implementation, and `patch` and `delete` here take an id too.\n */\nexport type DocumentModelRow<M extends string> = M extends keyof DocumentSchemas\n ? PlatformRow<DocumentSchemas[M]>\n : Record<string, unknown> & { id: string };\n\n/**\n * One related-records spec of a document model read's `include` (#4692),\n * answered on a db3 (a format-3 document) as `_related` on each record.\n */\nexport interface DocumentIncludeSpec {\n /** The related model. */\n model: string;\n /**\n * `refersTo`: this record's `sourceField` holds the related id (one record\n * or null). `hasMany`: the related `foreignKey` holds this record's\n * `localField` (an array). `refersToMany`: this record's `sourceField`\n * holds an array of ids (the records in member order, missing ones dropped).\n */\n type: \"refersTo\" | \"hasMany\" | \"refersToMany\";\n sourceField?: string;\n foreignKey?: string;\n /** The field the related `foreignKey` matches; `id` when omitted. */\n localField?: string;\n /** The key in `_related`; the model name when omitted. */\n as?: string;\n filter?: Record<string, unknown>;\n sort?: Record<string, 1 | -1>;\n /** Related rows per parent, `hasMany` only. */\n limit?: number;\n projection?: Record<string, 0 | 1>;\n /** Nested specs for the related records, to depth 3 in all. */\n include?: DocumentIncludeSpec[];\n}\n\n/** The options a document model read takes: a filter object (or its JSON), a page size, a cursor. */\nexport interface DocumentQueryOptions {\n filter?: Record<string, unknown> | string;\n /**\n * The order of the rows: each field maps to 1 (ascending) or -1\n * (descending), and key order is precedence, as in { createdAt: -1 }. `id`\n * breaks ties unless you name it. `limit` and `cursor` apply to the\n * ordered rows; pass the same sort with a `cursor`, since a cursor from\n * another sort is refused with a 400.\n */\n sort?: Record<string, 1 | -1>;\n /**\n * Records per page: 100 when omitted, at most 10,000; a larger value is\n * refused with a 400 naming the maximum, never clamped. A page also ends\n * before the record that would take it past 8 MiB (the sum of each\n * record's JSON in UTF-8 bytes; the envelope is not counted), answering\n * `hasMore: true` and a `nextCursor` that continues from the last record\n * returned; a single record larger than 8 MiB is answered alone. A page\n * that fills `limit` exactly also answers `hasMore: true`; loop on\n * `hasMore` rather than counting rows.\n */\n limit?: number;\n cursor?: string;\n /**\n * The document format you expect (#3764). When it disagrees with the format\n * the platform resolved, the call is refused with a 409\n * DOCUMENT_FORMAT_MISMATCH rather than answered out of the wrong tables.\n * Usually stated once on the handle, as ctx.doc(id, { documentFormat: 2 }),\n * rather than per read.\n */\n documentFormat?: 1 | 2 | 3;\n /**\n * Related records to answer with each record on a db3 (a format-3\n * document), as `_related`; ignored on a format-1 document. Nested to depth\n * 3. The response, `_related` included, is at most 8 MiB and a `hasMany`\n * spec reads at most 1,000 related rows per request; past either the read is\n * refused with a 400 DB3_PAGE_TOO_LARGE, never cut.\n */\n include?: DocumentIncludeSpec[] | string;\n}\n\n/**\n * One document model, bound to its document and its model name — a thin\n * binding over `ctx.api.documents.records.*` with the route's own shapes.\n */\n/**\n * One op of a document `batch` — the `documents.records.bulk` blob's shape,\n * typed to this handle's model (#3455).\n *\n * `model` is NOT a member: the handle already names it and assigns it last, so\n * a multi-model blob stays on the raw `ctx.api.documents.records.bulk`\n * operation rather than becoming a second way to say the same thing.\n *\n * `upsert` addresses the record by a unique constraint the model declares:\n * `data` carries every field of `constraint`, the record holding that key\n * gets `data` merged into it, and when none does one is created (at `id`\n * when given, else at a new id) with the model's defaults.\n */\nexport type DocumentBatchOp<TRow> =\n | { action: \"create\" | \"patch\"; id: string; data: Partial<TRow>; precondition?: Record<string, unknown> }\n | { action: \"delete\"; id: string; precondition?: Record<string, unknown> }\n | { action: \"upsert\"; constraint: string; id?: string; data: Partial<TRow>; precondition?: Record<string, unknown> };\n\n/**\n * What `documents.records.bulk` answers: the blob's aggregate effect.\n * `upserted` has one entry per `upsert` op, in input order: the op's\n * `index`, the record's `id`, and whether the op `created` it.\n */\nexport interface DocumentBulkResult {\n applied: number;\n added: Array<{ model: string; id: string }>;\n updated: Array<{ model: string; id: string }>;\n deleted: number;\n upserted: Array<{ index: number; model: string; id: string; created: boolean }>;\n}\n\nexport interface DocumentModelHandle<TRow> {\n /**\n * One page of the model's records: 100 by default, up to 10,000 with\n * `limit`, and at most 8 MiB of record JSON unless a single larger record\n * is answered alone. Pass `nextCursor` back as `cursor` while\n * `hasMore` is true.\n */\n query(options?: DocumentQueryOptions): Promise<{ items: Array<TRow & { _related?: Record<string, any> }>; hasMore: boolean; nextCursor?: string }>;\n count(options?: { filter?: Record<string, unknown> | string }): Promise<{ count: number }>;\n aggregate(body: Record<string, unknown>): Promise<any>;\n save(body: { id: string; data: Partial<TRow>; options?: Record<string, unknown> }): Promise<{ record: TRow }>;\n patch(recordId: string, body: { data: Partial<TRow>; options?: Record<string, unknown> }): Promise<{ record: TRow }>;\n delete(recordId: string): Promise<{ deleted: boolean }>;\n /**\n * Apply an ordered blob of this model's ops in ONE transaction — all of it\n * commits or none of it does, and connected clients see one update.\n *\n * One model's ops, by construction: every op's `model` is this handle's.\n * A blob that spans models is the raw `ctx.api.documents.records.bulk`\n * operation's job.\n */\n batch(ops: Array<DocumentBatchOp<TRow>>): Promise<DocumentBulkResult>;\n}\n\n/** A document, addressed once; its models are typed from `DocumentSchemas`. */\nexport interface DocumentHandle {\n documentId: string;\n model<M extends DocumentModelNames>(modelName: M): DocumentModelHandle<DocumentModelRow<M>>;\n}\n\n/**\n * The app's db3 types, model by model — EMPTY here and filled by the\n * declaration `primitive config push` writes into the config tree's\n * `functions/` directory (`primitive-db3-types.d.ts`, from `db3-types/` and\n * `database-type-configs/`). A tree that has not pushed gets the open form\n * and still compiles.\n */\nexport interface Db3Schemas {}\n\n/**\n * The type keys `ctx.db3` accepts: every key the augmentation declares and\n * nothing else once a tree has pushed, and any string before that.\n */\nexport type Db3TypeKeys = [keyof Db3Schemas] extends [never]\n ? string\n : keyof Db3Schemas & string;\n\n/** A db3 type's models, or an open record for a type with no schema. */\nexport type Db3Models<K extends string> = K extends keyof Db3Schemas\n ? Db3Schemas[K]\n : Record<string, Record<string, unknown>>;\n\n/** The model names a db3 type declares, or `string` for one that declares none. */\nexport type Db3ModelNames<TModels> = [keyof TModels] extends [never]\n ? string\n : keyof TModels & string;\n\n/** One db3 model's row shape, carrying the platform's record identity. */\nexport type Db3ModelRow<TModels, M extends string> = M extends keyof TModels\n ? PlatformRow<TModels[M]>\n : Record<string, unknown> & { id: string };\n\n/**\n * A change to a string-set field, in place of the whole set: `$add` and\n * `$remove` merge with concurrent writers' changes, `$clear` empties it.\n *\n * ```ts\n * await tasks.patch(id, { data: { tags: { $add: [\"urgent\"], $remove: [\"low\"] } } });\n * ```\n */\nexport interface Db3StringSetChange {\n $add?: string[];\n $remove?: string[];\n $clear?: true;\n}\n\n/**\n * The `data` a db3 write takes: any of the row's fields, each optional, and a\n * `Db3StringSetChange` on a string-set field beside the set itself.\n */\nexport type Db3WriteData<TRow> = {\n [K in keyof TRow]?: TRow[K] | (NonNullable<TRow[K]> extends string[] ? Db3StringSetChange : never);\n};\n\n/**\n * One op of a db3 `bulk`, typed to a model's row. `condition` is a guard in\n * the query filter grammar: the op applies only when the record is live and\n * matches it.\n */\nexport type Db3BulkOp<TRow = Record<string, unknown>> =\n | { action: \"create\"; id?: string; data: Db3WriteData<TRow>; condition?: Record<string, unknown>; requestId?: string }\n | { action: \"patch\"; id: string; data: Db3WriteData<TRow>; condition?: Record<string, unknown>; requestId?: string }\n | { action: \"delete\"; id: string; condition?: Record<string, unknown>; requestId?: string }\n | { action: \"upsert\"; constraint: string; id?: string; data: Db3WriteData<TRow>; condition?: Record<string, unknown>; requestId?: string }\n | { action: \"increment\"; id: string; fields: Record<string, number>; condition?: Record<string, unknown>; requestId?: string };\n\n/** One op of a handle-level `bulk`: its `model` picks the row its `data` is typed to. */\nexport type Db3HandleBulkOp<TModels> = {\n [M in Db3ModelNames<TModels>]: Db3BulkOp<Db3ModelRow<TModels, M>> & { model: M };\n}[Db3ModelNames<TModels>];\n\n/**\n * What `db3.records.bulk` answers. With `atomic: false` each op is applied on\n * its own and `results` names each one, a refused op carrying its `code`.\n */\nexport interface Db3BulkResult {\n applied: number;\n added: Array<{ model: string; id: string; appliedFields?: Record<string, unknown> }>;\n updated: Array<{ model: string; id: string; appliedFields?: Record<string, unknown> }>;\n deleted: number;\n upserted?: Array<{ index: number; model: string; id: string; created: boolean; appliedFields?: Record<string, unknown> }>;\n incremented?: Array<{ index: number; model: string; id: string; values: Record<string, number> }>;\n atomic?: boolean;\n results?: Array<\n | { index: number; model: string; id: string; ok: true; kind: string; values?: Record<string, number>; appliedFields?: Record<string, unknown>; requestId?: string }\n | { index: number; model: string; id?: string; ok: false; code: string; status: number; error: string; reason?: string; requestId?: string }\n >;\n requestId?: string;\n}\n\n/**\n * One db3 model, bound to its db3 and its model name — a thin binding over\n * `ctx.api.db3.records.*` with the routes' own answers. A refusal rejects\n * with the route's error: a db3 that does not exist in this app (never\n * created, or deleted) is 404 `DB3_NOT_FOUND`, a failing `condition` 409\n * `DB3_CONDITION_NOT_MET`, a missing record on `increment` 404\n * `DB3_RECORD_NOT_FOUND`, a model the type does not declare 400\n * `DB3_MODEL_NOT_DECLARED`.\n */\nexport interface Db3ModelHandle<TRow> {\n /** The record with this id, or `null` when there is none. */\n get(recordId: string): Promise<TRow | null>;\n /** One page of records: pass `nextCursor` back as `cursor` while `hasMore` is true. */\n query(options?: DocumentQueryOptions): Promise<{ items: Array<TRow & { _related?: Record<string, any> }>; hasMore: boolean; nextCursor?: string }>;\n count(options?: { filter?: Record<string, unknown> | string }): Promise<{ count: number }>;\n /** Counts, sums, averages, minimums and maximums, resolved to the bare row array. */\n aggregate(body: Record<string, unknown>): Promise<any[]>;\n /**\n * Create or replace a record; the id is minted when omitted. `ifNotExists`\n * applies only when no record has the id, `upsertOn` lands on the record\n * holding the same unique key. `appliedFields` names what the type's hook\n * rules wrote.\n */\n save(body: {\n id?: string;\n data: Db3WriteData<TRow>;\n condition?: Record<string, unknown>;\n ifNotExists?: boolean;\n upsertOn?: string;\n requestId?: string;\n }): Promise<{ record: TRow; appliedFields?: Record<string, unknown> }>;\n /** Merge fields into an existing record. */\n patch(\n recordId: string,\n body: { data: Db3WriteData<TRow>; condition?: Record<string, unknown>; requestId?: string }\n ): Promise<{ record: TRow; appliedFields?: Record<string, unknown> }>;\n /** Delete a record; deleting one that does not exist is not an error unless a `condition` asks. */\n delete(recordId: string, body?: { condition?: Record<string, unknown>; requestId?: string }): Promise<{ deleted: boolean }>;\n /** Add each delta to its numeric field, and answer each field's new value. */\n increment(\n recordId: string,\n fields: Record<string, number>,\n options?: { condition?: Record<string, unknown>; requestId?: string }\n ): Promise<{ record: TRow; values: Record<string, number> }>;\n /** This model's ops in one request: one transaction, or each on its own with `atomic: false`. */\n bulk(ops: Array<Db3BulkOp<TRow>>, options?: { atomic?: boolean; requestId?: string }): Promise<Db3BulkResult>;\n}\n\n/**\n * A db3, addressed once and typed by the type its `ctx.db3` call names.\n * Every call is a `db3.records.*` operation on the app's own authority: the\n * handle confers nothing and needs no grant.\n */\nexport interface Db3Handle<TModels> {\n db3Id: string;\n /** The type key this handle was opened with. */\n type: string;\n model<M extends Db3ModelNames<TModels>>(modelName: M): Db3ModelHandle<Db3ModelRow<TModels, M>>;\n /** Ops across models in one request; each op names its `model`. */\n bulk(\n ops: Array<Db3HandleBulkOp<TModels>>,\n options?: { atomic?: boolean; requestId?: string }\n ): Promise<Db3BulkResult>;\n}\n\n/**\n * How a `ctx.db3` handle's calls are judged — #4806.\n *\n * `asUser` names the member every call is judged by: their grant on the\n * db3 and nothing else, with no app or function authority, and the room's\n * hook rules see them as `user.userId`. A sync-off db3 refuses every\n * member (403). Naming a member other than the invoking user needs a run\n * with no caller, one an app owner or admin invoked, or a function declaring\n * `users:actAsAny` (`SUBJECT_USER_FORBIDDEN` otherwise); a user who is not a member is\n * `SUBJECT_USER_NOT_FOUND`.\n *\n * ```ts\n * const mine = ctx.db3(input.db3Id, \"orders\", { asUser: ctx.user.userId });\n * await mine.model(\"Order\").query(); // only what this member may read\n * ```\n */\nexport interface Db3HandleOptions {\n asUser?: string;\n}\n\n/** A db3 opened with no type: the model API over open record shapes, and no `type`. */\nexport type Db3UntypedHandle = Omit<Db3Handle<Record<string, Record<string, unknown>>>, \"type\">;\n\n/**\n * One call through a granted integration — #3183.\n *\n * `path` is RELATIVE to the integration's `baseUrl`, and the host is the\n * integration's: the platform resolves and normalizes the path before checking\n * it against `allowedPaths`, so a protocol-relative path or a `..` segment is\n * refused rather than silently sending the request somewhere else.\n */\nexport interface IntegrationCallRequest {\n /** Must be in the integration's `allowedMethods`. Defaults to its own default. */\n method?: string;\n /** Relative to the integration's `baseUrl`. */\n path?: string;\n query?: Record<string, unknown>;\n headers?: Record<string, string>;\n body?: unknown;\n /** form-urlencoded body; not combinable with `body`. */\n form?: Record<string, unknown>;\n bodyMode?: \"json\" | \"raw\" | \"multipart\";\n}\n\n/** What the upstream answered, as the platform saw it. */\nexport interface IntegrationCallResult {\n status: number;\n headers: Record<string, string>;\n body: unknown;\n durationMs: number;\n traceId: string;\n /** Set when the platform or the upstream refused; absent on success. */\n errorCode?: string;\n}\n\n/** What a prompt run is given — the member execute route's own body. */\nexport interface PromptRunArgs {\n /**\n * The prompt's variables. A `kind = \"decisions\"` prompt takes\n * `{ state, criteria? }`: `state` is the value its questions are asked\n * about, and `criteria.<question>` supplies this run's options for each\n * choice question declared `criteriaSource = \"dynamic\"` — a table of option\n * key = description (a string or a JSON object), at least two entries (#3813).\n */\n variables?: Record<string, unknown>;\n /** Run against a different model for this call only. */\n modelOverride?: string;\n /** Pin a specific config OF THIS PROMPT; defaults to its active one. */\n configId?: string;\n}\n\n/**\n * The app's PROMPTS — EMPTY here and filled by the declaration\n * `primitive config push` writes into the config tree's `functions/` directory\n * (`primitive-prompt-types.d.ts`, from the tree's `prompts/*.toml`). A prompt\n * that declares an `outputSchema` carries `{ output: <Key>PromptOutput }`; one\n * that declares none carries `{}`, so reading `parsed.field` on it is a\n * compile error rather than a runtime `undefined`.\n */\nexport interface PromptSchemas {}\n\n/**\n * The keys whose declaration is an AGENT (`kind = \"agent\"`, #3798): entries\n * carrying `{ agent: … }` instead of an output. An agent runs turn by turn in\n * a session and never single-shot, so these are the keys `PromptKeys` leaves\n * out.\n */\nexport type AgentKeys = {\n [K in keyof PromptSchemas]: PromptSchemas[K] extends { agent: unknown } ? K : never;\n}[keyof PromptSchemas] &\n string;\n\n/**\n * The keys `ctx.prompts.run` accepts — every declared one that is not an\n * agent, or `string` before a push.\n */\nexport type PromptKeys = [keyof PromptSchemas] extends [never]\n ? string\n : Exclude<keyof PromptSchemas & string, AgentKeys>;\n\n/** One agent's session variables, typed from its `inputSchema` (#3798). */\nexport type AgentVariables<K extends AgentKeys> = PromptSchemas[K] extends {\n agent: { variables: infer V };\n}\n ? V\n : never;\n\n/**\n * The keys `ctx.agents.createSession` accepts — #3803: every declared agent,\n * or `string` before the tree has pushed any prompt (the `PromptKeys`\n * rule).\n */\nexport type SessionAgentKeys = [keyof PromptSchemas] extends [never]\n ? string\n : AgentKeys;\n\n/**\n * What `ctx.agents.createSession` takes — #3803. Typed by the agent's key:\n * `variables` is that agent's `inputSchema` (any object before a push),\n * and the platform validates it again against the schema as pushed.\n */\nexport interface AgentSessionCreateOptions<K extends SessionAgentKeys> {\n /** The key of an agent prompt (`kind = \"agent\"`). */\n agent: K;\n /** The session's variables; at most 16 KiB of JSON. */\n variables?: K extends AgentKeys ? AgentVariables<K> : Record<string, unknown>;\n /** Free text the app groups sessions by, 1 to 256 characters. */\n scope?: string;\n /** 1 to 255 characters; defaults to the agent's display name. */\n title?: string;\n /**\n * Initial participants, who send messages and hold a `read-write` grant\n * on the session's document — #3805. Existing users of this app, not the\n * caller; with `viewers`, at most 50.\n */\n participants?: string[];\n /**\n * Initial viewers, who read the session and hold a `reader` grant — #3805.\n * Existing users of this app, not the caller, in neither list twice.\n */\n viewers?: string[];\n /**\n * The member who owns the session; omitted, the invoking user. A run with\n * no caller must name one; naming another member follows the header's\n * subject rule. Initial members may not name the owner.\n */\n userId?: string;\n}\n\n/** What `ctx.agents.createSession` answers — #3803. */\nexport interface AgentSessionCreateResult {\n /** The session: what the app keeps and uses for everything (#4883: its db3 has the same id). */\n sessionId: string;\n}\n\n/** What `ctx.agents.getSession` answers — #3805. Never the document's rows. */\nexport interface AgentSessionInfo {\n sessionId: string;\n agentKey: string;\n ownerUserId: string;\n /** ISO-8601. */\n createdAt: string;\n title: string | null;\n scope: string | null;\n /** ISO-8601; null when the session's listing row is missing. */\n lastActivityAt: string | null;\n /**\n * Whether the invoking user has activity in the session they have not\n * marked read (their client marks it); false for an admin with no role.\n */\n hasUnread: boolean;\n /** When the invoking user last marked the session read (ISO-8601), or null. */\n lastReadAt: string | null;\n /** The members, in the order they were added. */\n members: { viewers: string[]; participants: string[] };\n /** The standing on the session of the member the call acted as. */\n role: \"owner\" | \"participant\" | \"viewer\" | \"admin\";\n /**\n * The session's status, decided from the session object (never the\n * session row): the active turn's phase, else how the last turn ended.\n */\n status: AgentSessionStatus;\n /** The active turn, or null when none runs. */\n turn: AgentSessionTurnSummary | null;\n}\n\n/** A session's status: `idle` between turns, the active turn's phase, or how the last turn ended. */\nexport type AgentSessionStatus =\n | \"idle\"\n | \"thinking\"\n | \"running_tool\"\n | \"awaiting_answer\"\n | \"failed\"\n | \"expired\"\n | \"cancelled\";\n\n/** The active turn of a session, as `ctx.agents.getSession` answers it. */\nexport interface AgentSessionTurnSummary {\n turnId: string;\n /** The member whose messages started the turn. */\n initiatorUserId: string;\n /** ISO-8601; null until the turn has started. */\n startedAt: string | null;\n /** `model` while a model call runs, `tools` while server tools run, `paused` while a call waits on a person. */\n phase: \"model\" | \"tools\" | \"paused\" | \"draining\";\n /** Model rounds begun. */\n rounds: number;\n /** ISO-8601; until when the turn's runner holds it. */\n leaseUntil: string | null;\n /** Who may answer the turn's calls, as pinned at the turn's start. */\n answeredBy: string | null;\n /** The calls waiting on a person and until when, or null. */\n pause: { callIds: string[]; since: string; expiresAt: string } | null;\n /** A transition being made, or null. */\n pending: { kind: \"answer\" | \"end\" } | null;\n}\n\n/** One session in `ctx.agents.listSessions` — #3805. */\nexport interface AgentSessionListItem {\n sessionId: string;\n agentKey: string;\n scope: string | null;\n ownerUserId: string;\n role: \"owner\" | \"participant\" | \"viewer\";\n title: string | null;\n /** ISO-8601. */\n lastActivityAt: string;\n createdAt: string | null;\n /** Whether the user has activity in the session they have not marked read. */\n hasUnread: boolean;\n /** When the user last marked the session read (ISO-8601), or null. */\n lastReadAt: string | null;\n /**\n * The session's status as of its last listed activity, or null for an\n * entry written before the status was listed. It may lag a status change\n * that came with no activity (a server tool's round); `getSession` reads\n * the current one.\n */\n status: AgentSessionStatus | null;\n}\n\n/** What `ctx.agents.listSessions` takes — #3805. */\nexport interface AgentSessionListOptions {\n /**\n * Whose sessions; omitted, the invoking user's. A run with no caller must\n * name one, and naming another follows the header's subject rule. A user\n * with no sessions here, member or not, answers an empty page.\n */\n userId?: string;\n /** Only this agent's sessions. */\n agent?: string;\n /** Only sessions created with exactly this scope. */\n scope?: string;\n /** Page size, at most 100 (default 50). */\n limit?: number;\n /** The `nextCursor` of the previous page. */\n cursor?: string;\n}\n\n/**\n * Which member `ctx.agents.getSession`, `recordEvent` and\n * `deleteSession` act as. Omitted, the invoking user; a run with no caller\n * must name one, and naming another follows the header's subject rule.\n */\nexport interface AgentSessionSubjectOptions {\n userId?: string;\n}\n\n/** A page of `ctx.agents.listSessions` — #3805. */\nexport interface AgentSessionListPage {\n items: AgentSessionListItem[];\n hasMore: boolean;\n nextCursor?: string;\n}\n\n/** What `ctx.agents.recordEvent` takes — #3807. */\nexport interface AgentSessionEvent {\n /** An event kind the session's agent declares. */\n kind: string;\n /** The payload, validated against the kind's schema; at most 64 KiB of JSON. */\n data: unknown;\n /** Your own id for the event, 1 to 128 characters: a repeat with the same content records nothing. */\n eventId?: string;\n /** A call of this session (`call_<ULID>`) the event is about. */\n refersTo?: string;\n}\n\n/** What `ctx.agents.recordEvent` answers — #3807. */\nexport interface AgentSessionEventResult {\n messageId: string;\n seq: number;\n /** Set when the `eventId` was already recorded with this content: the first event's ids. */\n duplicate?: boolean;\n}\n\n/** What `ctx.agents.deleteSession` answers: the session deleted, with everything it held. */\nexport interface AgentSessionDeleteResult {\n deleted: true;\n sessionId: string;\n}\n\n/** One agent's client tools, by name: each one's `input` and `output` (#3798). */\nexport type AgentClientTools<K extends AgentKeys> = PromptSchemas[K] extends {\n agent: { clientTools: infer T };\n}\n ? T\n : never;\n\n/** One agent's event kinds, by name: each one's payload (#3798). */\nexport type AgentEvents<K extends AgentKeys> = PromptSchemas[K] extends {\n agent: { events: infer E };\n}\n ? E\n : never;\n\n/** One prompt's declared output type, or `unknown` where none is declared. */\nexport type PromptOutput<K extends string> = K extends keyof PromptSchemas\n ? PromptSchemas[K] extends { output: infer O }\n ? O\n : unknown\n : unknown;\n\n/**\n * Why a prompt's own answer was refused or incomplete — #3330, #4146. Never\n * set on a PROVIDER failure, which is what makes \"the model returned the wrong\n * shape\" distinguishable from \"the model failed\".\n *\n * `PROMPT_OUTPUT_TRUNCATED` is the answer cut off at the output token limit\n * (`truncated` is `true` beside it): a declared-JSON answer that stopped\n * before it was finished, whatever its shape, or a completion that spent the\n * whole limit and came back empty. Raise the config's `maxTokens` rather\n * than rewording the prompt.\n */\nexport type PromptOutputErrorCode =\n | \"PROMPT_OUTPUT_NOT_JSON\"\n | \"PROMPT_OUTPUT_SCHEMA_VIOLATION\"\n | \"PROMPT_OUTPUT_TRUNCATED\";\n\n/**\n * Every code the envelope's `errorCode` can carry — #3663, #3813.\n *\n * `PROMPT_UPSTREAM_TIMEOUT` and `PROMPT_UPSTREAM_REJECTED` are NOT about the\n * prompt's own answer: the provider ran out of time, or refused the request as\n * invalid (`upstreamStatus` 400 — a setting the model does not support, such\n * as a reasoning level, with the provider's message in `error`), so there was\n * no answer to refuse. They are the only provider failures that set\n * `errorCode`, which is what leaves \"the model returned the wrong shape\"\n * distinguishable from \"the model failed\" while still letting a caller retry\n * a timeout and fix the config for a refusal.\n *\n * `PROMPT_CRITERIA_INVALID` is the run that never reached a provider: a\n * decisions run's `variables.criteria` was refused before the call, so\n * nothing was billed (#3813).\n *\n * `PROMPT_STRICT_OUTPUT_SCHEMA_MISSING` never reached one either: the config\n * sets `strictOutput = true` and the prompt has no usable `outputSchema` to\n * send as the strict `json_schema` (#3801).\n */\nexport type PromptRunErrorCode =\n | PromptOutputErrorCode\n | \"PROMPT_UPSTREAM_TIMEOUT\"\n | \"PROMPT_UPSTREAM_REJECTED\"\n | \"PROMPT_CRITERIA_INVALID\"\n | \"PROMPT_STRICT_OUTPUT_SCHEMA_MISSING\";\n\n/** A prompt that declares an output shape, when the answer matched it. */\nexport interface PromptRunSuccess<TParsed> {\n success: true;\n output: string;\n /** The parsed, validated answer — no caller-side `JSON.parse` (#3330). */\n parsed: TParsed;\n error?: null;\n errorCode?: null;\n metrics?: Record<string, unknown>;\n configId: string;\n /**\n * `true` when the provider stopped at the output token limit\n * (`maxTokens`) before the answer was finished; absent otherwise. On\n * Gemini, reasoning tokens count against the same limit.\n */\n truncated?: true;\n}\n\n/**\n * The failure arm, whichever failed. `errorCode` is set for a SHAPE failure,\n * for a refused run (`PROMPT_CRITERIA_INVALID`, #3813), and for a provider\n * one only when the upstream TIMED OUT (#3663); `output` carries the text\n * either way, which is where the model's own value lives — a validation\n * `error` names paths and schema constraints only.\n */\nexport interface PromptRunFailure {\n success: false;\n output: string;\n error: string | null;\n errorCode?: PromptRunErrorCode | null;\n parsed?: undefined;\n metrics?: Record<string, unknown>;\n configId: string;\n /**\n * The upstream provider's HTTP status, when the call reached a provider and\n * it answered — #3663. This is what a retry decision is made on: a 504 or a\n * 503 is worth another attempt, a 400 on a refused payload is not.\n *\n * It does not depend on which provider the config named: Gemini and\n * OpenRouter report it identically. It is absent when no provider answer was\n * observed — an unset key, an oversized payload, a completion that came back\n * empty — so a number here is always the provider's own.\n */\n upstreamStatus?: number;\n /**\n * `true` when the provider stopped at the output token limit\n * (`maxTokens`) before the answer was finished; absent otherwise. On\n * Gemini, reasoning tokens count against the same limit.\n */\n truncated?: true;\n}\n\n/** The envelope for a key whose declaration says nothing about its output. */\nexport interface PromptRunOpenResult {\n success: boolean;\n output: string;\n /**\n * Present when the config that ran declares `outputFormat = \"json\"` and the\n * text parsed. Untyped: nothing declared its shape.\n */\n parsed?: unknown;\n error?: string | null;\n errorCode?: PromptRunErrorCode | null;\n metrics?: Record<string, unknown>;\n configId: string;\n /** The upstream provider's HTTP status on a provider failure — #3663. */\n upstreamStatus?: number;\n /**\n * `true` when the provider stopped at the output token limit\n * (`maxTokens`) before the answer was finished; absent otherwise. On\n * Gemini, reasoning tokens count against the same limit.\n */\n truncated?: true;\n}\n\n/**\n * The member execute envelope, plus what the prompt's own declaration adds.\n *\n * For a key whose `prompts/<key>.toml` declares an `outputSchema`, this is a\n * discriminated union: narrow on `success` and `parsed` is the declared type,\n * required. For every other key — and in a tree that has not pushed — it is\n * the open shape, with `parsed` optional and `unknown`.\n */\nexport type PromptRunResult<K extends string = string> = K extends keyof PromptSchemas\n ? PromptSchemas[K] extends { output: infer O }\n ? PromptRunSuccess<O> | PromptRunFailure\n : PromptRunOpenResult\n : PromptRunOpenResult;\n\n/** What a send delivered to. */\nexport interface SendResult {\n /** Unique live connections the frame was sent to. Zero is a success. */\n connections: number;\n /** True when the per-user connection ceiling stopped the fanout. */\n truncated: boolean;\n}\n\n/** Who a channel grant is for, and for how long — #3184. */\nexport interface ChannelAuthorizeOptions {\n /**\n * The member the grant names. Caller mode defaults to the invoking caller;\n * system mode has no caller and must say.\n */\n userId?: string;\n /** Default 300 s, clamped to the platform ceiling of 900 s. */\n ttlSeconds?: number;\n}\n\n/** The credential a client presents on the WebSocket it already has. */\nexport interface ChannelGrantResult {\n channel: string;\n /** The signed grant. Hand it to the client; it is not readable here. */\n grant: string;\n /** Epoch milliseconds. Expiry is the only revocation a channel has. */\n expiresAt: number;\n}\n\n/** Where to start and how big a page to take — #3280. */\nexport interface UserPageOptions {\n /** Page size. Capped by the route at 100. */\n limit?: number;\n /** The `nextCursor` of the page before this one. */\n cursor?: string;\n}\n\n/** One user on the roster, as the platform's own users route reports them. */\nexport interface UserPageItem {\n userId: string;\n email: string | null;\n name: string | null;\n avatarUrl: string | null;\n role: string;\n addedAt: string | null;\n status: string;\n disabledAt: string | null;\n [key: string]: unknown;\n}\n\n/** The decided paged envelope, the same shape every paged read answers. */\nexport interface UserPage {\n items: UserPageItem[];\n hasMore: boolean;\n /** Absent on the last page. */\n nextCursor?: string;\n}\n\n/** How a nested start is keyed and labelled — #3280. */\nexport interface FunctionStartOptions {\n /**\n * Idempotency key, scoped to the tree's root initiator and the resolved\n * context document: a repeat replays the run that already exists rather than\n * starting a second. At most 100 characters.\n */\n runKey?: string;\n /**\n * The document the child's run is keyed under. Defaults through the\n * inheritance rule: the parent run's context, else the root caller's root\n * document, else `fn:<the root function's id>`. At most 100 characters.\n */\n contextDocId?: string;\n /** Caller metadata, at most 1 KB encoded. */\n meta?: Record<string, unknown>;\n}\n\n/** The start envelope, the same one a workflow start answers with — #3280. */\nexport interface FunctionStartResult {\n /** Poll this on the platform's run-status route. */\n runId: string;\n runKey: string;\n instanceId: string;\n status: string;\n /**\n * True when `runKey` already named a run in this tree, which this envelope\n * describes. That is what makes a run key a singleton.\n */\n existing?: boolean;\n}\n\n/** A held named lock, as `ctx.locks.acquire` hands it back — #3930. */\nexport interface LockHandle {\n key: string;\n handleId: string;\n leaseExpiresAt: string;\n}\n\n/** How long to hold, and how long to wait — #3930. */\nexport interface LockAcquireOptions {\n /** The lease, in milliseconds (at most 24 h). Renew or release before it lapses. */\n ttlMs: number;\n /**\n * How long to wait for the key, in milliseconds, at most one hour. Under the\n * request runtime it must also fit the invocation's remaining budget.\n */\n timeoutMs: number;\n /**\n * Who this hold belongs to. Defaults to `ctx.runId` when the invocation\n * has a run, so a resumed slice re-takes its own hold with a fresh handle\n * rather than waiting on it.\n */\n owner?: string;\n}\n\n/**\n * The answer to a blocking acquire — #3930. Never a throw for \"not acquired\":\n * a refusal carries the last contention seen, and `rateLimited` says the\n * last attempt was refused by the acquire rate limit rather than by a holder.\n */\nexport type LockAcquireResult =\n | { acquired: true; handle: LockHandle }\n | {\n acquired: false;\n timedOut: true;\n rateLimited: boolean;\n heldBy: string | null;\n holderKind: string | null;\n owner: string | null;\n leaseExpiresAt: string | null;\n };\n\n/** The answer to `ctx.locks.release`. */\nexport type LockReleaseResult =\n | { released: true }\n | { released: false; reason: \"not_holder\" | \"not_held\" };\n\nexport interface FunctionContext {\n /** The HTTP caller, or null for a webhook or cron fire. */\n user: FunctionUser | null;\n trigger: FunctionTrigger;\n /**\n * The agent session this tool call belongs to, when an agent turn called\n * the function as a tool (`ctx.trigger.kind === \"tool\"`); otherwise\n * absent.\n *\n * Checking `ctx.trigger.kind` narrows `ctx.trigger` and not this\n * member, so call `assertTrigger(ctx, \"tool\")` first to read it without a\n * guard.\n */\n tool?: FunctionToolContext;\n /**\n * Which RUNTIME is hosting this code — #3482.\n *\n * Beside `trigger`, which says which DOOR fired, and they are different\n * questions: an HTTP call is whichever runtime the caller chose\n * (`invoke` or `start`), a cron fire is always a task and a webhook\n * delivery is always a request.\n *\n * To REFUSE a runtime rather than branch on it, call\n * `assertRuntime(\"task\")` — at module scope to refuse it outright, or in\n * the handler to refuse one call.\n */\n runtime: \"request\" | \"task\";\n /**\n * The RUN this invocation belongs to, or null — #3562.\n *\n * Set under the task runtime (every slice of the run, the first and every\n * resume) and for a webhook-fired request run, which writes a row. Null for\n * an HTTP `invoke`, which writes no run row at all.\n *\n * It is the deterministic OWNER a task run presents to re-take its own\n * lease: `ctx.api.locks.tryAcquire({ body: { key, ttlMs, owner: ctx.runId } })`\n * succeeds for the run that already holds the key, with a fresh handle.\n */\n runId: string | null;\n /**\n * The SLICE of the run this code is running in, or null — #3562.\n *\n * The same identifier `primitive functions runs` and the run-status\n * route's `slice.sliceId` report. A task run is a sequence of slices: it\n * changes when the run hibernates and wakes, which is how a handler can tell\n * a resume from a first pass.\n *\n * Null under the request runtime: a request invocation is not a slice.\n */\n sliceId: string | null;\n api: FunctionApi;\n /**\n * A typed handle over one database. The second argument is the database TYPE\n * key — the same key a `database:<type>/<model>:read|write` grant names —\n * and it is what selects the models this handle knows (#3182).\n */\n db<K extends DatabaseTypeKeys>(\n databaseId: string,\n databaseType: K\n ): DatabaseHandle<DatabaseModels<K>>;\n /**\n * A typed handle over one document's record models, typed from the\n * project's `models/models.toml` — `ctx.db`'s shape for documents. It\n * confers nothing: every call is a `documents.records.*` operation on the\n * same authority.\n */\n /**\n * A typed handle over one db3, typed from the pushed db3 types\n * (`primitive-db3-types.d.ts`):\n *\n * ```ts\n * const orders = ctx.db3(input.db3Id, \"orders\").model(\"Order\");\n * const { record } = await orders.save({ data: { total: 12 } });\n * await orders.increment(record.id, { total: 3 });\n * ```\n *\n * It confers nothing: every call is a `db3.records.*` operation on the\n * app's own authority, as `ctx.doc`'s are. A function that watches the\n * db3 it writes (`[[function.triggers.db3]]`) starts a run per flush of its\n * own writes; check `ctx.trigger.kind === \"db3\"` before writing back.\n *\n * A db3's lifecycle (create, get, delete, sync, type, app access, custody)\n * is `ctx.api.db3.*`, as `ctx.db`'s is `ctx.api.databases.*`.\n */\n db3<K extends Db3TypeKeys>(db3Id: string, type: K): Db3Handle<Db3Models<K>>;\n /**\n * The typed handle, with every call judged by the member `options.asUser`\n * names (`Db3HandleOptions`).\n */\n db3<K extends Db3TypeKeys>(db3Id: string, type: K, options: Db3HandleOptions): Db3Handle<Db3Models<K>>;\n /**\n * An untyped db3, from any tree: the same model API over open record\n * shapes, and no `type`.\n *\n * ```ts\n * const notes = ctx.db3(input.db3Id).model(\"Note\");\n * ```\n */\n db3(db3Id: string): Db3UntypedHandle;\n /** An untyped db3, with every call judged by the member `options.asUser` names. */\n db3(db3Id: string, type: undefined, options: Db3HandleOptions): Db3UntypedHandle;\n doc(documentId: string, options?: { documentFormat?: 1 | 2 | 3 }): DocumentHandle;\n /**\n * Outbound HTTP, through a granted integration and nowhere else (#3183).\n *\n * A function has no raw network access: every `fetch` to a host that is not\n * the platform answers `FUNCTION_EGRESS_DENIED`, grant or no grant. What an\n * `integration:<key>` grant buys is this call, which the MAIN WORKER makes on\n * the function's behalf — which is why the integration's `{{secrets.*}}`\n * credentials can be injected into the request without ever being visible to\n * the code that asked for it.\n */\n integrations: {\n call(\n integrationKey: string,\n request?: IntegrationCallRequest\n ): Promise<IntegrationCallResult>;\n };\n /**\n * Start another function as a TASK run from inside this one — #3280.\n *\n * The one nested door, and it is a START: code that wants a result composes\n * by IMPORTING the other function, so there is no synchronous nested\n * invocation to reach for.\n *\n * The callee's `access` gate is not consulted — this function's own gate was\n * the authorization — and every run in the tree is keyed by whoever started\n * it, so the member who invoked the root polls and terminates them all.\n * Nesting is bounded at four levels.\n */\n functions: {\n start(\n functionKey: string,\n input?: unknown,\n options?: FunctionStartOptions\n ): Promise<FunctionStartResult>;\n };\n /**\n * Run one of the app's prompts, with nothing to declare (#3183, #3279).\n *\n * The calling function's `authorize` is the authorization: it decided who\n * may invoke the function, and so who may run the prompt, which carries no\n * rule of its own. The provider request is bounded by the invocation's own\n * deadline.\n *\n * TYPED BY KEY (#3330). Where `prompts/<key>.toml` declares an\n * `outputSchema`, the platform parses the answer, validates it against that\n * schema and hands it back as `parsed`, typed — so the shape is written once\n * in TOML instead of restated as a `JSON.parse` at every call site. Where\n * only the config that ran declares `outputFormat = \"json\"`, `parsed` is\n * present but `unknown`. Where neither is declared the envelope is exactly\n * what it has always been.\n *\n * A shape the declaration refuses is `success: false` with an `errorCode`\n * (`PROMPT_OUTPUT_NOT_JSON` or `PROMPT_OUTPUT_SCHEMA_VIOLATION`) and the\n * text still in `output`; a PROVIDER failure has `error` and no\n * `errorCode`, so the two are told apart without guessing.\n *\n * Once a tree has pushed, a key it does not declare is a compile error.\n */\n prompts: {\n run<K extends PromptKeys>(\n promptKey: K,\n args?: PromptRunArgs\n ): Promise<PromptRunResult<K>>;\n };\n /**\n * Agent sessions (#3803, project `agents`), on the header's subject rule:\n * each call acts for `userId`, else the invoking user, and from any kind of\n * run — a run with no caller must name the member.\n *\n * `createSession` creates a session that member owns and answers\n * `{ sessionId }`. Variables failing the agent's\n * `inputSchema` reject with `AGENT_SESSION_VARIABLES_INVALID` and\n * `details.errors`. Once a tree has pushed, a key that is not an agent,\n * and variables the agent's schema refuses, are compile errors.\n * `participants` and `viewers` name initial members (#3805).\n *\n * `getSession` and `listSessions` (#3805) read the member's sessions —\n * the ones they own or are a member of — as that member, with no admin arm\n * whoever invoked the function: a session they are not in answers\n * `AGENT_SESSION_NOT_FOUND`, and function code never sees a session's\n * `object`, `turnContexts` or `lastTurn`.\n *\n * `deleteSession` deletes a session the member owns, with the same\n * outcome as the owner's delete from a client: the session, its document\n * and every member's listing go, and a repeat answers the same. A session\n * whose document is already gone can still be deleted. A participant or\n * viewer is refused `AGENT_SESSION_OWNER_ONLY`, anyone else\n * `AGENT_SESSION_NOT_FOUND`, with no admin arm. A `userId` that is\n * present but not a string (`null`, a number) is refused\n * `SUBJECT_USER_INVALID`, never read as the invoking user. Renaming and\n * changing members are the owner's, from a client.\n *\n * `recordEvent` (#3807) records an event as the member, who must be the\n * session's owner or a participant (`AGENT_SESSION_PARTICIPANT_ONLY` for a\n * viewer); the row is authored `app`. The kind must be one the agent\n * declares (`AGENT_EVENT_KIND_UNKNOWN`) and the data must match its schema\n * (`AGENT_EVENT_INVALID`). An event never starts a turn; the model reads\n * it in a later turn.\n */\n agents: {\n createSession<K extends SessionAgentKeys>(\n options: AgentSessionCreateOptions<K>\n ): Promise<AgentSessionCreateResult>;\n getSession(\n sessionId: string,\n options?: AgentSessionSubjectOptions\n ): Promise<AgentSessionInfo>;\n listSessions(options?: AgentSessionListOptions): Promise<AgentSessionListPage>;\n recordEvent(\n sessionId: string,\n event: AgentSessionEvent,\n options?: AgentSessionSubjectOptions\n ): Promise<AgentSessionEventResult>;\n deleteSession(\n sessionId: string,\n options?: AgentSessionSubjectOptions\n ): Promise<AgentSessionDeleteResult>;\n };\n /**\n * The value of one app secret, under a `secret:<NAME>` grant (#3183).\n *\n * Prefer `ctx.integrations.call` when the secret is a credential FOR an\n * integration: there the value is injected by the platform and never enters\n * the sandbox at all. This is for the cases an integration cannot express.\n *\n * Rejects with `FUNCTION_SECRET_NOT_FOUND` when the grant names a value\n * this environment has not been given — secrets are provisioned per\n * environment, out of band from the push.\n */\n secret(name: string): Promise<string>;\n /** The value of one app config var, under a `var:<NAME>` grant (#3183). */\n configVar(name: string): Promise<string>;\n /**\n * Realtime messages to this app's clients, under a `users:send` grant\n * (#3183).\n *\n * The recipient's client receives a `direct.message` frame carrying this\n * payload and the sending function's key. Presence is not guaranteed: a\n * member with no live socket answers `{ connections: 0 }` rather than an\n * error.\n */\n users: {\n /**\n * One page of the app's users — #3280.\n *\n * On the APP's system authority, whoever invoked the function: a member\n * who passes this function's gate reads whatever roster it chooses to\n * expose, so say who may in the function's own `access` expression.\n * `limit` is capped by the route at 100.\n */\n list(options?: UserPageOptions): Promise<UserPage>;\n /**\n * Every page of the app's users, in order — #3280.\n *\n * FOR A REQUEST FUNCTION AND A SINGLE-SLICE LOOP. A durable loop must take\n * its pages inside `step.do` with an EXPLICIT cursor: a memoized step does\n * not advance an iterator on resume, so an iteration across a sleep would\n * replay pages it had already taken.\n */\n iterate(options?: UserPageOptions): AsyncIterable<UserPage>;\n send(userId: string, payload: unknown): Promise<SendResult>;\n };\n /** The same frame to ONE connection, under a `connections:send` grant. */\n connections: {\n send(connectionId: string, payload: unknown): Promise<SendResult>;\n };\n /**\n * Realtime channels, under a `channel:<namespace>` grant that COVERS the\n * channel — #3184.\n *\n * `authorize` hands back a short-lived grant for ONE member to present on\n * the socket it already has; `publish` delivers a `channel.message` frame to\n * every connection that has joined and whose grant has not expired. Expiry is\n * the only revocation, so `expiresAt` comes back for the client to renew\n * ahead of — a renewal is another authorize and another subscribe.\n */\n channels: {\n authorize(\n channel: string,\n options?: ChannelAuthorizeOptions\n ): Promise<ChannelGrantResult>;\n publish(channel: string, payload: unknown): Promise<SendResult>;\n };\n /**\n * Named locks that WAIT — #3930. `ctx.api.locks.tryAcquire` is one attempt;\n * these wait for the key, up to `timeoutMs` (at most one hour).\n *\n * The owner defaults to `ctx.runId`, so a run never waits on its own hold:\n * a resumed slice, or a second call on a key the run already holds, re-takes\n * it at once with a fresh handle.\n *\n * Under the TASK runtime the wait is durable: each attempt is a step that\n * asks the platform to wait server-side for up to 30 s, so a wait costs one\n * platform call and one acquire slot per half-minute, no CPU, and the\n * slice's budget is refreshed at every attempt. It is not a suspension — the\n * engine does not hibernate a wait shorter than five minutes. Under the\n * REQUEST runtime the whole wait must fit the invocation's remaining budget,\n * or the call fails `FUNCTION_RUNTIME_REFUSED` before any attempt (a\n * webhook delivery has 5 s): hand longer waits to a task with\n * `ctx.functions.start`.\n */\n locks: {\n /**\n * Wait for `key`. Answers `acquired: true` with the handle, or\n * `acquired: false, timedOut: true` with the last contention seen.\n */\n acquire(key: string, options: LockAcquireOptions): Promise<LockAcquireResult>;\n /** Release a handle `acquire` handed back. */\n release(handle: LockHandle): Promise<LockReleaseResult>;\n /**\n * Acquire, run `fn`, and release in `finally` — on a return and on a\n * throw. Answers `fn`'s value; `fn`'s own error propagates after the\n * release. Throws an error named `LOCK_TIMEOUT` (`code` the same, the\n * contention in `details`) without running `fn` when the key is not\n * acquired within `timeoutMs`. A nested `withLock` on the same key in\n * one run re-enters, and its release frees the outer hold: use distinct\n * keys, or one wrapper.\n */\n withLock<T>(\n key: string,\n options: LockAcquireOptions,\n fn: (handle: LockHandle) => Promise<T>\n ): Promise<T>;\n };\n}\n\n/**\n * `FunctionContext` as `assertTrigger(ctx, kind)` leaves it: `trigger`\n * is the arm for `K`, `tool` is set for a tool call and `undefined` for\n * every other door, and `user` is the turn's initiator, never null, for the\n * three doors an agent turn opens (`tool`, `context` and `history`).\n *\n * Annotate a helper's parameter with it to take a context the caller has\n * already asserted:\n *\n * ```ts\n * async function lookup(ctx: FunctionContextFor<\"tool\">) {\n * return ctx.tool.variables.householdId;\n * }\n * ```\n */\nexport type FunctionContextFor<K extends FunctionTriggerKind> = FunctionContext & {\n trigger: Extract<FunctionTrigger, { kind: K }>;\n tool: K extends \"tool\" ? FunctionToolContext : undefined;\n user: K extends \"tool\" | \"context\" | \"history\" ? FunctionUser : FunctionUser | null;\n};\n\n/** How the wait between one step's retries grows. */\nexport type StepBackoff = \"constant\" | \"linear\" | \"exponential\";\n\n/**\n * The retry and timeout policy for ONE `step.do` — Cloudflare Workflows' own\n * step config.\n *\n * Under the TASK runner the platform forwards this object to Workflows\n * untouched, so these are its fields and its spellings: a duration is either a\n * number of milliseconds or a string Workflows parses (`\"10 seconds\"`,\n * `\"5 minutes\"`). Under the REQUEST runner `step.do` accepts a config and\n * ignores it — the body runs inline, and there is nothing to retry into.\n *\n * `stepPolicy.<family>` IS a `StepConfig`, so the platform's own defaults\n * hand straight to `step.do` (#3657). The shape is closed on purpose: a key\n * outside it — `retry` for `retries`, `timeoutMs` for `timeout` — is a\n * refusal at `config push` rather than an option the engine silently drops.\n */\nexport interface StepConfig {\n retries?: { limit: number; delay: string | number; backoff?: StepBackoff };\n timeout?: string | number;\n}\n\n/**\n * The step handle. `step` is the third argument under BOTH runners, so the\n * same body runs either way — which is what `mode = \"any\"` is for (#3454).\n *\n * Under the TASK runner it is Cloudflare Workflows' `WorkflowStep`, forwarded\n * untouched: `step.do` results are memoized and replayed, and `step.sleep`\n * hibernates.\n *\n * Under the REQUEST runner it is the platform's own, bounded by the request's\n * clock: `do` executes the body inline (there is no engine to memoize into,\n * and nothing is replayed); `sleep` and `sleepUntil` REALLY wait when the\n * remaining request budget covers the duration, and otherwise fail the\n * invocation with `errorCode: \"FUNCTION_RUNTIME_REFUSED\"` saying to start the\n * function as a task; `waitForEvent` fails the same way, because nothing can\n * deliver an event to an invocation that has to return now. The thrown error's\n * `name` is `STEP_NOT_AVAILABLE` in every case, so a body that catches it\n * keeps catching it.\n */\nexport interface FunctionStep {\n do<T>(name: string, body: () => T | Promise<T>): Promise<T>;\n do<T>(\n name: string,\n config: StepConfig,\n body: () => T | Promise<T>\n ): Promise<T>;\n sleep(name: string, duration: number | string): Promise<void>;\n sleepUntil(name: string, timestamp: Date | number): Promise<void>;\n waitForEvent<T = unknown>(\n name: string,\n options: Record<string, unknown>\n ): Promise<T>;\n}\n\nexport declare const SDK_STUB_VERSION: string;\n\n/**\n * Thrown by `assertRuntime` when this function is running under the other\n * runtime — #3482.\n *\n * The platform settles it as `status: \"failed\"` with\n * `errorCode: \"FUNCTION_RUNTIME_REFUSED\"`, on a request invocation's\n * envelope and on a task run's row and record alike.\n */\nexport declare class FunctionRuntimeError extends Error {\n name: \"FUNCTION_RUNTIME_REFUSED\";\n /** The runtime this invocation is actually running under. */\n runtime: \"request\" | \"task\";\n /** The runtime the function asked for. */\n required: \"request\" | \"task\";\n}\n\n/**\n * Refuse the runtime this function was not written for — #3482.\n *\n * A function is a function and the caller picks the runtime at each call, so\n * nothing in config says which one a function may run under. This is the lock,\n * and it lives in the one place that can always be right about the code:\n *\n * ```ts\n * import { assertRuntime } from \"primitive-functions\";\n *\n * // At module scope: this function is never runnable inside a request.\n * assertRuntime(\"task\");\n *\n * export default async function (input, ctx, step) {\n * await step.sleep(\"cool-off\", \"1 hour\");\n * return { ok: true };\n * }\n * ```\n *\n * Returns when the runtimes match; otherwise throws\n * {@link FunctionRuntimeError}, which the platform settles as\n * `status: \"failed\"` with `errorCode: \"FUNCTION_RUNTIME_REFUSED\"` and a\n * message naming both runtimes and the verb that takes the one required.\n * When `primitive config push` loads the module to check its export, no\n * runtime is running and every assertion returns.\n */\nexport declare function assertRuntime(required: \"request\" | \"task\"): void;\n\n/**\n * Refuse every door but the one this function was written for, and narrow\n * `ctx` to it.\n *\n * Make it the first line of a tool function: an agent turn calls it with\n * `ctx.tool` set, but the same function is also reachable over plain HTTP.\n * After the call, `ctx.trigger` is the named arm, `ctx.tool` needs no\n * guard, and `ctx.user` is the turn's initiator:\n *\n * ```ts\n * import { assertTrigger, defineFunction } from \"primitive-functions\";\n *\n * export default defineFunction(async (_input, ctx) => {\n * assertTrigger(ctx, \"tool\");\n * const { householdId } = ctx.tool.variables as { householdId: string };\n * await assertHouseholdMember(ctx.user.userId, householdId);\n * return { callId: ctx.trigger.callId };\n * });\n * ```\n *\n * Returns when `ctx.trigger.kind` is `kind`. Otherwise it throws an\n * `Error` naming both kinds, which the platform settles as\n * `status: \"failed\"` with `errorCode: \"FUNCTION_THREW\"`. A `kind` that is\n * not a trigger kind, or a first argument that is not a context, throws a\n * `TypeError`. It takes `ctx`, so it runs inside the handler, never at\n * module scope.\n */\nexport declare function assertTrigger<K extends FunctionTriggerKind>(\n ctx: FunctionContext,\n kind: K\n): asserts ctx is FunctionContextFor<K>;\n\n/**\n * The handler a function exports, typed for one declared key.\n *\n * `step` is the third argument under BOTH runners (#3186, #3454). A task run\n * gets the engine's live `WorkflowStep`; a request invocation gets the\n * platform's own, where `do` runs the body inline and a wait the request\n * budget cannot cover fails the invocation naming the task runner — so a\n * task-authored body can be exercised as a request, and the one place the two\n * genuinely differ says so rather than pretending.\n */\nexport type FunctionHandler<TInput, TOutput> = (\n input: TInput,\n ctx: FunctionContext,\n step: FunctionStep\n) => Promise<TOutput>;\n\n/** The codes a `deny` carries. */\nexport type AuthorizeCode = \"FORBIDDEN\" | \"NOT_FOUND\" | \"INVALID\";\n\n/**\n * What `allow(resolved)` returns. `resolved` is what the handler reads as\n * `ctx.auth`; `allow()` resolves `null`.\n */\nexport interface AllowDecision<T = null> {\n readonly decision: \"allow\";\n readonly resolved: T;\n}\n\n/** What `deny(code, message?, { expose? })` returns. */\nexport interface DenyDecision {\n readonly decision: \"deny\";\n readonly code: AuthorizeCode;\n /** The message, or `null` when none was given. */\n readonly message: string | null;\n /** Whether the deny asked for its code to be shown to the caller. */\n readonly expose: boolean;\n}\n\n/** Either decision. `T` is what an allow resolves. */\nexport type AuthorizeDecision<T = unknown> = AllowDecision<T> | DenyDecision;\n\n/** The caller `authorize` decides about. */\nexport interface FunctionAuthUser extends FunctionUser {\n /** The caller's role in the app, or `null` when it has none. */\n role: string | null;\n}\n\n/** An app role, as `requireRole` ranks it: owner > admin > member. */\nexport type AppRole = \"owner\" | \"admin\" | \"member\";\n\n/** A role on a group, ranked owner > manager > member. */\nexport type GroupRole = \"owner\" | \"manager\" | \"member\";\n\n/** A role on a collection, ranked owner > manager > editor > contributor > viewer. */\nexport type CollectionRole = \"owner\" | \"manager\" | \"editor\" | \"contributor\" | \"viewer\";\n\n/** The caller's permission on a document. */\nexport type DocumentPermission = \"owner\" | \"read-write\" | \"reader\";\n\n/** One group the caller belongs to, with the role they hold on it. */\nexport interface AuthMembership {\n groupType: string;\n groupId: string;\n role: GroupRole;\n}\n\n/** One database model, for reading inside `authorize`. */\nexport interface AuthDatabaseModelHandle<TRow> {\n /** The row with this id, or `null` when there is none. */\n get(recordId: string): Promise<TRow | null>;\n /** One page of rows, in the same envelope `ctx.db` answers. */\n query(body?: ModelScopedBody): Promise<{ items: TRow[]; hasMore: boolean; nextCursor?: string }>;\n}\n\n/** One database, typed by its type key the way `ctx.db` is, with reads only. */\nexport interface AuthDatabaseHandle<TModels> {\n model<M extends DatabaseModelNames<TModels>>(\n modelName: M\n ): AuthDatabaseModelHandle<DatabaseModelRow<TModels, M>>;\n}\n\n/** One document model, for reading inside `authorize`. */\nexport interface AuthDocumentModelHandle<TRow> {\n /** The record with this id, or `null` when there is none. */\n get(recordId: string): Promise<TRow | null>;\n /** One page of records, in the same envelope `ctx.doc` answers. */\n query(options?: DocumentQueryOptions): Promise<{ items: Array<TRow & { _related?: Record<string, any> }>; hasMore: boolean; nextCursor?: string }>;\n}\n\n/**\n * One db3 model, for reading inside `authorize`. A db3 that does not exist in\n * this app rejects 404 `DB3_NOT_FOUND`.\n */\nexport interface AuthDb3ModelHandle<TRow> {\n /** The record with this id, or `null` when there is none. */\n get(recordId: string): Promise<TRow | null>;\n /** One page of records, in the same envelope `ctx.db3` answers. */\n query(options?: DocumentQueryOptions): Promise<{ items: Array<TRow & { _related?: Record<string, any> }>; hasMore: boolean; nextCursor?: string }>;\n}\n\n/** One db3, typed by its type the way `ctx.db3` is, with reads only. */\nexport interface AuthDb3Handle<TModels> {\n model<M extends Db3ModelNames<TModels>>(modelName: M): AuthDb3ModelHandle<Db3ModelRow<TModels, M>>;\n /** The caller's level on the db3, or `null`: none, not a db3 of this app, or its sync is off. One read. */\n permissions(): Promise<DocumentPermission | null>;\n}\n\n/** One document, for reading inside `authorize`; its models are typed the way `ctx.doc`'s are. */\nexport interface AuthDocumentHandle {\n /** The document, or `null` when this app has none with that id. */\n get(): Promise<Record<string, any> | null>;\n /** The caller's permission on the document, or `null` when they have none. */\n permissions(): Promise<DocumentPermission | null>;\n /** The document's tags, or `null` when this app has no such document. */\n tags(): Promise<string[] | null>;\n model<M extends DocumentModelNames>(modelName: M): AuthDocumentModelHandle<DocumentModelRow<M>>;\n}\n\n/**\n * What `authorize` is handed beside the input. It only reads: there is no\n * write, secret, integration or start here, and the platform refuses one\n * reached any other way.\n */\nexport interface FunctionAuthContext {\n /** The caller, or `null` when no user started this invocation. */\n readonly user: FunctionAuthUser | null;\n /** What started this invocation. */\n readonly trigger: FunctionTrigger;\n /** Whether the caller's app role is exactly `role`: `hasRole(\"admin\")` is false for an owner. */\n hasRole(role: string): boolean;\n /** Every group the caller belongs to, loaded whole. */\n memberships(): Promise<AuthMembership[]>;\n /** Whether the caller belongs to the group. */\n isMemberOf(groupId: string): Promise<boolean>;\n /** The ids of the groups the caller belongs to. */\n memberGroups(): Promise<string[]>;\n /** Whether the caller holds `role` or above on the group. */\n hasGroupRole(groupId: string, role: GroupRole): Promise<boolean>;\n readonly collections: {\n /** The caller's role on the collection, or `null` when they have none. */\n resolveRole(collectionId: string): Promise<CollectionRole | null>;\n };\n /** One document, read-only. */\n doc(documentId: string): AuthDocumentHandle;\n /** One database, read-only, typed by its type key. */\n db<K extends DatabaseTypeKeys>(\n databaseId: string,\n databaseType: K\n ): AuthDatabaseHandle<DatabaseModels<K>>;\n /** One db3, read-only, typed by its type. */\n db3<K extends Db3TypeKeys>(db3Id: string, type: K): AuthDb3Handle<Db3Models<K>>;\n /** An app config var's value. */\n configVar(name: string): Promise<string>;\n}\n\n/**\n * An `authorize` method: it decides from the input and the read-only\n * `auth` context, and what its `allow` resolves is `TAuth`.\n */\nexport type AuthorizeFn<TInput = any, TAuth = unknown> = (\n input: TInput,\n auth: FunctionAuthContext\n) => AuthorizeDecision<TAuth> | Promise<AuthorizeDecision<TAuth>>;\n\n// A conditional rather than the function type itself, on purpose: the\n// compiler sets aside a generic call that returns a function type while it\n// infers `defineFunction`'s type arguments, so `ctx.auth` would be fixed\n// before `authorize: requireMember(...)` was read. Deferred, the helper's\n// result is read first and types both the selector's input and `ctx.auth`.\n/**\n * What a helper that reads its input returns: an {@link AuthorizeFn} over\n * that input.\n */\nexport type AuthorizeHelper<TInput, TAuth> = [TInput] extends [unknown]\n ? AuthorizeFn<TInput, TAuth>\n : never;\n\n/**\n * Admit the caller. The value passed is what the handler reads as\n * `ctx.auth`, and it must be JSON-serializable.\n *\n * ```ts\n * import { allow, defineFunction, deny } from \"primitive-functions\";\n *\n * export default defineFunction({\n * authorize: async (input: { orgId: string }, auth) =>\n * auth.user ? allow({ orgId: input.orgId }) : deny(\"FORBIDDEN\"),\n * handler: async (input, ctx) => ({ orgId: ctx.auth.orgId }),\n * });\n * ```\n */\nexport declare function allow(): AllowDecision<null>;\nexport declare function allow<const T>(resolved: T): AllowDecision<T>;\n\n/**\n * Refuse the caller with one of the three codes. A code outside them, a\n * message that is not a string, or an `expose` that is not a boolean throws\n * a `TypeError` where the deny is written.\n */\nexport declare function deny(\n code: AuthorizeCode,\n message?: string,\n options?: { expose?: boolean }\n): DenyDecision;\n\n/**\n * Fail the invocation with your own code. It throws, so nothing after it\n * runs. The caller gets `status: \"failed\"` with `errorCode` set to\n * `code` and `error` set to `message` (or the code when no message is\n * given):\n *\n * ```ts\n * import { defineFunction, fail, requireSignedIn } from \"primitive-functions\";\n *\n * export default defineFunction({\n * authorize: requireSignedIn(),\n * handler: async (input: { quantity: number }) => {\n * if (input.quantity > 100) fail(\"ORDER_TOO_LARGE\", \"orders are capped at 100 units\");\n * return { accepted: input.quantity };\n * },\n * });\n * ```\n *\n * Any non-empty string is a code. Under the task runtime the run fails with\n * `errorCode: \"FUNCTION_THREW\"` and an `errorMessage` of\n * `FUNCTION_THREW: <code>: <message>`. Called inside `authorize`, it is a\n * throw, so the caller is denied. A code that is not a non-empty string, or a\n * message that is not a string, throws a `TypeError` instead.\n */\nexport declare function fail(code: string, message?: string): never;\n\n/**\n * An `authorize` that admits every caller the function's routes already\n * admit, with no check. It reads nothing and resolves `null`. To require a\n * signed-in caller, use {@link requireSignedIn}.\n */\nexport declare function allowAnyone(): AuthorizeFn<any, null>;\n\n/** An `authorize` that admits a signed-in caller, resolving `{ userId }`. */\nexport declare function requireSignedIn(): AuthorizeFn<any, { userId: string }>;\n\n/**\n * An `authorize` that admits a caller whose app role is `role` or above,\n * ranked owner > admin > member, so `requireRole(\"admin\")` admits an owner.\n * Resolves `{ userId, role }`.\n */\nexport declare function requireRole(\n role: AppRole\n): AuthorizeFn<any, { userId: string; role: AppRole }>;\n\n/**\n * An `authorize` that admits a member of the group `groupIdOf(input)`\n * names, at `role` or above when one is given. Resolves\n * `{ userId, groupId, role }` with the highest role the caller holds there.\n * An input that names no group id is denied `INVALID`.\n *\n * ```ts\n * import { defineFunction, requireMember } from \"primitive-functions\";\n *\n * export default defineFunction(\"team-report\", {\n * authorize: requireMember((input) => input.teamId, \"manager\"),\n * handler: async (input, ctx) => ({ team: ctx.auth.groupId, as: ctx.auth.role }),\n * });\n * ```\n */\nexport declare function requireMember<TInput = any>(\n groupIdOf: (input: TInput) => string,\n role?: GroupRole\n): AuthorizeHelper<TInput, { userId: string; groupId: string; role: GroupRole }>;\n\n/**\n * An `authorize` that admits a caller whose role on the collection\n * `collectionIdOf(input)` names is `minRole` or above, ranked owner >\n * manager > editor > contributor > viewer. Resolves\n * `{ userId, collectionId, role }`.\n */\nexport declare function requireCollectionRole<TInput = any>(\n collectionIdOf: (input: TInput) => string,\n minRole: CollectionRole\n): AuthorizeHelper<TInput, { userId: string; collectionId: string; role: CollectionRole }>;\n\n/**\n * An `authorize` that admits the owner of the document\n * `documentIdOf(input)` names, resolving `{ userId, documentId }`.\n */\nexport declare function requireDocumentOwner<TInput = any>(\n documentIdOf: (input: TInput) => string\n): AuthorizeHelper<TInput, { userId: string; documentId: string }>;\n\n/**\n * Which doors {@link allowCallers} admits. `users` decides on `http` only.\n * The agent doors (`tool`, `context`, `history`) are admitted only\n * through `agents`: `true` applies the `users` rule there too, and a\n * function is a rule of its own, which may resolve something other than the\n * `users` rule does.\n */\nexport interface CallerRules<TInput = any, TAuth = unknown, TAgentAuth = TAuth> {\n webhook?: boolean;\n cron?: boolean;\n manual?: boolean;\n /** A flush of a db3 of a type a `[[function.triggers.db3]]` entry watches. */\n db3?: boolean;\n /** The parent functions whose nested start is admitted, by key. */\n functions?: readonly string[];\n agents?: boolean | AuthorizeFn<TInput, TAgentAuth>;\n users?: AuthorizeFn<TInput, TAuth>;\n}\n\n/**\n * An `authorize` that admits by the door. `webhook`, `cron`,\n * `manual` and `db3` admit with `true` and resolve `null`, as does a nested start\n * from a parent `functions` lists. `http` takes the `users` rule's own\n * decision, and the agent doors take `agents`. A door with no rule is\n * denied, including one added later:\n *\n * ```ts\n * import { allowCallers, defineFunction, requireRole } from \"primitive-functions\";\n *\n * export default defineFunction({\n * authorize: allowCallers({ cron: true, manual: true, users: requireRole(\"admin\") }),\n * handler: async () => ({ swept: true }),\n * });\n * ```\n *\n * An unknown key, or a value of the wrong type, throws a `TypeError` when\n * the module loads.\n */\nexport declare function allowCallers<TInput = any, TAuth = never, TAgentAuth = never>(\n rules: CallerRules<TInput, TAuth, TAgentAuth>\n): AuthorizeHelper<TInput, TAuth | TAgentAuth | null>;\n\n/**\n * What the object form's handler reads beside `FunctionContext`: the value\n * `authorize` resolved when the invocation was admitted, and a way to ask\n * `authorize` again.\n */\nexport interface FunctionAuthorizedContext<TAuth> {\n /** What `authorize` resolved at admission. A task run keeps it on every resume. */\n auth: TAuth;\n /**\n * Run this version's `authorize` again against current state, for the\n * user it admitted, with this invocation's input and trigger. Resolves the\n * fresh value and leaves `ctx.auth` as it was; a deny throws the error\n * `fail(code, message)` throws, with the decision on it:\n *\n * ```ts\n * await step.sleep(\"cool-off\", \"1 hour\");\n * await ctx.reauthorize(); // throws FORBIDDEN if the member left the group\n * ```\n */\n reauthorize(): Promise<TAuth>;\n}\n\n/**\n * What the handler reads as `ctx.auth`, with `null`, when nothing could be\n * inferred for it: the handler is written before an `authorize` arrow whose\n * parameters are not annotated, and the compiler types the handler's `ctx`\n * before it reads `authorize`. Write `authorize` first:\n *\n * ```ts\n * export default defineFunction(\"get-class\", {\n * authorize: async (input, auth) => allow({ classId: input.classId }),\n * handler: async (input, ctx) => ctx.auth.classId,\n * });\n * ```\n *\n * It stands for any value `allow` can resolve, so the handler can narrow it\n * but not treat it as an object, or as any one primitive, unchecked.\n */\nexport type WriteAuthorizeBeforeHandler =\n | AuthorizeNotInferred\n | string\n | number\n | bigint\n | boolean\n | symbol;\n\n// The object `WriteAuthorizeBeforeHandler` stands for: it has no field a\n// handler could read as any type. The member only keeps the marker distinct;\n// it is `unknown`, not `never`, so reading it proves nothing, and optional,\n// so an `in` check that finds it absent does not narrow the object to `never`.\ninterface AuthorizeNotInferred {\n /** Never present: this type only names the fix in a compile error. */\n readonly writeAuthorizeBeforeHandler?: unknown;\n}\n\n/**\n * The object form's definition: an `authorize` method beside the handler.\n * `TAuth` is what `authorize`'s `allow` resolves, and the handler reads\n * it as `ctx.auth`. `TAuthorized` is what `authorize` is held to, and\n * only `defineFunction` sets it apart from `TAuth`.\n */\nexport interface FunctionDefinition<TInput, TOutput, TAuth, TAuthorized = TAuth> {\n authorize: AuthorizeFn<TInput, TAuthorized>;\n handler: (\n input: TInput,\n ctx: FunctionContext & FunctionAuthorizedContext<TAuth>,\n step: FunctionStep\n ) => TOutput | Promise<TOutput>;\n}\n\n// What `defineFunction` holds `authorize` to. Uninferred, `TAuth` is\n// `WriteAuthorizeBeforeHandler | null` and `authorize` is accepted as\n// written, so the errors land on the `ctx.auth` read; the `null` keeps\n// that read as null-safe as a bare `allow()` needs. `never` passes\n// through first: it is what a helper such as `allowCallers(...)` sees for a\n// `TAuth` not inferred yet, and turned into `unknown` it would be\n// inferred as the helper's own value. The fallback is matched both ways: an\n// explicit `null` is assignable to it and must still hold `authorize` to\n// itself.\ntype DefinedAuthorize<TAuth> = [TAuth] extends [never]\n ? TAuth\n : [TAuth] extends [WriteAuthorizeBeforeHandler | null]\n ? [WriteAuthorizeBeforeHandler | null] extends [TAuth]\n ? unknown\n : TAuth\n : TAuth;\n\n/** What the object form returns: the handler, carrying its `authorize`. */\nexport type AuthorizedFunctionHandler<TInput, TOutput, TAuth> = FunctionHandler<\n TInput,\n TOutput\n> & {\n authorize: FunctionDefinition<TInput, TOutput, TAuth>[\"authorize\"];\n};\n\n/**\n * Declare a server function's handler, typed from its declaration.\n *\n * The KEYED form, `defineFunction(\"<key>\", handler)`, is typed from the\n * `FunctionSchemas` augmentation `primitive config push` writes beside the\n * sources: `input` is the key's declared input, the return is checked against\n * its declared output, and a key the tree does not declare is a compile error.\n * `config push` also refuses an entry whose key names another file's. In a\n * tree that has not pushed yet the key is any string and both types are `any`.\n *\n * The UNKEYED form is what it always was: author-declared generics. Both\n * styles reach the platform bootstrap identically — a plain default export\n * taking `(input, ctx, step)` runs exactly as a wrapped one does — so this is\n * a typing and intent marker, not a different calling convention.\n *\n * The OBJECT form, `defineFunction(key?, { authorize, handler })`, adds an\n * `authorize` method that decides who may run the handler; what its\n * `allow` resolves is the handler's `ctx.auth`. A definition with any\n * other key, or a member that is not a function, throws a `TypeError` when\n * the module loads.\n */\nexport declare function defineFunction<\n K extends FunctionKeys,\n TAuth = WriteAuthorizeBeforeHandler | null\n>(\n key: K,\n definition: FunctionDefinition<\n FunctionInput<K>,\n FunctionOutput<K>,\n TAuth,\n DefinedAuthorize<TAuth>\n >\n): AuthorizedFunctionHandler<FunctionInput<K>, FunctionOutput<K>, TAuth> & {\n functionKey: K;\n};\nexport declare function defineFunction<\n TInput = unknown,\n TOutput = unknown,\n TAuth = WriteAuthorizeBeforeHandler | null\n>(\n definition: FunctionDefinition<TInput, TOutput, TAuth, DefinedAuthorize<TAuth>>\n): AuthorizedFunctionHandler<TInput, TOutput, TAuth>;\n/**\n * A bare handler, keyed.\n *\n * @deprecated Define the object form, `defineFunction(key?, { authorize, handler })`:\n * a push that would create a new version of a bare handler is refused.\n */\nexport declare function defineFunction<K extends FunctionKeys>(\n key: K,\n handler: (\n input: FunctionInput<K>,\n ctx: FunctionContext,\n step: FunctionStep\n ) => FunctionOutput<K> | Promise<FunctionOutput<K>>\n): FunctionHandler<FunctionInput<K>, FunctionOutput<K>> & { functionKey: K };\n/**\n * A bare handler, unkeyed.\n *\n * @deprecated Define the object form, `defineFunction(key?, { authorize, handler })`:\n * a push that would create a new version of a bare handler is refused.\n */\nexport declare function defineFunction<TInput = unknown, TOutput = unknown>(\n handler: (\n input: TInput,\n ctx: FunctionContext,\n step: FunctionStep\n ) => TOutput | Promise<TOutput>\n): FunctionHandler<TInput, TOutput>;\n\n/**\n * One declared parameter of a registered query.\n *\n * `caller: true` (or `type: \"$caller\"`) is the intent's IMMUTABLE binding:\n * the platform injects the invocation's user and refuses a call that supplies\n * the parameter itself.\n */\n/** The scalar parameter types, and an array parameter's element types. */\nexport type QueryScalarParamType = \"string\" | \"number\" | \"boolean\" | \"any\";\n\nexport interface QueryParamSpec {\n type?: QueryScalarParamType | \"$caller\" | \"array\";\n /** For `type: \"array\"` — the element type; absent means any element. */\n items?: { type: QueryScalarParamType };\n caller?: boolean;\n optional?: boolean;\n default?: unknown;\n}\n\n/** A scalar parameter type's TypeScript type. */\nexport type QueryScalarValue<T> = T extends \"string\"\n ? string\n : T extends \"number\"\n ? number\n : T extends \"boolean\"\n ? boolean\n : T extends \"$caller\"\n ? string\n : any;\n\n/** The value `run` receives for one declared parameter. */\nexport type QueryParamValue<S> = S extends { caller: true }\n ? string\n : S extends { type: \"array\"; items: { type: infer I } }\n ? QueryScalarValue<I>[]\n : S extends { type: \"array\" }\n ? unknown[]\n : S extends { type: infer T }\n ? QueryScalarValue<T>\n : any;\n\ntype QueryOptionalKeys<P> = {\n [K in keyof P]: P[K] extends { optional: true } ? K : never;\n}[keyof P];\n\n/**\n * `run`'s `params`, typed from the declaration: scalars as their scalar,\n * `$caller` as a string, an array as `T[]`, an `optional: true` parameter\n * as an optional key (a parameter with a default is always present). An\n * undeclared name is a compile error.\n */\nexport type QueryParams<P> = {\n [K in Exclude<keyof P, QueryOptionalKeys<P>>]: QueryParamValue<P[K]>;\n} & {\n [K in QueryOptionalKeys<P>]?: QueryParamValue<P[K]>;\n};\n\n/** A registration's definition with its parameters DECLARED, so `run` is typed from them. */\nexport interface TypedQueryDefinition<TDb, TSpec extends Record<string, QueryParamSpec>, TResult> {\n models: string[];\n params?: TSpec;\n cache?: { ttlMs: number };\n run: (db: TDb, params: QueryParams<TSpec>) => TResult | Promise<TResult>;\n}\n\nexport interface QueryDefinition<TDb, TParams, TResult> {\n /** The models this query touches. Caching is off unless the run matches. */\n models: string[];\n params?: Record<string, QueryParamSpec>;\n /**\n * Cache the answer for `ttlMs` — capped by the platform, and applied ONLY\n * when the run is verified: every model the body touched was declared, and\n * no prepared operation was used. A write through the handle drops the\n * entries that read the written model.\n */\n cache?: { ttlMs: number };\n run: (db: TDb, params: TParams) => TResult | Promise<TResult>;\n}\n\n/**\n * Register a named query over a database handle (#3187).\n *\n * A registration helper, not a language: `run` is ordinary code over the same\n * typed handle, and what registration adds is a name, declared parameters\n * (validated, coerced and defaulted), the `$caller` binding, and a cache the\n * platform may use when it can verify what the run touched.\n *\n * Register at MODULE scope: a registration made inside the handler still works\n * for direct calls but is invisible to `config push`'s manifest.\n *\n * `run`'s `params` are TYPED from the declaration (the first overload,\n * inferred with a `const` type parameter): a scalar as its scalar, `$caller`\n * as a string, `{ type: \"array\", items: { type: \"string\" } }` as `string[]`,\n * an `optional: true` parameter as an optional key; an undeclared name inside\n * `run` is a compile error. A declared default is coerced to the declared\n * type at registration, so `run` receives what the declaration promises. The\n * second overload keeps an explicit `TParams`.\n */\nexport declare function defineQuery<\n const TSpec extends Record<string, QueryParamSpec>,\n TDb = DatabaseHandle<any>,\n TResult = any\n>(\n name: string,\n definition: TypedQueryDefinition<TDb, TSpec, TResult>\n): (db: TDb, params?: Record<string, unknown>) => Promise<TResult>;\nexport declare function defineQuery<\n TDb = DatabaseHandle<any>,\n TParams = Record<string, any>,\n TResult = any\n>(\n name: string,\n definition: QueryDefinition<TDb, TParams, TResult>\n): (db: TDb, params?: Record<string, unknown>) => Promise<TResult>;\n\n/** The same, for a registration that writes. A mutation is never cached. */\nexport declare function defineMutation<\n const TSpec extends Record<string, QueryParamSpec>,\n TDb = DatabaseHandle<any>,\n TResult = any\n>(\n name: string,\n definition: TypedQueryDefinition<TDb, TSpec, TResult>\n): (db: TDb, params?: Record<string, unknown>) => Promise<TResult>;\nexport declare function defineMutation<\n TDb = DatabaseHandle<any>,\n TParams = Record<string, any>,\n TResult = any\n>(\n name: string,\n definition: QueryDefinition<TDb, TParams, TResult>\n): (db: TDb, params?: Record<string, unknown>) => Promise<TResult>;\n\n/** The platform's cap on a registered query's cache TTL, in milliseconds. */\nexport declare const MAX_QUERY_CACHE_TTL_MS: number;\n\n/**\n * Map over items with BOUNDED concurrency (#3187). Results come back in the\n * input's order; the first rejection wins and nothing new is started after it.\n *\n * The bound matters inside a sandbox: an unbounded fan-out over a page of rows\n * spends the whole subrequest ceiling in one line.\n */\nexport declare function pMap<T, R>(\n items: Iterable<T>,\n mapper: (item: T, index: number) => R | Promise<R>,\n options?: { concurrency?: number }\n): Promise<R[]>;\n\n/** The default concurrency `pMap` applies when none is given. */\nexport declare const PMAP_DEFAULT_CONCURRENCY: number;\n\n/**\n * A time-ordered ULID.\n *\n * GENERATE IT INSIDE `step.do`. A durable run re-executes its handler on\n * every resume and memoizes only what a step returned, so an id minted at the\n * top of a handler is a different id after a sleep — and whatever it was\n * written into is orphaned.\n */\nexport declare function ulid(): string;\n\n/** One family's durable `step.do` configuration — a `StepConfig` with every field decided. */\nexport interface StepPolicy extends StepConfig {\n retries: { limit: number; delay: string; backoff: StepBackoff };\n timeout: string;\n}\n\n/**\n * The per-family step policies the DSL runners use, generated from their own\n * timeout module (#3187):\n *\n * await step.do(\"send-receipt\", stepPolicy.email, () =>\n * ctx.api.email.send({ body: { to, subject, htmlBody } }));\n *\n * `retries: 0` on email and the AI families is deliberate — a retried timeout\n * would send the same email twice or bill the same generation twice.\n */\nexport declare const stepPolicy: {\n email: StepPolicy;\n llm: StepPolicy;\n gemini: StepPolicy;\n database: StepPolicy;\n};\n\n// Every member the three runtime copies put on their own default export — the\n// platform's `sdk-core.ts`, the published stub and the CLI's collect stub —\n// and nothing else. A helper the module hands a default import but does not\n// declare here is one an author cannot call without the compiler refusing it\n// (#3482 CR3482-002); `tests/api/spec/function-profile.test.ts` holds the four\n// lists equal and compiles a default import against them.\ndeclare const _default: {\n SDK_STUB_VERSION: string;\n defineFunction: typeof defineFunction;\n allow: typeof allow;\n deny: typeof deny;\n fail: typeof fail;\n allowAnyone: typeof allowAnyone;\n allowCallers: typeof allowCallers;\n requireSignedIn: typeof requireSignedIn;\n requireRole: typeof requireRole;\n requireMember: typeof requireMember;\n requireCollectionRole: typeof requireCollectionRole;\n requireDocumentOwner: typeof requireDocumentOwner;\n defineQuery: typeof defineQuery;\n defineMutation: typeof defineMutation;\n pMap: typeof pMap;\n ulid: typeof ulid;\n assertRuntime: typeof assertRuntime;\n assertTrigger: typeof assertTrigger;\n FunctionRuntimeError: typeof FunctionRuntimeError;\n};\nexport default _default;\n";
13
13
  //# sourceMappingURL=generated-sdk-types.js.map