@mastra/factory 0.24.0-alpha.8 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/environment/build-runner.js +2 -1
- package/dist/environment/build-runner.js.map +1 -1
- package/dist/environment/build-workflow.js +1 -1
- package/dist/environment/build-workflow.js.map +1 -1
- package/dist/environment/build.js +16 -14
- package/dist/environment/build.js.map +1 -1
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +111 -19
- package/dist/factory.js.map +1 -1
- package/dist/integrations/base.d.ts +1 -1
- package/dist/integrations/base.d.ts.map +1 -1
- package/dist/integrations/github/app-identity.js.map +1 -1
- package/dist/integrations/github/integration.js +1 -1
- package/dist/integrations/github/integration.js.map +1 -1
- package/dist/integrations/github/reconcile-worker.js +1 -1
- package/dist/integrations/github/reconcile-worker.js.map +1 -1
- package/dist/integrations/github/routes.d.ts +1 -1
- package/dist/integrations/github/routes.d.ts.map +1 -1
- package/dist/integrations/github/routes.js +24 -13
- package/dist/integrations/github/routes.js.map +1 -1
- package/dist/integrations/github/rules.d.ts.map +1 -1
- package/dist/integrations/github/rules.js +53 -9
- package/dist/integrations/github/rules.js.map +1 -1
- package/dist/integrations/github/sandbox.js +2 -2
- package/dist/integrations/github/sandbox.js.map +1 -1
- package/dist/integrations/github/session-subscriptions.d.ts.map +1 -1
- package/dist/integrations/github/session-subscriptions.js +1 -2
- package/dist/integrations/github/session-subscriptions.js.map +1 -1
- package/dist/integrations/github/subscriptions.d.ts +7 -4
- package/dist/integrations/github/subscriptions.d.ts.map +1 -1
- package/dist/integrations/github/subscriptions.js +5 -5
- package/dist/integrations/github/subscriptions.js.map +1 -1
- package/dist/integrations/gitlab/api.js.map +1 -1
- package/dist/integrations/gitlab/integration.js.map +1 -1
- package/dist/integrations/gitlab/reconciliation-config.js +2 -1
- package/dist/integrations/gitlab/reconciliation-config.js.map +1 -1
- package/dist/integrations/gitlab/routes.d.ts.map +1 -1
- package/dist/integrations/gitlab/routes.js +10 -6
- package/dist/integrations/gitlab/routes.js.map +1 -1
- package/dist/integrations/gitlab/rules.js.map +1 -1
- package/dist/integrations/gitlab/session-subscriptions.d.ts.map +1 -1
- package/dist/integrations/gitlab/session-subscriptions.js +1 -2
- package/dist/integrations/gitlab/session-subscriptions.js.map +1 -1
- package/dist/integrations/gitlab/subscriptions.d.ts +7 -4
- package/dist/integrations/gitlab/subscriptions.d.ts.map +1 -1
- package/dist/integrations/gitlab/subscriptions.js +5 -5
- package/dist/integrations/gitlab/subscriptions.js.map +1 -1
- package/dist/integrations/incidentio/api.js.map +1 -1
- package/dist/integrations/incidentio/integration.js.map +1 -1
- package/dist/integrations/incidentio/rules.js.map +1 -1
- package/dist/integrations/issue-reconcile-worker.js +1 -1
- package/dist/integrations/issue-reconcile-worker.js.map +1 -1
- package/dist/integrations/issue-reconciler.js +1 -1
- package/dist/integrations/issue-reconciler.js.map +1 -1
- package/dist/integrations/jira/api.js.map +1 -1
- package/dist/integrations/jira/integration.js.map +1 -1
- package/dist/integrations/jira/rules.js.map +1 -1
- package/dist/integrations/linear/agent-tools.d.ts.map +1 -1
- package/dist/integrations/linear/agent-tools.js.map +1 -1
- package/dist/integrations/linear/integration.js.map +1 -1
- package/dist/integrations/linear/rules.js.map +1 -1
- package/dist/integrations/platform/api-client.js.map +1 -1
- package/dist/integrations/platform/github/event-worker.js +1 -1
- package/dist/integrations/platform/github/event-worker.js.map +1 -1
- package/dist/integrations/platform/github/integration.js +2 -2
- package/dist/integrations/platform/github/integration.js.map +1 -1
- package/dist/integrations/platform/gitlab/event-worker.js.map +1 -1
- package/dist/integrations/platform/gitlab/integration.js.map +1 -1
- package/dist/integrations/platform/incidentio/integration.js +2 -1
- package/dist/integrations/platform/incidentio/integration.js.map +1 -1
- package/dist/integrations/platform/jira/integration.js.map +1 -1
- package/dist/integrations/platform/linear/event-worker.js +1 -1
- package/dist/integrations/platform/linear/event-worker.js.map +1 -1
- package/dist/integrations/platform/linear/integration.js.map +1 -1
- package/dist/integrations/slack/connect-route.js +1 -1
- package/dist/integrations/slack/connect-route.js.map +1 -1
- package/dist/integrations/slack/feed-publisher.js +1 -1
- package/dist/integrations/slack/feed-publisher.js.map +1 -1
- package/dist/integrations/slack/integration.js +1 -1
- package/dist/integrations/slack/integration.js.map +1 -1
- package/dist/integrations/slack/slack.d.ts +16 -5
- package/dist/integrations/slack/slack.d.ts.map +1 -1
- package/dist/integrations/slack/slack.js +87 -34
- package/dist/integrations/slack/slack.js.map +1 -1
- package/dist/integrations/subscription-session.d.ts +0 -1
- package/dist/integrations/subscription-session.d.ts.map +1 -1
- package/dist/integrations/subscription-session.js +1 -4
- package/dist/integrations/subscription-session.js.map +1 -1
- package/dist/integrations/workos/integration.js.map +1 -1
- package/dist/mcp/routes.d.ts.map +1 -1
- package/dist/mcp/routes.js +1 -1
- package/dist/mcp/routes.js.map +1 -1
- package/dist/packages/_internals/workspace/dist/index.js +18 -1
- package/dist/packages/_internals/workspace/dist/index.js.map +1 -1
- package/dist/routes/attention-activity.d.ts.map +1 -1
- package/dist/routes/attention-activity.js +5 -2
- package/dist/routes/attention-activity.js.map +1 -1
- package/dist/routes/attention-parked.js.map +1 -1
- package/dist/routes/attention-providers.d.ts +0 -1
- package/dist/routes/attention-providers.d.ts.map +1 -1
- package/dist/routes/attention-providers.js +5 -6
- package/dist/routes/attention-providers.js.map +1 -1
- package/dist/routes/automation-runs.js.map +1 -1
- package/dist/routes/config.d.ts +6 -7
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +20 -19
- package/dist/routes/config.js.map +1 -1
- package/dist/routes/contracts.js +1 -1
- package/dist/routes/contracts.js.map +1 -1
- package/dist/routes/custom-provider-source.js.map +1 -1
- package/dist/routes/fs.d.ts +31 -23
- package/dist/routes/fs.d.ts.map +1 -1
- package/dist/routes/fs.js +218 -64
- package/dist/routes/fs.js.map +1 -1
- package/dist/routes/intake.js +2 -1
- package/dist/routes/intake.js.map +1 -1
- package/dist/routes/knowledge.js +1 -1
- package/dist/routes/knowledge.js.map +1 -1
- package/dist/routes/oauth.js +3 -2
- package/dist/routes/oauth.js.map +1 -1
- package/dist/routes/projects.d.ts +1 -1
- package/dist/routes/projects.d.ts.map +1 -1
- package/dist/routes/projects.js +33 -31
- package/dist/routes/projects.js.map +1 -1
- package/dist/routes/provider-credentials.d.ts.map +1 -1
- package/dist/routes/provider-credentials.js +6 -1
- package/dist/routes/provider-credentials.js.map +1 -1
- package/dist/routes/session-access.d.ts +55 -0
- package/dist/routes/session-access.d.ts.map +1 -0
- package/dist/routes/session-access.js +165 -0
- package/dist/routes/session-access.js.map +1 -0
- package/dist/routes/skills.d.ts +2 -4
- package/dist/routes/skills.d.ts.map +1 -1
- package/dist/routes/skills.js +19 -65
- package/dist/routes/skills.js.map +1 -1
- package/dist/routes/source-control-sessions.d.ts +6 -1
- package/dist/routes/source-control-sessions.d.ts.map +1 -1
- package/dist/routes/source-control-sessions.js +95 -12
- package/dist/routes/source-control-sessions.js.map +1 -1
- package/dist/routes/surface.d.ts +5 -0
- package/dist/routes/surface.d.ts.map +1 -1
- package/dist/routes/surface.js +10 -4
- package/dist/routes/surface.js.map +1 -1
- package/dist/routes/tenant-credentials.js.map +1 -1
- package/dist/routes/work-items.js.map +1 -1
- package/dist/rules/binding-context.js +11 -9
- package/dist/rules/binding-context.js.map +1 -1
- package/dist/rules/dispatcher.d.ts +1 -1
- package/dist/rules/dispatcher.d.ts.map +1 -1
- package/dist/rules/dispatcher.js +10 -10
- package/dist/rules/dispatcher.js.map +1 -1
- package/dist/rules/start-coordinator.d.ts +4 -0
- package/dist/rules/start-coordinator.d.ts.map +1 -1
- package/dist/rules/start-coordinator.js +36 -4
- package/dist/rules/start-coordinator.js.map +1 -1
- package/dist/rules/tools.js +2 -2
- package/dist/rules/tools.js.map +1 -1
- package/dist/rules/transition-service.js.map +1 -1
- package/dist/sandbox/callback-factory-sandbox.js.map +1 -1
- package/dist/sandbox/local-factory-sandbox.js.map +1 -1
- package/dist/sandbox/session-retirement.js.map +1 -1
- package/dist/secret-encryption.d.ts.map +1 -1
- package/dist/secret-encryption.js +65 -25
- package/dist/secret-encryption.js.map +1 -1
- package/dist/session/channel-reply-processor.d.ts +7 -6
- package/dist/session/channel-reply-processor.d.ts.map +1 -1
- package/dist/session/channel-reply-processor.js +9 -9
- package/dist/session/channel-reply-processor.js.map +1 -1
- package/dist/session/channel-session-link-processor.js +1 -0
- package/dist/session/channel-session-link-processor.js.map +1 -1
- package/dist/session/credential-policy.d.ts.map +1 -1
- package/dist/session/credential-policy.js +7 -6
- package/dist/session/credential-policy.js.map +1 -1
- package/dist/session/default-model-hydration.d.ts +1 -0
- package/dist/session/default-model-hydration.d.ts.map +1 -1
- package/dist/session/default-model-hydration.js +3 -2
- package/dist/session/default-model-hydration.js.map +1 -1
- package/dist/session/environment-state-processor.js +1 -1
- package/dist/session/environment-state-processor.js.map +1 -1
- package/dist/session/filesystem-capture.d.ts +3 -3
- package/dist/session/filesystem-capture.d.ts.map +1 -1
- package/dist/session/filesystem-capture.js +16 -17
- package/dist/session/filesystem-capture.js.map +1 -1
- package/dist/session/first-exec-capture.d.ts +1 -1
- package/dist/session/first-exec-capture.d.ts.map +1 -1
- package/dist/session/first-exec-capture.js +1 -1
- package/dist/session/first-exec-capture.js.map +1 -1
- package/dist/session/first-message-capture.d.ts +1 -1
- package/dist/session/first-message-capture.d.ts.map +1 -1
- package/dist/session/first-message-capture.js +1 -1
- package/dist/session/first-message-capture.js.map +1 -1
- package/dist/session/live-sessions.d.ts +1 -1
- package/dist/session/live-sessions.js +1 -1
- package/dist/session/live-sessions.js.map +1 -1
- package/dist/session/memory-settings-hydration.d.ts +1 -1
- package/dist/session/memory-settings-hydration.d.ts.map +1 -1
- package/dist/session/memory-settings-hydration.js +2 -1
- package/dist/session/memory-settings-hydration.js.map +1 -1
- package/dist/session/resource-migration.d.ts +105 -0
- package/dist/session/resource-migration.d.ts.map +1 -0
- package/dist/session/resource-migration.js +195 -0
- package/dist/session/resource-migration.js.map +1 -0
- package/dist/session/session-threads.d.ts +58 -0
- package/dist/session/session-threads.d.ts.map +1 -0
- package/dist/session/session-threads.js +90 -0
- package/dist/session/session-threads.js.map +1 -0
- package/dist/session/source-control-tools.js +8 -8
- package/dist/session/source-control-tools.js.map +1 -1
- package/dist/session/thinking-default.d.ts.map +1 -1
- package/dist/session/thinking-default.js +3 -4
- package/dist/session/thinking-default.js.map +1 -1
- package/dist/session/thread-session-stamp.d.ts +21 -0
- package/dist/session/thread-session-stamp.d.ts.map +1 -0
- package/dist/session/thread-session-stamp.js +20 -0
- package/dist/session/thread-session-stamp.js.map +1 -0
- package/dist/session/thread-title-mirror.d.ts +1 -1
- package/dist/session/thread-title-mirror.d.ts.map +1 -1
- package/dist/session/thread-title-mirror.js +1 -1
- package/dist/session/thread-title-mirror.js.map +1 -1
- package/dist/skills/service.d.ts +6 -8
- package/dist/skills/service.d.ts.map +1 -1
- package/dist/skills/service.js +3 -3
- package/dist/skills/service.js.map +1 -1
- package/dist/spa-static.js.map +1 -1
- package/dist/state-signing.js +1 -1
- package/dist/state-signing.js.map +1 -1
- package/dist/storage/domains/audit/agent-audit.d.ts.map +1 -1
- package/dist/storage/domains/audit/agent-audit.js +2 -2
- package/dist/storage/domains/audit/agent-audit.js.map +1 -1
- package/dist/storage/domains/audit/base.js.map +1 -1
- package/dist/storage/domains/audit/domain.js.map +1 -1
- package/dist/storage/domains/channel-identity/base.js.map +1 -1
- package/dist/storage/domains/comments/base.js.map +1 -1
- package/dist/storage/domains/comments/domain.js.map +1 -1
- package/dist/storage/domains/comments/feed-context.js.map +1 -1
- package/dist/storage/domains/credentials/base.js.map +1 -1
- package/dist/storage/domains/custom-providers/base.js.map +1 -1
- package/dist/storage/domains/intake/base.js.map +1 -1
- package/dist/storage/domains/integrations/base.d.ts +8 -0
- package/dist/storage/domains/integrations/base.d.ts.map +1 -1
- package/dist/storage/domains/integrations/base.js +7 -0
- package/dist/storage/domains/integrations/base.js.map +1 -1
- package/dist/storage/domains/memory-settings/base.js.map +1 -1
- package/dist/storage/domains/model-defaults/base.js.map +1 -1
- package/dist/storage/domains/projects/base.js.map +1 -1
- package/dist/storage/domains/queue-health/base.js.map +1 -1
- package/dist/storage/domains/source-control/base.d.ts +19 -0
- package/dist/storage/domains/source-control/base.d.ts.map +1 -1
- package/dist/storage/domains/source-control/base.js +42 -0
- package/dist/storage/domains/source-control/base.js.map +1 -1
- package/dist/storage/domains/source-control/inmemory.d.ts +5 -1
- package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
- package/dist/storage/domains/source-control/inmemory.js +7 -0
- package/dist/storage/domains/source-control/inmemory.js.map +1 -1
- package/dist/storage/domains/work-items/base.d.ts +14 -0
- package/dist/storage/domains/work-items/base.d.ts.map +1 -1
- package/dist/storage/domains/work-items/base.js +25 -1
- package/dist/storage/domains/work-items/base.js.map +1 -1
- package/dist/storage/domains/work-items/board-version.js.map +1 -1
- package/dist/storage/domains/work-items/metrics.js.map +1 -1
- package/dist/tools/approval-tools.js +1 -1
- package/dist/tools/approval-tools.js.map +1 -1
- package/dist/tools/deliver.d.ts +8 -5
- package/dist/tools/deliver.d.ts.map +1 -1
- package/dist/tools/deliver.js +22 -8
- package/dist/tools/deliver.js.map +1 -1
- package/dist/tools/messaging-tools.d.ts +1 -1
- package/dist/tools/messaging-tools.d.ts.map +1 -1
- package/dist/tools/messaging-tools.js +203 -72
- package/dist/tools/messaging-tools.js.map +1 -1
- package/dist/tools/permissions.d.ts +1 -1
- package/dist/tools/permissions.d.ts.map +1 -1
- package/dist/tools/permissions.js +1 -1
- package/dist/tools/permissions.js.map +1 -1
- package/dist/tools/reports.d.ts.map +1 -1
- package/dist/tools/reports.js +10 -3
- package/dist/tools/reports.js.map +1 -1
- package/dist/tools/run-watch.d.ts +2 -0
- package/dist/tools/run-watch.d.ts.map +1 -1
- package/dist/tools/run-watch.js +42 -2
- package/dist/tools/run-watch.js.map +1 -1
- package/dist/tools/scope.d.ts +2 -1
- package/dist/tools/scope.d.ts.map +1 -1
- package/dist/tools/scope.js +3 -2
- package/dist/tools/scope.js.map +1 -1
- package/dist/tools/session-tools.d.ts +1 -1
- package/dist/tools/session-tools.d.ts.map +1 -1
- package/dist/tools/session-tools.js +33 -16
- package/dist/tools/session-tools.js.map +1 -1
- package/dist/tools/sessions-state-processor.js +2 -2
- package/dist/tools/sessions-state-processor.js.map +1 -1
- package/dist/tools/side-sessions.d.ts +1 -1
- package/dist/tools/side-sessions.d.ts.map +1 -1
- package/dist/tools/side-sessions.js +1 -1
- package/dist/tools/side-sessions.js.map +1 -1
- package/dist/workspace.d.ts +5 -2
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +28 -15
- package/dist/workspace.js.map +1 -1
- package/package.json +13 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","names":["#migrateValue","#db"],"sources":["../../../../src/storage/domains/integrations/base.ts"],"sourcesContent":["/**\n * Generic integration storage — the default persistence surface for\n * `FactoryIntegration`s.\n *\n * Most integrations persist the same three shapes: an org-owned OAuth\n * **connection**, **subscriptions** binding external objects to\n * sessions/threads, and per-`(org, user)` **settings**. This built-in domain\n * stores all three in shared collections keyed by `integration_id`, so an\n * integration author writes zero schema, zero DDL, and zero queries — and\n * org scoping is enforced by construction through the pre-scoped handle\n * returned by {@link IntegrationStorage.forIntegration}.\n *\n * Source-control integrations additionally use the shared, provider-scoped\n * source-control domain for installations, projects, and sessions.\n *\n * Payloads (`data` / `config`) are JSON documents typed per-integration via\n * the handle's generics. JSON round-trips exactly what JSON can represent:\n * store timestamps inside payloads as epoch millis or ISO strings, not\n * `Date`s.\n */\n\nimport { FactoryStorageDomain, UniqueViolationError } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\nimport { createPlaintextFactorySecretEncryption } from '../../../secret-encryption.js';\nimport type { FactorySecretEncryption } from '../../../secret-encryption.js';\n\nexport const INTEGRATION_CONNECTIONS_SCHEMA: CollectionSchema = {\n name: 'integration_connections',\n columns: {\n id: { type: 'uuid-pk' },\n integration_id: { type: 'text' },\n org_id: { type: 'text' },\n /** Who connected it (audit only — never scopes reads). */\n user_id: { type: 'text', nullable: true },\n data: { type: 'json' },\n metadata: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [{ name: 'integration_connections_integration_org_unique', columns: ['integration_id', 'org_id'] }],\n};\n\nexport const INTEGRATION_SUBSCRIPTIONS_SCHEMA: CollectionSchema = {\n name: 'integration_subscriptions',\n columns: {\n id: { type: 'uuid-pk' },\n integration_id: { type: 'text' },\n org_id: { type: 'text' },\n /** Canonical external-object key the integration derives (e.g. `pr:{installation}:{repo}:{number}`). */\n target_key: { type: 'text' },\n session_id: { type: 'text', nullable: true },\n resource_id: { type: 'text', nullable: true },\n thread_id: { type: 'text', nullable: true },\n session_scope: { type: 'text', nullable: true },\n status: { type: 'text' },\n data: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n indexes: [\n { name: 'integration_subscriptions_target_idx', columns: ['integration_id', 'target_key'] },\n { name: 'integration_subscriptions_org_idx', columns: ['integration_id', 'org_id'] },\n ],\n};\n\nexport const INTEGRATION_SETTINGS_SCHEMA: CollectionSchema = {\n name: 'integration_settings',\n columns: {\n id: { type: 'uuid-pk' },\n integration_id: { type: 'text' },\n org_id: { type: 'text' },\n user_id: { type: 'text' },\n config: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n { name: 'integration_settings_integration_org_user_unique', columns: ['integration_id', 'org_id', 'user_id'] },\n ],\n};\n\n/** An integration's org-owned connection (typically the OAuth grant). */\nexport interface IntegrationConnection<TData> {\n id: string;\n orgId: string;\n /** Who connected it (audit only). */\n userId: string | null;\n data: TData;\n metadata: Record<string, unknown>;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/** A subscription binding an external object to a session/thread. */\nexport interface IntegrationSubscription<TData> {\n id: string;\n orgId: string;\n targetKey: string;\n sessionId: string | null;\n resourceId: string | null;\n threadId: string | null;\n sessionScope: string | null;\n status: string;\n data: TData;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport type CreateIntegrationSubscriptionInput<TData> = {\n orgId: string;\n targetKey: string;\n sessionId?: string | null;\n resourceId?: string | null;\n threadId?: string | null;\n sessionScope?: string | null;\n /** Defaults to `'active'`. */\n status?: string;\n} & ({} extends TData ? { data?: TData } : { data: TData });\n\n/**\n * Typed query surface pre-scoped to one `integration_id`. Every read and\n * write is automatically filtered/stamped with the integration id, so an\n * integration cannot reach another integration's rows.\n */\nexport interface IntegrationStorageHandle<\n TConnection = Record<string, unknown>,\n TSettings = Record<string, unknown>,\n TSubscription = Record<string, unknown>,\n> {\n readonly integrationId: string;\n connections: {\n /** The org's connection, or `null` when not connected. */\n get(orgId: string): Promise<IntegrationConnection<TConnection> | null>;\n /** Insert or replace the org's connection (one per org; `created_at` preserved on update). */\n upsert(\n orgId: string,\n input: { userId?: string | null; data: TConnection; metadata?: Record<string, unknown> },\n ): Promise<void>;\n /**\n * Atomic read-modify-write of the connection's `data` payload (token\n * rotation etc.). Returns the updated connection, or `null` when the org\n * has no connection.\n */\n update(orgId: string, fn: (data: TConnection) => TConnection): Promise<IntegrationConnection<TConnection> | null>;\n /** Remove the org's connection. Returns whether a row was deleted. */\n delete(orgId: string): Promise<boolean>;\n };\n subscriptions: {\n create(input: CreateIntegrationSubscriptionInput<TSubscription>): Promise<IntegrationSubscription<TSubscription>>;\n /** All subscriptions for an external object (webhook fan-out), optionally filtered by status. */\n listByTarget(targetKey: string, opts?: { status?: string }): Promise<IntegrationSubscription<TSubscription>[]>;\n listBySession(sessionId: string): Promise<IntegrationSubscription<TSubscription>[]>;\n listByThread(resourceId: string, threadId: string): Promise<IntegrationSubscription<TSubscription>[]>;\n updateStatus(id: string, status: string): Promise<void>;\n delete(id: string): Promise<boolean>;\n /** Targeted cleanup, always org-scoped. Returns the number of rows deleted. */\n deleteWhere(where: { orgId: string; targetKey?: string; sessionId?: string }): Promise<number>;\n };\n settings: {\n /** The `(org, user)` config, or `null` when never saved. */\n get(orgId: string, userId: string): Promise<TSettings | null>;\n /** Upsert the `(org, user)` config (`created_at` preserved on update). */\n save(orgId: string, userId: string, config: TSettings): Promise<void>;\n };\n}\n\ninterface ConnectionRow extends Record<string, unknown> {\n id: string;\n integration_id: string;\n org_id: string;\n user_id: string | null;\n data: unknown;\n metadata: Record<string, unknown>;\n created_at: Date;\n updated_at: Date;\n}\n\ninterface SubscriptionRow extends Record<string, unknown> {\n id: string;\n integration_id: string;\n org_id: string;\n target_key: string;\n session_id: string | null;\n resource_id: string | null;\n thread_id: string | null;\n session_scope: string | null;\n status: string;\n data: unknown;\n created_at: Date;\n updated_at: Date;\n}\n\n/**\n * The built-in generic integration domain, written once against the\n * `FactoryStorageOps` surface — works on any `FactoryStorage` backend.\n */\nexport class IntegrationStorage extends FactoryStorageDomain {\n constructor(private readonly encryption: FactorySecretEncryption = createPlaintextFactorySecretEncryption()) {\n super('integrations');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([\n INTEGRATION_CONNECTIONS_SCHEMA,\n INTEGRATION_SUBSCRIPTIONS_SCHEMA,\n INTEGRATION_SETTINGS_SCHEMA,\n ]);\n const [connections, settings] = await Promise.all([\n this.ops.findMany<ConnectionRow>('integration_connections', {}),\n this.ops.findMany<{ id: string; config: unknown }>('integration_settings', {}),\n ]);\n await Promise.all([\n ...connections.map(row => this.#migrateValue('integration_connections', row.id, 'data')),\n ...settings.map(row => this.#migrateValue('integration_settings', row.id, 'config')),\n ]);\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('integration_subscriptions', {});\n await this.ops.deleteMany('integration_settings', {});\n await this.ops.deleteMany('integration_connections', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n async #migrateValue(collection: string, id: string, column: 'data' | 'config'): Promise<void> {\n await this.#db.updateAtomic<Record<string, unknown>>(collection, { id }, async row => {\n const decrypted = await this.encryption.decrypt(row[column]);\n return decrypted.needsReencryption ? { [column]: await this.encryption.encrypt(decrypted.value) } : null;\n });\n }\n\n /** A typed handle pre-scoped to `integrationId`. */\n forIntegration<\n TConnection = Record<string, unknown>,\n TSettings = Record<string, unknown>,\n TSubscription = Record<string, unknown>,\n >(integrationId: string): IntegrationStorageHandle<TConnection, TSettings, TSubscription> {\n if (!integrationId) throw new Error('[IntegrationStorage] integrationId is required.');\n const db = () => this.#db;\n const scoped = { integration_id: integrationId };\n\n const mapConnection = async (row: ConnectionRow): Promise<IntegrationConnection<TConnection>> => ({\n id: row.id,\n orgId: row.org_id,\n userId: row.user_id,\n data: (await this.encryption.decrypt<TConnection>(row.data)).value,\n metadata: row.metadata ?? {},\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n });\n\n const mapSubscription = (row: SubscriptionRow): IntegrationSubscription<TSubscription> => ({\n id: row.id,\n orgId: row.org_id,\n targetKey: row.target_key,\n sessionId: row.session_id,\n resourceId: row.resource_id,\n threadId: row.thread_id,\n sessionScope: row.session_scope,\n status: row.status,\n data: row.data as TSubscription,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n });\n\n return {\n integrationId,\n connections: {\n get: async orgId => {\n const row = await db().findOne<ConnectionRow>('integration_connections', { ...scoped, org_id: orgId });\n return row ? mapConnection(row) : null;\n },\n upsert: async (orgId, input) => {\n const where = { ...scoped, org_id: orgId };\n const encrypted = await this.encryption.encrypt(input.data);\n const update = async () =>\n db().updateMany('integration_connections', where, {\n user_id: input.userId ?? null,\n data: encrypted,\n metadata: input.metadata ?? {},\n updated_at: new Date(),\n });\n\n let lastError: unknown;\n for (let attempt = 0; attempt < 2; attempt++) {\n if ((await update()) > 0) return;\n\n const now = new Date();\n try {\n await db().insertOne<ConnectionRow>('integration_connections', {\n ...where,\n user_id: input.userId ?? null,\n data: encrypted,\n metadata: input.metadata ?? {},\n created_at: now,\n updated_at: now,\n });\n return;\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n lastError = error;\n }\n }\n throw lastError;\n },\n update: async (orgId, fn) => {\n const row = await db().updateAtomic<ConnectionRow>(\n 'integration_connections',\n { ...scoped, org_id: orgId },\n async current => {\n const data = (await this.encryption.decrypt<TConnection>(current.data)).value;\n return { data: await this.encryption.encrypt(fn(data)), updated_at: new Date() };\n },\n );\n return row ? mapConnection(row) : null;\n },\n delete: async orgId => {\n const deleted = await db().deleteMany('integration_connections', { ...scoped, org_id: orgId });\n return deleted > 0;\n },\n },\n subscriptions: {\n create: async input => {\n const now = new Date();\n const row = await db().insertOne<SubscriptionRow>('integration_subscriptions', {\n ...scoped,\n org_id: input.orgId,\n target_key: input.targetKey,\n session_id: input.sessionId ?? null,\n resource_id: input.resourceId ?? null,\n thread_id: input.threadId ?? null,\n session_scope: input.sessionScope ?? null,\n status: input.status ?? 'active',\n data: input.data ?? {},\n created_at: now,\n updated_at: now,\n });\n return mapSubscription(row);\n },\n listByTarget: async (targetKey, opts) => {\n const rows = await db().findMany<SubscriptionRow>(\n 'integration_subscriptions',\n { ...scoped, target_key: targetKey, ...(opts?.status !== undefined ? { status: opts.status } : {}) },\n { orderBy: [['created_at', 'asc']] },\n );\n return rows.map(mapSubscription);\n },\n listBySession: async sessionId => {\n const rows = await db().findMany<SubscriptionRow>(\n 'integration_subscriptions',\n { ...scoped, session_id: sessionId },\n { orderBy: [['created_at', 'asc']] },\n );\n return rows.map(mapSubscription);\n },\n listByThread: async (resourceId, threadId) => {\n const rows = await db().findMany<SubscriptionRow>(\n 'integration_subscriptions',\n { ...scoped, resource_id: resourceId, thread_id: threadId },\n { orderBy: [['created_at', 'asc']] },\n );\n return rows.map(mapSubscription);\n },\n updateStatus: async (id, status) => {\n await db().updateMany('integration_subscriptions', { ...scoped, id }, { status, updated_at: new Date() });\n },\n delete: async id => {\n const deleted = await db().deleteMany('integration_subscriptions', { ...scoped, id });\n return deleted > 0;\n },\n deleteWhere: async where => {\n return db().deleteMany('integration_subscriptions', {\n ...scoped,\n org_id: where.orgId,\n ...(where.targetKey !== undefined ? { target_key: where.targetKey } : {}),\n ...(where.sessionId !== undefined ? { session_id: where.sessionId } : {}),\n });\n },\n },\n settings: {\n get: async (orgId, userId) => {\n const row = await db().findOne<{ config: unknown }>('integration_settings', {\n ...scoped,\n org_id: orgId,\n user_id: userId,\n });\n return row ? (await this.encryption.decrypt<TSettings>(row.config)).value : null;\n },\n save: async (orgId, userId, config) => {\n const where = { ...scoped, org_id: orgId, user_id: userId };\n const encrypted = await this.encryption.encrypt(config);\n const update = async () =>\n db().updateMany('integration_settings', where, {\n config: encrypted,\n updated_at: new Date(),\n });\n\n let lastError: unknown;\n for (let attempt = 0; attempt < 2; attempt++) {\n if ((await update()) > 0) return;\n\n const now = new Date();\n try {\n await db().insertOne('integration_settings', {\n ...where,\n config: encrypted,\n created_at: now,\n updated_at: now,\n });\n return;\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n lastError = error;\n }\n }\n throw lastError;\n },\n },\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base.js","names":[],"sources":["../../../../src/storage/domains/integrations/base.ts"],"sourcesContent":["/**\n * Generic integration storage — the default persistence surface for\n * `FactoryIntegration`s.\n *\n * Most integrations persist the same three shapes: an org-owned OAuth\n * **connection**, **subscriptions** binding external objects to\n * sessions/threads, and per-`(org, user)` **settings**. This built-in domain\n * stores all three in shared collections keyed by `integration_id`, so an\n * integration author writes zero schema, zero DDL, and zero queries — and\n * org scoping is enforced by construction through the pre-scoped handle\n * returned by {@link IntegrationStorage.forIntegration}.\n *\n * Source-control integrations additionally use the shared, provider-scoped\n * source-control domain for installations, projects, and sessions.\n *\n * Payloads (`data` / `config`) are JSON documents typed per-integration via\n * the handle's generics. JSON round-trips exactly what JSON can represent:\n * store timestamps inside payloads as epoch millis or ISO strings, not\n * `Date`s.\n */\n\nimport { FactoryStorageDomain, UniqueViolationError } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\nimport { createPlaintextFactorySecretEncryption } from '../../../secret-encryption.js';\nimport type { FactorySecretEncryption } from '../../../secret-encryption.js';\n\nexport const INTEGRATION_CONNECTIONS_SCHEMA: CollectionSchema = {\n name: 'integration_connections',\n columns: {\n id: { type: 'uuid-pk' },\n integration_id: { type: 'text' },\n org_id: { type: 'text' },\n /** Who connected it (audit only — never scopes reads). */\n user_id: { type: 'text', nullable: true },\n data: { type: 'json' },\n metadata: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [{ name: 'integration_connections_integration_org_unique', columns: ['integration_id', 'org_id'] }],\n};\n\nexport const INTEGRATION_SUBSCRIPTIONS_SCHEMA: CollectionSchema = {\n name: 'integration_subscriptions',\n columns: {\n id: { type: 'uuid-pk' },\n integration_id: { type: 'text' },\n org_id: { type: 'text' },\n /** Canonical external-object key the integration derives (e.g. `pr:{installation}:{repo}:{number}`). */\n target_key: { type: 'text' },\n session_id: { type: 'text', nullable: true },\n resource_id: { type: 'text', nullable: true },\n thread_id: { type: 'text', nullable: true },\n session_scope: { type: 'text', nullable: true },\n status: { type: 'text' },\n data: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n indexes: [\n { name: 'integration_subscriptions_target_idx', columns: ['integration_id', 'target_key'] },\n { name: 'integration_subscriptions_org_idx', columns: ['integration_id', 'org_id'] },\n ],\n};\n\nexport const INTEGRATION_SETTINGS_SCHEMA: CollectionSchema = {\n name: 'integration_settings',\n columns: {\n id: { type: 'uuid-pk' },\n integration_id: { type: 'text' },\n org_id: { type: 'text' },\n user_id: { type: 'text' },\n config: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [\n { name: 'integration_settings_integration_org_user_unique', columns: ['integration_id', 'org_id', 'user_id'] },\n ],\n};\n\n/** An integration's org-owned connection (typically the OAuth grant). */\nexport interface IntegrationConnection<TData> {\n id: string;\n orgId: string;\n /** Who connected it (audit only). */\n userId: string | null;\n data: TData;\n metadata: Record<string, unknown>;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/** A subscription binding an external object to a session/thread. */\nexport interface IntegrationSubscription<TData> {\n id: string;\n orgId: string;\n targetKey: string;\n sessionId: string | null;\n resourceId: string | null;\n threadId: string | null;\n sessionScope: string | null;\n status: string;\n data: TData;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport type CreateIntegrationSubscriptionInput<TData> = {\n orgId: string;\n targetKey: string;\n sessionId?: string | null;\n resourceId?: string | null;\n threadId?: string | null;\n sessionScope?: string | null;\n /** Defaults to `'active'`. */\n status?: string;\n} & ({} extends TData ? { data?: TData } : { data: TData });\n\n/**\n * Typed query surface pre-scoped to one `integration_id`. Every read and\n * write is automatically filtered/stamped with the integration id, so an\n * integration cannot reach another integration's rows.\n */\nexport interface IntegrationStorageHandle<\n TConnection = Record<string, unknown>,\n TSettings = Record<string, unknown>,\n TSubscription = Record<string, unknown>,\n> {\n readonly integrationId: string;\n connections: {\n /** The org's connection, or `null` when not connected. */\n get(orgId: string): Promise<IntegrationConnection<TConnection> | null>;\n /** Insert or replace the org's connection (one per org; `created_at` preserved on update). */\n upsert(\n orgId: string,\n input: { userId?: string | null; data: TConnection; metadata?: Record<string, unknown> },\n ): Promise<void>;\n /**\n * Atomic read-modify-write of the connection's `data` payload (token\n * rotation etc.). Returns the updated connection, or `null` when the org\n * has no connection.\n */\n update(orgId: string, fn: (data: TConnection) => TConnection): Promise<IntegrationConnection<TConnection> | null>;\n /** Remove the org's connection. Returns whether a row was deleted. */\n delete(orgId: string): Promise<boolean>;\n };\n subscriptions: {\n create(input: CreateIntegrationSubscriptionInput<TSubscription>): Promise<IntegrationSubscription<TSubscription>>;\n /** All subscriptions for an external object (webhook fan-out), optionally filtered by status. */\n listByTarget(targetKey: string, opts?: { status?: string }): Promise<IntegrationSubscription<TSubscription>[]>;\n listBySession(sessionId: string): Promise<IntegrationSubscription<TSubscription>[]>;\n listByThread(resourceId: string, threadId: string): Promise<IntegrationSubscription<TSubscription>[]>;\n updateStatus(id: string, status: string): Promise<void>;\n delete(id: string): Promise<boolean>;\n /** Targeted cleanup, always org-scoped. Returns the number of rows deleted. */\n deleteWhere(where: { orgId: string; targetKey?: string; sessionId?: string }): Promise<number>;\n };\n settings: {\n /** The `(org, user)` config, or `null` when never saved. */\n get(orgId: string, userId: string): Promise<TSettings | null>;\n /** Upsert the `(org, user)` config (`created_at` preserved on update). */\n save(orgId: string, userId: string, config: TSettings): Promise<void>;\n };\n}\n\ninterface ConnectionRow extends Record<string, unknown> {\n id: string;\n integration_id: string;\n org_id: string;\n user_id: string | null;\n data: unknown;\n metadata: Record<string, unknown>;\n created_at: Date;\n updated_at: Date;\n}\n\ninterface SubscriptionRow extends Record<string, unknown> {\n id: string;\n integration_id: string;\n org_id: string;\n target_key: string;\n session_id: string | null;\n resource_id: string | null;\n thread_id: string | null;\n session_scope: string | null;\n status: string;\n data: unknown;\n created_at: Date;\n updated_at: Date;\n}\n\n/**\n * The built-in generic integration domain, written once against the\n * `FactoryStorageOps` surface — works on any `FactoryStorage` backend.\n */\nexport class IntegrationStorage extends FactoryStorageDomain {\n constructor(private readonly encryption: FactorySecretEncryption = createPlaintextFactorySecretEncryption()) {\n super('integrations');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([\n INTEGRATION_CONNECTIONS_SCHEMA,\n INTEGRATION_SUBSCRIPTIONS_SCHEMA,\n INTEGRATION_SETTINGS_SCHEMA,\n ]);\n const [connections, settings] = await Promise.all([\n this.ops.findMany<ConnectionRow>('integration_connections', {}),\n this.ops.findMany<{ id: string; config: unknown }>('integration_settings', {}),\n ]);\n await Promise.all([\n ...connections.map(row => this.#migrateValue('integration_connections', row.id, 'data')),\n ...settings.map(row => this.#migrateValue('integration_settings', row.id, 'config')),\n ]);\n }\n\n /**\n * Move every subscription still recorded under `fromResourceId` onto\n * `toResourceId`, across integrations. A rerun finds nothing to move.\n */\n async moveSubscriptionsToResource(input: { fromResourceId: string; toResourceId: string }): Promise<number> {\n return this.ops.updateMany(\n 'integration_subscriptions',\n { resource_id: input.fromResourceId },\n { resource_id: input.toResourceId },\n );\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('integration_subscriptions', {});\n await this.ops.deleteMany('integration_settings', {});\n await this.ops.deleteMany('integration_connections', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n async #migrateValue(collection: string, id: string, column: 'data' | 'config'): Promise<void> {\n await this.#db.updateAtomic<Record<string, unknown>>(collection, { id }, async row => {\n const decrypted = await this.encryption.decrypt(row[column]);\n return decrypted.needsReencryption ? { [column]: await this.encryption.encrypt(decrypted.value) } : null;\n });\n }\n\n /** A typed handle pre-scoped to `integrationId`. */\n forIntegration<\n TConnection = Record<string, unknown>,\n TSettings = Record<string, unknown>,\n TSubscription = Record<string, unknown>,\n >(integrationId: string): IntegrationStorageHandle<TConnection, TSettings, TSubscription> {\n if (!integrationId) throw new Error('[IntegrationStorage] integrationId is required.');\n const db = () => this.#db;\n const scoped = { integration_id: integrationId };\n\n const mapConnection = async (row: ConnectionRow): Promise<IntegrationConnection<TConnection>> => ({\n id: row.id,\n orgId: row.org_id,\n userId: row.user_id,\n data: (await this.encryption.decrypt<TConnection>(row.data)).value,\n metadata: row.metadata ?? {},\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n });\n\n const mapSubscription = (row: SubscriptionRow): IntegrationSubscription<TSubscription> => ({\n id: row.id,\n orgId: row.org_id,\n targetKey: row.target_key,\n sessionId: row.session_id,\n resourceId: row.resource_id,\n threadId: row.thread_id,\n sessionScope: row.session_scope,\n status: row.status,\n data: row.data as TSubscription,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n });\n\n return {\n integrationId,\n connections: {\n get: async orgId => {\n const row = await db().findOne<ConnectionRow>('integration_connections', { ...scoped, org_id: orgId });\n return row ? mapConnection(row) : null;\n },\n upsert: async (orgId, input) => {\n const where = { ...scoped, org_id: orgId };\n const encrypted = await this.encryption.encrypt(input.data);\n const update = async () =>\n db().updateMany('integration_connections', where, {\n user_id: input.userId ?? null,\n data: encrypted,\n metadata: input.metadata ?? {},\n updated_at: new Date(),\n });\n\n let lastError: unknown;\n for (let attempt = 0; attempt < 2; attempt++) {\n if ((await update()) > 0) return;\n\n const now = new Date();\n try {\n await db().insertOne<ConnectionRow>('integration_connections', {\n ...where,\n user_id: input.userId ?? null,\n data: encrypted,\n metadata: input.metadata ?? {},\n created_at: now,\n updated_at: now,\n });\n return;\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n lastError = error;\n }\n }\n throw lastError;\n },\n update: async (orgId, fn) => {\n const row = await db().updateAtomic<ConnectionRow>(\n 'integration_connections',\n { ...scoped, org_id: orgId },\n async current => {\n const data = (await this.encryption.decrypt<TConnection>(current.data)).value;\n return { data: await this.encryption.encrypt(fn(data)), updated_at: new Date() };\n },\n );\n return row ? mapConnection(row) : null;\n },\n delete: async orgId => {\n const deleted = await db().deleteMany('integration_connections', { ...scoped, org_id: orgId });\n return deleted > 0;\n },\n },\n subscriptions: {\n create: async input => {\n const now = new Date();\n const row = await db().insertOne<SubscriptionRow>('integration_subscriptions', {\n ...scoped,\n org_id: input.orgId,\n target_key: input.targetKey,\n session_id: input.sessionId ?? null,\n resource_id: input.resourceId ?? null,\n thread_id: input.threadId ?? null,\n session_scope: input.sessionScope ?? null,\n status: input.status ?? 'active',\n data: input.data ?? {},\n created_at: now,\n updated_at: now,\n });\n return mapSubscription(row);\n },\n listByTarget: async (targetKey, opts) => {\n const rows = await db().findMany<SubscriptionRow>(\n 'integration_subscriptions',\n { ...scoped, target_key: targetKey, ...(opts?.status !== undefined ? { status: opts.status } : {}) },\n { orderBy: [['created_at', 'asc']] },\n );\n return rows.map(mapSubscription);\n },\n listBySession: async sessionId => {\n const rows = await db().findMany<SubscriptionRow>(\n 'integration_subscriptions',\n { ...scoped, session_id: sessionId },\n { orderBy: [['created_at', 'asc']] },\n );\n return rows.map(mapSubscription);\n },\n listByThread: async (resourceId, threadId) => {\n const rows = await db().findMany<SubscriptionRow>(\n 'integration_subscriptions',\n { ...scoped, resource_id: resourceId, thread_id: threadId },\n { orderBy: [['created_at', 'asc']] },\n );\n return rows.map(mapSubscription);\n },\n updateStatus: async (id, status) => {\n await db().updateMany('integration_subscriptions', { ...scoped, id }, { status, updated_at: new Date() });\n },\n delete: async id => {\n const deleted = await db().deleteMany('integration_subscriptions', { ...scoped, id });\n return deleted > 0;\n },\n deleteWhere: async where => {\n return db().deleteMany('integration_subscriptions', {\n ...scoped,\n org_id: where.orgId,\n ...(where.targetKey !== undefined ? { target_key: where.targetKey } : {}),\n ...(where.sessionId !== undefined ? { session_id: where.sessionId } : {}),\n });\n },\n },\n settings: {\n get: async (orgId, userId) => {\n const row = await db().findOne<{ config: unknown }>('integration_settings', {\n ...scoped,\n org_id: orgId,\n user_id: userId,\n });\n return row ? (await this.encryption.decrypt<TSettings>(row.config)).value : null;\n },\n save: async (orgId, userId, config) => {\n const where = { ...scoped, org_id: orgId, user_id: userId };\n const encrypted = await this.encryption.encrypt(config);\n const update = async () =>\n db().updateMany('integration_settings', where, {\n config: encrypted,\n updated_at: new Date(),\n });\n\n let lastError: unknown;\n for (let attempt = 0; attempt < 2; attempt++) {\n if ((await update()) > 0) return;\n\n const now = new Date();\n try {\n await db().insertOne('integration_settings', {\n ...where,\n config: encrypted,\n created_at: now,\n updated_at: now,\n });\n return;\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n lastError = error;\n }\n }\n throw lastError;\n },\n },\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","names":[
|
|
1
|
+
{"version":3,"file":"base.js","names":[],"sources":["../../../../src/storage/domains/memory-settings/base.ts"],"sourcesContent":["import { FactoryStorageDomain, UniqueViolationError } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\n/**\n * A user's persisted memory (observational-memory) configuration. The\n * DB-backed tenant counterpart of the local `settings.json` OM fields\n * (`observerModelOverride`, `reflectorModelOverride`, `omObservationThreshold`,\n * `omReflectionThreshold`, `omObserveAttachments`): one row per `(org, user)`,\n * every knob nullable so only explicitly-changed values are stored.\n */\nexport interface MemorySettingsRecord {\n orgId: string;\n userId: string;\n observerModelId: string | null;\n reflectorModelId: string | null;\n observationThreshold: number | null;\n reflectionThreshold: number | null;\n observeAttachments: 'auto' | boolean | null;\n createdAt: Date;\n updatedAt: Date;\n}\n\n/** Partial update — only the provided knobs are written. `null` resets a model role to auto. */\nexport interface MemorySettingsPatch {\n observerModelId?: string | null;\n reflectorModelId?: string | null;\n observationThreshold?: number;\n reflectionThreshold?: number;\n observeAttachments?: 'auto' | boolean;\n}\n\n/**\n * Sentinel `user_id` for a factory project's shared memory settings. Factory\n * runs are org-shared, so their OM configuration lives on the project — this\n * key reuses the same `(org, user)` table without a schema change. Real user\n * ids are WorkOS ids (`user_…`) or the `local` sentinel, so the prefix cannot\n * collide.\n */\nexport function factoryMemorySettingsUserId(factoryProjectId: string): string {\n return `factory-project:${factoryProjectId}`;\n}\n\nexport const MEMORY_SETTINGS_SCHEMA: CollectionSchema = {\n name: 'memory_settings',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n user_id: { type: 'text' },\n observer_model_id: { type: 'text', nullable: true },\n reflector_model_id: { type: 'text', nullable: true },\n observation_threshold: { type: 'integer', nullable: true },\n reflection_threshold: { type: 'integer', nullable: true },\n // 'auto' | true | false — json keeps the tri-state without string encoding.\n observe_attachments: { type: 'json', nullable: true },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [{ name: 'memory_settings_org_user_key', columns: ['org_id', 'user_id'] }],\n};\n\ninterface MemorySettingsDbRow extends Record<string, unknown> {\n id: string;\n org_id: string;\n user_id: string;\n observer_model_id: string | null;\n reflector_model_id: string | null;\n observation_threshold: number | null;\n reflection_threshold: number | null;\n observe_attachments: 'auto' | boolean | null;\n created_at: Date;\n updated_at: Date;\n}\n\nfunction toRecord(row: MemorySettingsDbRow): MemorySettingsRecord {\n return {\n orgId: row.org_id,\n userId: row.user_id,\n observerModelId: row.observer_model_id,\n reflectorModelId: row.reflector_model_id,\n observationThreshold: row.observation_threshold,\n reflectionThreshold: row.reflection_threshold,\n observeAttachments: row.observe_attachments,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nfunction patchToColumns(patch: MemorySettingsPatch): Partial<MemorySettingsDbRow> {\n const columns: Partial<MemorySettingsDbRow> = {};\n if (patch.observerModelId !== undefined) columns.observer_model_id = patch.observerModelId;\n if (patch.reflectorModelId !== undefined) columns.reflector_model_id = patch.reflectorModelId;\n if (patch.observationThreshold !== undefined) columns.observation_threshold = patch.observationThreshold;\n if (patch.reflectionThreshold !== undefined) columns.reflection_threshold = patch.reflectionThreshold;\n if (patch.observeAttachments !== undefined) columns.observe_attachments = patch.observeAttachments;\n return columns;\n}\n\nexport class MemorySettingsStorage extends FactoryStorageDomain {\n constructor() {\n super('memory-settings');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([MEMORY_SETTINGS_SCHEMA]);\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('memory_settings', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n async get({ orgId, userId }: { orgId: string; userId: string }): Promise<MemorySettingsRecord | null> {\n const row = await this.#db.findOne<MemorySettingsDbRow>('memory_settings', { org_id: orgId, user_id: userId });\n return row ? toRecord(row) : null;\n }\n\n /**\n * Upsert the user's row, writing only the knobs present in `patch`.\n * Concurrent first writes are resolved via the shared\n * insert-then-catch-unique-violation pattern (see `queue_health`).\n */\n async patch({\n orgId,\n userId,\n patch,\n }: {\n orgId: string;\n userId: string;\n patch: MemorySettingsPatch;\n }): Promise<MemorySettingsRecord> {\n const now = new Date();\n const updateExisting = () =>\n this.#db.updateAtomic<MemorySettingsDbRow>('memory_settings', { org_id: orgId, user_id: userId }, () => ({\n ...patchToColumns(patch),\n updated_at: now,\n }));\n\n const updated = await updateExisting();\n if (updated) return toRecord(updated);\n\n try {\n const row = await this.#db.insertOne<MemorySettingsDbRow>('memory_settings', {\n org_id: orgId,\n user_id: userId,\n observer_model_id: null,\n reflector_model_id: null,\n observation_threshold: null,\n reflection_threshold: null,\n observe_attachments: null,\n ...patchToColumns(patch),\n created_at: now,\n updated_at: now,\n });\n return toRecord(row);\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n // Lost the first-write race — apply the patch to the winning row.\n const row = await updateExisting();\n if (!row) throw error;\n return toRecord(row);\n }\n }\n}\n"],"mappings":";;;;;;;;;AAsCA,SAAgB,4BAA4B,kBAAkC;CAC5E,OAAO,mBAAmB;AAC5B;AAEA,MAAa,yBAA2C;CACtD,MAAM;CACN,SAAS;EACP,IAAI,EAAE,MAAM,UAAU;EACtB,QAAQ,EAAE,MAAM,OAAO;EACvB,SAAS,EAAE,MAAM,OAAO;EACxB,mBAAmB;GAAE,MAAM;GAAQ,UAAU;EAAK;EAClD,oBAAoB;GAAE,MAAM;GAAQ,UAAU;EAAK;EACnD,uBAAuB;GAAE,MAAM;GAAW,UAAU;EAAK;EACzD,sBAAsB;GAAE,MAAM;GAAW,UAAU;EAAK;EAExD,qBAAqB;GAAE,MAAM;GAAQ,UAAU;EAAK;EACpD,YAAY,EAAE,MAAM,YAAY;EAChC,YAAY,EAAE,MAAM,YAAY;CAClC;CACA,eAAe,CAAC;EAAE,MAAM;EAAgC,SAAS,CAAC,UAAU,SAAS;CAAE,CAAC;AAC1F;AAeA,SAAS,SAAS,KAAgD;CAChE,OAAO;EACL,OAAO,IAAI;EACX,QAAQ,IAAI;EACZ,iBAAiB,IAAI;EACrB,kBAAkB,IAAI;EACtB,sBAAsB,IAAI;EAC1B,qBAAqB,IAAI;EACzB,oBAAoB,IAAI;EACxB,WAAW,IAAI;EACf,WAAW,IAAI;CACjB;AACF;AAEA,SAAS,eAAe,OAA0D;CAChF,MAAM,UAAwC,CAAC;CAC/C,IAAI,MAAM,oBAAoB,KAAA,GAAW,QAAQ,oBAAoB,MAAM;CAC3E,IAAI,MAAM,qBAAqB,KAAA,GAAW,QAAQ,qBAAqB,MAAM;CAC7E,IAAI,MAAM,yBAAyB,KAAA,GAAW,QAAQ,wBAAwB,MAAM;CACpF,IAAI,MAAM,wBAAwB,KAAA,GAAW,QAAQ,uBAAuB,MAAM;CAClF,IAAI,MAAM,uBAAuB,KAAA,GAAW,QAAQ,sBAAsB,MAAM;CAChF,OAAO;AACT;AAEA,IAAa,wBAAb,cAA2C,qBAAqB;CAC9D,cAAc;EACZ,MAAM,iBAAiB;CACzB;CAEA,MAAM,OAAsB;EAC1B,MAAM,KAAK,kBAAkB,CAAC,sBAAsB,CAAC;CACvD;CAEA,MAAM,sBAAqC;EACzC,MAAM,KAAK,IAAI,WAAW,mBAAmB,CAAC,CAAC;CACjD;CAEA,IAAI,MAAyB;EAC3B,OAAO,KAAK;CACd;CAEA,MAAM,IAAI,EAAE,OAAO,UAAmF;EACpG,MAAM,MAAM,MAAM,KAAK,IAAI,QAA6B,mBAAmB;GAAE,QAAQ;GAAO,SAAS;EAAO,CAAC;EAC7G,OAAO,MAAM,SAAS,GAAG,IAAI;CAC/B;;;;;;CAOA,MAAM,MAAM,EACV,OACA,QACA,SAKgC;EAChC,MAAM,sBAAM,IAAI,KAAK;EACrB,MAAM,uBACJ,KAAK,IAAI,aAAkC,mBAAmB;GAAE,QAAQ;GAAO,SAAS;EAAO,UAAU;GACvG,GAAG,eAAe,KAAK;GACvB,YAAY;EACd,EAAE;EAEJ,MAAM,UAAU,MAAM,eAAe;EACrC,IAAI,SAAS,OAAO,SAAS,OAAO;EAEpC,IAAI;GAaF,OAAO,SAAS,MAZE,KAAK,IAAI,UAA+B,mBAAmB;IAC3E,QAAQ;IACR,SAAS;IACT,mBAAmB;IACnB,oBAAoB;IACpB,uBAAuB;IACvB,sBAAsB;IACtB,qBAAqB;IACrB,GAAG,eAAe,KAAK;IACvB,YAAY;IACZ,YAAY;GACd,CAAC,CACkB;EACrB,SAAS,OAAO;GACd,IAAI,EAAE,iBAAiB,uBAAuB,MAAM;GAEpD,MAAM,MAAM,MAAM,eAAe;GACjC,IAAI,CAAC,KAAK,MAAM;GAChB,OAAO,SAAS,GAAG;EACrB;CACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","names":[
|
|
1
|
+
{"version":3,"file":"base.js","names":[],"sources":["../../../../src/storage/domains/model-defaults/base.ts"],"sourcesContent":["import { FactoryStorageDomain, UniqueViolationError } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\nexport interface ModelDefaultRecord {\n orgId: string;\n userId: string;\n modelId: string;\n updatedAt: Date;\n}\n\nexport const USER_DEFAULT_MODELS_SCHEMA: CollectionSchema = {\n name: 'user_default_models',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n user_id: { type: 'text' },\n model_id: { type: 'text' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [{ name: 'user_default_models_org_user_key', columns: ['org_id', 'user_id'] }],\n};\n\ninterface ModelDefaultDbRow extends Record<string, unknown> {\n id: string;\n org_id: string;\n user_id: string;\n model_id: string;\n updated_at: Date;\n}\n\nfunction toRecord(row: ModelDefaultDbRow): ModelDefaultRecord {\n return {\n orgId: row.org_id,\n userId: row.user_id,\n modelId: row.model_id,\n updatedAt: row.updated_at,\n };\n}\n\nexport class ModelDefaultsStorage extends FactoryStorageDomain {\n constructor() {\n super('model-defaults');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([USER_DEFAULT_MODELS_SCHEMA]);\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('user_default_models', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n async get({ orgId, userId }: { orgId: string; userId: string }): Promise<ModelDefaultRecord | null> {\n const row = await this.#db.findOne<ModelDefaultDbRow>('user_default_models', {\n org_id: orgId,\n user_id: userId,\n });\n return row ? toRecord(row) : null;\n }\n\n async set({\n orgId,\n userId,\n modelId,\n }: {\n orgId: string;\n userId: string;\n modelId: string;\n }): Promise<ModelDefaultRecord> {\n const now = new Date();\n const values = { model_id: modelId, updated_at: now };\n const updateExisting = () =>\n this.#db.updateAtomic<ModelDefaultDbRow>('user_default_models', { org_id: orgId, user_id: userId }, () => values);\n\n const updated = await updateExisting();\n if (updated) return toRecord(updated);\n\n try {\n return toRecord(\n await this.#db.insertOne<ModelDefaultDbRow>('user_default_models', {\n org_id: orgId,\n user_id: userId,\n ...values,\n }),\n );\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n const row = await updateExisting();\n if (!row) throw error;\n return toRecord(row);\n }\n }\n\n async clear({ orgId, userId }: { orgId: string; userId: string }): Promise<boolean> {\n return (await this.#db.deleteMany('user_default_models', { org_id: orgId, user_id: userId })) > 0;\n }\n}\n"],"mappings":";;AAUA,MAAa,6BAA+C;CAC1D,MAAM;CACN,SAAS;EACP,IAAI,EAAE,MAAM,UAAU;EACtB,QAAQ,EAAE,MAAM,OAAO;EACvB,SAAS,EAAE,MAAM,OAAO;EACxB,UAAU,EAAE,MAAM,OAAO;EACzB,YAAY,EAAE,MAAM,YAAY;CAClC;CACA,eAAe,CAAC;EAAE,MAAM;EAAoC,SAAS,CAAC,UAAU,SAAS;CAAE,CAAC;AAC9F;AAUA,SAAS,SAAS,KAA4C;CAC5D,OAAO;EACL,OAAO,IAAI;EACX,QAAQ,IAAI;EACZ,SAAS,IAAI;EACb,WAAW,IAAI;CACjB;AACF;AAEA,IAAa,uBAAb,cAA0C,qBAAqB;CAC7D,cAAc;EACZ,MAAM,gBAAgB;CACxB;CAEA,MAAM,OAAsB;EAC1B,MAAM,KAAK,kBAAkB,CAAC,0BAA0B,CAAC;CAC3D;CAEA,MAAM,sBAAqC;EACzC,MAAM,KAAK,IAAI,WAAW,uBAAuB,CAAC,CAAC;CACrD;CAEA,IAAI,MAAyB;EAC3B,OAAO,KAAK;CACd;CAEA,MAAM,IAAI,EAAE,OAAO,UAAiF;EAClG,MAAM,MAAM,MAAM,KAAK,IAAI,QAA2B,uBAAuB;GAC3E,QAAQ;GACR,SAAS;EACX,CAAC;EACD,OAAO,MAAM,SAAS,GAAG,IAAI;CAC/B;CAEA,MAAM,IAAI,EACR,OACA,QACA,WAK8B;EAE9B,MAAM,SAAS;GAAE,UAAU;GAAS,4BAAY,IADhC,KACkC;EAAE;EACpD,MAAM,uBACJ,KAAK,IAAI,aAAgC,uBAAuB;GAAE,QAAQ;GAAO,SAAS;EAAO,SAAS,MAAM;EAElH,MAAM,UAAU,MAAM,eAAe;EACrC,IAAI,SAAS,OAAO,SAAS,OAAO;EAEpC,IAAI;GACF,OAAO,SACL,MAAM,KAAK,IAAI,UAA6B,uBAAuB;IACjE,QAAQ;IACR,SAAS;IACT,GAAG;GACL,CAAC,CACH;EACF,SAAS,OAAO;GACd,IAAI,EAAE,iBAAiB,uBAAuB,MAAM;GACpD,MAAM,MAAM,MAAM,eAAe;GACjC,IAAI,CAAC,KAAK,MAAM;GAChB,OAAO,SAAS,GAAG;EACrB;CACF;CAEA,MAAM,MAAM,EAAE,OAAO,UAA+D;EAClF,OAAQ,MAAM,KAAK,IAAI,WAAW,uBAAuB;GAAE,QAAQ;GAAO,SAAS;EAAO,CAAC,IAAK;CAClG;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","names":["#db"],"sources":["../../../../src/storage/domains/projects/base.ts"],"sourcesContent":["import { isThinkingLevelSetting } from '@mastra/code-sdk/thinking';\nimport type { ThinkingLevelSetting } from '@mastra/code-sdk/thinking';\nimport { FactoryStorageDomain } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\nexport const DEFAULT_BUILD_PUSH_DEBOUNCE_MINUTES = 10;\nexport const DEFAULT_FACTORY_THINKING_LEVEL: ThinkingLevelSetting = 'medium';\nexport const FACTORY_MODEL_SCOPES = ['factory', 'user', 'hybrid'] as const;\nexport type FactoryModelScope = (typeof FACTORY_MODEL_SCOPES)[number];\n/** The single credential scope one session or run resolves from; `hybrid` is never effective. */\nexport type EffectiveModelScope = Exclude<FactoryModelScope, 'hybrid'>;\n\n/**\n * Resolve the scope one context runs under. `hybrid` splits by context: work-item runs use the\n * Factory's model and credentials, interactive sessions use the session owner's.\n */\nexport function effectiveModelScope(scope: FactoryModelScope, context: 'run' | 'session'): EffectiveModelScope {\n if (scope === 'hybrid') return context === 'run' ? 'factory' : 'user';\n return scope;\n}\n\nexport interface FactoryProject {\n id: string;\n orgId: string;\n createdBy: string;\n name: string;\n description: string | null;\n /** Default model for sessions/runs started under this Factory (null = harness default). */\n defaultModelId: string | null;\n /**\n * Whose model and credentials sessions and runs use: the Factory's, the session owner's, or\n * `hybrid` (owner's for interactive sessions, the Factory's for work-item runs).\n */\n modelScope: FactoryModelScope;\n /** Thinking level for this Factory's sessions and runs that have not picked their own. */\n defaultThinkingLevel: ThinkingLevelSetting;\n /** Whether rules may start agent runs on their own; off, a run waits for approval on its card. */\n autoRunEnabled: boolean;\n /** Whether the Factory answers a run's plan itself instead of waiting for a person. */\n autoApprovePlans: boolean;\n /** Workspace root in the sandbox; linked repositories are checked out beneath it. */\n sandboxWorkingDirectory: string | null;\n /** Provider settings document validated by the configured FactorySandbox. Only keys the user set. */\n sandboxSettings: Record<string, unknown> | null;\n /** Command run once in the workspace root after every repository's own setup. */\n workspaceSetupCommand: string | null;\n /** Template id of the environment's current build, written by the build path. */\n activeTemplateId: string | null;\n /** Repository slug → commit the active template was built at. */\n activeTemplateHeads: Record<string, string> | null;\n /** Provider build id of the most recent build attempt; its status is read live from the provider. */\n lastBuildId: string | null;\n /** Repository slug → commit the most recent build attempt pinned, so its status can be read back. */\n lastBuildHeads: Record<string, string> | null;\n /** Fingerprint of the settings, repositories and setup commands the most recent build attempt used. */\n lastBuildInputs: string | null;\n /** When the most recent build attempt started, whatever triggered it. */\n lastBuildAttemptedAt: Date | null;\n /** When a push last started a build: the leading edge of the push debounce window. */\n lastPushBuildAt: Date | null;\n /**\n * A run's build-start lease lapsed, so a build it may have started is not\n * on record. Cleared once a run reconciles it with a provider that lists builds.\n */\n buildStartUncertain: boolean;\n /** Whether a push to an environment repository's default branch starts a build. */\n buildOnPushEnabled: boolean;\n /** Minutes after a push-triggered attempt during which further pushes do not build. */\n buildPushDebounceMinutes: number;\n /** Whether Review agents publish their test results as a commit check. Defaults to off. */\n reviewTestChecksEnabled: boolean;\n /** Whether Work items get an independent self-review before the change request opens. Defaults to off. */\n selfReviewEnabled: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateFactoryProjectInput {\n name: string;\n description?: string | null;\n defaultModelId?: string | null;\n modelScope?: FactoryModelScope;\n}\n\nexport interface UpdateFactoryProjectInput {\n name?: string;\n description?: string | null;\n defaultModelId?: string | null;\n modelScope?: FactoryModelScope;\n defaultThinkingLevel?: ThinkingLevelSetting;\n autoRunEnabled?: boolean;\n autoApprovePlans?: boolean;\n sandboxWorkingDirectory?: string | null;\n sandboxSettings?: Record<string, unknown> | null;\n workspaceSetupCommand?: string | null;\n activeTemplateId?: string | null;\n activeTemplateHeads?: Record<string, string> | null;\n lastBuildId?: string | null;\n lastBuildHeads?: Record<string, string> | null;\n lastBuildInputs?: string | null;\n lastBuildAttemptedAt?: Date | null;\n buildOnPushEnabled?: boolean;\n buildPushDebounceMinutes?: number;\n reviewTestChecksEnabled?: boolean;\n selfReviewEnabled?: boolean;\n}\n\nexport const FACTORY_PROJECTS_SCHEMA: CollectionSchema = {\n name: 'factory_projects',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n created_by: { type: 'text' },\n name: { type: 'text' },\n description: { type: 'text', nullable: true },\n default_model_id: { type: 'text', nullable: true },\n model_scope: { type: 'text', default: 'hybrid' },\n default_thinking_level: { type: 'text', default: DEFAULT_FACTORY_THINKING_LEVEL },\n // Deprecated: no longer read or written. Kept so existing databases need no\n // migration. Old rows may still hold `true`, so never read it to bring Slack\n // work items back. Drop it in a later migration.\n slack_work_items_enabled: { type: 'boolean', default: false },\n auto_run_enabled: { type: 'boolean', default: false },\n auto_approve_plans: { type: 'boolean', default: false },\n sandbox_working_directory: { type: 'text', nullable: true },\n sandbox_settings: { type: 'json', nullable: true },\n workspace_setup_command: { type: 'text', nullable: true },\n active_template_id: { type: 'text', nullable: true },\n active_template_heads: { type: 'json', nullable: true },\n last_build_id: { type: 'text', nullable: true },\n last_build_heads: { type: 'json', nullable: true },\n last_build_inputs: { type: 'text', nullable: true },\n last_build_attempted_at: { type: 'timestamp', nullable: true },\n last_push_build_at: { type: 'timestamp', nullable: true },\n build_start_uncertain: { type: 'boolean', default: false },\n build_start_claim: { type: 'text', nullable: true },\n build_start_claim_expires_at: { type: 'timestamp', nullable: true },\n build_on_push_enabled: { type: 'boolean', default: false },\n build_push_debounce_minutes: { type: 'integer', default: DEFAULT_BUILD_PUSH_DEBOUNCE_MINUTES },\n review_test_checks_enabled: { type: 'boolean', default: false },\n self_review_enabled: { type: 'boolean', default: false },\n /** Set once the source-control domain has backfilled repository positions and environment membership. */\n environment_backfilled_at: { type: 'timestamp', nullable: true },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n indexes: [{ name: 'factory_projects_org_updated_at_idx', columns: ['org_id', 'updated_at'] }],\n};\n\ninterface FactoryProjectDbRow extends Record<string, unknown> {\n id: string;\n org_id: string;\n created_by: string;\n name: string;\n description: string | null;\n default_model_id: string | null;\n model_scope: string;\n default_thinking_level: string | null;\n auto_run_enabled: boolean;\n auto_approve_plans: boolean;\n sandbox_working_directory: string | null;\n sandbox_settings: Record<string, unknown> | null;\n workspace_setup_command: string | null;\n active_template_id: string | null;\n active_template_heads: Record<string, string> | null;\n last_build_id: string | null;\n last_build_heads: Record<string, string> | null;\n last_build_inputs: string | null;\n last_build_attempted_at: Date | null;\n last_push_build_at: Date | null;\n build_start_uncertain: boolean | null;\n build_start_claim: string | null;\n build_start_claim_expires_at: Date | null;\n build_on_push_enabled: boolean | null;\n build_push_debounce_minutes: number | null;\n review_test_checks_enabled: boolean | null;\n self_review_enabled: boolean | null;\n environment_backfilled_at: Date | null;\n created_at: Date;\n updated_at: Date;\n}\n\nfunction toFactoryProject(row: FactoryProjectDbRow): FactoryProject {\n return {\n id: row.id,\n orgId: row.org_id,\n createdBy: row.created_by,\n name: row.name,\n description: row.description,\n defaultModelId: row.default_model_id,\n modelScope: row.model_scope === 'factory' || row.model_scope === 'user' ? row.model_scope : 'hybrid',\n defaultThinkingLevel: isThinkingLevelSetting(row.default_thinking_level)\n ? row.default_thinking_level\n : DEFAULT_FACTORY_THINKING_LEVEL,\n autoRunEnabled: row.auto_run_enabled,\n autoApprovePlans: row.auto_approve_plans ?? false,\n sandboxWorkingDirectory: row.sandbox_working_directory ?? null,\n sandboxSettings: row.sandbox_settings ?? null,\n workspaceSetupCommand: row.workspace_setup_command ?? null,\n activeTemplateId: row.active_template_id ?? null,\n activeTemplateHeads: row.active_template_heads ?? null,\n lastBuildId: row.last_build_id ?? null,\n lastBuildHeads: row.last_build_heads ?? null,\n lastBuildInputs: row.last_build_inputs ?? null,\n lastBuildAttemptedAt: row.last_build_attempted_at ?? null,\n lastPushBuildAt: row.last_push_build_at ?? null,\n buildStartUncertain: row.build_start_uncertain ?? false,\n buildOnPushEnabled: row.build_on_push_enabled ?? false,\n buildPushDebounceMinutes: row.build_push_debounce_minutes ?? DEFAULT_BUILD_PUSH_DEBOUNCE_MINUTES,\n reviewTestChecksEnabled: row.review_test_checks_enabled ?? false,\n selfReviewEnabled: row.self_review_enabled ?? false,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nexport class FactoryProjectsStorage extends FactoryStorageDomain {\n constructor() {\n super('projects');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([FACTORY_PROJECTS_SCHEMA]);\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('factory_projects', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n async create({\n orgId,\n userId,\n input,\n }: {\n orgId: string;\n userId: string;\n input: CreateFactoryProjectInput;\n }): Promise<FactoryProject> {\n const now = new Date();\n const row = await this.#db.insertOne<FactoryProjectDbRow>('factory_projects', {\n org_id: orgId,\n created_by: userId,\n name: input.name,\n description: input.description ?? null,\n default_model_id: input.defaultModelId ?? null,\n model_scope: input.modelScope ?? 'hybrid',\n auto_run_enabled: false,\n auto_approve_plans: false,\n created_at: now,\n updated_at: now,\n });\n return toFactoryProject(row);\n }\n\n async list({ orgId }: { orgId: string }): Promise<FactoryProject[]> {\n const rows = await this.#db.findMany<FactoryProjectDbRow>(\n 'factory_projects',\n { org_id: orgId },\n { orderBy: [['updated_at', 'desc']] },\n );\n return rows.map(toFactoryProject);\n }\n\n async listAll(): Promise<FactoryProject[]> {\n const rows = await this.#db.findMany<FactoryProjectDbRow>(\n 'factory_projects',\n {},\n { orderBy: [['updated_at', 'desc']] },\n );\n return rows.map(toFactoryProject);\n }\n\n async get({ orgId, id }: { orgId: string; id: string }): Promise<FactoryProject | null> {\n const row = await this.#db.findOne<FactoryProjectDbRow>('factory_projects', { org_id: orgId, id });\n return row ? toFactoryProject(row) : null;\n }\n\n async getById({ id }: { id: string }): Promise<FactoryProject | null> {\n const row = await this.#db.findOne<FactoryProjectDbRow>('factory_projects', { id });\n return row ? toFactoryProject(row) : null;\n }\n\n async update({\n orgId,\n id,\n input,\n }: {\n orgId: string;\n id: string;\n /** A function input runs in a transaction; writes through its `ops` commit or roll back with the project. */\n input:\n | UpdateFactoryProjectInput\n | ((current: FactoryProject, ops: FactoryStorageOps) => Promise<UpdateFactoryProjectInput | null>);\n }): Promise<FactoryProject | null> {\n const update = (ops: FactoryStorageOps) =>\n ops.updateAtomic<FactoryProjectDbRow>('factory_projects', { org_id: orgId, id }, async current => {\n const changes = typeof input === 'function' ? await input(toFactoryProject(current), ops) : input;\n if (changes === null) return null;\n return {\n ...(changes.name !== undefined ? { name: changes.name } : {}),\n ...(changes.description !== undefined ? { description: changes.description } : {}),\n ...(changes.defaultModelId !== undefined ? { default_model_id: changes.defaultModelId } : {}),\n ...(changes.modelScope !== undefined ? { model_scope: changes.modelScope } : {}),\n ...(changes.defaultThinkingLevel !== undefined\n ? { default_thinking_level: changes.defaultThinkingLevel }\n : {}),\n ...(changes.autoRunEnabled !== undefined ? { auto_run_enabled: changes.autoRunEnabled } : {}),\n ...(changes.autoApprovePlans !== undefined ? { auto_approve_plans: changes.autoApprovePlans } : {}),\n ...(changes.sandboxWorkingDirectory !== undefined\n ? { sandbox_working_directory: changes.sandboxWorkingDirectory }\n : {}),\n ...(changes.sandboxSettings !== undefined ? { sandbox_settings: changes.sandboxSettings } : {}),\n ...(changes.workspaceSetupCommand !== undefined\n ? { workspace_setup_command: changes.workspaceSetupCommand }\n : {}),\n ...(changes.activeTemplateId !== undefined ? { active_template_id: changes.activeTemplateId } : {}),\n ...(changes.activeTemplateHeads !== undefined ? { active_template_heads: changes.activeTemplateHeads } : {}),\n ...(changes.lastBuildId !== undefined ? { last_build_id: changes.lastBuildId } : {}),\n ...(changes.lastBuildHeads !== undefined ? { last_build_heads: changes.lastBuildHeads } : {}),\n ...(changes.lastBuildInputs !== undefined ? { last_build_inputs: changes.lastBuildInputs } : {}),\n ...(changes.lastBuildAttemptedAt !== undefined\n ? { last_build_attempted_at: changes.lastBuildAttemptedAt }\n : {}),\n ...(changes.buildOnPushEnabled !== undefined ? { build_on_push_enabled: changes.buildOnPushEnabled } : {}),\n ...(changes.buildPushDebounceMinutes !== undefined\n ? { build_push_debounce_minutes: changes.buildPushDebounceMinutes }\n : {}),\n ...(changes.reviewTestChecksEnabled !== undefined\n ? { review_test_checks_enabled: changes.reviewTestChecksEnabled }\n : {}),\n ...(changes.selfReviewEnabled !== undefined ? { self_review_enabled: changes.selfReviewEnabled } : {}),\n updated_at: new Date(),\n };\n });\n // LibSQL's standalone updateAtomic only serializes one client; a transaction\n // also protects a read-dependent update against other database connections.\n const row = typeof input === 'function' ? await this.storage.withTransaction(update) : await update(this.#db);\n return row ? toFactoryProject(row) : null;\n }\n\n /**\n * Leading-edge debounce for push-triggered builds: stamps\n * `last_push_build_at = now` and resolves true when no push started a build\n * within the last `debounceMinutes`, else writes nothing and resolves\n * false. Taken right before the provider start, so a push that skips\n * (another run starting, a build in progress) never closes the window. The read and the write run in one transaction, so two concurrent\n * webhooks never both win, even on different database connections.\n */\n async claimBuildAttempt({\n id,\n debounceMinutes,\n now = new Date(),\n }: {\n id: string;\n debounceMinutes: number;\n now?: Date;\n }): Promise<boolean> {\n let claimed = false;\n await this.storage.withTransaction(ops =>\n ops.updateAtomic<FactoryProjectDbRow>('factory_projects', { id }, current => {\n const last = current.last_push_build_at;\n if (last && now.getTime() - last.getTime() < debounceMinutes * 60_000) return null;\n claimed = true;\n return { last_push_build_at: now, updated_at: now };\n }),\n );\n return claimed;\n }\n\n /**\n * Takes the project's build-start lease for `token`. Every trigger (manual,\n * schedule, push) takes it before reading build state and holds it through\n * `builds.start` and recording the result, so two runs never both start a\n * build. `claimed` is false while another run holds an unexpired lease. The\n * holder renews the lease while it works (`renewBuildStart`), so a lease\n * only expires when its run died or stalled. Taking over an expired lease\n * marks the start uncertain (that run's build may have reached the provider\n * unrecorded), and the mark stays until a release resolves it; `uncertain`\n * reports it. Only the claim is transactional; provider calls run outside it.\n */\n async claimBuildStart({\n id,\n token,\n leaseMs,\n now = new Date(),\n }: {\n id: string;\n token: string;\n leaseMs: number;\n now?: Date;\n }): Promise<{ claimed: boolean; uncertain: boolean }> {\n const result = { claimed: false, uncertain: false };\n await this.storage.withTransaction(ops =>\n ops.updateAtomic<FactoryProjectDbRow>('factory_projects', { id }, current => {\n const expiresAt = current.build_start_claim_expires_at;\n if (current.build_start_claim && expiresAt && expiresAt.getTime() > now.getTime()) return null;\n result.claimed = true;\n result.uncertain = Boolean(current.build_start_claim) || current.build_start_uncertain === true;\n return {\n build_start_claim: token,\n build_start_claim_expires_at: new Date(now.getTime() + leaseMs),\n ...(result.uncertain ? { build_start_uncertain: true } : {}),\n updated_at: now,\n };\n }),\n );\n return result;\n }\n\n /**\n * Extends the build-start lease held by `token` to `now + leaseMs`. Resolves\n * false, writing nothing, when `token` no longer holds it.\n */\n async renewBuildStart({\n id,\n token,\n leaseMs,\n now = new Date(),\n }: {\n id: string;\n token: string;\n leaseMs: number;\n now?: Date;\n }): Promise<boolean> {\n let renewed = false;\n await this.storage.withTransaction(ops =>\n ops.updateAtomic<FactoryProjectDbRow>('factory_projects', { id }, current => {\n if (current.build_start_claim !== token) return null;\n renewed = true;\n return { build_start_claim_expires_at: new Date(now.getTime() + leaseMs), updated_at: now };\n }),\n );\n return renewed;\n }\n\n /**\n * Releases the build-start lease taken with `token` and writes `changes` in\n * the same transaction, but only while `token` still holds the lease. A run\n * whose lease expired and was taken by a newer run writes nothing, so it\n * never clears or overwrites that run's build. `resolved` clears an\n * uncertain start. Resolves false when skipped.\n */\n async releaseBuildStart({\n id,\n token,\n changes = {},\n resolved = false,\n now = new Date(),\n }: {\n id: string;\n token: string;\n resolved?: boolean;\n changes?: Pick<\n UpdateFactoryProjectInput,\n 'lastBuildId' | 'lastBuildHeads' | 'lastBuildInputs' | 'lastBuildAttemptedAt'\n >;\n now?: Date;\n }): Promise<boolean> {\n let released = false;\n await this.storage.withTransaction(ops =>\n ops.updateAtomic<FactoryProjectDbRow>('factory_projects', { id }, current => {\n if (current.build_start_claim !== token) return null;\n released = true;\n return {\n ...(changes.lastBuildId !== undefined ? { last_build_id: changes.lastBuildId } : {}),\n ...(changes.lastBuildHeads !== undefined ? { last_build_heads: changes.lastBuildHeads } : {}),\n ...(changes.lastBuildInputs !== undefined ? { last_build_inputs: changes.lastBuildInputs } : {}),\n ...(changes.lastBuildAttemptedAt !== undefined\n ? { last_build_attempted_at: changes.lastBuildAttemptedAt }\n : {}),\n ...(resolved ? { build_start_uncertain: false } : {}),\n build_start_claim: null,\n build_start_claim_expires_at: null,\n updated_at: now,\n };\n }),\n );\n return released;\n }\n\n /**\n * Pins the active template to a finished build, but only while that build is\n * still the project's last one. Overlapping runs (Build now during a push\n * build) can finish out of order; the write and the `last_build_id` check\n * run in one transaction so a stale run never overwrites a newer build's\n * pin. Resolves false when the pin was skipped.\n */\n async pinActiveTemplate({\n id,\n buildId,\n templateId,\n heads,\n now = new Date(),\n }: {\n id: string;\n buildId: string;\n templateId: string;\n heads: Record<string, string>;\n now?: Date;\n }): Promise<boolean> {\n let pinned = false;\n await this.storage.withTransaction(ops =>\n ops.updateAtomic<FactoryProjectDbRow>('factory_projects', { id }, current => {\n if (current.last_build_id !== buildId) return null;\n pinned = true;\n return { active_template_id: templateId, active_template_heads: heads, updated_at: now };\n }),\n );\n return pinned;\n }\n\n async delete({ orgId, id }: { orgId: string; id: string }): Promise<FactoryProject | null> {\n const project = await this.get({ orgId, id });\n if (!project) return null;\n const deleted = await this.#db.deleteMany('factory_projects', { org_id: orgId, id });\n return deleted > 0 ? project : null;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base.js","names":[],"sources":["../../../../src/storage/domains/projects/base.ts"],"sourcesContent":["import { isThinkingLevelSetting } from '@mastra/code-sdk/thinking';\nimport type { ThinkingLevelSetting } from '@mastra/code-sdk/thinking';\nimport { FactoryStorageDomain } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\nexport const DEFAULT_BUILD_PUSH_DEBOUNCE_MINUTES = 10;\nexport const DEFAULT_FACTORY_THINKING_LEVEL: ThinkingLevelSetting = 'medium';\nexport const FACTORY_MODEL_SCOPES = ['factory', 'user', 'hybrid'] as const;\nexport type FactoryModelScope = (typeof FACTORY_MODEL_SCOPES)[number];\n/** The single credential scope one session or run resolves from; `hybrid` is never effective. */\nexport type EffectiveModelScope = Exclude<FactoryModelScope, 'hybrid'>;\n\n/**\n * Resolve the scope one context runs under. `hybrid` splits by context: work-item runs use the\n * Factory's model and credentials, interactive sessions use the session owner's.\n */\nexport function effectiveModelScope(scope: FactoryModelScope, context: 'run' | 'session'): EffectiveModelScope {\n if (scope === 'hybrid') return context === 'run' ? 'factory' : 'user';\n return scope;\n}\n\nexport interface FactoryProject {\n id: string;\n orgId: string;\n createdBy: string;\n name: string;\n description: string | null;\n /** Default model for sessions/runs started under this Factory (null = harness default). */\n defaultModelId: string | null;\n /**\n * Whose model and credentials sessions and runs use: the Factory's, the session owner's, or\n * `hybrid` (owner's for interactive sessions, the Factory's for work-item runs).\n */\n modelScope: FactoryModelScope;\n /** Thinking level for this Factory's sessions and runs that have not picked their own. */\n defaultThinkingLevel: ThinkingLevelSetting;\n /** Whether rules may start agent runs on their own; off, a run waits for approval on its card. */\n autoRunEnabled: boolean;\n /** Whether the Factory answers a run's plan itself instead of waiting for a person. */\n autoApprovePlans: boolean;\n /** Workspace root in the sandbox; linked repositories are checked out beneath it. */\n sandboxWorkingDirectory: string | null;\n /** Provider settings document validated by the configured FactorySandbox. Only keys the user set. */\n sandboxSettings: Record<string, unknown> | null;\n /** Command run once in the workspace root after every repository's own setup. */\n workspaceSetupCommand: string | null;\n /** Template id of the environment's current build, written by the build path. */\n activeTemplateId: string | null;\n /** Repository slug → commit the active template was built at. */\n activeTemplateHeads: Record<string, string> | null;\n /** Provider build id of the most recent build attempt; its status is read live from the provider. */\n lastBuildId: string | null;\n /** Repository slug → commit the most recent build attempt pinned, so its status can be read back. */\n lastBuildHeads: Record<string, string> | null;\n /** Fingerprint of the settings, repositories and setup commands the most recent build attempt used. */\n lastBuildInputs: string | null;\n /** When the most recent build attempt started, whatever triggered it. */\n lastBuildAttemptedAt: Date | null;\n /** When a push last started a build: the leading edge of the push debounce window. */\n lastPushBuildAt: Date | null;\n /**\n * A run's build-start lease lapsed, so a build it may have started is not\n * on record. Cleared once a run reconciles it with a provider that lists builds.\n */\n buildStartUncertain: boolean;\n /** Whether a push to an environment repository's default branch starts a build. */\n buildOnPushEnabled: boolean;\n /** Minutes after a push-triggered attempt during which further pushes do not build. */\n buildPushDebounceMinutes: number;\n /** Whether Review agents publish their test results as a commit check. Defaults to off. */\n reviewTestChecksEnabled: boolean;\n /** Whether Work items get an independent self-review before the change request opens. Defaults to off. */\n selfReviewEnabled: boolean;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateFactoryProjectInput {\n name: string;\n description?: string | null;\n defaultModelId?: string | null;\n modelScope?: FactoryModelScope;\n}\n\nexport interface UpdateFactoryProjectInput {\n name?: string;\n description?: string | null;\n defaultModelId?: string | null;\n modelScope?: FactoryModelScope;\n defaultThinkingLevel?: ThinkingLevelSetting;\n autoRunEnabled?: boolean;\n autoApprovePlans?: boolean;\n sandboxWorkingDirectory?: string | null;\n sandboxSettings?: Record<string, unknown> | null;\n workspaceSetupCommand?: string | null;\n activeTemplateId?: string | null;\n activeTemplateHeads?: Record<string, string> | null;\n lastBuildId?: string | null;\n lastBuildHeads?: Record<string, string> | null;\n lastBuildInputs?: string | null;\n lastBuildAttemptedAt?: Date | null;\n buildOnPushEnabled?: boolean;\n buildPushDebounceMinutes?: number;\n reviewTestChecksEnabled?: boolean;\n selfReviewEnabled?: boolean;\n}\n\nexport const FACTORY_PROJECTS_SCHEMA: CollectionSchema = {\n name: 'factory_projects',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n created_by: { type: 'text' },\n name: { type: 'text' },\n description: { type: 'text', nullable: true },\n default_model_id: { type: 'text', nullable: true },\n model_scope: { type: 'text', default: 'hybrid' },\n default_thinking_level: { type: 'text', default: DEFAULT_FACTORY_THINKING_LEVEL },\n // Deprecated: no longer read or written. Kept so existing databases need no\n // migration. Old rows may still hold `true`, so never read it to bring Slack\n // work items back. Drop it in a later migration.\n slack_work_items_enabled: { type: 'boolean', default: false },\n auto_run_enabled: { type: 'boolean', default: false },\n auto_approve_plans: { type: 'boolean', default: false },\n sandbox_working_directory: { type: 'text', nullable: true },\n sandbox_settings: { type: 'json', nullable: true },\n workspace_setup_command: { type: 'text', nullable: true },\n active_template_id: { type: 'text', nullable: true },\n active_template_heads: { type: 'json', nullable: true },\n last_build_id: { type: 'text', nullable: true },\n last_build_heads: { type: 'json', nullable: true },\n last_build_inputs: { type: 'text', nullable: true },\n last_build_attempted_at: { type: 'timestamp', nullable: true },\n last_push_build_at: { type: 'timestamp', nullable: true },\n build_start_uncertain: { type: 'boolean', default: false },\n build_start_claim: { type: 'text', nullable: true },\n build_start_claim_expires_at: { type: 'timestamp', nullable: true },\n build_on_push_enabled: { type: 'boolean', default: false },\n build_push_debounce_minutes: { type: 'integer', default: DEFAULT_BUILD_PUSH_DEBOUNCE_MINUTES },\n review_test_checks_enabled: { type: 'boolean', default: false },\n self_review_enabled: { type: 'boolean', default: false },\n /** Set once the source-control domain has backfilled repository positions and environment membership. */\n environment_backfilled_at: { type: 'timestamp', nullable: true },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n indexes: [{ name: 'factory_projects_org_updated_at_idx', columns: ['org_id', 'updated_at'] }],\n};\n\ninterface FactoryProjectDbRow extends Record<string, unknown> {\n id: string;\n org_id: string;\n created_by: string;\n name: string;\n description: string | null;\n default_model_id: string | null;\n model_scope: string;\n default_thinking_level: string | null;\n auto_run_enabled: boolean;\n auto_approve_plans: boolean;\n sandbox_working_directory: string | null;\n sandbox_settings: Record<string, unknown> | null;\n workspace_setup_command: string | null;\n active_template_id: string | null;\n active_template_heads: Record<string, string> | null;\n last_build_id: string | null;\n last_build_heads: Record<string, string> | null;\n last_build_inputs: string | null;\n last_build_attempted_at: Date | null;\n last_push_build_at: Date | null;\n build_start_uncertain: boolean | null;\n build_start_claim: string | null;\n build_start_claim_expires_at: Date | null;\n build_on_push_enabled: boolean | null;\n build_push_debounce_minutes: number | null;\n review_test_checks_enabled: boolean | null;\n self_review_enabled: boolean | null;\n environment_backfilled_at: Date | null;\n created_at: Date;\n updated_at: Date;\n}\n\nfunction toFactoryProject(row: FactoryProjectDbRow): FactoryProject {\n return {\n id: row.id,\n orgId: row.org_id,\n createdBy: row.created_by,\n name: row.name,\n description: row.description,\n defaultModelId: row.default_model_id,\n modelScope: row.model_scope === 'factory' || row.model_scope === 'user' ? row.model_scope : 'hybrid',\n defaultThinkingLevel: isThinkingLevelSetting(row.default_thinking_level)\n ? row.default_thinking_level\n : DEFAULT_FACTORY_THINKING_LEVEL,\n autoRunEnabled: row.auto_run_enabled,\n autoApprovePlans: row.auto_approve_plans ?? false,\n sandboxWorkingDirectory: row.sandbox_working_directory ?? null,\n sandboxSettings: row.sandbox_settings ?? null,\n workspaceSetupCommand: row.workspace_setup_command ?? null,\n activeTemplateId: row.active_template_id ?? null,\n activeTemplateHeads: row.active_template_heads ?? null,\n lastBuildId: row.last_build_id ?? null,\n lastBuildHeads: row.last_build_heads ?? null,\n lastBuildInputs: row.last_build_inputs ?? null,\n lastBuildAttemptedAt: row.last_build_attempted_at ?? null,\n lastPushBuildAt: row.last_push_build_at ?? null,\n buildStartUncertain: row.build_start_uncertain ?? false,\n buildOnPushEnabled: row.build_on_push_enabled ?? false,\n buildPushDebounceMinutes: row.build_push_debounce_minutes ?? DEFAULT_BUILD_PUSH_DEBOUNCE_MINUTES,\n reviewTestChecksEnabled: row.review_test_checks_enabled ?? false,\n selfReviewEnabled: row.self_review_enabled ?? false,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nexport class FactoryProjectsStorage extends FactoryStorageDomain {\n constructor() {\n super('projects');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([FACTORY_PROJECTS_SCHEMA]);\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('factory_projects', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n async create({\n orgId,\n userId,\n input,\n }: {\n orgId: string;\n userId: string;\n input: CreateFactoryProjectInput;\n }): Promise<FactoryProject> {\n const now = new Date();\n const row = await this.#db.insertOne<FactoryProjectDbRow>('factory_projects', {\n org_id: orgId,\n created_by: userId,\n name: input.name,\n description: input.description ?? null,\n default_model_id: input.defaultModelId ?? null,\n model_scope: input.modelScope ?? 'hybrid',\n auto_run_enabled: false,\n auto_approve_plans: false,\n created_at: now,\n updated_at: now,\n });\n return toFactoryProject(row);\n }\n\n async list({ orgId }: { orgId: string }): Promise<FactoryProject[]> {\n const rows = await this.#db.findMany<FactoryProjectDbRow>(\n 'factory_projects',\n { org_id: orgId },\n { orderBy: [['updated_at', 'desc']] },\n );\n return rows.map(toFactoryProject);\n }\n\n async listAll(): Promise<FactoryProject[]> {\n const rows = await this.#db.findMany<FactoryProjectDbRow>(\n 'factory_projects',\n {},\n { orderBy: [['updated_at', 'desc']] },\n );\n return rows.map(toFactoryProject);\n }\n\n async get({ orgId, id }: { orgId: string; id: string }): Promise<FactoryProject | null> {\n const row = await this.#db.findOne<FactoryProjectDbRow>('factory_projects', { org_id: orgId, id });\n return row ? toFactoryProject(row) : null;\n }\n\n async getById({ id }: { id: string }): Promise<FactoryProject | null> {\n const row = await this.#db.findOne<FactoryProjectDbRow>('factory_projects', { id });\n return row ? toFactoryProject(row) : null;\n }\n\n async update({\n orgId,\n id,\n input,\n }: {\n orgId: string;\n id: string;\n /** A function input runs in a transaction; writes through its `ops` commit or roll back with the project. */\n input:\n | UpdateFactoryProjectInput\n | ((current: FactoryProject, ops: FactoryStorageOps) => Promise<UpdateFactoryProjectInput | null>);\n }): Promise<FactoryProject | null> {\n const update = (ops: FactoryStorageOps) =>\n ops.updateAtomic<FactoryProjectDbRow>('factory_projects', { org_id: orgId, id }, async current => {\n const changes = typeof input === 'function' ? await input(toFactoryProject(current), ops) : input;\n if (changes === null) return null;\n return {\n ...(changes.name !== undefined ? { name: changes.name } : {}),\n ...(changes.description !== undefined ? { description: changes.description } : {}),\n ...(changes.defaultModelId !== undefined ? { default_model_id: changes.defaultModelId } : {}),\n ...(changes.modelScope !== undefined ? { model_scope: changes.modelScope } : {}),\n ...(changes.defaultThinkingLevel !== undefined\n ? { default_thinking_level: changes.defaultThinkingLevel }\n : {}),\n ...(changes.autoRunEnabled !== undefined ? { auto_run_enabled: changes.autoRunEnabled } : {}),\n ...(changes.autoApprovePlans !== undefined ? { auto_approve_plans: changes.autoApprovePlans } : {}),\n ...(changes.sandboxWorkingDirectory !== undefined\n ? { sandbox_working_directory: changes.sandboxWorkingDirectory }\n : {}),\n ...(changes.sandboxSettings !== undefined ? { sandbox_settings: changes.sandboxSettings } : {}),\n ...(changes.workspaceSetupCommand !== undefined\n ? { workspace_setup_command: changes.workspaceSetupCommand }\n : {}),\n ...(changes.activeTemplateId !== undefined ? { active_template_id: changes.activeTemplateId } : {}),\n ...(changes.activeTemplateHeads !== undefined ? { active_template_heads: changes.activeTemplateHeads } : {}),\n ...(changes.lastBuildId !== undefined ? { last_build_id: changes.lastBuildId } : {}),\n ...(changes.lastBuildHeads !== undefined ? { last_build_heads: changes.lastBuildHeads } : {}),\n ...(changes.lastBuildInputs !== undefined ? { last_build_inputs: changes.lastBuildInputs } : {}),\n ...(changes.lastBuildAttemptedAt !== undefined\n ? { last_build_attempted_at: changes.lastBuildAttemptedAt }\n : {}),\n ...(changes.buildOnPushEnabled !== undefined ? { build_on_push_enabled: changes.buildOnPushEnabled } : {}),\n ...(changes.buildPushDebounceMinutes !== undefined\n ? { build_push_debounce_minutes: changes.buildPushDebounceMinutes }\n : {}),\n ...(changes.reviewTestChecksEnabled !== undefined\n ? { review_test_checks_enabled: changes.reviewTestChecksEnabled }\n : {}),\n ...(changes.selfReviewEnabled !== undefined ? { self_review_enabled: changes.selfReviewEnabled } : {}),\n updated_at: new Date(),\n };\n });\n // LibSQL's standalone updateAtomic only serializes one client; a transaction\n // also protects a read-dependent update against other database connections.\n const row = typeof input === 'function' ? await this.storage.withTransaction(update) : await update(this.#db);\n return row ? toFactoryProject(row) : null;\n }\n\n /**\n * Leading-edge debounce for push-triggered builds: stamps\n * `last_push_build_at = now` and resolves true when no push started a build\n * within the last `debounceMinutes`, else writes nothing and resolves\n * false. Taken right before the provider start, so a push that skips\n * (another run starting, a build in progress) never closes the window. The read and the write run in one transaction, so two concurrent\n * webhooks never both win, even on different database connections.\n */\n async claimBuildAttempt({\n id,\n debounceMinutes,\n now = new Date(),\n }: {\n id: string;\n debounceMinutes: number;\n now?: Date;\n }): Promise<boolean> {\n let claimed = false;\n await this.storage.withTransaction(ops =>\n ops.updateAtomic<FactoryProjectDbRow>('factory_projects', { id }, current => {\n const last = current.last_push_build_at;\n if (last && now.getTime() - last.getTime() < debounceMinutes * 60_000) return null;\n claimed = true;\n return { last_push_build_at: now, updated_at: now };\n }),\n );\n return claimed;\n }\n\n /**\n * Takes the project's build-start lease for `token`. Every trigger (manual,\n * schedule, push) takes it before reading build state and holds it through\n * `builds.start` and recording the result, so two runs never both start a\n * build. `claimed` is false while another run holds an unexpired lease. The\n * holder renews the lease while it works (`renewBuildStart`), so a lease\n * only expires when its run died or stalled. Taking over an expired lease\n * marks the start uncertain (that run's build may have reached the provider\n * unrecorded), and the mark stays until a release resolves it; `uncertain`\n * reports it. Only the claim is transactional; provider calls run outside it.\n */\n async claimBuildStart({\n id,\n token,\n leaseMs,\n now = new Date(),\n }: {\n id: string;\n token: string;\n leaseMs: number;\n now?: Date;\n }): Promise<{ claimed: boolean; uncertain: boolean }> {\n const result = { claimed: false, uncertain: false };\n await this.storage.withTransaction(ops =>\n ops.updateAtomic<FactoryProjectDbRow>('factory_projects', { id }, current => {\n const expiresAt = current.build_start_claim_expires_at;\n if (current.build_start_claim && expiresAt && expiresAt.getTime() > now.getTime()) return null;\n result.claimed = true;\n result.uncertain = Boolean(current.build_start_claim) || current.build_start_uncertain === true;\n return {\n build_start_claim: token,\n build_start_claim_expires_at: new Date(now.getTime() + leaseMs),\n ...(result.uncertain ? { build_start_uncertain: true } : {}),\n updated_at: now,\n };\n }),\n );\n return result;\n }\n\n /**\n * Extends the build-start lease held by `token` to `now + leaseMs`. Resolves\n * false, writing nothing, when `token` no longer holds it.\n */\n async renewBuildStart({\n id,\n token,\n leaseMs,\n now = new Date(),\n }: {\n id: string;\n token: string;\n leaseMs: number;\n now?: Date;\n }): Promise<boolean> {\n let renewed = false;\n await this.storage.withTransaction(ops =>\n ops.updateAtomic<FactoryProjectDbRow>('factory_projects', { id }, current => {\n if (current.build_start_claim !== token) return null;\n renewed = true;\n return { build_start_claim_expires_at: new Date(now.getTime() + leaseMs), updated_at: now };\n }),\n );\n return renewed;\n }\n\n /**\n * Releases the build-start lease taken with `token` and writes `changes` in\n * the same transaction, but only while `token` still holds the lease. A run\n * whose lease expired and was taken by a newer run writes nothing, so it\n * never clears or overwrites that run's build. `resolved` clears an\n * uncertain start. Resolves false when skipped.\n */\n async releaseBuildStart({\n id,\n token,\n changes = {},\n resolved = false,\n now = new Date(),\n }: {\n id: string;\n token: string;\n resolved?: boolean;\n changes?: Pick<\n UpdateFactoryProjectInput,\n 'lastBuildId' | 'lastBuildHeads' | 'lastBuildInputs' | 'lastBuildAttemptedAt'\n >;\n now?: Date;\n }): Promise<boolean> {\n let released = false;\n await this.storage.withTransaction(ops =>\n ops.updateAtomic<FactoryProjectDbRow>('factory_projects', { id }, current => {\n if (current.build_start_claim !== token) return null;\n released = true;\n return {\n ...(changes.lastBuildId !== undefined ? { last_build_id: changes.lastBuildId } : {}),\n ...(changes.lastBuildHeads !== undefined ? { last_build_heads: changes.lastBuildHeads } : {}),\n ...(changes.lastBuildInputs !== undefined ? { last_build_inputs: changes.lastBuildInputs } : {}),\n ...(changes.lastBuildAttemptedAt !== undefined\n ? { last_build_attempted_at: changes.lastBuildAttemptedAt }\n : {}),\n ...(resolved ? { build_start_uncertain: false } : {}),\n build_start_claim: null,\n build_start_claim_expires_at: null,\n updated_at: now,\n };\n }),\n );\n return released;\n }\n\n /**\n * Pins the active template to a finished build, but only while that build is\n * still the project's last one. Overlapping runs (Build now during a push\n * build) can finish out of order; the write and the `last_build_id` check\n * run in one transaction so a stale run never overwrites a newer build's\n * pin. Resolves false when the pin was skipped.\n */\n async pinActiveTemplate({\n id,\n buildId,\n templateId,\n heads,\n now = new Date(),\n }: {\n id: string;\n buildId: string;\n templateId: string;\n heads: Record<string, string>;\n now?: Date;\n }): Promise<boolean> {\n let pinned = false;\n await this.storage.withTransaction(ops =>\n ops.updateAtomic<FactoryProjectDbRow>('factory_projects', { id }, current => {\n if (current.last_build_id !== buildId) return null;\n pinned = true;\n return { active_template_id: templateId, active_template_heads: heads, updated_at: now };\n }),\n );\n return pinned;\n }\n\n async delete({ orgId, id }: { orgId: string; id: string }): Promise<FactoryProject | null> {\n const project = await this.get({ orgId, id });\n if (!project) return null;\n const deleted = await this.#db.deleteMany('factory_projects', { org_id: orgId, id });\n return deleted > 0 ? project : null;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","names":[
|
|
1
|
+
{"version":3,"file":"base.js","names":[],"sources":["../../../../src/storage/domains/queue-health/base.ts"],"sourcesContent":["/**\n * Queue-health threshold configuration domain: per-project age buckets for the\n * Factory Overview queue-health chart.\n *\n * Stored per `(org, github_project)` — each connected GitHub project gets its\n * own age thresholds so a fast-moving automated pipeline and a slow human one\n * can bucket \"how old is the work\" differently. `thresholdsSeconds` is an\n * ordered-ascending list of age boundaries in seconds: an item younger than\n * the first boundary is green, younger than the second amber, younger than the\n * third orange, and red otherwise. Seconds (not hours) so sub-minute buckets\n * are representable for fast automated flows.\n */\n\nimport { FactoryStorageDomain, UniqueViolationError } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\nexport interface QueueHealthConfig {\n /** Ordered-ascending age boundaries in seconds, e.g. `[14400, 86400, 259200]`. */\n thresholdsSeconds: number[];\n}\n\n/** Default: green <4h, amber <24h, orange <72h, red 72h+. */\nexport const DEFAULT_QUEUE_HEALTH_CONFIG: QueueHealthConfig = {\n thresholdsSeconds: [14400, 86400, 259200],\n};\n\n/**\n * Throw unless `thresholdsSeconds` is a non-empty ascending number list. A\n * descending config would silently invert bucket semantics, so validate at the\n * write boundary rather than trusting callers.\n */\nexport function assertValidThresholds(config: QueueHealthConfig): void {\n const t = config.thresholdsSeconds;\n if (!Array.isArray(t) || t.length === 0 || t.some(v => typeof v !== 'number' || !Number.isFinite(v))) {\n throw new Error('[QueueHealthStorage] thresholdsSeconds must be a non-empty array of finite numbers.');\n }\n for (let i = 1; i < t.length; i++) {\n if (t[i]! <= t[i - 1]!) {\n throw new Error('[QueueHealthStorage] thresholdsSeconds must be strictly ascending.');\n }\n }\n}\n\n/** Validate untrusted JSON into a `QueueHealthConfig`, or `null` when invalid. */\nexport function parseQueueHealthConfig(body: unknown): QueueHealthConfig | null {\n if (typeof body !== 'object' || body === null) return null;\n const config = body as { thresholdsSeconds?: unknown };\n if (!Array.isArray(config.thresholdsSeconds)) return null;\n try {\n assertValidThresholds(config as QueueHealthConfig);\n } catch {\n return null;\n }\n return { thresholdsSeconds: [...(config as QueueHealthConfig).thresholdsSeconds] };\n}\n\n/**\n * Return `config.thresholdsSeconds` when valid, else the default. Validation\n * lives at the `saveConfig` write boundary, but `getConfig` round-trips a\n * stored JSON row — a corrupted or hand-edited row (empty / non-ascending)\n * would otherwise reach the chart and invert bucket colors, so the read route\n * re-validates and falls back.\n */\nexport function thresholdsOrDefault(config: QueueHealthConfig): number[] {\n return parseQueueHealthConfig(config)?.thresholdsSeconds ?? DEFAULT_QUEUE_HEALTH_CONFIG.thresholdsSeconds;\n}\n\nexport const QUEUE_HEALTH_SETTINGS_SCHEMA: CollectionSchema = {\n name: 'queue_health_settings',\n columns: {\n id: { type: 'uuid-pk' },\n org_id: { type: 'text' },\n factory_project_id: { type: 'text' },\n config: { type: 'json' },\n created_at: { type: 'timestamp' },\n updated_at: { type: 'timestamp' },\n },\n uniqueIndexes: [{ name: 'queue_health_settings_org_project_unique', columns: ['org_id', 'factory_project_id'] }],\n};\n\n/**\n * Queue-health settings storage, written once against the generic\n * `FactoryStorageOps` surface — works on any `FactoryStorage` backend.\n */\nexport class QueueHealthStorage extends FactoryStorageDomain {\n constructor() {\n super('queue-health');\n }\n\n async init(): Promise<void> {\n await this.ensureCollections([QUEUE_HEALTH_SETTINGS_SCHEMA]);\n }\n\n async dangerouslyClearAll(): Promise<void> {\n await this.ops.deleteMany('queue_health_settings', {});\n }\n\n get #db(): FactoryStorageOps {\n return this.ops;\n }\n\n /** Read the project's queue-health config, falling back to {@link DEFAULT_QUEUE_HEALTH_CONFIG}. */\n async getConfig(orgId: string, factoryProjectId: string): Promise<QueueHealthConfig> {\n const row = await this.#db.findOne<{ config: unknown }>('queue_health_settings', {\n org_id: orgId,\n factory_project_id: factoryProjectId,\n });\n return structuredClone(parseQueueHealthConfig(row?.config) ?? DEFAULT_QUEUE_HEALTH_CONFIG);\n }\n\n /** Upsert the project's queue-health config (`created_at` is preserved on update). */\n async saveConfig(orgId: string, factoryProjectId: string, config: QueueHealthConfig): Promise<void> {\n assertValidThresholds(config);\n const where = { org_id: orgId, factory_project_id: factoryProjectId };\n const updateExisting = () =>\n this.#db.updateAtomic('queue_health_settings', where, () => ({ config, updated_at: new Date() }));\n if (await updateExisting()) return;\n\n const now = new Date();\n try {\n await this.#db.insertOne('queue_health_settings', { ...where, config, created_at: now, updated_at: now });\n } catch (error) {\n if (!(error instanceof UniqueViolationError)) throw error;\n // Lost the insert race — update the winning row under the backend's serialized write primitive.\n if (!(await updateExisting())) throw error;\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAsBA,MAAa,8BAAiD,EAC5D,mBAAmB;CAAC;CAAO;CAAO;AAAM,EAC1C;;;;;;AAOA,SAAgB,sBAAsB,QAAiC;CACrE,MAAM,IAAI,OAAO;CACjB,IAAI,CAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,WAAW,KAAK,EAAE,MAAK,MAAK,OAAO,MAAM,YAAY,CAAC,OAAO,SAAS,CAAC,CAAC,GACjG,MAAM,IAAI,MAAM,qFAAqF;CAEvG,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAC5B,IAAI,EAAE,MAAO,EAAE,IAAI,IACjB,MAAM,IAAI,MAAM,oEAAoE;AAG1F;;AAGA,SAAgB,uBAAuB,MAAyC;CAC9E,IAAI,OAAO,SAAS,YAAY,SAAS,MAAM,OAAO;CACtD,MAAM,SAAS;CACf,IAAI,CAAC,MAAM,QAAQ,OAAO,iBAAiB,GAAG,OAAO;CACrD,IAAI;EACF,sBAAsB,MAA2B;CACnD,QAAQ;EACN,OAAO;CACT;CACA,OAAO,EAAE,mBAAmB,CAAC,GAAI,OAA6B,iBAAiB,EAAE;AACnF;;;;;;;;AASA,SAAgB,oBAAoB,QAAqC;CACvE,OAAO,uBAAuB,MAAM,CAAC,EAAE,qBAAqB,4BAA4B;AAC1F;AAEA,MAAa,+BAAiD;CAC5D,MAAM;CACN,SAAS;EACP,IAAI,EAAE,MAAM,UAAU;EACtB,QAAQ,EAAE,MAAM,OAAO;EACvB,oBAAoB,EAAE,MAAM,OAAO;EACnC,QAAQ,EAAE,MAAM,OAAO;EACvB,YAAY,EAAE,MAAM,YAAY;EAChC,YAAY,EAAE,MAAM,YAAY;CAClC;CACA,eAAe,CAAC;EAAE,MAAM;EAA4C,SAAS,CAAC,UAAU,oBAAoB;CAAE,CAAC;AACjH;;;;;AAMA,IAAa,qBAAb,cAAwC,qBAAqB;CAC3D,cAAc;EACZ,MAAM,cAAc;CACtB;CAEA,MAAM,OAAsB;EAC1B,MAAM,KAAK,kBAAkB,CAAC,4BAA4B,CAAC;CAC7D;CAEA,MAAM,sBAAqC;EACzC,MAAM,KAAK,IAAI,WAAW,yBAAyB,CAAC,CAAC;CACvD;CAEA,IAAI,MAAyB;EAC3B,OAAO,KAAK;CACd;;CAGA,MAAM,UAAU,OAAe,kBAAsD;EACnF,MAAM,MAAM,MAAM,KAAK,IAAI,QAA6B,yBAAyB;GAC/E,QAAQ;GACR,oBAAoB;EACtB,CAAC;EACD,OAAO,gBAAgB,uBAAuB,KAAK,MAAM,KAAK,2BAA2B;CAC3F;;CAGA,MAAM,WAAW,OAAe,kBAA0B,QAA0C;EAClG,sBAAsB,MAAM;EAC5B,MAAM,QAAQ;GAAE,QAAQ;GAAO,oBAAoB;EAAiB;EACpE,MAAM,uBACJ,KAAK,IAAI,aAAa,yBAAyB,cAAc;GAAE;GAAQ,4BAAY,IAAI,KAAK;EAAE,EAAE;EAClG,IAAI,MAAM,eAAe,GAAG;EAE5B,MAAM,sBAAM,IAAI,KAAK;EACrB,IAAI;GACF,MAAM,KAAK,IAAI,UAAU,yBAAyB;IAAE,GAAG;IAAO;IAAQ,YAAY;IAAK,YAAY;GAAI,CAAC;EAC1G,SAAS,OAAO;GACd,IAAI,EAAE,iBAAiB,uBAAuB,MAAM;GAEpD,IAAI,CAAE,MAAM,eAAe,GAAI,MAAM;EACvC;CACF;AACF"}
|
|
@@ -374,6 +374,11 @@ export interface SourceControlStorageHandle {
|
|
|
374
374
|
sessionId: string;
|
|
375
375
|
muted: boolean;
|
|
376
376
|
}): Promise<void>;
|
|
377
|
+
/** Change who can see the session. Returns the updated row, or null when it does not exist. */
|
|
378
|
+
setVisibility(args: {
|
|
379
|
+
sessionId: string;
|
|
380
|
+
visibility: SourceControlSessionVisibility;
|
|
381
|
+
}): Promise<SourceControlSession | null>;
|
|
377
382
|
/** Keyed by the link (today's callers) or by the factory. */
|
|
378
383
|
getForBranch(args: SessionBranchKey): Promise<SourceControlSession | null>;
|
|
379
384
|
create(input: CreateSourceControlSessionInput): Promise<SourceControlSession>;
|
|
@@ -425,6 +430,20 @@ export interface SourceControlStorageHandle {
|
|
|
425
430
|
export declare class SourceControlStorage extends FactoryStorageDomain {
|
|
426
431
|
#private;
|
|
427
432
|
constructor();
|
|
433
|
+
/** Sessions, across providers and organizations, the memory-resource migration has not finished. */
|
|
434
|
+
listSessionsAwaitingResourceMigration(): Promise<SourceControlSession[]>;
|
|
435
|
+
/**
|
|
436
|
+
* Sessions, across providers and organizations, whose visibility startup has not yet checked against
|
|
437
|
+
* their memory resource. Only sessions already on their resource are returned; the rest wait for the
|
|
438
|
+
* resource migration.
|
|
439
|
+
*/
|
|
440
|
+
listSessionsAwaitingVisibilityCheck(): Promise<SourceControlSession[]>;
|
|
441
|
+
/** Record that a session's visibility was checked, making it private when `makePrivate`. */
|
|
442
|
+
markVisibilityChecked(sessionId: string, { makePrivate }: {
|
|
443
|
+
makePrivate: boolean;
|
|
444
|
+
}): Promise<void>;
|
|
445
|
+
/** Record that a session's threads are on their memory resource, so later starts skip it. */
|
|
446
|
+
markResourcesMigrated(sessionId: string): Promise<void>;
|
|
428
447
|
init(): Promise<void>;
|
|
429
448
|
/**
|
|
430
449
|
* Applies environment patches to a project's repository links through `ops`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/source-control/base.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/storage/domains/source-control/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -210,6 +210,14 @@ const SOURCE_CONTROL_SCHEMAS = [
|
|
|
210
210
|
type: "timestamp",
|
|
211
211
|
nullable: true
|
|
212
212
|
},
|
|
213
|
+
resources_migrated_at: {
|
|
214
|
+
type: "timestamp",
|
|
215
|
+
nullable: true
|
|
216
|
+
},
|
|
217
|
+
visibility_checked_at: {
|
|
218
|
+
type: "timestamp",
|
|
219
|
+
nullable: true
|
|
220
|
+
},
|
|
213
221
|
created_at: { type: "timestamp" },
|
|
214
222
|
updated_at: { type: "timestamp" }
|
|
215
223
|
},
|
|
@@ -386,6 +394,31 @@ var SourceControlStorage = class extends FactoryStorageDomain {
|
|
|
386
394
|
constructor() {
|
|
387
395
|
super("source-control");
|
|
388
396
|
}
|
|
397
|
+
/** Sessions, across providers and organizations, the memory-resource migration has not finished. */
|
|
398
|
+
async listSessionsAwaitingResourceMigration() {
|
|
399
|
+
return (await this.ops.findMany(SESSIONS, { resources_migrated_at: null })).map(toSession);
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Sessions, across providers and organizations, whose visibility startup has not yet checked against
|
|
403
|
+
* their memory resource. Only sessions already on their resource are returned; the rest wait for the
|
|
404
|
+
* resource migration.
|
|
405
|
+
*/
|
|
406
|
+
async listSessionsAwaitingVisibilityCheck() {
|
|
407
|
+
return (await this.ops.findMany(SESSIONS, { visibility_checked_at: null })).filter((row) => row.resources_migrated_at).map(toSession);
|
|
408
|
+
}
|
|
409
|
+
/** Record that a session's visibility was checked, making it private when `makePrivate`. */
|
|
410
|
+
async markVisibilityChecked(sessionId, { makePrivate }) {
|
|
411
|
+
const now = /* @__PURE__ */ new Date();
|
|
412
|
+
await this.ops.updateMany(SESSIONS, { session_id: sessionId }, makePrivate ? {
|
|
413
|
+
visibility: "private",
|
|
414
|
+
visibility_checked_at: now,
|
|
415
|
+
updated_at: now
|
|
416
|
+
} : { visibility_checked_at: now });
|
|
417
|
+
}
|
|
418
|
+
/** Record that a session's threads are on their memory resource, so later starts skip it. */
|
|
419
|
+
async markResourcesMigrated(sessionId) {
|
|
420
|
+
await this.ops.updateMany(SESSIONS, { session_id: sessionId }, { resources_migrated_at: /* @__PURE__ */ new Date() });
|
|
421
|
+
}
|
|
389
422
|
async init() {
|
|
390
423
|
await this.ensureCollections(SOURCE_CONTROL_SCHEMAS);
|
|
391
424
|
await this.#backfillEnvironment();
|
|
@@ -994,6 +1027,13 @@ var SourceControlStorage = class extends FactoryStorageDomain {
|
|
|
994
1027
|
updated_at: /* @__PURE__ */ new Date()
|
|
995
1028
|
}));
|
|
996
1029
|
},
|
|
1030
|
+
setVisibility: async ({ sessionId, visibility }) => {
|
|
1031
|
+
const row = await db().updateAtomic(SESSIONS, { session_id: sessionId }, () => ({
|
|
1032
|
+
visibility,
|
|
1033
|
+
updated_at: /* @__PURE__ */ new Date()
|
|
1034
|
+
}));
|
|
1035
|
+
return row ? toSession(row) : null;
|
|
1036
|
+
},
|
|
997
1037
|
getForBranch: async (args) => {
|
|
998
1038
|
if ("factoryProjectId" in args) {
|
|
999
1039
|
const row = await db().findOne(SESSIONS, {
|
|
@@ -1050,6 +1090,8 @@ var SourceControlStorage = class extends FactoryStorageDomain {
|
|
|
1050
1090
|
sandbox_workdir: null,
|
|
1051
1091
|
materialized_at: null,
|
|
1052
1092
|
first_message_at: null,
|
|
1093
|
+
resources_migrated_at: now,
|
|
1094
|
+
visibility_checked_at: now,
|
|
1053
1095
|
created_at: now,
|
|
1054
1096
|
updated_at: now
|
|
1055
1097
|
}));
|