@protobase/server 0.51.2 → 0.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/aggregate-groups.js +2 -2
  2. package/dist/aggregate-service.js +4 -4
  3. package/dist/aggregate-splits.js +1 -1
  4. package/dist/assistant/batch-approval.js +49 -51
  5. package/dist/assistant/batch-before.js +38 -0
  6. package/dist/assistant/batch-echo.js +36 -0
  7. package/dist/assistant/batch-write-args.js +14 -5
  8. package/dist/assistant/batch-write-tool.js +30 -11
  9. package/dist/assistant/budgeted-page.js +30 -0
  10. package/dist/assistant/comment-tools.d.ts +20 -0
  11. package/dist/assistant/comment-tools.js +120 -0
  12. package/dist/assistant/count-records-tool.d.ts +5 -0
  13. package/dist/assistant/count-records-tool.js +84 -0
  14. package/dist/assistant/query-result-budget.js +32 -0
  15. package/dist/assistant/query-tools.js +7 -7
  16. package/dist/assistant/record-before.js +2 -1
  17. package/dist/assistant/record-field-piece.js +54 -0
  18. package/dist/assistant/record-tool-args.js +6 -3
  19. package/dist/assistant/record-tools.d.ts +4 -1
  20. package/dist/assistant/record-tools.js +17 -6
  21. package/dist/assistant/records.d.ts +19 -0
  22. package/dist/assistant/records.js +20 -13
  23. package/dist/assistant/result-budget.js +72 -0
  24. package/dist/assistant/tools.d.ts +3 -0
  25. package/dist/assistant/write-echo.js +41 -0
  26. package/dist/assistant/write-messages.js +26 -6
  27. package/dist/assistant/write-prompts.js +37 -12
  28. package/dist/assistant/write-record-tools.js +15 -6
  29. package/dist/batch/run-batch.js +1 -1
  30. package/dist/better-auth/auth-settings.d.ts +1 -1
  31. package/dist/changes/capture-schema.js +1 -1
  32. package/dist/changes/resource-change.d.ts +4 -1
  33. package/dist/changes/resource-change.js +27 -3
  34. package/dist/comments/post-comment.js +1 -1
  35. package/dist/comments/read-comments.js +1 -1
  36. package/dist/comments/tool-comment-types.d.ts +28 -0
  37. package/dist/comments/tool-comments.js +30 -0
  38. package/dist/create-admin.d.ts +5 -2
  39. package/dist/create-admin.js +20 -10
  40. package/dist/deps.d.ts +1 -1
  41. package/dist/encryption/scan.js +1 -1
  42. package/dist/error-handler.js +3 -2
  43. package/dist/etag.js +1 -1
  44. package/dist/files/download.js +1 -1
  45. package/dist/files/file-cleanup.d.ts +1 -1
  46. package/dist/functions/records.d.ts +1 -1
  47. package/dist/functions/records.js +2 -2
  48. package/dist/history/read-history.js +2 -2
  49. package/dist/index.d.ts +9 -3
  50. package/dist/index.js +9 -4
  51. package/dist/jobs/run-job.d.ts +1 -1
  52. package/dist/list-photos.js +2 -2
  53. package/dist/list-service.js +6 -6
  54. package/dist/map-service.js +2 -2
  55. package/dist/mcp/mcp-context.d.ts +7 -4
  56. package/dist/mcp/mcp-context.js +6 -4
  57. package/dist/mcp/mcp-server.d.ts +3 -2
  58. package/dist/mcp/mcp-tools.d.ts +6 -1
  59. package/dist/mcp/mcp-tools.js +8 -4
  60. package/dist/package.js +1 -1
  61. package/dist/read-service.js +2 -2
  62. package/dist/realtime/broadcast-api.js +3 -3
  63. package/dist/realtime/broadcast-frame.js +16 -8
  64. package/dist/realtime/broadcast-hub.js +16 -6
  65. package/dist/realtime/broadcast-request.js +1 -1
  66. package/dist/realtime/change-checker.js +1 -1
  67. package/dist/realtime/channel-access.js +1 -1
  68. package/dist/realtime/database-broadcasts.js +83 -0
  69. package/dist/realtime/presence-hub.js +74 -39
  70. package/dist/realtime/realtime-app.js +39 -3
  71. package/dist/realtime/realtime-routes.js +12 -9
  72. package/dist/realtime/realtime-socket.js +10 -7
  73. package/dist/realtime/relay/frame-cursor.js +38 -0
  74. package/dist/realtime/relay/presence-replica.js +57 -0
  75. package/dist/realtime/relay/realtime-options.d.ts +13 -0
  76. package/dist/realtime/relay/realtime-options.js +9 -0
  77. package/dist/realtime/relay/realtime-relay.js +104 -0
  78. package/dist/realtime/relay/relay-frame-sql.js +82 -0
  79. package/dist/realtime/relay/relay-presence-sql.js +71 -0
  80. package/dist/realtime/relay/relay-schema-sql.js +55 -0
  81. package/dist/realtime/relay/relay-schema.d.ts +7 -0
  82. package/dist/realtime/relay/relay-schema.js +18 -0
  83. package/dist/realtime/relay/relayed-hubs.js +61 -0
  84. package/dist/records.js +1 -1
  85. package/dist/related-labels.js +1 -1
  86. package/dist/rest/rest-context.js +1 -1
  87. package/dist/routes/batch.js +1 -1
  88. package/dist/routes/collection.js +2 -2
  89. package/dist/routes/record.js +3 -3
  90. package/dist/row-permissions.js +1 -1
  91. package/dist/sql-parts.js +1 -1
  92. package/dist/web-app/mcp-icons.d.ts +9 -0
  93. package/dist/web-app/mcp-icons.js +26 -0
  94. package/dist/webhooks/subscriber-view.js +27 -2
  95. package/dist/webhooks/webhooks.js +41 -12
  96. package/dist/write-pipeline.js +1 -1
  97. package/dist/write-shared.js +1 -1
  98. package/package.json +4 -4
@@ -1,9 +1,12 @@
1
+ import { forcedJson } from "./result-budget.js";
1
2
  import { defineTool } from "./tools.js";
2
3
  import { keyOf, keyParameter, refused, resourceOf } from "./record-tool-args.js";
4
+ import { cutRecordNote } from "./budgeted-page.js";
3
5
  import { createApproval, updateApproval } from "./write-prompts.js";
4
6
  import { approvalTexts, recordBefore } from "./record-before.js";
5
7
  import { forbiddenText, notApproved, onlyNote, outside, resourceParameterFor } from "./write-tool-limits.js";
6
8
  import { deleteRecordTool } from "./delete-record-tool.js";
9
+ import { echoFieldsOf, fieldsParameter, invalidFields, writeEcho } from "./write-echo.js";
7
10
  //#region src/assistant/write-record-tools.ts
8
11
  const writes = {
9
12
  readOnlyHint: false,
@@ -18,12 +21,13 @@ const dataOf = (value) => typeof value === "object" && value !== null && !Array.
18
21
  /** Creates a record of a resource once the user approves it, under the caller's access rules. */
19
22
  const createRecordTool = (input = {}) => defineTool({
20
23
  name: "create_record",
21
- description: `Creates a record of a resource and returns it as JSON ({ record, etag }). The user approves each write in their client first; nothing is written without it.${onlyNote(input)}`,
24
+ description: `Creates a record of a resource and returns its key, new etag and, in record, the fields written and the read-only fields the write changed, as JSON ({ key, etag, record }). The user approves each write in their client first; nothing is written without it.${onlyNote(input)}`,
22
25
  parameters: {
23
26
  type: "object",
24
27
  properties: {
25
28
  resource: resourceParameterFor(input),
26
- data: dataParameter
29
+ data: dataParameter,
30
+ fields: fieldsParameter
27
31
  },
28
32
  required: ["resource", "data"]
29
33
  },
@@ -32,18 +36,20 @@ const createRecordTool = (input = {}) => defineTool({
32
36
  const resource = resourceOf(args);
33
37
  const data = dataOf(args.data);
34
38
  if (!resource || !data) return "Pass the resource and data as { \"resource\": \"<name>\", \"data\": { \"<field>\": <value> } }.";
39
+ const fields = echoFieldsOf(args.fields);
40
+ if (!fields) return invalidFields;
35
41
  const refusal = outside(input, resource);
36
42
  if (refusal) return refusal;
37
43
  const { text, described } = await approvalTexts(context, resource);
38
44
  const answer = await context.approve(createApproval(text, described, data));
39
45
  if (answer !== "approved") return notApproved(answer);
40
- return context.records.create(resource, data).then((record) => JSON.stringify(record), refused);
46
+ return context.records.create(resource, data).then((written) => forcedJson(writeEcho(described.model, written, data, void 0, fields), cutRecordNote), refused);
41
47
  }
42
48
  });
43
49
  /** Updates one record by its key once the user approves it, under the caller's access rules. */
44
50
  const updateRecordTool = (input = {}) => defineTool({
45
51
  name: "update_record",
46
- description: `Updates fields of one record of a resource by its key and returns it as JSON ({ record, etag }). Pass the etag get_record gave to fail when someone changed the record since. The user approves each write in their client first; nothing is written without it.${onlyNote(input)}`,
52
+ description: `Updates fields of one record of a resource by its key and returns its key, new etag and, in record, the fields written and the read-only fields the write changed, as JSON ({ key, etag, record }). Pass the etag get_record gave to fail when someone changed the record since. The user approves each write in their client first; nothing is written without it.${onlyNote(input)}`,
47
53
  parameters: {
48
54
  type: "object",
49
55
  properties: {
@@ -56,7 +62,8 @@ const updateRecordTool = (input = {}) => defineTool({
56
62
  etag: {
57
63
  type: "string",
58
64
  description: "The etag get_record gave, to fail when the record changed since."
59
- }
65
+ },
66
+ fields: fieldsParameter
60
67
  },
61
68
  required: [
62
69
  "resource",
@@ -70,6 +77,8 @@ const updateRecordTool = (input = {}) => defineTool({
70
77
  const key = keyOf(args.key);
71
78
  const data = dataOf(args.data);
72
79
  if (!resource || key === void 0 || !data) return "Pass the resource, key and data as { \"resource\": \"<name>\", \"key\": \"<key>\", \"data\": { \"<field>\": <value> } }.";
80
+ const fields = echoFieldsOf(args.fields);
81
+ if (!fields) return invalidFields;
73
82
  const refusal = outside(input, resource);
74
83
  if (refusal) return refusal;
75
84
  const softDelete = await context.records.softDeleteField(resource).then((field) => ({ field }), refused);
@@ -81,7 +90,7 @@ const updateRecordTool = (input = {}) => defineTool({
81
90
  const { text, described } = await approvalTexts(context, resource);
82
91
  const answer = await context.approve(updateApproval(text, described, key, before?.record ?? {}, data));
83
92
  if (answer !== "approved") return notApproved(answer);
84
- return context.records.update(resource, key, data, { etag }).then((record) => JSON.stringify(record), refused);
93
+ return context.records.update(resource, key, data, { etag }).then((written) => forcedJson(writeEcho(described.model, written, data, before?.record, fields), cutRecordNote), refused);
85
94
  }
86
95
  });
87
96
  /** `create_record`, `update_record` and `delete_record`, on the resources `input` allows. */
@@ -1,9 +1,9 @@
1
1
  import { HttpProblem, badRequest, notFound } from "../problem.js";
2
2
  import { requestAccess } from "../request-access.js";
3
+ import { writeTransaction } from "../transactions.js";
3
4
  import { actorSettings, wakeDispatch } from "../changes/actor.js";
4
5
  import { problemOf } from "../error-handler.js";
5
6
  import { scheduleRemovedFiles } from "../files/attach.js";
6
- import { writeTransaction } from "../transactions.js";
7
7
  import { keyOf } from "../write-shared.js";
8
8
  import { checkBeforeWrite, writeIn } from "../write-pipeline.js";
9
9
  import { resolveData, resolveKey } from "./refs.js";
@@ -12,8 +12,8 @@ import { OrganizationsOptions, ResolvedOrganizations } from "./organizations/opt
12
12
  import { McpAuthOptions } from "./mcp/mcp-plugins.js";
13
13
  import "../index.js";
14
14
  import { CreateAuthOptions, UserCreatedHook } from "./create-auth.js";
15
- import { PostgresPool } from "kysely";
16
15
  import { Db } from "@protobase/query";
16
+ import { PostgresPool } from "kysely";
17
17
  import { OrganizationOptions } from "better-auth/plugins/organization";
18
18
  //#region src/better-auth/auth-settings.d.ts
19
19
  /** What every hook of the project's own gets as its last argument: the app's database, the one jobs get. */
@@ -1,6 +1,6 @@
1
1
  import { isCaptured, quoteIdent, tableSql } from "./capture-sql.js";
2
- import { changesSchema } from "./events-options.js";
3
2
  import { capturePlan, planSql, uncaptured } from "./capture-plan.js";
3
+ import { changesSchema } from "./events-options.js";
4
4
  import { sql } from "kysely";
5
5
  //#region src/changes/capture-schema.ts
6
6
  /** The command that writes what the config needs as a migration file of the project. */
@@ -24,7 +24,10 @@ export type ResourceChange = {
24
24
  /** When the change's transaction started, ISO 8601. */
25
25
  at: string;
26
26
  };
27
- /** A captured row by field name, fields without a captured column left out. */
27
+ /**
28
+ * A captured row by field name, fields without a captured column and sensitive ones left out, whatever the capture
29
+ * kept: a row captured before a field became sensitive holds its value.
30
+ */
28
31
  export declare const recordOf: (model: ResourceModel, columns: Row) => Row;
29
32
  /** A coalesced change of the resource's table, by field name, with deletes and undeletes told apart from updates. */
30
33
  export declare const resourceChange: (model: ResourceModel, change: CoalescedChange) => ResourceChange;
@@ -6,8 +6,11 @@ const fieldValue = (type, value) => {
6
6
  if (type === "integer") return Number(value);
7
7
  return value;
8
8
  };
9
- /** A captured row by field name, fields without a captured column left out. */
10
- const recordOf = (model, columns) => Object.fromEntries(Object.values(model.fields).filter((field) => Object.hasOwn(columns, field.column)).map((field) => [field.name, fieldValue(field.type, columns[field.column])]));
9
+ /**
10
+ * A captured row by field name, fields without a captured column and sensitive ones left out, whatever the capture
11
+ * kept: a row captured before a field became sensitive holds its value.
12
+ */
13
+ const recordOf = (model, columns) => Object.fromEntries(Object.values(model.fields).filter((field) => !field.sensitive && Object.hasOwn(columns, field.column)).map((field) => [field.name, fieldValue(field.type, columns[field.column])]));
11
14
  const operationOf = (model, before, after) => {
12
15
  if (!before) return "create";
13
16
  if (!after) return "delete";
@@ -41,5 +44,26 @@ const resourceChange = (model, change) => {
41
44
  at: change.at
42
45
  };
43
46
  };
47
+ /** A record by field name with only the fields the model has now and that are not sensitive. */
48
+ const currentRecord = (model, record) => Object.fromEntries(Object.entries(record).filter(([name]) => Object.hasOwn(model.fields, name) && !model.fields[name].sensitive));
49
+ /**
50
+ * A change kept by an earlier dispatch, as the model has it now: a record kept before a field became sensitive, or was
51
+ * removed, holds it. Built from the change's known properties, so one an earlier release kept is dropped too.
52
+ */
53
+ const currentChange = (model, change) => ({
54
+ resource: change.resource,
55
+ key: change.key,
56
+ operation: change.operation,
57
+ ...change.before && { before: currentRecord(model, change.before) },
58
+ ...change.after && { after: currentRecord(model, change.after) },
59
+ changed: change.changed,
60
+ actor: change.actor,
61
+ source: change.source,
62
+ databaseRole: change.databaseRole,
63
+ ...change.tenant !== void 0 && { tenant: change.tenant },
64
+ transaction: change.transaction,
65
+ sequence: change.sequence,
66
+ at: change.at
67
+ });
44
68
  //#endregion
45
- export { recordOf, resourceChange };
69
+ export { currentChange, currentRecord, recordOf, resourceChange };
@@ -1,10 +1,10 @@
1
1
  import { badRequest, notFound } from "../problem.js";
2
2
  import { tenantScope } from "../tenant.js";
3
3
  import { writeTransaction } from "../transactions.js";
4
- import { commentsTable } from "./comments-sql.js";
5
4
  import { commentAccess, mayRead, readableRecord, requireSignedIn, userSessions } from "./comment-access.js";
6
5
  import { parseCommentInput } from "./comment-input.js";
7
6
  import { commentColumns, commentItem, namedUsers } from "./comment-item.js";
7
+ import { commentsTable } from "./comments-sql.js";
8
8
  import { readableTitle, recordLabel } from "./record-label.js";
9
9
  import { encodeKey } from "@protobase/schema/internal";
10
10
  import { appPath } from "@protobase/schema";
@@ -2,9 +2,9 @@ import { notFound } from "../problem.js";
2
2
  import { tenantScope } from "../tenant.js";
3
3
  import { readTransaction } from "../transactions.js";
4
4
  import { parseParams } from "../params.js";
5
- import { commentsTable } from "./comments-sql.js";
6
5
  import { commentAccess, readableRecord } from "./comment-access.js";
7
6
  import { commentColumns, commentItem, namedUsers } from "./comment-item.js";
7
+ import { commentsTable } from "./comments-sql.js";
8
8
  import { encodeKey } from "@protobase/schema/internal";
9
9
  import { z } from "zod";
10
10
  import { sql } from "kysely";
@@ -0,0 +1,28 @@
1
+ import { RecordKeyInput } from "../assistant/records.js";
2
+ //#region src/comments/tool-comment-types.d.ts
3
+ /** A comment as a tool gives it: who wrote it, when, and what it says. */
4
+ export type ToolComment = {
5
+ author: {
6
+ id: string;
7
+ name?: string;
8
+ };
9
+ created_at: string;
10
+ text: string;
11
+ };
12
+ /** A page of a record's comments, newest first, and the token of the next page, empty on the last. */
13
+ export type ToolCommentPage = {
14
+ items: ToolComment[];
15
+ next_page_token: string;
16
+ };
17
+ /**
18
+ * A record's comments as the session's user, through the REST API's comments (`GET` and `POST
19
+ * /{resource}/{key}:comments`): the same access rules, tenant and refusals, which reject with an `HttpProblem`.
20
+ */
21
+ export type ToolComments = {
22
+ list: (resource: string, key: RecordKeyInput, params?: {
23
+ page_size?: number;
24
+ page_token?: string;
25
+ }) => Promise<ToolCommentPage>;
26
+ add: (resource: string, key: RecordKeyInput, text: string) => Promise<ToolComment>;
27
+ };
28
+ //#endregion
@@ -0,0 +1,30 @@
1
+ import { toolKey } from "../assistant/records.js";
2
+ import { postComment } from "./post-comment.js";
3
+ import { readComments } from "./read-comments.js";
4
+ //#region src/comments/tool-comments.ts
5
+ const compact = ({ author, created_at, body }) => ({
6
+ author,
7
+ created_at,
8
+ text: body
9
+ });
10
+ /** `ToolComments` over the admin's resources for `session`; `requestURL` is the request's, as `postComment` takes it. */
11
+ const toolComments = (deps, session, requestURL) => ({
12
+ list: async (resource, input, { page_size, page_token } = {}) => {
13
+ const { entry, key } = toolKey(deps, resource, input);
14
+ const query = {
15
+ ...page_size !== void 0 && { page_size: String(page_size) },
16
+ ...page_token !== void 0 && { page_token }
17
+ };
18
+ const page = await readComments(deps, entry, session, key, query);
19
+ return {
20
+ items: page.items.map(compact),
21
+ next_page_token: page.next_page_token
22
+ };
23
+ },
24
+ add: async (resource, input, text) => {
25
+ const { entry, key } = toolKey(deps, resource, input);
26
+ return compact(await postComment(deps, entry, session, key, { body: text }, requestURL));
27
+ }
28
+ });
29
+ //#endregion
30
+ export { toolComments };
@@ -1,6 +1,7 @@
1
1
  import { MobileConfig } from "./mobile-config.js";
2
2
  import { AppIdentity } from "./app-identity.js";
3
3
  import { AppIcons } from "./web-app/app-icons.js";
4
+ import { RealtimeOptions } from "./realtime/relay/realtime-options.js";
4
5
  import { EventsOptions } from "./changes/events-options.js";
5
6
  import { JobDefinition } from "./jobs/job-types.js";
6
7
  import { Admin, Authenticator, PageSource, ViewSource } from "./types.js";
@@ -49,6 +50,8 @@ export type CreateAdminInput = {
49
50
  subscriptions?: SubscriptionDefinition[];
50
51
  /** Webhook subscriptions made in the admin app, from `webhooks: {}` (see `WebhooksOptions`). */
51
52
  webhooks?: WebhooksOptions;
53
+ /** How `/api/sb/realtime/v1` is served: by one process or several (see `RealtimeOptions`). */
54
+ realtime?: RealtimeOptions;
52
55
  /** Each user's devices and the endpoints that register them, from `notifications: {}` (see `NotificationsOptions`). */
53
56
  notifications?: NotificationsOptions;
54
57
  /**
@@ -60,7 +63,7 @@ export type CreateAdminInput = {
60
63
  app?: AppIdentity;
61
64
  /**
62
65
  * The icons the project has of its own, as `protobase build` and `protobase dev` find them beside its favicon: the
63
- * web manifest names its PNGs, and `/meta` the favicon when it is the project's, which the sidebar's logo draws.
66
+ * web manifest and the MCP server name its PNGs, and `/meta` the favicon when it is the project's, which the sidebar's logo draws.
64
67
  */
65
68
  icons?: AppIcons;
66
69
  /**
@@ -90,5 +93,5 @@ export type CreateAdminInput = {
90
93
  upgradeWebSocket?: UpgradeWebSocket;
91
94
  };
92
95
  /** The admin REST API as a Hono app. It uses only Web APIs, so it runs on Node, Workers and anywhere else Hono does. */
93
- export declare const createAdmin: ({ resources: appResources, views: appViews, pages, userMenu, bottomBars, db, authenticate, auth, functions, secret, files: filesOptions, events, history: historyOptions, jobs, subscriptions, webhooks: webhooksOptions, notifications, mobile, app: identity, icons, bundlePlugins, fieldTypes, options, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }: CreateAdminInput) => Admin;
96
+ export declare const createAdmin: ({ resources: appResources, views: appViews, pages, userMenu, bottomBars, db, authenticate, auth, functions, secret, files: filesOptions, events, history: historyOptions, jobs, subscriptions, webhooks: webhooksOptions, realtime, notifications, mobile, app: identity, icons, bundlePlugins, fieldTypes, options, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }: CreateAdminInput) => Admin;
94
97
  //#endregion
@@ -27,6 +27,8 @@ import { mcpDiscovery } from "./better-auth/mcp/discovery-routes.js";
27
27
  import { mcpApprovals } from "./mcp/mcp-approval-store.js";
28
28
  import { checkMcpWrites, rolesWithoutApproval } from "./mcp/mcp-writes.js";
29
29
  import { mcpAuthenticator } from "./mcp/mcp-authenticator.js";
30
+ import { visitorsBrowse, withAnonymous } from "./anonymous.js";
31
+ import { changesSchema } from "./changes/events-options.js";
30
32
  import { mcpToolContext } from "./mcp/mcp-context.js";
31
33
  import { mcpHandler } from "./mcp/mcp-handler.js";
32
34
  import { closedMcpRoutes, mcpRoutes } from "./mcp/mcp-routes.js";
@@ -38,7 +40,6 @@ import { statusRoute } from "./better-auth/status-route.js";
38
40
  import { betterAuthSessionToken } from "./better-auth/session-token.js";
39
41
  import { goTrueTokens } from "./gotrue/access-tokens.js";
40
42
  import { goTrueRoutes } from "./gotrue/routes.js";
41
- import { changesSchema } from "./changes/events-options.js";
42
43
  import { appOrigin } from "./comments/app-origin.js";
43
44
  import { betterAuthActorNames } from "./history/actor-names.js";
44
45
  import { betterAuthCommentUsers } from "./comments/comment-users.js";
@@ -60,7 +61,6 @@ import { deviceRoutes } from "./notifications/routes.js";
60
61
  import { notificationSenders, webPushKey } from "./notifications/senders-of.js";
61
62
  import { pushJob } from "./notifications/push-job.js";
62
63
  import { liveSessions } from "./better-auth/live-sessions.js";
63
- import { visitorsBrowse, withAnonymous } from "./anonymous.js";
64
64
  import { checkBottomBars, checkShell } from "./check-shell.js";
65
65
  import { checkOwnerFields } from "./check-owners.js";
66
66
  import { checkRoleLimits } from "./check-roles.js";
@@ -93,6 +93,7 @@ import { docsRoutes } from "./routes/docs.js";
93
93
  import { metaRoutes } from "./routes/meta.js";
94
94
  import { faviconPath } from "./web-app/web-manifest.js";
95
95
  import { webManifestRoute } from "./web-app/web-manifest-route.js";
96
+ import { mcpIcons } from "./web-app/mcp-icons.js";
96
97
  import { recordRoutes } from "./routes/record.js";
97
98
  import { createScanGuard } from "./scan-guard.js";
98
99
  import { failedJobs, failedJobsView } from "./jobs/failed-jobs.js";
@@ -104,7 +105,7 @@ const declaredRoles = (auth, roles) => {
104
105
  return names.length > 0 ? [...new Set(names)] : void 0;
105
106
  };
106
107
  /** The admin REST API as a Hono app. It uses only Web APIs, so it runs on Node, Workers and anywhere else Hono does. */
107
- const createAdmin = ({ resources: appResources, views: appViews = [], pages = [], userMenu, bottomBars = [], db, authenticate, auth, functions = {}, secret, files: filesOptions, events, history: historyOptions, jobs = [], subscriptions = [], webhooks: webhooksOptions, notifications, mobile, app: identity, icons, bundlePlugins = [], fieldTypes = {}, options = {}, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }) => {
108
+ const createAdmin = ({ resources: appResources, views: appViews = [], pages = [], userMenu, bottomBars = [], db, authenticate, auth, functions = {}, secret, files: filesOptions, events, history: historyOptions, jobs = [], subscriptions = [], webhooks: webhooksOptions, realtime, notifications, mobile, app: identity, icons, bundlePlugins = [], fieldTypes = {}, options = {}, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }) => {
108
109
  const basePath = options.basePath ?? "/api/v1";
109
110
  const appModels = appResources.map((resource) => resource.toModel());
110
111
  const withComments = appModels.some((model) => model.comments);
@@ -324,19 +325,27 @@ const createAdmin = ({ resources: appResources, views: appViews = [], pages = []
324
325
  if (auth?.mcp && options.mcp === false) closedMcpRoutes(app, auth.mcp.path);
325
326
  else if (auth?.mcp && mcpAuthenticate) {
326
327
  const writes = options.mcp !== false && options.mcp?.writes || false;
328
+ const commented = registry.entries.filter((entry) => entry.model.comments).map((entry) => entry.name);
327
329
  const tools = mcpTools({
328
330
  db,
329
331
  sql: options.mcp !== false && options.mcp?.sql === true,
330
- writes
332
+ writes,
333
+ commented
331
334
  });
332
335
  const approvals = mcpApprovals();
336
+ const { resource } = auth.mcp;
337
+ const info = {
338
+ name: appName,
339
+ version: "1.0.0",
340
+ icons: mcpIcons(resource, icons)
341
+ };
333
342
  const server = (session, request) => {
334
- const context = mcpToolContext(deps, meta, session, request ? requestLocale(locale, request) : locale);
343
+ const context = mcpToolContext(deps, meta, session, {
344
+ locale: request ? requestLocale(locale, request) : locale,
345
+ requestURL: request?.url ?? resource
346
+ });
335
347
  return mcpServer({
336
- info: {
337
- name: appName,
338
- version: "1.0.0"
339
- },
348
+ info,
340
349
  tools: tools(session),
341
350
  context,
342
351
  report,
@@ -417,7 +426,8 @@ const createAdmin = ({ resources: appResources, views: appViews = [], pages = []
417
426
  feed,
418
427
  upgradeWebSocket,
419
428
  caller,
420
- report
429
+ report,
430
+ ...realtime && { options: realtime }
421
431
  }));
422
432
  if (files?.storage) {
423
433
  const storage = {
package/dist/deps.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { AuditQueue, PipelineHook, WriteCheck } from "./types.js";
2
2
  import { CommentUsers } from "./comments/comment-users.js";
3
+ import { Registry } from "./registry.js";
3
4
  import { ErrorReportingSettings } from "./error-reporting/error-reporting-settings.js";
4
5
  import { mentionJob } from "./comments/mention-job.js";
5
6
  import { ModelSettings } from "./assistant/chat-completions.js";
@@ -7,7 +8,6 @@ import { EncryptionRuntime } from "./encryption/runtime.js";
7
8
  import { FilesRuntime } from "./files/runtime.js";
8
9
  import { MapSettings } from "./maps/map-settings.js";
9
10
  import { PluginOption } from "./plugins/plugin-settings.js";
10
- import { Registry } from "./registry.js";
11
11
  import { SourceOption } from "./sources/source-settings.js";
12
12
  import { ScanGuard } from "./scan-guard.js";
13
13
  import { PageModel } from "@protobase/layout";
@@ -1,5 +1,5 @@
1
- import { aliasedColumn, columnId, tableId } from "../sql-parts.js";
2
1
  import { exposeRow } from "../rows.js";
2
+ import { aliasedColumn, columnId, tableId } from "../sql-parts.js";
3
3
  import { sql } from "kysely";
4
4
  //#region src/encryption/scan.ts
5
5
  const batchSize = 500;
@@ -1,8 +1,8 @@
1
1
  import { HttpProblem, problemResponse } from "./problem.js";
2
2
  import { ConnectionsBusy, connectionsBusyProblem } from "./connections-busy.js";
3
3
  import { StatementTimeout } from "./statement-timeout.js";
4
- import { HTTPException } from "hono/http-exception";
5
4
  import { QueryError } from "@protobase/query";
5
+ import { HTTPException } from "hono/http-exception";
6
6
  //#region src/error-handler.ts
7
7
  const titles = {
8
8
  400: "Bad Request",
@@ -20,6 +20,7 @@ const queryStatus = {
20
20
  no_statistics: 409,
21
21
  missing_extension: 501
22
22
  };
23
+ /** The problem a query-layer refusal, such as an unknown field or an out-of-range option, stands for. */
23
24
  const queryProblem = (error) => {
24
25
  const status = queryStatus[error.code] ?? 400;
25
26
  return new HttpProblem(status, error.code.replaceAll("_", "-"), titles[status] ?? "Not Implemented", error.message);
@@ -64,4 +65,4 @@ const createErrorHandler = (onUnhandledError, statementTimeoutMs) => (error, c)
64
65
  return problemResponse(new HttpProblem(500, "internal-error", titles[500], "The server failed to handle the request"), c.req.path);
65
66
  };
66
67
  //#endregion
67
- export { createErrorHandler, isDatabaseError, problemOf };
68
+ export { createErrorHandler, isDatabaseError, problemOf, queryProblem };
package/dist/etag.js CHANGED
@@ -1,5 +1,5 @@
1
- import { sha256Hex, stableJson } from "./hash.js";
2
1
  import { etagAlias } from "./sql-parts.js";
2
+ import { sha256Hex, stableJson } from "./hash.js";
3
3
  //#region src/etag.ts
4
4
  /**
5
5
  * The version of a row. With a version or `updated_at` column it is a hash of that column's exact text (so a hidden column's
@@ -1,7 +1,7 @@
1
1
  import { HttpProblem, forbidden, notFound } from "../problem.js";
2
+ import { readTransaction } from "../transactions.js";
2
3
  import { contentDisposition, downloadName, servedType } from "./media-types.js";
3
4
  import { isFilePath, parseUri, tenantSegment, variantPaths } from "./uri.js";
4
- import { readTransaction } from "../transactions.js";
5
5
  import { fetchRecord } from "../records.js";
6
6
  import { downloadExpiry, readDownloadUrl } from "./download-url.js";
7
7
  import { decodeKeyText } from "../key.js";
@@ -1,6 +1,6 @@
1
1
  import { FilesOptions } from "./options.js";
2
- import { CleanupReport } from "./cleanup-runner.js";
3
2
  import { ResourceSource } from "../resource-source.js";
3
+ import { CleanupReport } from "./cleanup-runner.js";
4
4
  import { Db } from "@protobase/query";
5
5
  //#region src/files/file-cleanup.d.ts
6
6
  export type FileCleanupInput = {
@@ -7,5 +7,5 @@ import { ListParams, RecordPage, ToolRecords } from "../assistant/records.js";
7
7
  * in the REST API. A refusal or a missing record rejects with an `HttpProblem`, which becomes the function's response
8
8
  * when it is not caught.
9
9
  */
10
- export type FunctionRecords = Omit<ToolRecords, 'batch'>;
10
+ export type FunctionRecords = Omit<ToolRecords, 'batch' | 'aggregate'>;
11
11
  //#endregion
@@ -1,8 +1,8 @@
1
1
  import { assistantRecords } from "../assistant/records.js";
2
2
  //#region src/functions/records.ts
3
- /** `FunctionRecords` over the admin's resources for `session`; the batch is the MCP tools' alone. */
3
+ /** `FunctionRecords` over the admin's resources for `session`; the batch and the aggregate are the tools' alone. */
4
4
  const callerRecords = (deps, session) => {
5
- const { batch: _batch, ...records } = assistantRecords(deps, session);
5
+ const { batch: _batch, aggregate: _aggregate, ...records } = assistantRecords(deps, session);
6
6
  return records;
7
7
  };
8
8
  //#endregion
@@ -1,10 +1,10 @@
1
1
  import { notFound } from "../problem.js";
2
2
  import { tenantScope } from "../tenant.js";
3
3
  import { requestAccess, requireOperation } from "../request-access.js";
4
- import { quoteIdent } from "../changes/capture-sql.js";
5
4
  import { readTransaction } from "../transactions.js";
6
- import { fetchReadable } from "../fetch-readable.js";
7
5
  import { parseParams } from "../params.js";
6
+ import { quoteIdent } from "../changes/capture-sql.js";
7
+ import { fetchReadable } from "../fetch-readable.js";
8
8
  import { encodeKey } from "@protobase/schema/internal";
9
9
  import { z } from "zod";
10
10
  import { sql } from "kysely";
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { MobileConfig } from "./mobile-config.js";
2
2
  import { AppIdentity } from "./app-identity.js";
3
3
  import { AppIcons, PngIcon, pngIcons } from "./web-app/app-icons.js";
4
+ import { RealtimeOptions, relayed } from "./realtime/relay/realtime-options.js";
4
5
  import { EventsOptions } from "./changes/events-options.js";
5
6
  import { StandardSchema, readJson } from "./functions/read-json.js";
6
7
  import { MailMessage, Mailer } from "./mail/smtp-mailer.js";
@@ -25,6 +26,7 @@ import { FilesOptions } from "./files/options.js";
25
26
  import { ApiKeys, ApiKeysOptions, apiKeySettings, apiKeyVariables } from "./api-keys/api-key-settings.js";
26
27
  import { Caller, CallerOptions, apiKeyCaller } from "./api-keys/resolve-caller.js";
27
28
  import { FunctionSocket, SocketEvents } from "./functions/function-socket.js";
29
+ import { ResourceSource, configExports } from "./resource-source.js";
28
30
  import { ErrorReportingOptions, ErrorReportingSettings, errorReportingSettings, errorReportingVariable } from "./error-reporting/error-reporting-settings.js";
29
31
  import { ChatMessage, ChatTextPart, Completion, CompletionOptions, ModelError, ModelSettings, ReasoningDetail, ReasoningEffort, ToolCall, ToolSpec, streamChatCompletion } from "./assistant/chat-completions.js";
30
32
  import { CleanupEntry, CleanupSchedule, ScheduledDelete, storageCleanupSchedule } from "./files/cleanup-schedule.js";
@@ -32,15 +34,15 @@ import { CleanupReport } from "./files/cleanup-runner.js";
32
34
  import { MapLayer } from "./maps/map-layers.js";
33
35
  import { MapOptions, MapSettings, mapSettings, mapStyleUrl, mapStyleVariable } from "./maps/map-settings.js";
34
36
  import { PluginOption, PluginRef, beforeSignInPluginsVariable, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable } from "./plugins/plugin-settings.js";
35
- import { ResourceSource, configExports } from "./resource-source.js";
36
37
  import { SourceOption, SourceRef, checkSourceNames, sourceOptions, sourcesFor, sourcesVariable } from "./sources/source-settings.js";
37
38
  import { HttpProblem, MissingCredentials, badRequest, forbidden, notFound, unauthorized } from "./problem.js";
38
39
  import { BatchOperation } from "./batch/schema.js";
39
40
  import { BatchResult } from "./batch/run-batch.js";
40
- import { ListParams, RecordKeyInput, RecordPage, ToolRecord, ToolRecords } from "./assistant/records.js";
41
+ import { AggregateParams, ListParams, RecordGroups, RecordKeyInput, RecordPage, ToolRecord, ToolRecords } from "./assistant/records.js";
41
42
  import { FunctionRecords } from "./functions/records.js";
42
43
  import { ApiFunction, CorsOptions, FunctionApp, FunctionCaller, FunctionContext, FunctionHandler, FunctionOptions, FunctionSource, KeyFunctionContext, ProtectedFunctionOptions, PublicFunctionContext, PublicFunctionHandler, PublicFunctionOptions, defineFunction } from "./functions/define-function.js";
43
44
  import { CorsOrigins } from "./api-cors.js";
45
+ import { ToolComment, ToolCommentPage, ToolComments } from "./comments/tool-comment-types.js";
44
46
  import { ConversationRecord, ConversationStore } from "./assistant/conversation-store.js";
45
47
  import { Conversation, ConversationsOptions, conversationKey, createConversations } from "./assistant/conversations.js";
46
48
  import { ApprovalAnswer, ApprovalRequest, requestApproval } from "./assistant/approval.js";
@@ -92,6 +94,7 @@ import { eventMatcher } from "./changes/match-events.js";
92
94
  import { parseColumns, readOutbox } from "./changes/outbox.js";
93
95
  import { newWebhookSecret } from "./webhooks/standard-webhooks.js";
94
96
  import { checkWebhooksSchema, webhooksMigration } from "./webhooks/table/schema.js";
97
+ import { checkRealtimeRelay, realtimeRelayMigration } from "./realtime/relay/relay-schema.js";
95
98
  import { checkComments, commentsMigration } from "./comments/comments-sql.js";
96
99
  import { CheckAiInput, checkAi } from "./ai/check-ai.js";
97
100
  import { CommentItem } from "./comments/comment-item.js";
@@ -118,12 +121,15 @@ import { WidgetOptions, maxWidgetPropsBytes, widget } from "./assistant/widget.j
118
121
  import { QueryOptions, QueryResult, runReadOnlyQuery, runReadWriteQuery } from "./assistant/run-query.js";
119
122
  import { readOnlyQueryTool, readWriteQueryTool } from "./assistant/query-tools.js";
120
123
  import { getRecordTool, listRecordsTool, listResourcesTool, readRecordTools } from "./assistant/record-tools.js";
124
+ import { countRecordsTool } from "./assistant/count-records-tool.js";
121
125
  import { WriteRecordToolsInput } from "./assistant/write-tool-limits.js";
122
126
  import { createRecordTool, updateRecordTool, writeRecordTools } from "./assistant/write-record-tools.js";
123
127
  import { deleteRecordTool } from "./assistant/delete-record-tool.js";
124
128
  import { batchWriteTool } from "./assistant/batch-write-tool.js";
129
+ import { CommentToolsInput, addCommentTool, commentTools, listCommentsTool } from "./assistant/comment-tools.js";
125
130
  import { McpApprovals, mcpApprovals } from "./mcp/mcp-approval-store.js";
126
131
  import { McpServerInput, mcpServer } from "./mcp/mcp-server.js";
132
+ import { mcpIcons } from "./web-app/mcp-icons.js";
127
133
  import { McpToolsInput, mcpTools } from "./mcp/mcp-tools.js";
128
134
  import { McpGateInput, mcpGate, sessionOf } from "./mcp/mcp-gate.js";
129
135
  import { McpHandlerInput, mcpHandler } from "./mcp/mcp-handler.js";
@@ -164,4 +170,4 @@ import { MobileRelease, ReleaseFile, ServedReleaseFile, composeRelease, releaseM
164
170
  import { MobileReleaseAppInput, OfferedRelease, mobileReleaseApp } from "./mobile-release/release-app.js";
165
171
  import { mobileSigningKeyVariable, readSigningKey } from "./mobile-release/signing-key.js";
166
172
  import { AdminAuth, CreateAuthOptions, UserCreatedHook, normalizeRoles } from "./better-auth/create-auth.js";
167
- export { type Admin, type AdminAuth, type AdminOptions, type ApiFunction, type ApiKeys, type ApiKeysOptions, type ApnsEnvironment, type AppIcons, type AppIdentity, type AppPoolConfig, type ApplyOptions, type ApplyResult, type ApprovalAnswer, type ApprovalRequest, type ArgumentsPayload, type AssistantBackend, type AssistantOptions, type AssistantSettings, type AssistantTool, type AuditEvent, type AuditQueue, type AuthHooks, type AuthSettings, type AuthenticateSettings, type Authenticator, type BatchOperation, type BatchResult, type BetterAuthAuthenticator, type BetterAuthAuthenticatorOptions, type Caller, type CallerOptions, type CapturedRow, type CascadingKey, type ChatMessage, type ChatTextPart, type CheckAiInput, type CleanupEntry, type CleanupReport, type CleanupSchedule, type CoalescedChange, type CommentItem, type CommentUsers, type Completion, type CompletionOptions, ConnectionsBusy, type Conversation, type ConversationRecord, type ConversationStore, type ConversationsOptions, type CorsOptions, type CorsOrigins, type CreateAdminInput, type CreateAuthOptions, type Device, type DeviceColumn, type DeviceKind, type DeviceStore, DeviceStoreError, type DrainResult, type EmailComponent, type EmailOptions, type EmailTemplate, type EncryptionStatus, type EncryptionTools, type EncryptionToolsInput, type EnqueueJob, type EnqueueOptions, type ErrorReporter, type ErrorReportingOptions, type ErrorReportingSettings, type EventData, type EventsOptions, FatalJobError, type FieldApplied, type FieldStatus, type FileCleanupInput, type FileLimits, type FileObject, type FileProvider, type FileProviderSettings, type FileRef, type FileStore, type FileVariantObject, type FilesOptions, type FunctionApp, type FunctionCaller, type FunctionContext, type FunctionEnv, type FunctionHandler, type FunctionOptions, type FunctionRecords, type FunctionSocket, type FunctionSource, type HistoryColumn, type HistoryOptions, type HistoryPosition, type HistoryStore, HistoryStoreError, type HookContext, HttpProblem, type IssueTokenOptions, type JobContext, type JobDeclaration, type JobDefinition, type JobName, type JobOptions, type JobPayload, type JobRun, type JobsRuntime, type JsonObject, type JsonValue, type JwtOptions, type JwtVerifyOptions, type KeyFunctionContext, type LinkedAccount, type ListParams, type LocalFilesOptions, type MailMessage, type Mailer, type MapLayer, type MapOptions, type MapSettings, type McpApprovals, type McpGateInput, type McpHandlerInput, type McpRoutesInput, type McpServerInput, type McpToolsInput, type McpWrites, type MemberInput, type Membership, MissingCredentials, type MobileConfig, type MobileRelease, type MobileReleaseAppInput, ModelError, type ModelSettings, type NewDevice, type NewNotification, type NewOrganization, type NewUser, type NotificationRecipients, NotificationSendError, type NotificationsOptions, type OfferedRelease, type OperatorProvider, type OrganizationRole, type OrganizationsOptions, type PgModule, type PipelineHook, type PlatformSignIn, type PluginOption, type PluginRef, type PngIcon, type ProtectedFunctionOptions, type PublicFunctionContext, type PublicFunctionEnv, type PublicFunctionHandler, type PublicFunctionOptions, type PushAnswer, type PushMessage, PushMessageError, type PushSender, type QueryOptions, type QueryResult, type ReadableResources, type ReasoningDetail, type ReasoningEffort, type RebindOption, type RecordKeyInput, type RecordPage, type ReleaseFile, type RenderedEmail, type ResourceChange, type ResourceSource, type RoleDefinition, type RolesInput, type RunContext, type RuntimeOptions, type S3Bucket, type S3FilesOptions, type S3ListPage, type S3Object, type ScanGuardMode, type ScheduledDelete, type SendNotification, type ServedReleaseFile, type Session, type SessionOrganization, type Sharp, type SignInPolicy, type SignInRule, type SignatureOptions, type SocketEvents, type SourceOption, type SourceRef, type StaffAccessRule, type StaffSignIn, type StandardSchema, type StandardWebhookOptions, type StartJobsOptions, type StoreFileInput, type StoredMember, type StoredNotification, type StoredObject, type StoredOrganization, type StoredUser, type StrayValues, type SubscriptionDefinition, type SubscriptionEvent, type SubscriptionOptions, type TenantValue, type ToolAnnotations, type ToolCall, type ToolContext, type ToolRecord, type ToolRecords, type ToolSpec, type TrustedApp, type TurnOptions, type UnreadableEntry, type Urgency, type User, type UserCreatedHook, type VapidSettings, type ViewSource, type WebPushFields, type WebPushOptions, type WebhooksOptions, type WidgetOptions, type WriteEvent, type WriteOperation, type WriteRecordToolsInput, addAppRoleToOwners, addMember, apiKeyCaller, apiKeySettings, apiKeyVariables, appNameOver, aspectRatio, assistantProtocolRoutes, assistantRoles, assistantSettings, assistantVariables, authSchemaDrift, authSchemaMigration, authStoreTables, backgroundSettled, badRequest, batchWriteTool, beforeSignInPluginsVariable, betterAuthTokens, capSocketMessages, changesMigration, checkAi, checkAuthSchema, checkChanges, checkComments, checkComputed, checkJobsSchema, checkNotificationsSchema, checkQueryRunner, checkResourcesOutsideAuthStore, checkSourceNames, checkViewQueries, checkWebhooksSchema, coalesce, commentsMigration, composeRelease, computedMigration, configExports, consoleAuditQueue, conversationKey, createAdmin, createConversations, createEncryptionTools, createFileCleanup, createOrganization, createRecordTool, createUser, defaultAppName, defaultHistoryPage, defaultSignInPolicy, defineEmail, defineFunction, defineJob, defineTool, deleteRecordTool, deleteUser, deviceIdParam, deviceStore, devicesPath, enqueueJob, errorReportingSettings, errorReportingVariable, eventMatcher, fileConversationStore, fileSize, fileType, forbidden, formatUri, functionApp, generateVapidKeys, getRecordTool, goTruePath, handleDroppedConnections, hasUsers, historyIdParam, historyIdPattern, historyLimits, historyPath, historyStore, honorSocketMessageCaps, imageSize, isBackgroundWork, isCaptured, isJobDefinition, isOAuthWellKnownPath, isSchedule, issueToken, jobDefinitions, jobsDrainApp, jobsSchema, jobsSchemaMigration, jwtAuthenticator, jwtVerifier, limitedFileStore, listOrganizations, listRecordsTool, listResourcesTool, listUsers, localFileStore, longQueryTimeoutMs, mapSettings, mapStyleUrl, mapStyleVariable, maxDevicesPerUser, maxHistoryPage, maxMessageBytes, maxRecipients, maxTokenTtlSeconds, maxTtlSeconds, maxUnreadCount, maxWidgetPropsBytes, mcpApprovals, mcpGate, mcpHandler, mcpRoutes, mcpServer, mcpToolContext, mcpTools, migrationCommand, mobileReleaseApp, mobileSigningKeyVariable, newWebhookSecret, normalizeRoles, notFound, notificationSenders, notificationsMigration, oauthWellKnownPaths, objectKey, parseColumns, parseRoles, passwordLength, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, pngIcons, poolWaitMs, postgresDeviceStore, postgresHistoryStore, processor, pushMessage, queryRunnerMigration, readDbConnections, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readRecordTools, readSigningKey, readVapidSettings, readWriteQueryTool, readableResources, realtimeLimits, recordOf, releaseManifest, removeDevicesWithUsers, removeHistoryWithUsers, removeMember, renderVariant, requestApproval, requireEnv, resourceChange, roleChoices, runInBackground, runReadOnlyQuery, runReadWriteQuery, runTurn, runtimeUrl, runtimeVariable, s3FileStore, seesAssistant, seesRuntime, sendNotification, sessionOf, setMemberRoles, setUserBanned, setUserRole, shownAppName, signInPolicyMethods, socketMessageCapOf, sourceOptions, sourcesFor, sourcesVariable, startErrorReporting, startJobs, storageCleanupSchedule, storageProvider, storeFile, storeUsage, streamChatCompletion, subscription, supabasePath, thumbHash, unauthorized, updateRecordTool, urgencies, vapidPrivateKeyVariable, vapidPublicKeyVariable, vapidSubjectVariable, variantPath, verifySignature, verifyStandardWebhook, waitUntil, wantsLongQueries, webManifestPath, webPushSender, webauthnPath, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps, writeRecordTools };
173
+ export { type Admin, type AdminAuth, type AdminOptions, type AggregateParams, type ApiFunction, type ApiKeys, type ApiKeysOptions, type ApnsEnvironment, type AppIcons, type AppIdentity, type AppPoolConfig, type ApplyOptions, type ApplyResult, type ApprovalAnswer, type ApprovalRequest, type ArgumentsPayload, type AssistantBackend, type AssistantOptions, type AssistantSettings, type AssistantTool, type AuditEvent, type AuditQueue, type AuthHooks, type AuthSettings, type AuthenticateSettings, type Authenticator, type BatchOperation, type BatchResult, type BetterAuthAuthenticator, type BetterAuthAuthenticatorOptions, type Caller, type CallerOptions, type CapturedRow, type CascadingKey, type ChatMessage, type ChatTextPart, type CheckAiInput, type CleanupEntry, type CleanupReport, type CleanupSchedule, type CoalescedChange, type CommentItem, type CommentToolsInput, type CommentUsers, type Completion, type CompletionOptions, ConnectionsBusy, type Conversation, type ConversationRecord, type ConversationStore, type ConversationsOptions, type CorsOptions, type CorsOrigins, type CreateAdminInput, type CreateAuthOptions, type Device, type DeviceColumn, type DeviceKind, type DeviceStore, DeviceStoreError, type DrainResult, type EmailComponent, type EmailOptions, type EmailTemplate, type EncryptionStatus, type EncryptionTools, type EncryptionToolsInput, type EnqueueJob, type EnqueueOptions, type ErrorReporter, type ErrorReportingOptions, type ErrorReportingSettings, type EventData, type EventsOptions, FatalJobError, type FieldApplied, type FieldStatus, type FileCleanupInput, type FileLimits, type FileObject, type FileProvider, type FileProviderSettings, type FileRef, type FileStore, type FileVariantObject, type FilesOptions, type FunctionApp, type FunctionCaller, type FunctionContext, type FunctionEnv, type FunctionHandler, type FunctionOptions, type FunctionRecords, type FunctionSocket, type FunctionSource, type HistoryColumn, type HistoryOptions, type HistoryPosition, type HistoryStore, HistoryStoreError, type HookContext, HttpProblem, type IssueTokenOptions, type JobContext, type JobDeclaration, type JobDefinition, type JobName, type JobOptions, type JobPayload, type JobRun, type JobsRuntime, type JsonObject, type JsonValue, type JwtOptions, type JwtVerifyOptions, type KeyFunctionContext, type LinkedAccount, type ListParams, type LocalFilesOptions, type MailMessage, type Mailer, type MapLayer, type MapOptions, type MapSettings, type McpApprovals, type McpGateInput, type McpHandlerInput, type McpRoutesInput, type McpServerInput, type McpToolsInput, type McpWrites, type MemberInput, type Membership, MissingCredentials, type MobileConfig, type MobileRelease, type MobileReleaseAppInput, ModelError, type ModelSettings, type NewDevice, type NewNotification, type NewOrganization, type NewUser, type NotificationRecipients, NotificationSendError, type NotificationsOptions, type OfferedRelease, type OperatorProvider, type OrganizationRole, type OrganizationsOptions, type PgModule, type PipelineHook, type PlatformSignIn, type PluginOption, type PluginRef, type PngIcon, type ProtectedFunctionOptions, type PublicFunctionContext, type PublicFunctionEnv, type PublicFunctionHandler, type PublicFunctionOptions, type PushAnswer, type PushMessage, PushMessageError, type PushSender, type QueryOptions, type QueryResult, type ReadableResources, type RealtimeOptions, type ReasoningDetail, type ReasoningEffort, type RebindOption, type RecordGroups, type RecordKeyInput, type RecordPage, type ReleaseFile, type RenderedEmail, type ResourceChange, type ResourceSource, type RoleDefinition, type RolesInput, type RunContext, type RuntimeOptions, type S3Bucket, type S3FilesOptions, type S3ListPage, type S3Object, type ScanGuardMode, type ScheduledDelete, type SendNotification, type ServedReleaseFile, type Session, type SessionOrganization, type Sharp, type SignInPolicy, type SignInRule, type SignatureOptions, type SocketEvents, type SourceOption, type SourceRef, type StaffAccessRule, type StaffSignIn, type StandardSchema, type StandardWebhookOptions, type StartJobsOptions, type StoreFileInput, type StoredMember, type StoredNotification, type StoredObject, type StoredOrganization, type StoredUser, type StrayValues, type SubscriptionDefinition, type SubscriptionEvent, type SubscriptionOptions, type TenantValue, type ToolAnnotations, type ToolCall, type ToolComment, type ToolCommentPage, type ToolComments, type ToolContext, type ToolRecord, type ToolRecords, type ToolSpec, type TrustedApp, type TurnOptions, type UnreadableEntry, type Urgency, type User, type UserCreatedHook, type VapidSettings, type ViewSource, type WebPushFields, type WebPushOptions, type WebhooksOptions, type WidgetOptions, type WriteEvent, type WriteOperation, type WriteRecordToolsInput, addAppRoleToOwners, addCommentTool, addMember, apiKeyCaller, apiKeySettings, apiKeyVariables, appNameOver, aspectRatio, assistantProtocolRoutes, assistantRoles, assistantSettings, assistantVariables, authSchemaDrift, authSchemaMigration, authStoreTables, backgroundSettled, badRequest, batchWriteTool, beforeSignInPluginsVariable, betterAuthTokens, capSocketMessages, changesMigration, checkAi, checkAuthSchema, checkChanges, checkComments, checkComputed, checkJobsSchema, checkNotificationsSchema, checkQueryRunner, checkRealtimeRelay, checkResourcesOutsideAuthStore, checkSourceNames, checkViewQueries, checkWebhooksSchema, coalesce, commentTools, commentsMigration, composeRelease, computedMigration, configExports, consoleAuditQueue, conversationKey, countRecordsTool, createAdmin, createConversations, createEncryptionTools, createFileCleanup, createOrganization, createRecordTool, createUser, defaultAppName, defaultHistoryPage, defaultSignInPolicy, defineEmail, defineFunction, defineJob, defineTool, deleteRecordTool, deleteUser, deviceIdParam, deviceStore, devicesPath, enqueueJob, errorReportingSettings, errorReportingVariable, eventMatcher, fileConversationStore, fileSize, fileType, forbidden, formatUri, functionApp, generateVapidKeys, getRecordTool, goTruePath, handleDroppedConnections, hasUsers, historyIdParam, historyIdPattern, historyLimits, historyPath, historyStore, honorSocketMessageCaps, imageSize, isBackgroundWork, isCaptured, isJobDefinition, isOAuthWellKnownPath, isSchedule, issueToken, jobDefinitions, jobsDrainApp, jobsSchema, jobsSchemaMigration, jwtAuthenticator, jwtVerifier, limitedFileStore, listCommentsTool, listOrganizations, listRecordsTool, listResourcesTool, listUsers, localFileStore, longQueryTimeoutMs, mapSettings, mapStyleUrl, mapStyleVariable, maxDevicesPerUser, maxHistoryPage, maxMessageBytes, maxRecipients, maxTokenTtlSeconds, maxTtlSeconds, maxUnreadCount, maxWidgetPropsBytes, mcpApprovals, mcpGate, mcpHandler, mcpIcons, mcpRoutes, mcpServer, mcpToolContext, mcpTools, migrationCommand, mobileReleaseApp, mobileSigningKeyVariable, newWebhookSecret, normalizeRoles, notFound, notificationSenders, notificationsMigration, oauthWellKnownPaths, objectKey, parseColumns, parseRoles, passwordLength, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, pngIcons, poolWaitMs, postgresDeviceStore, postgresHistoryStore, processor, pushMessage, queryRunnerMigration, readDbConnections, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readRecordTools, readSigningKey, readVapidSettings, readWriteQueryTool, readableResources, realtimeLimits, realtimeRelayMigration, recordOf, relayed, releaseManifest, removeDevicesWithUsers, removeHistoryWithUsers, removeMember, renderVariant, requestApproval, requireEnv, resourceChange, roleChoices, runInBackground, runReadOnlyQuery, runReadWriteQuery, runTurn, runtimeUrl, runtimeVariable, s3FileStore, seesAssistant, seesRuntime, sendNotification, sessionOf, setMemberRoles, setUserBanned, setUserRole, shownAppName, signInPolicyMethods, socketMessageCapOf, sourceOptions, sourcesFor, sourcesVariable, startErrorReporting, startJobs, storageCleanupSchedule, storageProvider, storeFile, storeUsage, streamChatCompletion, subscription, supabasePath, thumbHash, unauthorized, updateRecordTool, urgencies, vapidPrivateKeyVariable, vapidPublicKeyVariable, vapidSubjectVariable, variantPath, verifySignature, verifyStandardWebhook, waitUntil, wantsLongQueries, webManifestPath, webPushSender, webauthnPath, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps, writeRecordTools };