@mastra/factory 0.23.0-alpha.9 → 0.23.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.
|
@@ -31,7 +31,7 @@ const FACTORY_PROJECTS_SCHEMA = {
|
|
|
31
31
|
},
|
|
32
32
|
model_scope: {
|
|
33
33
|
type: "text",
|
|
34
|
-
default: "
|
|
34
|
+
default: "hybrid"
|
|
35
35
|
},
|
|
36
36
|
slack_work_items_enabled: {
|
|
37
37
|
type: "boolean",
|
|
@@ -126,7 +126,7 @@ function toFactoryProject(row) {
|
|
|
126
126
|
name: row.name,
|
|
127
127
|
description: row.description,
|
|
128
128
|
defaultModelId: row.default_model_id,
|
|
129
|
-
modelScope: row.model_scope === "
|
|
129
|
+
modelScope: row.model_scope === "factory" || row.model_scope === "user" ? row.model_scope : "hybrid",
|
|
130
130
|
autoRunEnabled: row.auto_run_enabled,
|
|
131
131
|
autoApprovePlans: row.auto_approve_plans ?? false,
|
|
132
132
|
sandboxWorkingDirectory: row.sandbox_working_directory ?? null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","names":["#db"],"sources":["../../../../src/storage/domains/projects/base.ts"],"sourcesContent":["import { FactoryStorageDomain } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\nexport const DEFAULT_BUILD_PUSH_DEBOUNCE_MINUTES = 10;\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 /** 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 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 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}\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: 'factory' },\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 /** 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 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 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 === 'user' || row.model_scope === 'hybrid' ? row.model_scope : 'factory',\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 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.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 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":["#db"],"sources":["../../../../src/storage/domains/projects/base.ts"],"sourcesContent":["import { FactoryStorageDomain } from '@mastra/core/storage';\nimport type { CollectionSchema, FactoryStorageOps } from '@mastra/core/storage';\n\nexport const DEFAULT_BUILD_PUSH_DEBOUNCE_MINUTES = 10;\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 /** 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 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 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}\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 // 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 /** 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 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 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 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 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.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 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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/factory",
|
|
3
|
-
"version": "0.23.0
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Mastra Software Factory module: the server core behind the Mastra Software Factory — storage domains, integrations, and surfaces for agent-powered software delivery",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -58,10 +58,10 @@
|
|
|
58
58
|
"posthog-node": "^5.46.1",
|
|
59
59
|
"zod": "^4.6.4",
|
|
60
60
|
"@mastra/auth-studio": "1.3.9",
|
|
61
|
+
"@mastra/code-sdk": "1.14.0",
|
|
61
62
|
"@mastra/auth-workos": "1.6.6",
|
|
62
|
-
"@mastra/code-sdk": "1.14.0-alpha.9",
|
|
63
63
|
"@mastra/slack": "1.7.2",
|
|
64
|
-
"@mastra/core": "1.78.0
|
|
64
|
+
"@mastra/core": "1.78.0"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
67
|
"@types/node": "22.20.1",
|
|
@@ -70,12 +70,12 @@
|
|
|
70
70
|
"typescript": "^6.0.3",
|
|
71
71
|
"typescript-eslint": "^8.57.0",
|
|
72
72
|
"vitest": "4.1.11",
|
|
73
|
-
"@
|
|
74
|
-
"@mastra/
|
|
75
|
-
"@mastra/
|
|
76
|
-
"@
|
|
77
|
-
"@internal/
|
|
78
|
-
"@internal/
|
|
73
|
+
"@mastra/libsql": "1.26.2",
|
|
74
|
+
"@mastra/pg": "1.31.2",
|
|
75
|
+
"@mastra/server": "1.78.0",
|
|
76
|
+
"@internal/lint": "0.0.144",
|
|
77
|
+
"@internal/types-builder": "0.0.119",
|
|
78
|
+
"@internal/workspace": "0.0.16"
|
|
79
79
|
},
|
|
80
80
|
"engines": {
|
|
81
81
|
"node": ">=22.19.0"
|