@protobase/server 0.67.8 → 0.67.10

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 (44) hide show
  1. package/dist/config-exports.d.ts +2 -1
  2. package/dist/config-exports.js +2 -1
  3. package/dist/create-admin.d.ts +4 -1
  4. package/dist/create-admin.js +11 -2
  5. package/dist/index.d.ts +7 -1
  6. package/dist/index.js +6 -1
  7. package/dist/internal.d.ts +2 -1
  8. package/dist/internal.js +2 -1
  9. package/dist/mcp/mcp-tools.d.ts +8 -2
  10. package/dist/mcp/mcp-tools.js +10 -3
  11. package/dist/package.js +1 -1
  12. package/dist/webhooks/attempt.js +2 -2
  13. package/dist/webhooks/table/webhook-table.js +1 -1
  14. package/dist/workflows/http-step.js +103 -0
  15. package/dist/workflows/input-limits.js +22 -0
  16. package/dist/workflows/mail-step.js +58 -0
  17. package/dist/workflows/mcp/merge-patch.js +15 -0
  18. package/dist/workflows/mcp/type-catalog.js +144 -0
  19. package/dist/workflows/mcp/workflow-instructions.d.ts +7 -0
  20. package/dist/workflows/mcp/workflow-instructions.js +77 -0
  21. package/dist/workflows/mcp/workflow-read-tools.d.ts +6 -0
  22. package/dist/workflows/mcp/workflow-read-tools.js +209 -0
  23. package/dist/workflows/mcp/workflow-tool-args.js +35 -0
  24. package/dist/workflows/mcp/workflow-write-tools.d.ts +7 -0
  25. package/dist/workflows/mcp/workflow-write-tools.js +149 -0
  26. package/dist/workflows/options.d.ts +27 -0
  27. package/dist/workflows/options.js +19 -0
  28. package/dist/workflows/piece-step.js +11 -0
  29. package/dist/workflows/records-step.js +114 -0
  30. package/dist/workflows/run-files.js +70 -0
  31. package/dist/workflows/save-hook.js +20 -0
  32. package/dist/workflows/schema-sql.js +147 -0
  33. package/dist/workflows/schema.d.ts +11 -0
  34. package/dist/workflows/schema.js +41 -0
  35. package/dist/workflows/segment-job.js +51 -0
  36. package/dist/workflows/start-hook.js +26 -0
  37. package/dist/workflows/start-workflow.d.ts +26 -0
  38. package/dist/workflows/start-workflow.js +28 -0
  39. package/dist/workflows/step-types.js +34 -0
  40. package/dist/workflows/store.js +42 -0
  41. package/dist/workflows/workflow-engine.js +37 -0
  42. package/dist/workflows/workflows-module.d.ts +124 -0
  43. package/dist/workflows/workflows-module.js +11 -0
  44. package/package.json +5 -4
@@ -6,4 +6,5 @@ import { maxTextLength } from "./user-tables/definition-resource.js";
6
6
  import { userTableResources } from "./user-tables/user-table-resources.js";
7
7
  import { builtInResources } from "./built-in-resources.js";
8
8
  import { webhooksModule } from "./webhooks/table/webhooks-module.js";
9
- export { type CheckedDefinition, builtInResources, configExports, definitionsSchema, maxTextLength, ownedTableNames, userTableResources, userTablesSchema, webhooksModule };
9
+ import { workflowsModule } from "./workflows/workflows-module.js";
10
+ export { type CheckedDefinition, builtInResources, configExports, definitionsSchema, maxTextLength, ownedTableNames, userTableResources, userTablesSchema, webhooksModule, workflowsModule };
@@ -5,4 +5,5 @@ import { configExports } from "./resource-source.js";
5
5
  import { ownedTableNames } from "./user-tables/owned-definitions.js";
6
6
  import { userTableResources } from "./user-tables/user-table-resources.js";
7
7
  import { webhooksModule } from "./webhooks/table/webhooks-module.js";
8
- export { builtInResources, configExports, definitionsSchema, maxTextLength, ownedTableNames, userTableResources, userTablesSchema, webhooksModule };
8
+ import { workflowsModule } from "./workflows/workflows-module.js";
9
+ export { builtInResources, configExports, definitionsSchema, maxTextLength, ownedTableNames, userTableResources, userTablesSchema, webhooksModule, workflowsModule };
@@ -8,6 +8,7 @@ import { Admin, Authenticator, PageSource, ViewSource } from "./types.js";
8
8
  import { CommentUsers } from "./comments/comment-users.js";
9
9
  import { HistoryOptions } from "./history/options.js";
10
10
  import { WebhooksOptions } from "./webhooks/table/options.js";
11
+ import { WorkflowsOptions } from "./workflows/options.js";
11
12
  import { NotificationsOptions } from "./notifications/options.js";
12
13
  import { CallsOptions } from "./calls/calls-options.js";
13
14
  import { StatusOptions } from "./status/options.js";
@@ -60,6 +61,8 @@ export type CreateAdminInput = {
60
61
  subscriptions?: SubscriptionDefinition[];
61
62
  /** Webhook subscriptions made in the admin app, from `webhooks: {}` (see `WebhooksOptions`). */
62
63
  webhooks?: WebhooksOptions;
64
+ /** Workflows made in the admin app and run on the app's jobs, from `workflows: {}` (see `WorkflowsOptions`). */
65
+ workflows?: WorkflowsOptions;
63
66
  /** How `/api/sb/realtime/v1` and `/api/channels` are served: by one process or several, and whether SQL sends to channels (see `RealtimeOptions`). */
64
67
  realtime?: RealtimeOptions;
65
68
  /** Each user's devices and the endpoints that register them, from `notifications: {}` (see `NotificationsOptions`). */
@@ -107,5 +110,5 @@ export type CreateAdminInput = {
107
110
  upgradeWebSocket?: UpgradeWebSocket;
108
111
  };
109
112
  /** The admin REST API as a Hono app. It uses only Web APIs, so it runs on Node, Workers and anywhere else Hono does. */
110
- export declare const createAdmin: ({ resources: appResources, views: appViews, userTables, pages, userMenu, bottomBars, db, authenticate, auth, functions, secret, files: filesOptions, events, history: historyOptions, jobs, subscriptions, webhooks: webhooksOptions, realtime, notifications, status, calls, mobile, app: identity, icons, bundlePlugins, fieldTypes, options, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }: CreateAdminInput) => Admin;
113
+ export declare const createAdmin: ({ resources: appResources, views: appViews, userTables, pages, userMenu, bottomBars, db, authenticate, auth, functions, secret, files: filesOptions, events, history: historyOptions, jobs, subscriptions, webhooks: webhooksOptions, workflows: workflowsOptions, realtime, notifications, status, calls, mobile, app: identity, icons, bundlePlugins, fieldTypes, options, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }: CreateAdminInput) => Admin;
111
114
  //#endregion
@@ -38,8 +38,10 @@ import { changesSchema } from "./changes/events-options.js";
38
38
  import { mcpToolContext } from "./mcp/mcp-context.js";
39
39
  import { mcpHandler } from "./mcp/mcp-handler.js";
40
40
  import { closedMcpRoutes, mcpRoutes } from "./mcp/mcp-routes.js";
41
+ import { mcpInstructions } from "./mcp/mcp-instructions.js";
41
42
  import { mcpServer } from "./mcp/mcp-server.js";
42
43
  import { mcpTools } from "./mcp/mcp-tools.js";
44
+ import { workflowInstructions } from "./workflows/mcp/workflow-instructions.js";
43
45
  import { withoutSessionTokens } from "./better-auth/without-session-tokens.js";
44
46
  import { organizationRoutes } from "./better-auth/organizations/admin-routes.js";
45
47
  import { statusRoute } from "./better-auth/status-route.js";
@@ -57,6 +59,7 @@ import { toApiFunction } from "./functions/define-function.js";
57
59
  import { createWebhooks } from "./webhooks/webhooks.js";
58
60
  import { webhookTable } from "./webhooks/table/webhook-table.js";
59
61
  import { subscriptionUrlCheck, subscriptionWriteCheck } from "./webhooks/table/validate-hook.js";
62
+ import { workflowEngine } from "./workflows/workflow-engine.js";
60
63
  import { callsService } from "./calls/calls-service.js";
61
64
  import { ringRoutes } from "./calls/ring-routes.js";
62
65
  import { upgradeAuthenticator } from "./functions/upgrade-caller.js";
@@ -124,7 +127,7 @@ const declaredRoles = (auth, roles) => {
124
127
  return names.length > 0 ? [...new Set(names)] : void 0;
125
128
  };
126
129
  /** The admin REST API as a Hono app. It uses only Web APIs, so it runs on Node, Workers and anywhere else Hono does. */
127
- const createAdmin = ({ resources: appResources, views: appViews = [], userTables, pages = [], userMenu, bottomBars = [], db, authenticate, auth, functions = {}, secret, files: filesOptions, events, history: historyOptions, jobs = [], subscriptions = [], webhooks: webhooksOptions, realtime, notifications, status, calls, mobile, app: identity, icons, bundlePlugins = [], fieldTypes = {}, options = {}, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }) => {
130
+ const createAdmin = ({ resources: appResources, views: appViews = [], userTables, pages = [], userMenu, bottomBars = [], db, authenticate, auth, functions = {}, secret, files: filesOptions, events, history: historyOptions, jobs = [], subscriptions = [], webhooks: webhooksOptions, workflows: workflowsOptions, realtime, notifications, status, calls, mobile, app: identity, icons, bundlePlugins = [], fieldTypes = {}, options = {}, formsDifficulty, commentUsers: givenCommentUsers, verifyToken, upgradeWebSocket }) => {
128
131
  const basePath = options.basePath ?? "/api/v1";
129
132
  const appModels = appResources.map((resource) => resource.toModel());
130
133
  const withComments = appModels.some((model) => model.comments);
@@ -223,6 +226,7 @@ const createAdmin = ({ resources: appResources, views: appViews = [], userTables
223
226
  storage: servesKeys
224
227
  });
225
228
  const table = webhooksOptions && webhookTable(webhooksOptions, auth);
229
+ const engine = workflowsOptions && workflowEngine(workflowsOptions, () => deps, auth);
226
230
  const withAi = withAiFields || hasAiActions(viewModels);
227
231
  const model = withAi ? aiModel(options.assistant, globalThis.process?.env ?? {}) : void 0;
228
232
  const fill = withAiFields ? fillJob(() => deps) : void 0;
@@ -242,9 +246,10 @@ const createAdmin = ({ resources: appResources, views: appViews = [], userTables
242
246
  ...options.writeHooks ?? [],
243
247
  ...served.hooks,
244
248
  ...table ? [subscriptionWriteCheck(registry.entries.map((entry) => entry.model))] : [],
249
+ ...engine?.hooks ?? [],
245
250
  ...fill ? [fillHook(() => deps, fill)] : []
246
251
  ],
247
- writeChecks: table?.checkUrl ? [subscriptionUrlCheck(table.checkUrl)] : [],
252
+ writeChecks: [...table?.checkUrl ? [subscriptionUrlCheck(table.checkUrl)] : [], ...engine?.writeChecks ?? []],
248
253
  audit: options.audit ?? consoleAuditQueue(),
249
254
  report: options.onUnhandledError ?? ((error) => console.error(error)),
250
255
  accessOptions: {
@@ -381,8 +386,10 @@ const createAdmin = ({ resources: appResources, views: appViews = [], userTables
381
386
  sql: options.mcp !== false && options.mcp?.sql === true,
382
387
  writes,
383
388
  commented,
389
+ workflows: Boolean(engine),
384
390
  own: options.mcp !== false && options.mcp?.tools || []
385
391
  });
392
+ const instructions = engine ? `${mcpInstructions}\n${workflowInstructions}` : mcpInstructions;
386
393
  const approvals = mcpApprovals();
387
394
  const { resource } = auth.mcp;
388
395
  const info = {
@@ -397,6 +404,7 @@ const createAdmin = ({ resources: appResources, views: appViews = [], userTables
397
404
  });
398
405
  return mcpServer({
399
406
  info,
407
+ instructions,
400
408
  tools: tools(session),
401
409
  context,
402
410
  report,
@@ -572,6 +580,7 @@ const createAdmin = ({ resources: appResources, views: appViews = [], userTables
572
580
  metaPath: `${deps.systemPath}/meta`,
573
581
  jobs: [
574
582
  ...webhooks.jobs,
583
+ ...engine ? [engine.job] : [],
575
584
  ...withHistory && days !== void 0 ? [pruneHistoryJob(changes, days)] : [],
576
585
  ...mentions ? [mentions] : [],
577
586
  ...fill ? [fill] : [],
package/dist/index.d.ts CHANGED
@@ -16,6 +16,7 @@ import { Admin, AuditEvent, AuditQueue, Authenticator, Membership, PipelineHook,
16
16
  import { CommentUsers } from "./comments/comment-users.js";
17
17
  import { HistoryOptions } from "./history/options.js";
18
18
  import { WebhooksOptions } from "./webhooks/table/options.js";
19
+ import { WorkflowsOptions } from "./workflows/options.js";
19
20
  import { ApnsEnvironment, Device, DeviceKind, NewDevice } from "./notifications/device.js";
20
21
  import { DeviceStore } from "./notifications/device-store.js";
21
22
  import { HistoryStore, maxHistoryPage, maxUnreadCount } from "./notifications/history-store.js";
@@ -101,6 +102,8 @@ import { eventMatcher } from "./changes/match-events.js";
101
102
  import { parseColumns, readOutbox } from "./changes/outbox.js";
102
103
  import { newWebhookSecret } from "./webhooks/standard-webhooks.js";
103
104
  import { checkWebhooksSchema, webhooksMigration } from "./webhooks/table/schema.js";
105
+ import { checkWorkflowsSchema, workflowsMigration } from "./workflows/schema.js";
106
+ import { StartWorkflowOptions, startWorkflow } from "./workflows/start-workflow.js";
104
107
  import { checkUserTablesSchema, userTablesMigration } from "./user-tables/schema.js";
105
108
  import { ownedDefinitionsMigration } from "./user-tables/owned-definitions.js";
106
109
  import { UserTables, userTableResources } from "./user-tables/user-table-resources.js";
@@ -149,6 +152,9 @@ import { McpServerInput, mcpServer } from "./mcp/mcp-server.js";
149
152
  import { mcpIcons } from "./web-app/mcp-icons.js";
150
153
  import { mcpInstructions } from "./mcp/mcp-instructions.js";
151
154
  import { McpToolsInput, mcpTools } from "./mcp/mcp-tools.js";
155
+ import { workflowReadTools } from "./workflows/mcp/workflow-read-tools.js";
156
+ import { workflowWriteTools } from "./workflows/mcp/workflow-write-tools.js";
157
+ import { workflowInstructions } from "./workflows/mcp/workflow-instructions.js";
152
158
  import { McpGateInput, mcpGate, sessionOf } from "./mcp/mcp-gate.js";
153
159
  import { McpHandlerInput, mcpHandler } from "./mcp/mcp-handler.js";
154
160
  import { McpRoutesInput, mcpRoutes } from "./mcp/mcp-routes.js";
@@ -189,4 +195,4 @@ import { DrainResult, JobsRuntime, StartJobsOptions, startJobs } from "./jobs/ru
189
195
  import { jobsDrainApp } from "./jobs/drain-route.js";
190
196
  import { checkJobsSchema, jobsSchema, jobsSchemaMigration } from "./jobs/schema.js";
191
197
  import { AdminAuth, CreateAuthOptions, UserCreatedHook, normalizeRoles } from "./better-auth/create-auth.js";
192
- 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 BaseToolContext, type BatchOperation, type BatchResult, type BetterAuthAuthenticator, type BetterAuthAuthenticatorOptions, type CallBackend, type CallMember, type Caller, type CallerOptions, type CallsAccess, type CallsOptions, type CapturedRow, type CascadingKey, type ChannelBroadcast, type ChannelSender, 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 DecryptField, 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 FieldDecrypter, type FieldReader, 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 LiveKitBackend, type LocalFilesOptions, type MailAttachment, type MailMessage, MailServerTimeoutError, 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, ModelError, type ModelSettings, type NewDevice, type NewNotification, type NewOrganization, type NewUser, type NotificationRecipients, NotificationSendError, type NotificationsOptions, type OperatorProvider, type OrganizationRole, type OrganizationsOptions, type PdfComponent, type PdfOptions, type PdfTemplate, PersonalMailError, type PersonalMailErrorCode, type PersonalMailProviderId, 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 RealtimePrune, type ReasoningDetail, type ReasoningEffort, type RebindOption, type RecordGroups, type RecordKey, type RecordKeyInput, type RecordPage, 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 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 StatusOptions, 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 UserTables, 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, callsMigration, capSocketMessages, changesMigration, channelSendsMigration, checkAi, checkAuthSchema, checkCalls, checkChanges, checkChannelSends, checkComments, checkComputed, checkJobsSchema, checkNotificationsSchema, checkQueryRunner, checkRealtimeRelay, checkResourcesOutsideAuthStore, checkSourceNames, checkStatusSchema, checkUserTablesSchema, checkViewQueries, checkWebhooksSchema, coalesce, commentTools, commentsMigration, computedMigration, configExports, consoleAuditQueue, conversationKey, countRecordsTool, createAdmin, createConversations, createEncryptionTools, createFileCleanup, createOrganization, createRecordTool, createUser, defaultAppName, defaultHistoryPage, defaultSignInPolicy, defineEmail, defineFunction, defineJob, definePdf, defineTool, deleteRecordTool, deleteUser, describeResourceTool, 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, mcpInstructions, mcpRoutes, mcpServer, mcpToolContext, mcpTools, migrationCommand, newWebhookSecret, normalizeRoles, notFound, notificationSenders, notificationsMigration, oauthWellKnownPaths, objectKey, onDoNotDisturb, ownedDefinitionsMigration, parseColumns, parseRoles, passwordLength, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, pngIcons, poolWaitMs, postgresDeviceStore, postgresHistoryStore, processor, pushMessage, queryRunnerMigration, readDbConnections, readDefinitionsVersion, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readRecordTools, readVapidSettings, readWriteQueryTool, readableResources, realtimeLimits, realtimeRelayMigration, recordOf, refusalOf, refused, relayed, reloadingAdmin, 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, sqlSends, startErrorReporting, startJobs, statusMigration, statusNames, storageCleanupSchedule, storageProvider, storeFile, storeUsage, streamChatCompletion, subscription, supabasePath, thumbHash, unauthorized, updateRecordTool, urgencies, userTableResources, userTablesMigration, vapidPrivateKeyVariable, vapidPublicKeyVariable, vapidSubjectVariable, variantPath, verifySignature, verifyStandardWebhook, waitUntil, wantsLongQueries, webManifestPath, webPushSender, webauthnPath, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps, writeRecordTools };
198
+ 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 BaseToolContext, type BatchOperation, type BatchResult, type BetterAuthAuthenticator, type BetterAuthAuthenticatorOptions, type CallBackend, type CallMember, type Caller, type CallerOptions, type CallsAccess, type CallsOptions, type CapturedRow, type CascadingKey, type ChannelBroadcast, type ChannelSender, 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 DecryptField, 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 FieldDecrypter, type FieldReader, 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 LiveKitBackend, type LocalFilesOptions, type MailAttachment, type MailMessage, MailServerTimeoutError, 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, ModelError, type ModelSettings, type NewDevice, type NewNotification, type NewOrganization, type NewUser, type NotificationRecipients, NotificationSendError, type NotificationsOptions, type OperatorProvider, type OrganizationRole, type OrganizationsOptions, type PdfComponent, type PdfOptions, type PdfTemplate, PersonalMailError, type PersonalMailErrorCode, type PersonalMailProviderId, 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 RealtimePrune, type ReasoningDetail, type ReasoningEffort, type RebindOption, type RecordGroups, type RecordKey, type RecordKeyInput, type RecordPage, 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 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 StartWorkflowOptions, type StatusOptions, 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 UserTables, type VapidSettings, type ViewSource, type WebPushFields, type WebPushOptions, type WebhooksOptions, type WidgetOptions, type WorkflowsOptions, 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, callsMigration, capSocketMessages, changesMigration, channelSendsMigration, checkAi, checkAuthSchema, checkCalls, checkChanges, checkChannelSends, checkComments, checkComputed, checkJobsSchema, checkNotificationsSchema, checkQueryRunner, checkRealtimeRelay, checkResourcesOutsideAuthStore, checkSourceNames, checkStatusSchema, checkUserTablesSchema, checkViewQueries, checkWebhooksSchema, checkWorkflowsSchema, coalesce, commentTools, commentsMigration, computedMigration, configExports, consoleAuditQueue, conversationKey, countRecordsTool, createAdmin, createConversations, createEncryptionTools, createFileCleanup, createOrganization, createRecordTool, createUser, defaultAppName, defaultHistoryPage, defaultSignInPolicy, defineEmail, defineFunction, defineJob, definePdf, defineTool, deleteRecordTool, deleteUser, describeResourceTool, 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, mcpInstructions, mcpRoutes, mcpServer, mcpToolContext, mcpTools, migrationCommand, newWebhookSecret, normalizeRoles, notFound, notificationSenders, notificationsMigration, oauthWellKnownPaths, objectKey, onDoNotDisturb, ownedDefinitionsMigration, parseColumns, parseRoles, passwordLength, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, pngIcons, poolWaitMs, postgresDeviceStore, postgresHistoryStore, processor, pushMessage, queryRunnerMigration, readDbConnections, readDefinitionsVersion, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readRecordTools, readVapidSettings, readWriteQueryTool, readableResources, realtimeLimits, realtimeRelayMigration, recordOf, refusalOf, refused, relayed, reloadingAdmin, 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, sqlSends, startErrorReporting, startJobs, startWorkflow, statusMigration, statusNames, storageCleanupSchedule, storageProvider, storeFile, storeUsage, streamChatCompletion, subscription, supabasePath, thumbHash, unauthorized, updateRecordTool, urgencies, userTableResources, userTablesMigration, vapidPrivateKeyVariable, vapidPublicKeyVariable, vapidSubjectVariable, variantPath, verifySignature, verifyStandardWebhook, waitUntil, wantsLongQueries, webManifestPath, webPushSender, webauthnPath, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps, workflowInstructions, workflowReadTools, workflowWriteTools, workflowsMigration, writeRecordTools };
package/dist/index.js CHANGED
@@ -55,7 +55,10 @@ import { deleteRecordTool } from "./assistant/delete-record-tool.js";
55
55
  import { createRecordTool, updateRecordTool, writeRecordTools } from "./assistant/write-record-tools.js";
56
56
  import { batchWriteTool } from "./assistant/batch-write-tool.js";
57
57
  import { addCommentTool, commentTools, listCommentsTool } from "./assistant/comment-tools.js";
58
+ import { workflowReadTools } from "./workflows/mcp/workflow-read-tools.js";
59
+ import { workflowWriteTools } from "./workflows/mcp/workflow-write-tools.js";
58
60
  import { mcpTools } from "./mcp/mcp-tools.js";
61
+ import { workflowInstructions } from "./workflows/mcp/workflow-instructions.js";
59
62
  import { addAppRoleToOwners, addMember, createOrganization, listOrganizations, removeMember, setMemberRoles } from "./better-auth/organizations/host.js";
60
63
  import { createUser, deleteUser, hasUsers, listUsers, roleChoices, setUserBanned, setUserRole } from "./better-auth/users.js";
61
64
  import { coalesce } from "./changes/coalesce.js";
@@ -113,6 +116,8 @@ import { authStoreTables } from "./better-auth/auth-tables.js";
113
116
  import { checkResourcesOutsideAuthStore } from "./better-auth/store/resources-outside.js";
114
117
  import { checkComputed, computedMigration } from "./computed/computed-schema.js";
115
118
  import { checkWebhooksSchema, webhooksMigration } from "./webhooks/table/schema.js";
119
+ import { checkWorkflowsSchema, workflowsMigration } from "./workflows/schema.js";
120
+ import { startWorkflow } from "./workflows/start-workflow.js";
116
121
  import { checkUserTablesSchema, userTablesMigration } from "./user-tables/schema.js";
117
122
  import { ownedDefinitionsMigration } from "./user-tables/owned-definitions.js";
118
123
  import { userTableResources } from "./user-tables/user-table-resources.js";
@@ -140,4 +145,4 @@ import { defineEmail } from "./mail/define-email.js";
140
145
  import { definePdf } from "./pdf/define-pdf.js";
141
146
  import { startJobs } from "./jobs/runtime.js";
142
147
  import { jobsDrainApp } from "./jobs/drain-route.js";
143
- export { ConnectionsBusy, DeviceStoreError, FatalJobError, HistoryStoreError, HttpProblem, MailServerTimeoutError, MissingCredentials, ModelError, NotificationSendError, PersonalMailError, PushMessageError, addAppRoleToOwners, addCommentTool, addMember, apiKeyCaller, apiKeySettings, apiKeyVariables, appNameOver, aspectRatio, assistantProtocolRoutes, assistantRoles, assistantSettings, assistantVariables, authSchemaDrift, authSchemaMigration, authStoreTables, backgroundSettled, badRequest, batchWriteTool, beforeSignInPluginsVariable, betterAuthTokens, callsMigration, capSocketMessages, changesMigration, channelSendsMigration, checkAi, checkAuthSchema, checkCalls, checkChanges, checkChannelSends, checkComments, checkComputed, checkJobsSchema, checkNotificationsSchema, checkQueryRunner, checkRealtimeRelay, checkResourcesOutsideAuthStore, checkSourceNames, checkStatusSchema, checkUserTablesSchema, checkViewQueries, checkWebhooksSchema, coalesce, commentTools, commentsMigration, computedMigration, configExports, consoleAuditQueue, conversationKey, countRecordsTool, createAdmin, createConversations, createEncryptionTools, createFileCleanup, createOrganization, createRecordTool, createUser, defaultAppName, defaultHistoryPage, defaultSignInPolicy, defineEmail, defineFunction, defineJob, definePdf, defineTool, deleteRecordTool, deleteUser, describeResourceTool, 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, mcpInstructions, mcpRoutes, mcpServer, mcpToolContext, mcpTools, migrationCommand, newWebhookSecret, normalizeRoles, notFound, notificationSenders, notificationsMigration, oauthWellKnownPaths, objectKey, onDoNotDisturb, ownedDefinitionsMigration, parseColumns, parseRoles, passwordLength, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, pngIcons, poolWaitMs, postgresDeviceStore, postgresHistoryStore, processor, pushMessage, queryRunnerMigration, readDbConnections, readDefinitionsVersion, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readRecordTools, readVapidSettings, readWriteQueryTool, readableResources, realtimeLimits, realtimeRelayMigration, recordOf, refusalOf, refused, relayed, reloadingAdmin, 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, sqlSends, startErrorReporting, startJobs, statusMigration, statusNames, storageCleanupSchedule, storageProvider, storeFile, storeUsage, streamChatCompletion, subscription, supabasePath, thumbHash, unauthorized, updateRecordTool, urgencies, userTableResources, userTablesMigration, vapidPrivateKeyVariable, vapidPublicKeyVariable, vapidSubjectVariable, variantPath, verifySignature, verifyStandardWebhook, waitUntil, wantsLongQueries, webManifestPath, webPushSender, webauthnPath, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps, writeRecordTools };
148
+ export { ConnectionsBusy, DeviceStoreError, FatalJobError, HistoryStoreError, HttpProblem, MailServerTimeoutError, MissingCredentials, ModelError, NotificationSendError, PersonalMailError, PushMessageError, addAppRoleToOwners, addCommentTool, addMember, apiKeyCaller, apiKeySettings, apiKeyVariables, appNameOver, aspectRatio, assistantProtocolRoutes, assistantRoles, assistantSettings, assistantVariables, authSchemaDrift, authSchemaMigration, authStoreTables, backgroundSettled, badRequest, batchWriteTool, beforeSignInPluginsVariable, betterAuthTokens, callsMigration, capSocketMessages, changesMigration, channelSendsMigration, checkAi, checkAuthSchema, checkCalls, checkChanges, checkChannelSends, checkComments, checkComputed, checkJobsSchema, checkNotificationsSchema, checkQueryRunner, checkRealtimeRelay, checkResourcesOutsideAuthStore, checkSourceNames, checkStatusSchema, checkUserTablesSchema, checkViewQueries, checkWebhooksSchema, checkWorkflowsSchema, coalesce, commentTools, commentsMigration, computedMigration, configExports, consoleAuditQueue, conversationKey, countRecordsTool, createAdmin, createConversations, createEncryptionTools, createFileCleanup, createOrganization, createRecordTool, createUser, defaultAppName, defaultHistoryPage, defaultSignInPolicy, defineEmail, defineFunction, defineJob, definePdf, defineTool, deleteRecordTool, deleteUser, describeResourceTool, 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, mcpInstructions, mcpRoutes, mcpServer, mcpToolContext, mcpTools, migrationCommand, newWebhookSecret, normalizeRoles, notFound, notificationSenders, notificationsMigration, oauthWellKnownPaths, objectKey, onDoNotDisturb, ownedDefinitionsMigration, parseColumns, parseRoles, passwordLength, pluginOptions, pluginsBeforeSignIn, pluginsFor, pluginsVariable, pngIcons, poolWaitMs, postgresDeviceStore, postgresHistoryStore, processor, pushMessage, queryRunnerMigration, readDbConnections, readDefinitionsVersion, readJson, readOnlyQueryTool, readOperatorSettings, readOutbox, readPlatformSignIn, readRecordTools, readVapidSettings, readWriteQueryTool, readableResources, realtimeLimits, realtimeRelayMigration, recordOf, refusalOf, refused, relayed, reloadingAdmin, 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, sqlSends, startErrorReporting, startJobs, startWorkflow, statusMigration, statusNames, storageCleanupSchedule, storageProvider, storeFile, storeUsage, streamChatCompletion, subscription, supabasePath, thumbHash, unauthorized, updateRecordTool, urgencies, userTableResources, userTablesMigration, vapidPrivateKeyVariable, vapidPublicKeyVariable, vapidSubjectVariable, variantPath, verifySignature, verifyStandardWebhook, waitUntil, wantsLongQueries, webManifestPath, webPushSender, webauthnPath, webhooksMigration, widget, withCacheBreakpoints, withTrustedApps, workflowInstructions, workflowReadTools, workflowWriteTools, workflowsMigration, writeRecordTools };
@@ -12,4 +12,5 @@ import { fileProviderOf } from "./files/provider-settings.js";
12
12
  import { declaredJob } from "./jobs/declared-job.js";
13
13
  import { AuthPlugins, buildAuth, createAuth, loadAuthPlugins } from "./better-auth/create-auth.js";
14
14
  import { webhooksModule } from "./webhooks/table/webhooks-module.js";
15
- export { type AppAuthInput, type AuthPlugins, appAuthOptions, appPool, betterAuthAuthenticator, buildAppAuth, buildAuth, buildAuthenticator, checkCallsOptions, checkNotificationsOptions, checkStatusOptions, createAuth, declaredJob, fileProviderOf, isSubscription, loadAuthPlugins, localFiles, longQueryPool, s3Files, webhooksModule };
15
+ import { workflowsModule } from "./workflows/workflows-module.js";
16
+ export { type AppAuthInput, type AuthPlugins, appAuthOptions, appPool, betterAuthAuthenticator, buildAppAuth, buildAuth, buildAuthenticator, checkCallsOptions, checkNotificationsOptions, checkStatusOptions, createAuth, declaredJob, fileProviderOf, isSubscription, loadAuthPlugins, localFiles, longQueryPool, s3Files, webhooksModule, workflowsModule };
package/dist/internal.js CHANGED
@@ -9,7 +9,8 @@ import { betterAuthAuthenticator } from "./better-auth/authenticator.js";
9
9
  import { fileProviderOf } from "./files/provider-settings.js";
10
10
  import { declaredJob } from "./jobs/declared-job.js";
11
11
  import { webhooksModule } from "./webhooks/table/webhooks-module.js";
12
+ import { workflowsModule } from "./workflows/workflows-module.js";
12
13
  import { appAuthOptions, buildAppAuth } from "./better-auth/auth-settings.js";
13
14
  import { buildAuthenticator } from "./better-auth/authenticate-settings.js";
14
15
  import { checkCallsOptions } from "./calls/calls-options.js";
15
- export { appAuthOptions, appPool, betterAuthAuthenticator, buildAppAuth, buildAuth, buildAuthenticator, checkCallsOptions, checkNotificationsOptions, checkStatusOptions, createAuth, declaredJob, fileProviderOf, isSubscription, loadAuthPlugins, localFiles, longQueryPool, s3Files, webhooksModule };
16
+ export { appAuthOptions, appPool, betterAuthAuthenticator, buildAppAuth, buildAuth, buildAuthenticator, checkCallsOptions, checkNotificationsOptions, checkStatusOptions, createAuth, declaredJob, fileProviderOf, isSubscription, loadAuthPlugins, localFiles, longQueryPool, s3Files, webhooksModule, workflowsModule };
@@ -18,14 +18,20 @@ export type McpToolsInput = {
18
18
  * those of them that `writes` lists when it lists some. None by default.
19
19
  */
20
20
  commented?: string[];
21
+ /**
22
+ * Offers the workflow tools, for an app with `workflows`: reading workflows, their types and runs, and checking
23
+ * definitions; with writes on, `create_workflow`, `update_workflow` and `run_workflow` too. Off by default.
24
+ */
25
+ workflows?: boolean;
21
26
  /** The app's own tools, offered to every caller after the built-in ones. */
22
27
  own?: AssistantTool[];
23
28
  };
24
29
  /**
25
30
  * The MCP tools for a caller: the record tools, the write tools when `writes` is on, the comment tools when a resource
26
- * takes comments, read-only SQL when `sql` is on and the caller sees the assistant, then the app's own tools. The
31
+ * takes comments, the workflow tools with `workflows`, read-only SQL when `sql` is on and the caller sees the
32
+ * assistant, then the app's own tools. The
27
33
  * tools are built once and only chosen per session: the MCP server compiles each tool's schema, and a schema object made
28
34
  * per request would be compiled again.
29
35
  */
30
- export declare const mcpTools: ({ db, sql, writes, commented, own }: McpToolsInput) => (session: Session) => AssistantTool[];
36
+ export declare const mcpTools: ({ db, sql, writes, commented, workflows, own }: McpToolsInput) => (session: Session) => AssistantTool[];
31
37
  //#endregion
@@ -5,13 +5,17 @@ import { readRecordTools } from "../assistant/record-tools.js";
5
5
  import { writeRecordTools } from "../assistant/write-record-tools.js";
6
6
  import { batchWriteTool } from "../assistant/batch-write-tool.js";
7
7
  import { commentTools } from "../assistant/comment-tools.js";
8
+ import { workflowReadTools } from "../workflows/mcp/workflow-read-tools.js";
9
+ import { workflowWriteTools } from "../workflows/mcp/workflow-write-tools.js";
8
10
  //#region src/mcp/mcp-tools.ts
9
11
  const writeTools = (input) => [...writeRecordTools(input), batchWriteTool(input)];
10
12
  const builtInNames = (db) => new Set([
11
13
  ...readRecordTools(),
12
14
  ...writeTools({}),
13
15
  ...commentTools({ commented: ["comments"] }, {}),
14
- readOnlyQueryTool(db)
16
+ readOnlyQueryTool(db),
17
+ ...workflowReadTools(),
18
+ ...workflowWriteTools()
15
19
  ].map((tool) => tool.name));
16
20
  /** The app's own tools; one whose name is taken twice, or by a built-in tool, stops the server at startup. */
17
21
  const checkedOwnTools = (db, own) => {
@@ -22,21 +26,24 @@ const checkedOwnTools = (db, own) => {
22
26
  };
23
27
  /**
24
28
  * The MCP tools for a caller: the record tools, the write tools when `writes` is on, the comment tools when a resource
25
- * takes comments, read-only SQL when `sql` is on and the caller sees the assistant, then the app's own tools. The
29
+ * takes comments, the workflow tools with `workflows`, read-only SQL when `sql` is on and the caller sees the
30
+ * assistant, then the app's own tools. The
26
31
  * tools are built once and only chosen per session: the MCP server compiles each tool's schema, and a schema object made
27
32
  * per request would be compiled again.
28
33
  */
29
- const mcpTools = ({ db, sql, writes, commented = [], own = [] }) => {
34
+ const mcpTools = ({ db, sql, writes, commented = [], workflows = false, own = [] }) => {
30
35
  const ownTools = checkedOwnTools(db, own);
31
36
  const read = readRecordTools();
32
37
  const limits = writes === false ? false : writes === true || !writes.resources ? {} : { resources: writes.resources };
33
38
  const write = limits === false ? [] : writeTools(limits);
34
39
  const comments = commentTools({ commented }, limits);
40
+ const flows = workflows ? [...workflowReadTools(), ...limits === false ? [] : workflowWriteTools(limits)] : [];
35
41
  const query = sql ? [readOnlyQueryTool(db)] : [];
36
42
  return (session) => [
37
43
  ...read,
38
44
  ...write,
39
45
  ...comments,
46
+ ...flows,
40
47
  ...seesAssistant(session.user.roles) ? query : [],
41
48
  ...ownTools
42
49
  ];
package/dist/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "0.67.8";
2
+ var version = "0.67.10";
3
3
  //#endregion
4
4
  export { version };
@@ -1,9 +1,9 @@
1
+ import { AddressRefusedError, pinnedRequest } from "./table/pinned-request.js";
2
+ import { readLimited } from "./table/read-limited.js";
1
3
  import { invokeFunction } from "../functions/define-function.js";
2
4
  import { retryAfterMs } from "./retry-schedule.js";
3
5
  import { standardWebhookHeaders } from "./standard-webhooks.js";
4
6
  import { subscriberSession } from "./subscriber-view.js";
5
- import { AddressRefusedError, pinnedRequest } from "./table/pinned-request.js";
6
- import { readLimited } from "./table/read-limited.js";
7
7
  //#region src/webhooks/attempt.ts
8
8
  /** How long a receiver has to answer. */
9
9
  const attemptTimeoutMs = 15e3;
@@ -1,5 +1,5 @@
1
- import { betterAuthOwnerRoles } from "./owner-roles.js";
2
1
  import { checkWebhookUrl } from "./address-check.js";
2
+ import { betterAuthOwnerRoles } from "./owner-roles.js";
3
3
  import { webhooksSchema } from "./options.js";
4
4
  import { tableSubscriptions } from "./table-subscriptions.js";
5
5
  //#region src/webhooks/table/webhook-table.ts
@@ -0,0 +1,103 @@
1
+ import { AddressRefusedError, pinnedRequest } from "../webhooks/table/pinned-request.js";
2
+ import { readLimited } from "../webhooks/table/read-limited.js";
3
+ import { isFileValue, readRunFile, storeRunFile } from "./run-files.js";
4
+ import { StepError } from "@protobase/workflows";
5
+ //#region src/workflows/http-step.ts
6
+ /** The most of an answer's body the `http` step reads; a larger one fails the step. */
7
+ const httpBodyLimit = 10485760;
8
+ /** How much of a failing answer's body its error keeps, after secrets are blanked out of it. */
9
+ const causeBodyLength = 200;
10
+ const methods = /* @__PURE__ */ new Set([
11
+ "GET",
12
+ "POST",
13
+ "PUT",
14
+ "PATCH",
15
+ "DELETE"
16
+ ]);
17
+ const readings = /* @__PURE__ */ new Set([
18
+ "json",
19
+ "text",
20
+ "file"
21
+ ]);
22
+ const invalid = (reason) => new StepError("Http.InvalidArguments", reason);
23
+ const isTextRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && Object.values(value).every((item) => typeof item === "string");
24
+ const checked = (args) => {
25
+ if (typeof args.url !== "string" || !URL.canParse(args.url)) throw invalid("url must be an http or https URL");
26
+ const method = args.method === void 0 ? "GET" : String(args.method).toUpperCase();
27
+ if (!methods.has(method)) throw invalid(`method must be one of ${[...methods].join(", ")}`);
28
+ if (args.headers !== void 0 && !isTextRecord(args.headers)) throw invalid("headers must be an object of text values");
29
+ if (args.query !== void 0 && !isTextRecord(args.query)) throw invalid("query must be an object of text values");
30
+ const response = args.response ?? "json";
31
+ if (typeof response !== "string" || !readings.has(response)) throw invalid("response must be json, text or file");
32
+ const url = new URL(args.url);
33
+ for (const [name, value] of Object.entries(args.query ?? {})) url.searchParams.append(name, value);
34
+ return {
35
+ url,
36
+ method,
37
+ headers: new Headers(args.headers),
38
+ response
39
+ };
40
+ };
41
+ const answerBody = async (bytes, response, url, type, keep) => {
42
+ if (response === "file") return keep(bytes, decodeURIComponent(url.pathname.slice(url.pathname.lastIndexOf("/") + 1)), type?.split(";")[0]?.trim() || "application/octet-stream");
43
+ const text = new TextDecoder().decode(bytes);
44
+ if (response === "text") return text;
45
+ if (text.trim() === "") return null;
46
+ try {
47
+ return JSON.parse(text);
48
+ } catch (error) {
49
+ if (!(error instanceof SyntaxError)) throw error;
50
+ throw new StepError("Http.InvalidBody", `${url.host} answered with a body that is not JSON; read it with "response": "text"`);
51
+ }
52
+ };
53
+ /**
54
+ * The `app:http` step: one request to `url`, built at run time, through the pinned request, which resolves its host
55
+ * once and connects only to a public address it checked. It follows no redirect, reads at most `httpBodyLimit` of
56
+ * the answer, and fails with `Http.Status` on a status outside 2xx, `Http.Network` when no answer came.
57
+ */
58
+ const httpStep = ({ allowPrivateAddresses = false, resolve, files = () => void 0 } = {}) => async (args, { runId, signal, log, redact }) => {
59
+ const given = args ?? {};
60
+ const { url, method, headers, response: reading } = checked(given);
61
+ let body;
62
+ if (given.body !== void 0 && method !== "GET") {
63
+ if (isFileValue(given.body)) {
64
+ const file = await readRunFile(files(), runId, given.body, "body");
65
+ body = file.bytes;
66
+ if (!headers.has("content-type")) headers.set("content-type", file.ref.type ?? "application/octet-stream");
67
+ } else if (typeof given.body === "string") body = given.body;
68
+ else {
69
+ body = JSON.stringify(given.body);
70
+ if (!headers.has("content-type")) headers.set("content-type", "application/json");
71
+ }
72
+ }
73
+ const started = Date.now();
74
+ const answer = await pinnedRequest(url.href, {
75
+ method,
76
+ headers,
77
+ ...body !== void 0 && { body },
78
+ signal
79
+ }, {
80
+ allowPrivateAddresses,
81
+ ...resolve && { resolve }
82
+ }).catch((error) => {
83
+ if (error instanceof AddressRefusedError) throw new StepError("Http.AddressRefused", error.message);
84
+ if (signal.aborted) throw error;
85
+ throw new StepError("Http.Network", `No answer from ${url.host}: ${error instanceof Error ? error.message : String(error)}`);
86
+ });
87
+ const bytes = await readLimited(answer, 10485761);
88
+ log(`${method} ${given.url}`.replace(/[?#].*$/, "") + `: ${answer.status} in ${Date.now() - started} ms`);
89
+ if (bytes.length > 10485760) throw new StepError("Http.ResponseTooLarge", `The answer's body is larger than ${httpBodyLimit / 1024 / 1024} MiB, the most the http step reads`);
90
+ if (answer.status < 200 || answer.status > 299) {
91
+ const excerpt = redact(new TextDecoder().decode(bytes)).slice(0, causeBodyLength);
92
+ throw new StepError("Http.Status", `${url.host} answered ${answer.status}${excerpt ? `: ${excerpt}` : ""}`);
93
+ }
94
+ const kept = Object.fromEntries([...answer.headers].filter(([name]) => name !== "set-cookie"));
95
+ const keep = (data, name, type) => storeRunFile(files(), runId, data, name, type);
96
+ return {
97
+ status: answer.status,
98
+ headers: kept,
99
+ body: await answerBody(bytes, reading, url, answer.headers.get("content-type"), keep)
100
+ };
101
+ };
102
+ //#endregion
103
+ export { httpBodyLimit, httpStep };
@@ -0,0 +1,22 @@
1
+ import { badRequest } from "../problem.js";
2
+ import { limits, nestingDepth } from "@protobase/workflows";
3
+ //#region src/workflows/input-limits.ts
4
+ /**
5
+ * Refuses a run's input over `limits.inputBytes` as JSON or nested deeper than `limits.inputDepth`, before anything
6
+ * evaluates it: a 400 problem, so the run is not created.
7
+ */
8
+ const checkRunInput = (input) => {
9
+ if (nestingDepth(input, limits.inputDepth) > limits.inputDepth) throw badRequest("input-too-deep", `A run's input nests at most ${limits.inputDepth} levels of arrays and objects`);
10
+ const bytes = new TextEncoder().encode(JSON.stringify(input ?? null)).length;
11
+ if (bytes > limits.inputBytes) throw badRequest("input-too-large", `A run's input is at most ${limits.inputBytes / 1024 / 1024} MiB as JSON; this one is ${bytes} bytes`);
12
+ };
13
+ /**
14
+ * The same limits on a run's input as the API sent it, before the body is validated, whose walk of a deeply nested
15
+ * value would overflow the call stack.
16
+ */
17
+ const runInputCheck = async ({ resource, operation, body }) => {
18
+ if (resource !== "workflow_runs" || operation !== "create" || typeof body !== "object" || body === null) return;
19
+ checkRunInput(body.input);
20
+ };
21
+ //#endregion
22
+ export { checkRunInput, runInputCheck };
@@ -0,0 +1,58 @@
1
+ import { readRunFile, runFileLimit } from "./run-files.js";
2
+ import { StepError } from "@protobase/workflows";
3
+ const invalid = (reason) => new StepError("Mail.InvalidArguments", reason);
4
+ const line = (value, name) => {
5
+ if (typeof value !== "string" || value.trim() === "") throw invalid(`${name} must be text`);
6
+ if (/[\r\n]/.test(value)) throw invalid(`${name} must be one line`);
7
+ return value;
8
+ };
9
+ const recipients = (value) => {
10
+ const list = Array.isArray(value) ? value : [value];
11
+ if (list.length === 0 || list.length > 50) throw invalid(`to must be one address or a list of 1 to 50`);
12
+ return list.map((address, index) => {
13
+ const name = Array.isArray(value) ? `to[${index}]` : "to";
14
+ if (/[,;]/.test(line(address, name))) throw invalid(`${name} must be one address; give several as a list`);
15
+ return address;
16
+ }).join(", ");
17
+ };
18
+ const attachmentsOf = async (value, files, runId) => {
19
+ if (value === void 0 || value === null) return [];
20
+ if (!Array.isArray(value)) throw invalid("attachments must be a list of file values");
21
+ const attachments = [];
22
+ let total = 0;
23
+ for (const [index, item] of value.entries()) {
24
+ const { ref, bytes } = await readRunFile(files, runId, item, `attachments[${index}]`);
25
+ total += bytes.length;
26
+ if (total > 10485760) throw invalid(`attachments are larger than ${runFileLimit / 1024 / 1024} MiB together`);
27
+ attachments.push({
28
+ filename: ref.name,
29
+ content: bytes,
30
+ ...ref.type && { contentType: ref.type }
31
+ });
32
+ }
33
+ return attachments;
34
+ };
35
+ /**
36
+ * The `app:mail.send` step: one message from the app's own sender, with the app's mailer; a workflow cannot set the
37
+ * sender. Its Message-ID comes from the step's idempotency key, the same for each try, so a receiver can tell a
38
+ * repeated try from a new mail.
39
+ */
40
+ const mailStep = (mail, files) => async (args, { runId, idempotencyKey }) => {
41
+ const given = args ?? {};
42
+ const mailer = mail();
43
+ if (!mailer) throw new StepError("States.TaskFailed", "The app sends no mail: set its mailer, or PROTOBASE_SMTP_URL and PROTOBASE_MAIL_FROM");
44
+ if (typeof given.text !== "string") throw invalid("text must be text");
45
+ if (given.html !== void 0 && typeof given.html !== "string") throw invalid("html must be text");
46
+ const messageId = `<${idempotencyKey.replace(/[^A-Za-z0-9.-]/g, ".")}@workflows.invalid>`;
47
+ await mailer.send({
48
+ to: recipients(given.to),
49
+ subject: line(given.subject, "subject"),
50
+ text: given.text,
51
+ ...given.html !== void 0 && { html: given.html },
52
+ headers: { "Message-ID": messageId },
53
+ attachments: await attachmentsOf(given.attachments, files(), runId)
54
+ });
55
+ return { message_id: messageId };
56
+ };
57
+ //#endregion
58
+ export { mailStep };
@@ -0,0 +1,15 @@
1
+ //#region src/workflows/mcp/merge-patch.ts
2
+ const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
3
+ /**
4
+ * `patch` applied to `target` as a JSON Merge Patch (RFC 7396): an object merges into the object at its place, a member
5
+ * set to null is removed, and any other value, a list included, replaces what was there. Neither input is changed.
6
+ */
7
+ const mergePatch = (target, patch) => {
8
+ if (!isObject(patch)) return patch;
9
+ const merged = isObject(target) ? { ...target } : {};
10
+ for (const [name, value] of Object.entries(patch)) if (value === null) delete merged[name];
11
+ else merged[name] = mergePatch(merged[name], value);
12
+ return merged;
13
+ };
14
+ //#endregion
15
+ export { mergePatch };