@mastra/server 1.66.0-alpha.2 → 1.66.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/{api-schema-manifest-Cpw4nIVv.cjs → api-schema-manifest-ByH3iaGn.cjs} +2 -2
  2. package/dist/{api-schema-manifest-Cpw4nIVv.cjs.map → api-schema-manifest-ByH3iaGn.cjs.map} +1 -1
  3. package/dist/{api-schema-manifest-BkKHbFJi.js → api-schema-manifest-D8q7uq5S.js} +2 -2
  4. package/dist/{api-schema-manifest-BkKHbFJi.js.map → api-schema-manifest-D8q7uq5S.js.map} +1 -1
  5. package/dist/{dist-BmrsK_KX.cjs → dist-3A2vpk0A.cjs} +2 -2
  6. package/dist/{dist-BmrsK_KX.cjs.map → dist-3A2vpk0A.cjs.map} +1 -1
  7. package/dist/{dist-4Qm6OSPJ.js → dist-CPemc7JX.js} +2 -2
  8. package/dist/{dist-4Qm6OSPJ.js.map → dist-CPemc7JX.js.map} +1 -1
  9. package/dist/docs/SKILL.md +1 -1
  10. package/dist/docs/assets/SOURCE_MAP.json +1 -1
  11. package/dist/dynamic-workflows-Cn9MXevC.js.map +1 -1
  12. package/dist/dynamic-workflows-DSg9_yec.cjs.map +1 -1
  13. package/dist/{routes-Dgd2S9av.cjs → routes-CnUWgoC8.cjs} +6 -6
  14. package/dist/{routes-Dgd2S9av.cjs.map → routes-CnUWgoC8.cjs.map} +1 -1
  15. package/dist/{routes-DCwOOz84.js → routes-DoFMsPa7.js} +6 -6
  16. package/dist/{routes-DCwOOz84.js.map → routes-DoFMsPa7.js.map} +1 -1
  17. package/dist/schedules-BcEUUuX_.js.map +1 -1
  18. package/dist/schedules-fj9U0_tA.cjs.map +1 -1
  19. package/dist/server/handlers/agent-builder.cjs +1 -1
  20. package/dist/server/handlers/agent-builder.js +1 -1
  21. package/dist/server/handlers/authorship.cjs.map +1 -1
  22. package/dist/server/handlers/authorship.js.map +1 -1
  23. package/dist/server/handlers/mcp-client-versions.cjs +1 -1
  24. package/dist/server/handlers/mcp-client-versions.js +1 -1
  25. package/dist/server/handlers/mcp.cjs.map +1 -1
  26. package/dist/server/handlers/mcp.js.map +1 -1
  27. package/dist/server/handlers/prompt-block-versions.cjs +1 -1
  28. package/dist/server/handlers/prompt-block-versions.js +1 -1
  29. package/dist/server/handlers/scorer-versions.cjs +1 -1
  30. package/dist/server/handlers/scorer-versions.js +1 -1
  31. package/dist/server/handlers/stored-agents.cjs +2 -2
  32. package/dist/server/handlers/stored-agents.js +2 -2
  33. package/dist/server/handlers/stored-mcp-clients.cjs +1 -1
  34. package/dist/server/handlers/stored-mcp-clients.js +1 -1
  35. package/dist/server/handlers/stored-prompt-blocks.cjs +1 -1
  36. package/dist/server/handlers/stored-prompt-blocks.js +1 -1
  37. package/dist/server/handlers/stored-scorers.cjs +1 -1
  38. package/dist/server/handlers/stored-scorers.js +1 -1
  39. package/dist/server/handlers/stored-skill-favorites.cjs +1 -1
  40. package/dist/server/handlers/stored-skill-favorites.js +1 -1
  41. package/dist/server/handlers/stored-skills.cjs +1 -1
  42. package/dist/server/handlers/stored-skills.js +1 -1
  43. package/dist/server/handlers/system.cjs +1 -1
  44. package/dist/server/handlers/system.js +1 -1
  45. package/dist/server/schemas/index.cjs +1 -1
  46. package/dist/server/schemas/index.js +1 -1
  47. package/dist/server/server-adapter/index.cjs +1 -1
  48. package/dist/server/server-adapter/index.cjs.map +1 -1
  49. package/dist/server/server-adapter/index.js +1 -1
  50. package/dist/server/server-adapter/index.js.map +1 -1
  51. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"schedules-fj9U0_tA.cjs","names":["z","HTTPException","createRoute"],"sources":["../src/server/schemas/schedules.ts","../src/server/handlers/schedules.ts"],"sourcesContent":["import { z } from 'zod';\n\nexport const scheduleStatusSchema = z.enum(['active', 'paused']);\n\n/** Mirrors the core `AgentSignalType` union. */\nconst signalTypeSchema = z.enum(['user', 'state', 'reactive', 'notification', 'user-message', 'system-reminder']);\n\n/** Attributes rendered onto the signal's XML tag. */\nconst signalAttributesSchema = z.record(\n z.string(),\n z.union([z.string(), z.number(), z.boolean(), z.null()]).optional(),\n);\n\n/** Behavior + attributes applied when the thread is already streaming. */\nconst ifActiveSchema = z.object({\n behavior: z.enum(['deliver', 'persist', 'discard']).optional(),\n attributes: signalAttributesSchema.optional(),\n});\n\n/**\n * Behavior + attributes applied when the thread is idle, plus a serializable\n * subset of stream options forwarded to the woken run.\n */\nconst ifIdleSchema = z.object({\n behavior: z.enum(['wake', 'persist', 'discard']).optional(),\n attributes: signalAttributesSchema.optional(),\n streamOptions: z\n .object({\n requestContext: z.record(z.string(), z.unknown()).optional(),\n })\n .optional(),\n});\n\nexport const workflowRunStatusSchema = z.enum([\n 'running',\n 'success',\n 'failed',\n 'tripwire',\n 'suspended',\n 'waiting',\n 'pending',\n 'canceled',\n 'bailed',\n 'paused',\n 'skipped',\n]);\n\nexport const scheduleRunSummarySchema = z.object({\n status: workflowRunStatusSchema,\n startedAt: z.number().optional(),\n completedAt: z.number().optional(),\n durationMs: z.number().optional(),\n error: z.string().optional(),\n});\n\n/**\n * Flat agent-schedule view. Persisted as a `Schedule` row with a\n * `target.type === 'agent'` variant; the HTTP surface flattens that\n * representation to the fields a user cares about (cron, prompt, threading,\n * status, lifecycle) without exposing the schedule plumbing. Discriminate\n * from workflow schedules by the presence of `agentId`.\n */\nexport const agentScheduleSchema = z.object({\n id: z.string(),\n agentId: z.string(),\n /** Mirror of the workflow-schedule discriminator — always absent on agent schedules. */\n workflowId: z.undefined().optional(),\n /** Workflow-run summary — never hydrated for agent schedules. */\n lastRun: z.undefined().optional(),\n name: z.string().optional(),\n threadId: z.string().optional(),\n resourceId: z.string().optional(),\n prompt: z.string(),\n cron: z.string(),\n timezone: z.string().optional(),\n status: scheduleStatusSchema,\n nextFireAt: z.number(),\n lastFireAt: z.number().optional(),\n lastRunId: z.string().optional(),\n signalType: signalTypeSchema.optional(),\n tagName: z.string().optional(),\n attributes: signalAttributesSchema.optional(),\n ifActive: ifActiveSchema.optional(),\n ifIdle: ifIdleSchema.optional(),\n providerOptions: z.record(z.string(), z.unknown()).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n});\n\n/**\n * Flat workflow-schedule view. Discriminate from agent schedules by the\n * presence of `workflowId`.\n */\nexport const workflowScheduleSchema = z.object({\n id: z.string(),\n workflowId: z.string(),\n /** Mirror of the agent-schedule discriminator — always absent on workflow schedules. */\n agentId: z.undefined().optional(),\n cron: z.string(),\n timezone: z.string().optional(),\n status: scheduleStatusSchema,\n nextFireAt: z.number(),\n lastFireAt: z.number().optional(),\n lastRunId: z.string().optional(),\n lastRun: scheduleRunSummarySchema.optional(),\n inputData: z.unknown().optional(),\n initialState: z.unknown().optional(),\n requestContext: z.record(z.string(), z.unknown()).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n});\n\n/** Union of the flat views returned by the unified `/schedules` surface. */\nexport const scheduleSchema = z.union([agentScheduleSchema, workflowScheduleSchema]);\n\nexport const scheduleTriggerOutcomeSchema = z.enum([\n 'published',\n 'succeeded',\n 'delivered',\n 'persisted',\n 'discarded',\n 'skipped',\n 'aborted',\n 'failed',\n // Legacy queue/notification outcomes — no longer written, but trigger rows\n // persisted by older builds may still carry them. Kept readable so the\n // response validator does not reject historical rows. Mirrors the core\n // ScheduleTriggerOutcome union.\n 'acked',\n 'alerted',\n 'deferred',\n 'appended-from-queue',\n 'dropped-stale',\n 'dropped-superseded',\n 'dropped-busy',\n]);\n\nexport const scheduleTriggerKindSchema = z.enum(['schedule-fire', 'queue-drain', 'manual']);\n\nexport const scheduleTriggerResponseSchema = z.object({\n id: z.string().optional(),\n scheduleId: z.string(),\n runId: z.string().nullable(),\n scheduledFireAt: z.number(),\n actualFireAt: z.number(),\n outcome: scheduleTriggerOutcomeSchema,\n error: z.string().optional(),\n triggerKind: scheduleTriggerKindSchema.optional(),\n parentTriggerId: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n run: scheduleRunSummarySchema.optional(),\n});\n\nexport const listSchedulesQuerySchema = z.object({\n agentId: z.string().optional(),\n workflowId: z.string().optional(),\n status: scheduleStatusSchema.optional(),\n /** Agent-schedule only: match the target threadId. */\n threadId: z.string().optional(),\n /** Agent-schedule only: match the target resourceId. */\n resourceId: z.string().optional(),\n /** Agent-schedule only: match the free-form target name. */\n name: z.string().optional(),\n});\n\nexport const listSchedulesResponseSchema = z.object({\n schedules: z.array(scheduleSchema),\n});\n\nexport const scheduleIdPathParams = z.object({\n scheduleId: z.string(),\n});\n\n/**\n * Agent variant of the create body — targets an agent by `agentId`. Strict so\n * a body carrying both `agentId` and `workflowId` is rejected as ambiguous\n * instead of silently matching the agent branch of the union.\n */\nconst createAgentScheduleBodySchema = z.strictObject({\n /** Optional stable id; normalized to `agent_<slug>`. A random id is generated when omitted. */\n id: z.string().optional(),\n agentId: z.string().min(1),\n cron: z.string(),\n timezone: z.string().optional(),\n prompt: z.string(),\n name: z.string().optional(),\n threadId: z.string().optional(),\n resourceId: z.string().optional(),\n signalType: signalTypeSchema.optional(),\n tagName: z.string().optional(),\n attributes: signalAttributesSchema.optional(),\n ifActive: ifActiveSchema.optional(),\n ifIdle: ifIdleSchema.optional(),\n providerOptions: z.record(z.string(), z.unknown()).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\n/**\n * Workflow variant of the create body — targets a workflow by `workflowId`.\n * Strict so ambiguous bodies (both ids) are rejected by the union.\n */\nconst createWorkflowScheduleBodySchema = z.strictObject({\n /** Optional stable id; normalized to `schedule_<slug>`. A random id is generated when omitted. */\n id: z.string().optional(),\n workflowId: z.string().min(1),\n cron: z.string(),\n timezone: z.string().optional(),\n inputData: z.unknown().optional(),\n initialState: z.unknown().optional(),\n requestContext: z.record(z.string(), z.unknown()).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\n/**\n * Body for POST /schedules. Discriminated by which target id is present:\n * `agentId` creates an agent schedule, `workflowId` a workflow schedule.\n * Both variants are strict, so a body carrying both ids (or unknown keys)\n * fails validation instead of silently dropping fields.\n */\nexport const createScheduleBodySchema = z.union([createAgentScheduleBodySchema, createWorkflowScheduleBodySchema]);\n\n/**\n * Body for PATCH /schedules/:scheduleId — partial update. Fields apply to\n * the matching target type; agent-only fields on a workflow schedule are\n * rejected by the service. `threadId` / `resourceId` are intentionally not\n * editable; they are part of an agent schedule's identity. To re-target,\n * delete and recreate.\n */\nexport const updateScheduleBodySchema = z.object({\n cron: z.string().optional(),\n timezone: z.string().optional(),\n status: scheduleStatusSchema.optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n // Agent-schedule fields\n prompt: z.string().optional(),\n name: z.string().optional(),\n signalType: signalTypeSchema.optional(),\n tagName: z.string().optional(),\n attributes: signalAttributesSchema.optional(),\n ifActive: ifActiveSchema.optional(),\n ifIdle: ifIdleSchema.optional(),\n providerOptions: z.record(z.string(), z.unknown()).optional(),\n // Workflow-schedule fields\n inputData: z.unknown().optional(),\n initialState: z.unknown().optional(),\n requestContext: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const deleteScheduleResponseSchema = z.object({\n message: z.string(),\n});\n\n/** Response for POST /schedules/:scheduleId/run. */\nexport const runScheduleResponseSchema = z.object({\n scheduleId: z.string(),\n claimId: z.string(),\n scheduledFireAt: z.number(),\n});\n\nexport const listScheduleTriggersQuerySchema = z.object({\n limit: z.coerce.number().int().positive().optional(),\n fromActualFireAt: z.coerce.number().int().nonnegative().optional(),\n toActualFireAt: z.coerce.number().int().nonnegative().optional(),\n});\n\nexport const listScheduleTriggersResponseSchema = z.object({\n triggers: z.array(scheduleTriggerResponseSchema),\n});\n\nexport type AgentScheduleResponse = z.infer<typeof agentScheduleSchema>;\nexport type WorkflowScheduleResponse = z.infer<typeof workflowScheduleSchema>;\nexport type ScheduleResponse = z.infer<typeof scheduleSchema>;\n","import type { Mastra } from '@mastra/core';\nimport type { AgentSchedule, AnySchedule, WorkflowSchedule } from '@mastra/core/schedules';\nimport type { WorkflowRunState } from '@mastra/core/workflows';\nimport { HTTPException } from '../http-exception';\nimport {\n createScheduleBodySchema,\n deleteScheduleResponseSchema,\n listSchedulesQuerySchema,\n listSchedulesResponseSchema,\n listScheduleTriggersQuerySchema,\n listScheduleTriggersResponseSchema,\n runScheduleResponseSchema,\n scheduleIdPathParams,\n scheduleSchema,\n updateScheduleBodySchema,\n} from '../schemas/schedules';\nimport { createRoute } from '../server-adapter/routes/route-builder';\n\ntype RunSummary = {\n status: WorkflowRunState['status'];\n startedAt?: number;\n completedAt?: number;\n durationMs?: number;\n error?: string;\n};\n\nfunction snapshotToRunSummary(run: {\n snapshot: WorkflowRunState | string;\n createdAt: Date;\n updatedAt: Date;\n}): RunSummary | undefined {\n const snapshot = typeof run.snapshot === 'string' ? null : run.snapshot;\n if (!snapshot) return undefined;\n const startedAt = run.createdAt instanceof Date ? run.createdAt.getTime() : undefined;\n const isTerminal =\n snapshot.status === 'success' ||\n snapshot.status === 'failed' ||\n snapshot.status === 'canceled' ||\n snapshot.status === 'bailed' ||\n snapshot.status === 'tripwire';\n const completedAt = isTerminal ? (run.updatedAt instanceof Date ? run.updatedAt.getTime() : undefined) : undefined;\n const durationMs = startedAt !== undefined && completedAt !== undefined ? completedAt - startedAt : undefined;\n return {\n status: snapshot.status,\n startedAt,\n completedAt,\n durationMs,\n error: snapshot.error?.message,\n };\n}\n\nasync function fetchRunSummary(mastra: Mastra, workflowName: string, runId: string): Promise<RunSummary | undefined> {\n try {\n const workflowsStore = await mastra.getStorage()?.getStore('workflows');\n const run = await workflowsStore?.getWorkflowRunById({ runId, workflowName });\n if (!run) return undefined;\n return snapshotToRunSummary(run);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Attach a `lastRun` summary to workflow schedules. Agent schedules pass\n * through unchanged — their `lastRunId` is an agent run, not a workflow run.\n */\nasync function hydrateScheduleResponse(\n mastra: Mastra,\n schedule: AnySchedule,\n): Promise<AgentSchedule | (WorkflowSchedule & { lastRun?: RunSummary })> {\n if (!schedule.workflowId || !schedule.lastRunId) {\n return schedule;\n }\n const lastRun = await fetchRunSummary(mastra, schedule.workflowId, schedule.lastRunId);\n return lastRun ? { ...schedule, lastRun } : schedule;\n}\n\n/**\n * Resolve a schedule by id via `mastra.schedules`. Returns 404 for missing\n * rows so handlers surface a clean HTTP error instead of a service error.\n */\nasync function loadSchedule(mastra: Mastra, scheduleId: string): Promise<AnySchedule> {\n const schedule = await mastra.schedules.get(scheduleId);\n if (!schedule) {\n throw new HTTPException(404, { message: 'Schedule not found' });\n }\n return schedule;\n}\n\nexport const LIST_SCHEDULES_ROUTE = createRoute({\n method: 'GET',\n path: '/schedules',\n responseType: 'json' as const,\n queryParamSchema: listSchedulesQuerySchema,\n responseSchema: listSchedulesResponseSchema,\n summary: 'List schedules',\n description:\n 'Returns all schedules — agent schedules and workflow schedules — optionally filtered by agentId, workflowId, or status. Agent schedules can additionally be filtered by threadId, resourceId, or name.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, agentId, workflowId, status, threadId, resourceId, name }) => {\n const schedulesStore = await mastra.getStorage()?.getStore('schedules');\n if (!schedulesStore) {\n // Schedules domain not configured — there are no schedules to return.\n return { schedules: [] };\n }\n const schedules = await mastra.schedules.list({ agentId, workflowId, status, threadId, resourceId, name });\n const hydrated = await Promise.all(schedules.map(schedule => hydrateScheduleResponse(mastra, schedule)));\n return { schedules: hydrated };\n },\n});\n\nexport const GET_SCHEDULE_ROUTE = createRoute({\n method: 'GET',\n path: '/schedules/:scheduleId',\n responseType: 'json' as const,\n pathParamSchema: scheduleIdPathParams,\n responseSchema: scheduleSchema,\n summary: 'Get a schedule by ID',\n description: 'Returns a single schedule by its id.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, scheduleId }) => {\n const schedule = await loadSchedule(mastra, scheduleId);\n return hydrateScheduleResponse(mastra, schedule);\n },\n});\n\nexport const CREATE_SCHEDULE_ROUTE = createRoute({\n method: 'POST',\n path: '/schedules',\n responseType: 'json' as const,\n bodySchema: createScheduleBodySchema,\n responseSchema: scheduleSchema,\n summary: 'Create a schedule',\n description:\n 'Creates a new schedule. Pass `agentId` (plus `prompt`) to schedule an agent, or `workflowId` (plus optional `inputData`) to schedule a workflow. Agent schedules get a random `agent_<uuid>` id, workflow schedules a random `schedule_<uuid>` id; pass `id` for a stable slug instead.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, ...body }) => {\n // getAgentById / getWorkflowById throw a MastraError (status 404) when the\n // target is unknown; translate that into a clean HTTP 404 instead of\n // letting it surface as 500.\n if ('workflowId' in body && body.workflowId) {\n try {\n mastra.getWorkflowById(body.workflowId);\n } catch {\n throw new HTTPException(404, { message: `Workflow \"${body.workflowId}\" not found` });\n }\n return await mastra.schedules.create({\n workflowId: body.workflowId,\n cron: body.cron,\n ...(body.id ? { id: body.id } : {}),\n ...(body.timezone ? { timezone: body.timezone } : {}),\n ...(body.inputData !== undefined ? { inputData: body.inputData } : {}),\n ...(body.initialState !== undefined ? { initialState: body.initialState } : {}),\n ...(body.requestContext ? { requestContext: body.requestContext } : {}),\n ...(body.metadata ? { metadata: body.metadata } : {}),\n });\n }\n const agentBody = body as Extract<typeof body, { agentId: string }>;\n try {\n mastra.getAgentById(agentBody.agentId);\n } catch {\n throw new HTTPException(404, { message: `Agent \"${agentBody.agentId}\" not found` });\n }\n return await mastra.schedules.create({\n agentId: agentBody.agentId,\n cron: agentBody.cron,\n prompt: agentBody.prompt,\n ...(agentBody.id ? { id: agentBody.id } : {}),\n ...(agentBody.name ? { name: agentBody.name } : {}),\n ...(agentBody.timezone ? { timezone: agentBody.timezone } : {}),\n ...(agentBody.threadId ? { threadId: agentBody.threadId } : {}),\n ...(agentBody.resourceId ? { resourceId: agentBody.resourceId } : {}),\n ...(agentBody.signalType ? { signalType: agentBody.signalType } : {}),\n ...(agentBody.tagName ? { tagName: agentBody.tagName } : {}),\n ...(agentBody.attributes ? { attributes: agentBody.attributes } : {}),\n ...(agentBody.ifActive ? { ifActive: agentBody.ifActive } : {}),\n ...(agentBody.ifIdle ? { ifIdle: agentBody.ifIdle } : {}),\n ...(agentBody.providerOptions ? { providerOptions: agentBody.providerOptions } : {}),\n ...(agentBody.metadata ? { metadata: agentBody.metadata } : {}),\n });\n },\n});\n\nexport const UPDATE_SCHEDULE_ROUTE = createRoute({\n method: 'PATCH',\n path: '/schedules/:scheduleId',\n responseType: 'json' as const,\n pathParamSchema: scheduleIdPathParams,\n bodySchema: updateScheduleBodySchema,\n responseSchema: scheduleSchema,\n summary: 'Update a schedule',\n description:\n 'Partial update of a schedule. Fields apply to the matching target type; agent-only fields on a workflow schedule are rejected. `threadId` and `resourceId` are part of an agent schedule identity and cannot be changed — to re-target, delete and recreate. Editing `cron` (or `timezone`) recomputes `nextFireAt`.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, scheduleId, ...body }) => {\n await loadSchedule(mastra, scheduleId);\n return await mastra.schedules.update(scheduleId, {\n ...(body.cron !== undefined ? { cron: body.cron } : {}),\n ...(body.timezone !== undefined ? { timezone: body.timezone } : {}),\n ...(body.status !== undefined ? { status: body.status } : {}),\n ...(body.metadata !== undefined ? { metadata: body.metadata } : {}),\n ...(body.prompt !== undefined ? { prompt: body.prompt } : {}),\n ...(body.name !== undefined ? { name: body.name } : {}),\n ...(body.signalType !== undefined ? { signalType: body.signalType } : {}),\n ...(body.tagName !== undefined ? { tagName: body.tagName } : {}),\n ...(body.attributes !== undefined ? { attributes: body.attributes } : {}),\n ...(body.ifActive !== undefined ? { ifActive: body.ifActive } : {}),\n ...(body.ifIdle !== undefined ? { ifIdle: body.ifIdle } : {}),\n ...(body.providerOptions !== undefined ? { providerOptions: body.providerOptions } : {}),\n ...(body.inputData !== undefined ? { inputData: body.inputData } : {}),\n ...(body.initialState !== undefined ? { initialState: body.initialState } : {}),\n ...(body.requestContext !== undefined ? { requestContext: body.requestContext } : {}),\n });\n },\n});\n\nexport const DELETE_SCHEDULE_ROUTE = createRoute({\n method: 'DELETE',\n path: '/schedules/:scheduleId',\n responseType: 'json' as const,\n pathParamSchema: scheduleIdPathParams,\n responseSchema: deleteScheduleResponseSchema,\n summary: 'Delete a schedule',\n description: 'Permanently deletes the schedule. 404 when the schedule does not exist.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, scheduleId }) => {\n await loadSchedule(mastra, scheduleId);\n await mastra.schedules.delete(scheduleId);\n return { message: 'Schedule deleted' };\n },\n});\n\nexport const PAUSE_SCHEDULE_ROUTE = createRoute({\n method: 'POST',\n path: '/schedules/:scheduleId/pause',\n responseType: 'json' as const,\n pathParamSchema: scheduleIdPathParams,\n responseSchema: scheduleSchema,\n summary: 'Pause a schedule',\n description:\n 'Marks the schedule as paused. The scheduler tick loop will skip paused schedules. Idempotent — pausing an already-paused schedule returns the current state unchanged. Pause status survives redeploys.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, scheduleId }) => {\n await loadSchedule(mastra, scheduleId);\n const updated = await mastra.schedules.pause(scheduleId);\n return hydrateScheduleResponse(mastra, updated);\n },\n});\n\nexport const RESUME_SCHEDULE_ROUTE = createRoute({\n method: 'POST',\n path: '/schedules/:scheduleId/resume',\n responseType: 'json' as const,\n pathParamSchema: scheduleIdPathParams,\n responseSchema: scheduleSchema,\n summary: 'Resume a paused schedule',\n description:\n 'Marks the schedule as active and recomputes nextFireAt from \"now\" so a long-paused schedule does not fire a backlog. Idempotent — resuming an already-active schedule returns the current state unchanged.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, scheduleId }) => {\n await loadSchedule(mastra, scheduleId);\n const updated = await mastra.schedules.resume(scheduleId);\n return hydrateScheduleResponse(mastra, updated);\n },\n});\n\nexport const RUN_SCHEDULE_ROUTE = createRoute({\n method: 'POST',\n path: '/schedules/:scheduleId/run',\n responseType: 'json' as const,\n pathParamSchema: scheduleIdPathParams,\n responseSchema: runScheduleResponseSchema,\n summary: 'Fire a schedule now',\n description:\n 'Manually triggers a single schedule fire out-of-band from the cron schedule. Records a trigger row with `triggerKind: \"manual\"`. Does not advance `nextFireAt`.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, scheduleId }) => {\n await loadSchedule(mastra, scheduleId);\n return await mastra.schedules.run(scheduleId);\n },\n});\n\nexport const LIST_SCHEDULE_TRIGGERS_ROUTE = createRoute({\n method: 'GET',\n path: '/schedules/:scheduleId/triggers',\n responseType: 'json' as const,\n pathParamSchema: scheduleIdPathParams,\n queryParamSchema: listScheduleTriggersQuerySchema,\n responseSchema: listScheduleTriggersResponseSchema,\n summary: 'List trigger history for a schedule',\n description: 'Returns the audit trail of trigger attempts for a schedule, ordered by actualFireAt descending.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, scheduleId, limit, fromActualFireAt, toActualFireAt }) => {\n const schedulesStore = await mastra.getStorage()?.getStore('schedules');\n if (!schedulesStore) {\n return { triggers: [] };\n }\n const schedule = await mastra.schedules.get(scheduleId);\n const triggers = await schedulesStore.listTriggers(schedule?.id ?? scheduleId, {\n limit,\n fromActualFireAt,\n toActualFireAt,\n });\n if (!schedule?.workflowId) {\n return { triggers };\n }\n const workflowName = (schedule as WorkflowSchedule).workflowId;\n const hydrated = await Promise.all(\n triggers.map(async trigger => {\n if (trigger.outcome !== 'published' || !trigger.runId) return trigger;\n const run = await fetchRunSummary(mastra, workflowName, trigger.runId);\n return run ? { ...trigger, run } : trigger;\n }),\n );\n return { triggers: hydrated };\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"schedules-fj9U0_tA.cjs","names":["z","HTTPException","createRoute"],"sources":["../src/server/schemas/schedules.ts","../src/server/handlers/schedules.ts"],"sourcesContent":["import { z } from 'zod';\n\nexport const scheduleStatusSchema = z.enum(['active', 'paused']);\n\n/** Mirrors the core `AgentSignalType` union. */\nconst signalTypeSchema = z.enum(['user', 'state', 'reactive', 'notification', 'user-message', 'system-reminder']);\n\n/** Attributes rendered onto the signal's XML tag. */\nconst signalAttributesSchema = z.record(\n z.string(),\n z.union([z.string(), z.number(), z.boolean(), z.null()]).optional(),\n);\n\n/** Behavior + attributes applied when the thread is already streaming. */\nconst ifActiveSchema = z.object({\n behavior: z.enum(['deliver', 'persist', 'discard']).optional(),\n attributes: signalAttributesSchema.optional(),\n});\n\n/**\n * Behavior + attributes applied when the thread is idle, plus a serializable\n * subset of stream options forwarded to the woken run.\n */\nconst ifIdleSchema = z.object({\n behavior: z.enum(['wake', 'persist', 'discard']).optional(),\n attributes: signalAttributesSchema.optional(),\n streamOptions: z\n .object({\n requestContext: z.record(z.string(), z.unknown()).optional(),\n })\n .optional(),\n});\n\nexport const workflowRunStatusSchema = z.enum([\n 'running',\n 'success',\n 'failed',\n 'tripwire',\n 'suspended',\n 'waiting',\n 'pending',\n 'canceled',\n 'bailed',\n 'paused',\n 'skipped',\n]);\n\nexport const scheduleRunSummarySchema = z.object({\n status: workflowRunStatusSchema,\n startedAt: z.number().optional(),\n completedAt: z.number().optional(),\n durationMs: z.number().optional(),\n error: z.string().optional(),\n});\n\n/**\n * Flat agent-schedule view. Persisted as a `Schedule` row with a\n * `target.type === 'agent'` variant; the HTTP surface flattens that\n * representation to the fields a user cares about (cron, prompt, threading,\n * status, lifecycle) without exposing the schedule plumbing. Discriminate\n * from workflow schedules by the presence of `agentId`.\n */\nexport const agentScheduleSchema = z.object({\n id: z.string(),\n agentId: z.string(),\n /** Mirror of the workflow-schedule discriminator — always absent on agent schedules. */\n workflowId: z.undefined().optional(),\n /** Workflow-run summary — never hydrated for agent schedules. */\n lastRun: z.undefined().optional(),\n name: z.string().optional(),\n threadId: z.string().optional(),\n resourceId: z.string().optional(),\n prompt: z.string(),\n cron: z.string(),\n timezone: z.string().optional(),\n status: scheduleStatusSchema,\n nextFireAt: z.number(),\n lastFireAt: z.number().optional(),\n lastRunId: z.string().optional(),\n signalType: signalTypeSchema.optional(),\n tagName: z.string().optional(),\n attributes: signalAttributesSchema.optional(),\n ifActive: ifActiveSchema.optional(),\n ifIdle: ifIdleSchema.optional(),\n providerOptions: z.record(z.string(), z.unknown()).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n});\n\n/**\n * Flat workflow-schedule view. Discriminate from agent schedules by the\n * presence of `workflowId`.\n */\nexport const workflowScheduleSchema = z.object({\n id: z.string(),\n workflowId: z.string(),\n /** Mirror of the agent-schedule discriminator — always absent on workflow schedules. */\n agentId: z.undefined().optional(),\n cron: z.string(),\n timezone: z.string().optional(),\n status: scheduleStatusSchema,\n nextFireAt: z.number(),\n lastFireAt: z.number().optional(),\n lastRunId: z.string().optional(),\n lastRun: scheduleRunSummarySchema.optional(),\n inputData: z.unknown().optional(),\n initialState: z.unknown().optional(),\n requestContext: z.record(z.string(), z.unknown()).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n createdAt: z.number(),\n updatedAt: z.number(),\n});\n\n/** Union of the flat views returned by the unified `/schedules` surface. */\nexport const scheduleSchema = z.union([agentScheduleSchema, workflowScheduleSchema]);\n\nexport const scheduleTriggerOutcomeSchema = z.enum([\n 'published',\n 'succeeded',\n 'delivered',\n 'persisted',\n 'discarded',\n 'skipped',\n 'aborted',\n 'failed',\n // Legacy queue/notification outcomes — no longer written, but trigger rows\n // persisted by older builds may still carry them. Kept readable so the\n // response validator does not reject historical rows. Mirrors the core\n // ScheduleTriggerOutcome union.\n 'acked',\n 'alerted',\n 'deferred',\n 'appended-from-queue',\n 'dropped-stale',\n 'dropped-superseded',\n 'dropped-busy',\n]);\n\nexport const scheduleTriggerKindSchema = z.enum(['schedule-fire', 'queue-drain', 'manual']);\n\nexport const scheduleTriggerResponseSchema = z.object({\n id: z.string().optional(),\n scheduleId: z.string(),\n runId: z.string().nullable(),\n scheduledFireAt: z.number(),\n actualFireAt: z.number(),\n outcome: scheduleTriggerOutcomeSchema,\n error: z.string().optional(),\n triggerKind: scheduleTriggerKindSchema.optional(),\n parentTriggerId: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n run: scheduleRunSummarySchema.optional(),\n});\n\nexport const listSchedulesQuerySchema = z.object({\n agentId: z.string().optional(),\n workflowId: z.string().optional(),\n status: scheduleStatusSchema.optional(),\n /** Agent-schedule only: match the target threadId. */\n threadId: z.string().optional(),\n /** Agent-schedule only: match the target resourceId. */\n resourceId: z.string().optional(),\n /** Agent-schedule only: match the free-form target name. */\n name: z.string().optional(),\n});\n\nexport const listSchedulesResponseSchema = z.object({\n schedules: z.array(scheduleSchema),\n});\n\nexport const scheduleIdPathParams = z.object({\n scheduleId: z.string(),\n});\n\n/**\n * Agent variant of the create body — targets an agent by `agentId`. Strict so\n * a body carrying both `agentId` and `workflowId` is rejected as ambiguous\n * instead of silently matching the agent branch of the union.\n */\nconst createAgentScheduleBodySchema = z.strictObject({\n /** Optional stable id; normalized to `agent_<slug>`. A random id is generated when omitted. */\n id: z.string().optional(),\n agentId: z.string().min(1),\n cron: z.string(),\n timezone: z.string().optional(),\n prompt: z.string(),\n name: z.string().optional(),\n threadId: z.string().optional(),\n resourceId: z.string().optional(),\n signalType: signalTypeSchema.optional(),\n tagName: z.string().optional(),\n attributes: signalAttributesSchema.optional(),\n ifActive: ifActiveSchema.optional(),\n ifIdle: ifIdleSchema.optional(),\n providerOptions: z.record(z.string(), z.unknown()).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\n/**\n * Workflow variant of the create body — targets a workflow by `workflowId`.\n * Strict so ambiguous bodies (both ids) are rejected by the union.\n */\nconst createWorkflowScheduleBodySchema = z.strictObject({\n /** Optional stable id; normalized to `schedule_<slug>`. A random id is generated when omitted. */\n id: z.string().optional(),\n workflowId: z.string().min(1),\n cron: z.string(),\n timezone: z.string().optional(),\n inputData: z.unknown().optional(),\n initialState: z.unknown().optional(),\n requestContext: z.record(z.string(), z.unknown()).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\n/**\n * Body for POST /schedules. Discriminated by which target id is present:\n * `agentId` creates an agent schedule, `workflowId` a workflow schedule.\n * Both variants are strict, so a body carrying both ids (or unknown keys)\n * fails validation instead of silently dropping fields.\n */\nexport const createScheduleBodySchema = z.union([createAgentScheduleBodySchema, createWorkflowScheduleBodySchema]);\n\n/**\n * Body for PATCH /schedules/:scheduleId — partial update. Fields apply to\n * the matching target type; agent-only fields on a workflow schedule are\n * rejected by the service. `threadId` / `resourceId` are intentionally not\n * editable; they are part of an agent schedule's identity. To re-target,\n * delete and recreate.\n */\nexport const updateScheduleBodySchema = z.object({\n cron: z.string().optional(),\n timezone: z.string().optional(),\n status: scheduleStatusSchema.optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n // Agent-schedule fields\n prompt: z.string().optional(),\n name: z.string().optional(),\n signalType: signalTypeSchema.optional(),\n tagName: z.string().optional(),\n attributes: signalAttributesSchema.optional(),\n ifActive: ifActiveSchema.optional(),\n ifIdle: ifIdleSchema.optional(),\n providerOptions: z.record(z.string(), z.unknown()).optional(),\n // Workflow-schedule fields\n inputData: z.unknown().optional(),\n initialState: z.unknown().optional(),\n requestContext: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const deleteScheduleResponseSchema = z.object({\n message: z.string(),\n});\n\n/** Response for POST /schedules/:scheduleId/run. */\nexport const runScheduleResponseSchema = z.object({\n scheduleId: z.string(),\n claimId: z.string(),\n scheduledFireAt: z.number(),\n});\n\nexport const listScheduleTriggersQuerySchema = z.object({\n limit: z.coerce.number().int().positive().optional(),\n fromActualFireAt: z.coerce.number().int().nonnegative().optional(),\n toActualFireAt: z.coerce.number().int().nonnegative().optional(),\n});\n\nexport const listScheduleTriggersResponseSchema = z.object({\n triggers: z.array(scheduleTriggerResponseSchema),\n});\n\nexport type AgentScheduleResponse = z.infer<typeof agentScheduleSchema>;\nexport type WorkflowScheduleResponse = z.infer<typeof workflowScheduleSchema>;\nexport type ScheduleResponse = z.infer<typeof scheduleSchema>;\n","import type { Mastra } from '@mastra/core';\nimport type { AgentSchedule, AnySchedule, WorkflowSchedule } from '@mastra/core/schedules';\nimport type { WorkflowRunState } from '@mastra/core/workflows';\nimport { HTTPException } from '../http-exception';\nimport {\n createScheduleBodySchema,\n deleteScheduleResponseSchema,\n listSchedulesQuerySchema,\n listSchedulesResponseSchema,\n listScheduleTriggersQuerySchema,\n listScheduleTriggersResponseSchema,\n runScheduleResponseSchema,\n scheduleIdPathParams,\n scheduleSchema,\n updateScheduleBodySchema,\n} from '../schemas/schedules';\nimport { createRoute } from '../server-adapter/routes/route-builder';\n\ntype RunSummary = {\n status: WorkflowRunState['status'];\n startedAt?: number;\n completedAt?: number;\n durationMs?: number;\n error?: string;\n};\n\nfunction snapshotToRunSummary(run: {\n snapshot: WorkflowRunState | string;\n createdAt: Date;\n updatedAt: Date;\n}): RunSummary | undefined {\n const snapshot = typeof run.snapshot === 'string' ? null : run.snapshot;\n if (!snapshot) return undefined;\n const startedAt = run.createdAt instanceof Date ? run.createdAt.getTime() : undefined;\n const isTerminal =\n snapshot.status === 'success' ||\n snapshot.status === 'failed' ||\n snapshot.status === 'canceled' ||\n snapshot.status === 'bailed' ||\n snapshot.status === 'tripwire';\n const completedAt = isTerminal ? (run.updatedAt instanceof Date ? run.updatedAt.getTime() : undefined) : undefined;\n const durationMs = startedAt !== undefined && completedAt !== undefined ? completedAt - startedAt : undefined;\n return {\n status: snapshot.status,\n startedAt,\n completedAt,\n durationMs,\n error: snapshot.error?.message,\n };\n}\n\nasync function fetchRunSummary(mastra: Mastra, workflowName: string, runId: string): Promise<RunSummary | undefined> {\n try {\n const workflowsStore = await mastra.getStorage()?.getStore('workflows');\n const run = await workflowsStore?.getWorkflowRunById({ runId, workflowName });\n if (!run) return undefined;\n return snapshotToRunSummary(run);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Attach a `lastRun` summary to workflow schedules. Agent schedules pass\n * through unchanged — their `lastRunId` is an agent run, not a workflow run.\n */\nasync function hydrateScheduleResponse(\n mastra: Mastra,\n schedule: AnySchedule,\n): Promise<AgentSchedule | (WorkflowSchedule & { lastRun?: RunSummary })> {\n if (!schedule.workflowId || !schedule.lastRunId) {\n return schedule;\n }\n const lastRun = await fetchRunSummary(mastra, schedule.workflowId, schedule.lastRunId);\n return lastRun ? { ...schedule, lastRun } : schedule;\n}\n\n/**\n * Resolve a schedule by id via `mastra.schedules`. Returns 404 for missing\n * rows so handlers surface a clean HTTP error instead of a service error.\n */\nasync function loadSchedule(mastra: Mastra, scheduleId: string): Promise<AnySchedule> {\n const schedule = await mastra.schedules.get(scheduleId);\n if (!schedule) {\n throw new HTTPException(404, { message: 'Schedule not found' });\n }\n return schedule;\n}\n\nexport const LIST_SCHEDULES_ROUTE = createRoute({\n method: 'GET',\n path: '/schedules',\n responseType: 'json' as const,\n queryParamSchema: listSchedulesQuerySchema,\n responseSchema: listSchedulesResponseSchema,\n summary: 'List schedules',\n description:\n 'Returns all schedules — agent schedules and workflow schedules — optionally filtered by agentId, workflowId, or status. Agent schedules can additionally be filtered by threadId, resourceId, or name.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, agentId, workflowId, status, threadId, resourceId, name }) => {\n const schedulesStore = await mastra.getStorage()?.getStore('schedules');\n if (!schedulesStore) {\n // Schedules domain not configured — there are no schedules to return.\n return { schedules: [] };\n }\n const schedules = await mastra.schedules.list({ agentId, workflowId, status, threadId, resourceId, name });\n const hydrated = await Promise.all(schedules.map(schedule => hydrateScheduleResponse(mastra, schedule)));\n return { schedules: hydrated };\n },\n});\n\nexport const GET_SCHEDULE_ROUTE = createRoute({\n method: 'GET',\n path: '/schedules/:scheduleId',\n responseType: 'json' as const,\n pathParamSchema: scheduleIdPathParams,\n responseSchema: scheduleSchema,\n summary: 'Get a schedule by ID',\n description: 'Returns a single schedule by its id.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, scheduleId }) => {\n const schedule = await loadSchedule(mastra, scheduleId);\n return hydrateScheduleResponse(mastra, schedule);\n },\n});\n\nexport const CREATE_SCHEDULE_ROUTE = createRoute({\n method: 'POST',\n path: '/schedules',\n responseType: 'json' as const,\n bodySchema: createScheduleBodySchema,\n responseSchema: scheduleSchema,\n summary: 'Create a schedule',\n description:\n 'Creates a new schedule. Pass `agentId` (plus `prompt`) to schedule an agent, or `workflowId` (plus optional `inputData`) to schedule a workflow. Agent schedules get a random `agent_<uuid>` id, workflow schedules a random `schedule_<uuid>` id; pass `id` for a stable slug instead.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, ...body }) => {\n // getAgentById / getWorkflowById throw a MastraError (status 404) when the\n // target is unknown; translate that into a clean HTTP 404 instead of\n // letting it surface as 500.\n if ('workflowId' in body && body.workflowId) {\n try {\n mastra.getWorkflowById(body.workflowId);\n } catch {\n throw new HTTPException(404, { message: `Workflow \"${body.workflowId}\" not found` });\n }\n return await mastra.schedules.create({\n workflowId: body.workflowId,\n cron: body.cron,\n ...(body.id ? { id: body.id } : {}),\n ...(body.timezone ? { timezone: body.timezone } : {}),\n ...(body.inputData !== undefined ? { inputData: body.inputData } : {}),\n ...(body.initialState !== undefined ? { initialState: body.initialState } : {}),\n ...(body.requestContext ? { requestContext: body.requestContext } : {}),\n ...(body.metadata ? { metadata: body.metadata } : {}),\n });\n }\n const agentBody = body as Extract<typeof body, { agentId: string }>;\n try {\n mastra.getAgentById(agentBody.agentId);\n } catch {\n throw new HTTPException(404, { message: `Agent \"${agentBody.agentId}\" not found` });\n }\n return await mastra.schedules.create({\n agentId: agentBody.agentId,\n cron: agentBody.cron,\n prompt: agentBody.prompt,\n ...(agentBody.id ? { id: agentBody.id } : {}),\n ...(agentBody.name ? { name: agentBody.name } : {}),\n ...(agentBody.timezone ? { timezone: agentBody.timezone } : {}),\n ...(agentBody.threadId ? { threadId: agentBody.threadId } : {}),\n ...(agentBody.resourceId ? { resourceId: agentBody.resourceId } : {}),\n ...(agentBody.signalType ? { signalType: agentBody.signalType } : {}),\n ...(agentBody.tagName ? { tagName: agentBody.tagName } : {}),\n ...(agentBody.attributes ? { attributes: agentBody.attributes } : {}),\n ...(agentBody.ifActive ? { ifActive: agentBody.ifActive } : {}),\n ...(agentBody.ifIdle ? { ifIdle: agentBody.ifIdle } : {}),\n ...(agentBody.providerOptions ? { providerOptions: agentBody.providerOptions } : {}),\n ...(agentBody.metadata ? { metadata: agentBody.metadata } : {}),\n });\n },\n});\n\nexport const UPDATE_SCHEDULE_ROUTE = createRoute({\n method: 'PATCH',\n path: '/schedules/:scheduleId',\n responseType: 'json' as const,\n pathParamSchema: scheduleIdPathParams,\n bodySchema: updateScheduleBodySchema,\n responseSchema: scheduleSchema,\n summary: 'Update a schedule',\n description:\n 'Partial update of a schedule. Fields apply to the matching target type; agent-only fields on a workflow schedule are rejected. `threadId` and `resourceId` are part of an agent schedule identity and cannot be changed — to re-target, delete and recreate. Editing `cron` (or `timezone`) recomputes `nextFireAt`.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, scheduleId, ...body }) => {\n await loadSchedule(mastra, scheduleId);\n return await mastra.schedules.update(scheduleId, {\n ...(body.cron !== undefined ? { cron: body.cron } : {}),\n ...(body.timezone !== undefined ? { timezone: body.timezone } : {}),\n ...(body.status !== undefined ? { status: body.status } : {}),\n ...(body.metadata !== undefined ? { metadata: body.metadata } : {}),\n ...(body.prompt !== undefined ? { prompt: body.prompt } : {}),\n ...(body.name !== undefined ? { name: body.name } : {}),\n ...(body.signalType !== undefined ? { signalType: body.signalType } : {}),\n ...(body.tagName !== undefined ? { tagName: body.tagName } : {}),\n ...(body.attributes !== undefined ? { attributes: body.attributes } : {}),\n ...(body.ifActive !== undefined ? { ifActive: body.ifActive } : {}),\n ...(body.ifIdle !== undefined ? { ifIdle: body.ifIdle } : {}),\n ...(body.providerOptions !== undefined ? { providerOptions: body.providerOptions } : {}),\n ...(body.inputData !== undefined ? { inputData: body.inputData } : {}),\n ...(body.initialState !== undefined ? { initialState: body.initialState } : {}),\n ...(body.requestContext !== undefined ? { requestContext: body.requestContext } : {}),\n });\n },\n});\n\nexport const DELETE_SCHEDULE_ROUTE = createRoute({\n method: 'DELETE',\n path: '/schedules/:scheduleId',\n responseType: 'json' as const,\n pathParamSchema: scheduleIdPathParams,\n responseSchema: deleteScheduleResponseSchema,\n summary: 'Delete a schedule',\n description: 'Permanently deletes the schedule. 404 when the schedule does not exist.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, scheduleId }) => {\n await loadSchedule(mastra, scheduleId);\n await mastra.schedules.delete(scheduleId);\n return { message: 'Schedule deleted' };\n },\n});\n\nexport const PAUSE_SCHEDULE_ROUTE = createRoute({\n method: 'POST',\n path: '/schedules/:scheduleId/pause',\n responseType: 'json' as const,\n pathParamSchema: scheduleIdPathParams,\n responseSchema: scheduleSchema,\n summary: 'Pause a schedule',\n description:\n 'Marks the schedule as paused. The scheduler tick loop will skip paused schedules. Idempotent — pausing an already-paused schedule returns the current state unchanged. Pause status survives redeploys.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, scheduleId }) => {\n await loadSchedule(mastra, scheduleId);\n const updated = await mastra.schedules.pause(scheduleId);\n return hydrateScheduleResponse(mastra, updated);\n },\n});\n\nexport const RESUME_SCHEDULE_ROUTE = createRoute({\n method: 'POST',\n path: '/schedules/:scheduleId/resume',\n responseType: 'json' as const,\n pathParamSchema: scheduleIdPathParams,\n responseSchema: scheduleSchema,\n summary: 'Resume a paused schedule',\n description:\n 'Marks the schedule as active and recomputes nextFireAt from \"now\" so a long-paused schedule does not fire a backlog. Idempotent — resuming an already-active schedule returns the current state unchanged.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, scheduleId }) => {\n await loadSchedule(mastra, scheduleId);\n const updated = await mastra.schedules.resume(scheduleId);\n return hydrateScheduleResponse(mastra, updated);\n },\n});\n\nexport const RUN_SCHEDULE_ROUTE = createRoute({\n method: 'POST',\n path: '/schedules/:scheduleId/run',\n responseType: 'json' as const,\n pathParamSchema: scheduleIdPathParams,\n responseSchema: runScheduleResponseSchema,\n summary: 'Fire a schedule now',\n description:\n 'Manually triggers a single schedule fire out-of-band from the cron schedule. Records a trigger row with `triggerKind: \"manual\"`. Does not advance `nextFireAt`.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, scheduleId }) => {\n await loadSchedule(mastra, scheduleId);\n return await mastra.schedules.run(scheduleId);\n },\n});\n\nexport const LIST_SCHEDULE_TRIGGERS_ROUTE = createRoute({\n method: 'GET',\n path: '/schedules/:scheduleId/triggers',\n responseType: 'json' as const,\n pathParamSchema: scheduleIdPathParams,\n queryParamSchema: listScheduleTriggersQuerySchema,\n responseSchema: listScheduleTriggersResponseSchema,\n summary: 'List trigger history for a schedule',\n description: 'Returns the audit trail of trigger attempts for a schedule, ordered by actualFireAt descending.',\n tags: ['Schedules'],\n requiresAuth: true,\n handler: async ({ mastra, scheduleId, limit, fromActualFireAt, toActualFireAt }) => {\n const schedulesStore = await mastra.getStorage()?.getStore('schedules');\n if (!schedulesStore) {\n return { triggers: [] };\n }\n const schedule = await mastra.schedules.get(scheduleId);\n const triggers = await schedulesStore.listTriggers(schedule?.id ?? scheduleId, {\n limit,\n fromActualFireAt,\n toActualFireAt,\n });\n if (!schedule?.workflowId) {\n return { triggers };\n }\n const workflowName = schedule.workflowId;\n const hydrated = await Promise.all(\n triggers.map(async trigger => {\n if (trigger.outcome !== 'published' || !trigger.runId) return trigger;\n const run = await fetchRunSummary(mastra, workflowName, trigger.runId);\n return run ? { ...trigger, run } : trigger;\n }),\n );\n return { triggers: hydrated };\n },\n});\n"],"mappings":";;;;AAEA,MAAa,uBAAuBA,IAAAA,EAAE,KAAK,CAAC,UAAU,QAAQ,CAAC;;AAG/D,MAAM,mBAAmBA,IAAAA,EAAE,KAAK;CAAC;CAAQ;CAAS;CAAY;CAAgB;CAAgB;AAAiB,CAAC;;AAGhH,MAAM,yBAAyBA,IAAAA,EAAE,OAC/BA,IAAAA,EAAE,OAAO,GACTA,IAAAA,EAAE,MAAM;CAACA,IAAAA,EAAE,OAAO;CAAGA,IAAAA,EAAE,OAAO;CAAGA,IAAAA,EAAE,QAAQ;CAAGA,IAAAA,EAAE,KAAK;AAAC,CAAC,CAAC,CAAC,SAAS,CACpE;;AAGA,MAAM,iBAAiBA,IAAAA,EAAE,OAAO;CAC9B,UAAUA,IAAAA,EAAE,KAAK;EAAC;EAAW;EAAW;CAAS,CAAC,CAAC,CAAC,SAAS;CAC7D,YAAY,uBAAuB,SAAS;AAC9C,CAAC;;;;;AAMD,MAAM,eAAeA,IAAAA,EAAE,OAAO;CAC5B,UAAUA,IAAAA,EAAE,KAAK;EAAC;EAAQ;EAAW;CAAS,CAAC,CAAC,CAAC,SAAS;CAC1D,YAAY,uBAAuB,SAAS;CAC5C,eAAeA,IAAAA,EACZ,OAAO,EACN,gBAAgBA,IAAAA,EAAE,OAAOA,IAAAA,EAAE,OAAO,GAAGA,IAAAA,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,EAC7D,CAAC,CAAC,CACD,SAAS;AACd,CAAC;AAED,MAAa,0BAA0BA,IAAAA,EAAE,KAAK;CAC5C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAa,2BAA2BA,IAAAA,EAAE,OAAO;CAC/C,QAAQ;CACR,WAAWA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC/B,aAAaA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CACjC,YAAYA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAChC,OAAOA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;AAC7B,CAAC;;;;;;;;AASD,MAAa,sBAAsBA,IAAAA,EAAE,OAAO;CAC1C,IAAIA,IAAAA,EAAE,OAAO;CACb,SAASA,IAAAA,EAAE,OAAO;;CAElB,YAAYA,IAAAA,EAAE,UAAU,CAAC,CAAC,SAAS;;CAEnC,SAASA,IAAAA,EAAE,UAAU,CAAC,CAAC,SAAS;CAChC,MAAMA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,UAAUA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,YAAYA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAChC,QAAQA,IAAAA,EAAE,OAAO;CACjB,MAAMA,IAAAA,EAAE,OAAO;CACf,UAAUA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,QAAQ;CACR,YAAYA,IAAAA,EAAE,OAAO;CACrB,YAAYA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAChC,WAAWA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC/B,YAAY,iBAAiB,SAAS;CACtC,SAASA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC7B,YAAY,uBAAuB,SAAS;CAC5C,UAAU,eAAe,SAAS;CAClC,QAAQ,aAAa,SAAS;CAC9B,iBAAiBA,IAAAA,EAAE,OAAOA,IAAAA,EAAE,OAAO,GAAGA,IAAAA,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;CAC5D,UAAUA,IAAAA,EAAE,OAAOA,IAAAA,EAAE,OAAO,GAAGA,IAAAA,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;CACrD,WAAWA,IAAAA,EAAE,OAAO;CACpB,WAAWA,IAAAA,EAAE,OAAO;AACtB,CAAC;;;;;AAMD,MAAa,yBAAyBA,IAAAA,EAAE,OAAO;CAC7C,IAAIA,IAAAA,EAAE,OAAO;CACb,YAAYA,IAAAA,EAAE,OAAO;;CAErB,SAASA,IAAAA,EAAE,UAAU,CAAC,CAAC,SAAS;CAChC,MAAMA,IAAAA,EAAE,OAAO;CACf,UAAUA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,QAAQ;CACR,YAAYA,IAAAA,EAAE,OAAO;CACrB,YAAYA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAChC,WAAWA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC/B,SAAS,yBAAyB,SAAS;CAC3C,WAAWA,IAAAA,EAAE,QAAQ,CAAC,CAAC,SAAS;CAChC,cAAcA,IAAAA,EAAE,QAAQ,CAAC,CAAC,SAAS;CACnC,gBAAgBA,IAAAA,EAAE,OAAOA,IAAAA,EAAE,OAAO,GAAGA,IAAAA,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;CAC3D,UAAUA,IAAAA,EAAE,OAAOA,IAAAA,EAAE,OAAO,GAAGA,IAAAA,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;CACrD,WAAWA,IAAAA,EAAE,OAAO;CACpB,WAAWA,IAAAA,EAAE,OAAO;AACtB,CAAC;;AAGD,MAAa,iBAAiBA,IAAAA,EAAE,MAAM,CAAC,qBAAqB,sBAAsB,CAAC;AAEnF,MAAa,+BAA+BA,IAAAA,EAAE,KAAK;CACjD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAKA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAa,4BAA4BA,IAAAA,EAAE,KAAK;CAAC;CAAiB;CAAe;AAAQ,CAAC;AAE1F,MAAa,gCAAgCA,IAAAA,EAAE,OAAO;CACpD,IAAIA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CACxB,YAAYA,IAAAA,EAAE,OAAO;CACrB,OAAOA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC3B,iBAAiBA,IAAAA,EAAE,OAAO;CAC1B,cAAcA,IAAAA,EAAE,OAAO;CACvB,SAAS;CACT,OAAOA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC3B,aAAa,0BAA0B,SAAS;CAChD,iBAAiBA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CACrC,UAAUA,IAAAA,EAAE,OAAOA,IAAAA,EAAE,OAAO,GAAGA,IAAAA,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;CACrD,KAAK,yBAAyB,SAAS;AACzC,CAAC;AAED,MAAa,2BAA2BA,IAAAA,EAAE,OAAO;CAC/C,SAASA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC7B,YAAYA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAChC,QAAQ,qBAAqB,SAAS;;CAEtC,UAAUA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;;CAE9B,YAAYA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;;CAEhC,MAAMA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;AAC5B,CAAC;AAED,MAAa,8BAA8BA,IAAAA,EAAE,OAAO,EAClD,WAAWA,IAAAA,EAAE,MAAM,cAAc,EACnC,CAAC;AAED,MAAa,uBAAuBA,IAAAA,EAAE,OAAO,EAC3C,YAAYA,IAAAA,EAAE,OAAO,EACvB,CAAC;;;;;;AAOD,MAAM,gCAAgCA,IAAAA,EAAE,aAAa;;CAEnD,IAAIA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CACxB,SAASA,IAAAA,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACzB,MAAMA,IAAAA,EAAE,OAAO;CACf,UAAUA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,QAAQA,IAAAA,EAAE,OAAO;CACjB,MAAMA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,UAAUA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,YAAYA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAChC,YAAY,iBAAiB,SAAS;CACtC,SAASA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC7B,YAAY,uBAAuB,SAAS;CAC5C,UAAU,eAAe,SAAS;CAClC,QAAQ,aAAa,SAAS;CAC9B,iBAAiBA,IAAAA,EAAE,OAAOA,IAAAA,EAAE,OAAO,GAAGA,IAAAA,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;CAC5D,UAAUA,IAAAA,EAAE,OAAOA,IAAAA,EAAE,OAAO,GAAGA,IAAAA,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;AACvD,CAAC;;;;;AAMD,MAAM,mCAAmCA,IAAAA,EAAE,aAAa;;CAEtD,IAAIA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CACxB,YAAYA,IAAAA,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CAC5B,MAAMA,IAAAA,EAAE,OAAO;CACf,UAAUA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,WAAWA,IAAAA,EAAE,QAAQ,CAAC,CAAC,SAAS;CAChC,cAAcA,IAAAA,EAAE,QAAQ,CAAC,CAAC,SAAS;CACnC,gBAAgBA,IAAAA,EAAE,OAAOA,IAAAA,EAAE,OAAO,GAAGA,IAAAA,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;CAC3D,UAAUA,IAAAA,EAAE,OAAOA,IAAAA,EAAE,OAAO,GAAGA,IAAAA,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;AACvD,CAAC;;;;;;;AAQD,MAAa,2BAA2BA,IAAAA,EAAE,MAAM,CAAC,+BAA+B,gCAAgC,CAAC;;;;;;;;AASjH,MAAa,2BAA2BA,IAAAA,EAAE,OAAO;CAC/C,MAAMA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,UAAUA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC9B,QAAQ,qBAAqB,SAAS;CACtC,UAAUA,IAAAA,EAAE,OAAOA,IAAAA,EAAE,OAAO,GAAGA,IAAAA,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;CAErD,QAAQA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC5B,MAAMA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,YAAY,iBAAiB,SAAS;CACtC,SAASA,IAAAA,EAAE,OAAO,CAAC,CAAC,SAAS;CAC7B,YAAY,uBAAuB,SAAS;CAC5C,UAAU,eAAe,SAAS;CAClC,QAAQ,aAAa,SAAS;CAC9B,iBAAiBA,IAAAA,EAAE,OAAOA,IAAAA,EAAE,OAAO,GAAGA,IAAAA,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;CAE5D,WAAWA,IAAAA,EAAE,QAAQ,CAAC,CAAC,SAAS;CAChC,cAAcA,IAAAA,EAAE,QAAQ,CAAC,CAAC,SAAS;CACnC,gBAAgBA,IAAAA,EAAE,OAAOA,IAAAA,EAAE,OAAO,GAAGA,IAAAA,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;AAC7D,CAAC;AAED,MAAa,+BAA+BA,IAAAA,EAAE,OAAO,EACnD,SAASA,IAAAA,EAAE,OAAO,EACpB,CAAC;;AAGD,MAAa,4BAA4BA,IAAAA,EAAE,OAAO;CAChD,YAAYA,IAAAA,EAAE,OAAO;CACrB,SAASA,IAAAA,EAAE,OAAO;CAClB,iBAAiBA,IAAAA,EAAE,OAAO;AAC5B,CAAC;AAED,MAAa,kCAAkCA,IAAAA,EAAE,OAAO;CACtD,OAAOA,IAAAA,EAAE,OAAO,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS;CACnD,kBAAkBA,IAAAA,EAAE,OAAO,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS;CACjE,gBAAgBA,IAAAA,EAAE,OAAO,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS;AACjE,CAAC;AAED,MAAa,qCAAqCA,IAAAA,EAAE,OAAO,EACzD,UAAUA,IAAAA,EAAE,MAAM,6BAA6B,EACjD,CAAC;;;ACnPD,SAAS,qBAAqB,KAIH;CACzB,MAAM,WAAW,OAAO,IAAI,aAAa,WAAW,OAAO,IAAI;CAC/D,IAAI,CAAC,UAAU,OAAO,KAAA;CACtB,MAAM,YAAY,IAAI,qBAAqB,OAAO,IAAI,UAAU,QAAQ,IAAI,KAAA;CAO5E,MAAM,cALJ,SAAS,WAAW,aACpB,SAAS,WAAW,YACpB,SAAS,WAAW,cACpB,SAAS,WAAW,YACpB,SAAS,WAAW,aACY,IAAI,qBAAqB,OAAO,IAAI,UAAU,QAAQ,IAAI,KAAA,IAAa,KAAA;CACzG,MAAM,aAAa,cAAc,KAAA,KAAa,gBAAgB,KAAA,IAAY,cAAc,YAAY,KAAA;CACpG,OAAO;EACL,QAAQ,SAAS;EACjB;EACA;EACA;EACA,OAAO,SAAS,OAAO;CACzB;AACF;AAEA,eAAe,gBAAgB,QAAgB,cAAsB,OAAgD;CACnH,IAAI;EAEF,MAAM,MAAM,OAAM,MADW,OAAO,WAAW,CAAC,EAAE,SAAS,WAAW,EAAA,EACpC,mBAAmB;GAAE;GAAO;EAAa,CAAC;EAC5E,IAAI,CAAC,KAAK,OAAO,KAAA;EACjB,OAAO,qBAAqB,GAAG;CACjC,QAAQ;EACN;CACF;AACF;;;;;AAMA,eAAe,wBACb,QACA,UACwE;CACxE,IAAI,CAAC,SAAS,cAAc,CAAC,SAAS,WACpC,OAAO;CAET,MAAM,UAAU,MAAM,gBAAgB,QAAQ,SAAS,YAAY,SAAS,SAAS;CACrF,OAAO,UAAU;EAAE,GAAG;EAAU;CAAQ,IAAI;AAC9C;;;;;AAMA,eAAe,aAAa,QAAgB,YAA0C;CACpF,MAAM,WAAW,MAAM,OAAO,UAAU,IAAI,UAAU;CACtD,IAAI,CAAC,UACH,MAAM,IAAIC,uBAAAA,cAAc,KAAK,EAAE,SAAS,qBAAqB,CAAC;CAEhE,OAAO;AACT;AAEA,MAAa,uBAAuBC,sBAAAA,YAAY;CAC9C,QAAQ;CACR,MAAM;CACN,cAAc;CACd,kBAAkB;CAClB,gBAAgB;CAChB,SAAS;CACT,aACE;CACF,MAAM,CAAC,WAAW;CAClB,cAAc;CACd,SAAS,OAAO,EAAE,QAAQ,SAAS,YAAY,QAAQ,UAAU,YAAY,WAAW;EAEtF,IAAI,CAAC,MADwB,OAAO,WAAW,CAAC,EAAE,SAAS,WAAW,GAGpE,OAAO,EAAE,WAAW,CAAC,EAAE;EAEzB,MAAM,YAAY,MAAM,OAAO,UAAU,KAAK;GAAE;GAAS;GAAY;GAAQ;GAAU;GAAY;EAAK,CAAC;EAEzG,OAAO,EAAE,WAAW,MADG,QAAQ,IAAI,UAAU,KAAI,aAAY,wBAAwB,QAAQ,QAAQ,CAAC,CAAC,EAC1E;CAC/B;AACF,CAAC;AAED,MAAa,qBAAqBA,sBAAAA,YAAY;CAC5C,QAAQ;CACR,MAAM;CACN,cAAc;CACd,iBAAiB;CACjB,gBAAgB;CAChB,SAAS;CACT,aAAa;CACb,MAAM,CAAC,WAAW;CAClB,cAAc;CACd,SAAS,OAAO,EAAE,QAAQ,iBAAiB;EAEzC,OAAO,wBAAwB,QAAQ,MADhB,aAAa,QAAQ,UAAU,CACP;CACjD;AACF,CAAC;AAED,MAAa,wBAAwBA,sBAAAA,YAAY;CAC/C,QAAQ;CACR,MAAM;CACN,cAAc;CACd,YAAY;CACZ,gBAAgB;CAChB,SAAS;CACT,aACE;CACF,MAAM,CAAC,WAAW;CAClB,cAAc;CACd,SAAS,OAAO,EAAE,QAAQ,GAAG,WAAW;EAItC,IAAI,gBAAgB,QAAQ,KAAK,YAAY;GAC3C,IAAI;IACF,OAAO,gBAAgB,KAAK,UAAU;GACxC,QAAQ;IACN,MAAM,IAAID,uBAAAA,cAAc,KAAK,EAAE,SAAS,aAAa,KAAK,WAAW,aAAa,CAAC;GACrF;GACA,OAAO,MAAM,OAAO,UAAU,OAAO;IACnC,YAAY,KAAK;IACjB,MAAM,KAAK;IACX,GAAI,KAAK,KAAK,EAAE,IAAI,KAAK,GAAG,IAAI,CAAC;IACjC,GAAI,KAAK,WAAW,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;IACnD,GAAI,KAAK,cAAc,KAAA,IAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;IACpE,GAAI,KAAK,iBAAiB,KAAA,IAAY,EAAE,cAAc,KAAK,aAAa,IAAI,CAAC;IAC7E,GAAI,KAAK,iBAAiB,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;IACrE,GAAI,KAAK,WAAW,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;GACrD,CAAC;EACH;EACA,MAAM,YAAY;EAClB,IAAI;GACF,OAAO,aAAa,UAAU,OAAO;EACvC,QAAQ;GACN,MAAM,IAAIA,uBAAAA,cAAc,KAAK,EAAE,SAAS,UAAU,UAAU,QAAQ,aAAa,CAAC;EACpF;EACA,OAAO,MAAM,OAAO,UAAU,OAAO;GACnC,SAAS,UAAU;GACnB,MAAM,UAAU;GAChB,QAAQ,UAAU;GAClB,GAAI,UAAU,KAAK,EAAE,IAAI,UAAU,GAAG,IAAI,CAAC;GAC3C,GAAI,UAAU,OAAO,EAAE,MAAM,UAAU,KAAK,IAAI,CAAC;GACjD,GAAI,UAAU,WAAW,EAAE,UAAU,UAAU,SAAS,IAAI,CAAC;GAC7D,GAAI,UAAU,WAAW,EAAE,UAAU,UAAU,SAAS,IAAI,CAAC;GAC7D,GAAI,UAAU,aAAa,EAAE,YAAY,UAAU,WAAW,IAAI,CAAC;GACnE,GAAI,UAAU,aAAa,EAAE,YAAY,UAAU,WAAW,IAAI,CAAC;GACnE,GAAI,UAAU,UAAU,EAAE,SAAS,UAAU,QAAQ,IAAI,CAAC;GAC1D,GAAI,UAAU,aAAa,EAAE,YAAY,UAAU,WAAW,IAAI,CAAC;GACnE,GAAI,UAAU,WAAW,EAAE,UAAU,UAAU,SAAS,IAAI,CAAC;GAC7D,GAAI,UAAU,SAAS,EAAE,QAAQ,UAAU,OAAO,IAAI,CAAC;GACvD,GAAI,UAAU,kBAAkB,EAAE,iBAAiB,UAAU,gBAAgB,IAAI,CAAC;GAClF,GAAI,UAAU,WAAW,EAAE,UAAU,UAAU,SAAS,IAAI,CAAC;EAC/D,CAAC;CACH;AACF,CAAC;AAED,MAAa,wBAAwBC,sBAAAA,YAAY;CAC/C,QAAQ;CACR,MAAM;CACN,cAAc;CACd,iBAAiB;CACjB,YAAY;CACZ,gBAAgB;CAChB,SAAS;CACT,aACE;CACF,MAAM,CAAC,WAAW;CAClB,cAAc;CACd,SAAS,OAAO,EAAE,QAAQ,YAAY,GAAG,WAAW;EAClD,MAAM,aAAa,QAAQ,UAAU;EACrC,OAAO,MAAM,OAAO,UAAU,OAAO,YAAY;GAC/C,GAAI,KAAK,SAAS,KAAA,IAAY,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;GACrD,GAAI,KAAK,aAAa,KAAA,IAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;GACjE,GAAI,KAAK,WAAW,KAAA,IAAY,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;GAC3D,GAAI,KAAK,aAAa,KAAA,IAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;GACjE,GAAI,KAAK,WAAW,KAAA,IAAY,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;GAC3D,GAAI,KAAK,SAAS,KAAA,IAAY,EAAE,MAAM,KAAK,KAAK,IAAI,CAAC;GACrD,GAAI,KAAK,eAAe,KAAA,IAAY,EAAE,YAAY,KAAK,WAAW,IAAI,CAAC;GACvE,GAAI,KAAK,YAAY,KAAA,IAAY,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;GAC9D,GAAI,KAAK,eAAe,KAAA,IAAY,EAAE,YAAY,KAAK,WAAW,IAAI,CAAC;GACvE,GAAI,KAAK,aAAa,KAAA,IAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;GACjE,GAAI,KAAK,WAAW,KAAA,IAAY,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;GAC3D,GAAI,KAAK,oBAAoB,KAAA,IAAY,EAAE,iBAAiB,KAAK,gBAAgB,IAAI,CAAC;GACtF,GAAI,KAAK,cAAc,KAAA,IAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;GACpE,GAAI,KAAK,iBAAiB,KAAA,IAAY,EAAE,cAAc,KAAK,aAAa,IAAI,CAAC;GAC7E,GAAI,KAAK,mBAAmB,KAAA,IAAY,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;EACrF,CAAC;CACH;AACF,CAAC;AAED,MAAa,wBAAwBA,sBAAAA,YAAY;CAC/C,QAAQ;CACR,MAAM;CACN,cAAc;CACd,iBAAiB;CACjB,gBAAgB;CAChB,SAAS;CACT,aAAa;CACb,MAAM,CAAC,WAAW;CAClB,cAAc;CACd,SAAS,OAAO,EAAE,QAAQ,iBAAiB;EACzC,MAAM,aAAa,QAAQ,UAAU;EACrC,MAAM,OAAO,UAAU,OAAO,UAAU;EACxC,OAAO,EAAE,SAAS,mBAAmB;CACvC;AACF,CAAC;AAED,MAAa,uBAAuBA,sBAAAA,YAAY;CAC9C,QAAQ;CACR,MAAM;CACN,cAAc;CACd,iBAAiB;CACjB,gBAAgB;CAChB,SAAS;CACT,aACE;CACF,MAAM,CAAC,WAAW;CAClB,cAAc;CACd,SAAS,OAAO,EAAE,QAAQ,iBAAiB;EACzC,MAAM,aAAa,QAAQ,UAAU;EAErC,OAAO,wBAAwB,QAAQ,MADjB,OAAO,UAAU,MAAM,UAAU,CACT;CAChD;AACF,CAAC;AAED,MAAa,wBAAwBA,sBAAAA,YAAY;CAC/C,QAAQ;CACR,MAAM;CACN,cAAc;CACd,iBAAiB;CACjB,gBAAgB;CAChB,SAAS;CACT,aACE;CACF,MAAM,CAAC,WAAW;CAClB,cAAc;CACd,SAAS,OAAO,EAAE,QAAQ,iBAAiB;EACzC,MAAM,aAAa,QAAQ,UAAU;EAErC,OAAO,wBAAwB,QAAQ,MADjB,OAAO,UAAU,OAAO,UAAU,CACV;CAChD;AACF,CAAC;AAED,MAAa,qBAAqBA,sBAAAA,YAAY;CAC5C,QAAQ;CACR,MAAM;CACN,cAAc;CACd,iBAAiB;CACjB,gBAAgB;CAChB,SAAS;CACT,aACE;CACF,MAAM,CAAC,WAAW;CAClB,cAAc;CACd,SAAS,OAAO,EAAE,QAAQ,iBAAiB;EACzC,MAAM,aAAa,QAAQ,UAAU;EACrC,OAAO,MAAM,OAAO,UAAU,IAAI,UAAU;CAC9C;AACF,CAAC;AAED,MAAa,+BAA+BA,sBAAAA,YAAY;CACtD,QAAQ;CACR,MAAM;CACN,cAAc;CACd,iBAAiB;CACjB,kBAAkB;CAClB,gBAAgB;CAChB,SAAS;CACT,aAAa;CACb,MAAM,CAAC,WAAW;CAClB,cAAc;CACd,SAAS,OAAO,EAAE,QAAQ,YAAY,OAAO,kBAAkB,qBAAqB;EAClF,MAAM,iBAAiB,MAAM,OAAO,WAAW,CAAC,EAAE,SAAS,WAAW;EACtE,IAAI,CAAC,gBACH,OAAO,EAAE,UAAU,CAAC,EAAE;EAExB,MAAM,WAAW,MAAM,OAAO,UAAU,IAAI,UAAU;EACtD,MAAM,WAAW,MAAM,eAAe,aAAa,UAAU,MAAM,YAAY;GAC7E;GACA;GACA;EACF,CAAC;EACD,IAAI,CAAC,UAAU,YACb,OAAO,EAAE,SAAS;EAEpB,MAAM,eAAe,SAAS;EAQ9B,OAAO,EAAE,UAAU,MAPI,QAAQ,IAC7B,SAAS,IAAI,OAAM,YAAW;GAC5B,IAAI,QAAQ,YAAY,eAAe,CAAC,QAAQ,OAAO,OAAO;GAC9D,MAAM,MAAM,MAAM,gBAAgB,QAAQ,cAAc,QAAQ,KAAK;GACrE,OAAO,MAAM;IAAE,GAAG;IAAS;GAAI,IAAI;EACrC,CAAC,CACH,EAC4B;CAC9B;AACF,CAAC"}
@@ -30,7 +30,7 @@ var agent_builder_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll
30
30
  });
31
31
  let agentBuilderWorkflowsPromise;
32
32
  async function loadAgentBuilderWorkflows() {
33
- agentBuilderWorkflowsPromise ??= Promise.resolve().then(() => require("../../dist-BmrsK_KX.cjs")).then((mod) => mod.agentBuilderWorkflows);
33
+ agentBuilderWorkflowsPromise ??= Promise.resolve().then(() => require("../../dist-3A2vpk0A.cjs")).then((mod) => mod.agentBuilderWorkflows);
34
34
  return agentBuilderWorkflowsPromise;
35
35
  }
36
36
  async function registerAgentBuilderWorkflows(mastra) {
@@ -29,7 +29,7 @@ var agent_builder_exports = /* @__PURE__ */ __exportAll({
29
29
  });
30
30
  let agentBuilderWorkflowsPromise;
31
31
  async function loadAgentBuilderWorkflows() {
32
- agentBuilderWorkflowsPromise ??= import("../../dist-4Qm6OSPJ.js").then((mod) => mod.agentBuilderWorkflows);
32
+ agentBuilderWorkflowsPromise ??= import("../../dist-CPemc7JX.js").then((mod) => mod.agentBuilderWorkflows);
33
33
  return agentBuilderWorkflowsPromise;
34
34
  }
35
35
  async function registerAgentBuilderWorkflows(mastra) {
@@ -1 +1 @@
1
- {"version":3,"file":"authorship.cjs","names":["MASTRA_RESOURCE_ID_KEY","MASTRA_USER_KEY","MASTRA_USER_PERMISSIONS_KEY","HTTPException"],"sources":["../../../src/server/handlers/authorship.ts"],"sourcesContent":["import { matchesPermission } from '@mastra/core/auth/ee';\nimport type { RequestContext } from '@mastra/core/di';\n\nimport { MASTRA_RESOURCE_ID_KEY, MASTRA_USER_KEY, MASTRA_USER_PERMISSIONS_KEY } from '../constants';\nimport { HTTPException } from '../http-exception';\n\n/**\n * Shape of a stored record that carries ownership + visibility metadata.\n * Used by `matchesAuthorFilter` and the access-assertion helpers.\n */\nexport type OwnedRecord = {\n authorId?: string | null;\n visibility?: 'private' | 'public';\n};\n\n/**\n * Returns the author id associated with the authenticated caller, or `null`\n * if auth is not configured / the caller cannot be resolved.\n *\n * Prefers `MASTRA_RESOURCE_ID_KEY` (set by `authConfig.mapUserToResourceId`)\n * and falls back to `user.id` on the authenticated user object.\n */\nexport function getCallerAuthorId(requestContext: RequestContext): string | null {\n const resourceId = requestContext.get(MASTRA_RESOURCE_ID_KEY);\n if (typeof resourceId === 'string' && resourceId.length > 0) {\n return resourceId;\n }\n\n const user = requestContext.get(MASTRA_USER_KEY);\n if (user && typeof user === 'object' && 'id' in user) {\n const id = (user as { id: unknown }).id;\n if (typeof id === 'string' && id.length > 0) {\n return id;\n }\n }\n\n return null;\n}\n\n/**\n * Returns the list of permission strings currently attached to the caller by\n * the RBAC provider. Returns an empty array when RBAC isn't configured.\n */\nexport function getCallerPermissions(requestContext: RequestContext): string[] {\n const raw = requestContext.get(MASTRA_USER_PERMISSIONS_KEY);\n if (Array.isArray(raw)) {\n return raw.filter((p): p is string => typeof p === 'string');\n }\n return [];\n}\n\n/**\n * True if the caller holds a wildcard permission that lets them manage a\n * resource they don't own (e.g. admins listing agents across tenants).\n *\n * Recognizes `*`, `<resource>:*`, and `<resource>:admin`.\n */\nexport function hasAdminBypass(requestContext: RequestContext, resource: string): boolean {\n const permissions = getCallerPermissions(requestContext);\n if (permissions.length === 0) return false;\n const wildcardAll = '*';\n const resourceWildcard = `${resource}:*`;\n const resourceAdmin = `${resource}:admin`;\n return permissions.some(p => p === wildcardAll || p === resourceWildcard || p === resourceAdmin);\n}\n\n/**\n * True if the caller holds a permission explicitly scoped to a specific\n * resource id — e.g. `agents:read:agent-123` or `agents:*:agent-123`.\n *\n * Broad grants without a resource-id segment (e.g. the role-default\n * `agents:execute`) are intentionally NOT treated as satisfying ownership\n * overrides. Those broad grants already gate route access at the\n * `requiresPermission` layer; giving them a second life as per-record\n * overrides would defeat the owner/visibility model.\n *\n * When called without `resourceId` (the legacy shape), falls back to the\n * original \"any matching permission\" behavior.\n */\nexport function hasScopedPermission(args: {\n requestContext: RequestContext;\n resource: string;\n action: string;\n resourceId?: string;\n}): boolean {\n const { requestContext, resource, action, resourceId } = args;\n const permissions = getCallerPermissions(requestContext);\n if (permissions.length === 0) return false;\n\n if (!resourceId) {\n const required = `${resource}:${action}`;\n return permissions.some(p => matchesPermission(p, required));\n }\n\n const required = `${resource}:${action}:${resourceId}`;\n return permissions.some(p => {\n // Only honor grants that explicitly name a resource id. A granted\n // permission with just `<resource>:<action>` (no id segment) is\n // considered a broad role grant, not a per-record override.\n const parts = p.split(':');\n if (parts.length < 3) return false;\n return matchesPermission(p, required);\n });\n}\n\nexport type AuthorFilter =\n | { kind: 'unrestricted' }\n | { kind: 'exact'; authorId: string }\n | { kind: 'ownedOrPublic'; callerAuthorId: string }\n | { kind: 'publicOnly' }\n | { kind: 'ownedOrPublicOthers'; callerAuthorId: string; queryAuthorId: string };\n\n/**\n * Resolves the filter to apply when listing owner-scoped records.\n *\n * Behavior matrix:\n * - Admin bypass + no query overrides → `unrestricted`.\n * - Admin bypass + `authorId=X` → `exact` (all of X's rows).\n * - `visibility=public` (any caller) → `publicOnly` (aggregate public rows across owners).\n * - `authorId=X`, caller === X → `exact` (all of caller's rows).\n * - `authorId=X`, caller !== X (non-admin) → `ownedOrPublicOthers` (only X's public rows).\n * - No caller (auth off) → `unrestricted` (or `exact` if query supplied).\n * - Default → `ownedOrPublic` (caller's rows + legacy unowned + any public rows).\n */\nexport function resolveAuthorFilter(args: {\n requestContext: RequestContext;\n resource: string;\n queryAuthorId?: string;\n queryVisibility?: 'public';\n}): AuthorFilter {\n const { requestContext, resource, queryAuthorId, queryVisibility } = args;\n const callerAuthorId = getCallerAuthorId(requestContext);\n const bypass = hasAdminBypass(requestContext, resource);\n\n if (queryVisibility === 'public' && !queryAuthorId) {\n return { kind: 'publicOnly' };\n }\n\n if (bypass) {\n return queryAuthorId ? { kind: 'exact', authorId: queryAuthorId } : { kind: 'unrestricted' };\n }\n\n // Auth isn't configured (no caller) → treat as unrestricted. The route's\n // `requiresAuth`/`requiresPermission` is what gates access in that mode.\n if (!callerAuthorId) {\n return queryAuthorId ? { kind: 'exact', authorId: queryAuthorId } : { kind: 'unrestricted' };\n }\n\n if (queryAuthorId) {\n if (queryAuthorId === callerAuthorId) {\n return { kind: 'exact', authorId: callerAuthorId };\n }\n // Non-owner asking about another user: only that user's public rows are visible.\n return { kind: 'ownedOrPublicOthers', callerAuthorId, queryAuthorId };\n }\n\n return { kind: 'ownedOrPublic', callerAuthorId };\n}\n\n/**\n * Returns `true` if the record is visible to the caller given the resolved\n * filter. See `resolveAuthorFilter` for the filter semantics.\n *\n * Legacy rows with `authorId == null` are treated as public (visible to all).\n */\nexport function matchesAuthorFilter(record: OwnedRecord, filter: AuthorFilter): boolean {\n const owner = record.authorId ?? null;\n const isPublic = record.visibility === 'public';\n\n switch (filter.kind) {\n case 'unrestricted':\n return true;\n case 'exact':\n return owner === filter.authorId;\n case 'ownedOrPublic':\n return owner === null || owner === filter.callerAuthorId || isPublic;\n case 'publicOnly':\n return owner === null || isPublic;\n case 'ownedOrPublicOthers':\n // Filtering by another author's rows: only expose their public ones.\n // Legacy unowned rows match if the query is for `null`; here the query\n // is always for a concrete id, so unowned rows don't match.\n return owner === filter.queryAuthorId && isPublic;\n }\n}\n\n/**\n * Asserts the caller has read access to the record. Throws 404 if not.\n *\n * Read access is granted when:\n * - The record has no owner (legacy/public), OR\n * - The record is marked `visibility: 'public'`, OR\n * - The caller owns the record, OR\n * - The caller has admin bypass (`*`, `<resource>:*`, `<resource>:admin`), OR\n * - The caller holds `<resource>:read` or `<resource>:read:<resourceId>`.\n */\nexport function assertReadAccess(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n record: OwnedRecord;\n}): void {\n const { requestContext, resource, resourceId, record } = args;\n const owner = record.authorId ?? null;\n\n if (owner === null) return;\n if (record.visibility === 'public') return;\n if (hasAdminBypass(requestContext, resource)) return;\n\n const callerAuthorId = getCallerAuthorId(requestContext);\n // No authenticated user on the request context means auth is not configured\n // (single-user/dev mode). When auth IS configured, coreAuthMiddleware\n // rejects unauthenticated requests with 401 before they reach handlers,\n // so an absent user here genuinely means no auth provider.\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return;\n if (callerAuthorId === owner) return;\n\n if (hasScopedPermission({ requestContext, resource, action: 'read', resourceId })) {\n return;\n }\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n/**\n * Asserts the caller has execute access to the record. Throws 404 if not.\n *\n * Execute access is granted when:\n * - The record has no owner (legacy/public), OR\n * - The record is marked `visibility: 'public'`, OR\n * - The caller owns the record, OR\n * - The caller has admin bypass (`*`, `<resource>:*`, `<resource>:admin`), OR\n * - The caller holds `<resource>:execute` / `<resource>:execute:<resourceId>`, OR\n * - The caller holds `<resource>:read` / `<resource>:read:<resourceId>`\n * (read implies the ability to consume/chat with the resource).\n */\nexport function assertExecuteAccess(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n record: OwnedRecord;\n}): void {\n const { requestContext, resource, resourceId, record } = args;\n const owner = record.authorId ?? null;\n\n if (owner === null) return;\n if (record.visibility === 'public') return;\n if (hasAdminBypass(requestContext, resource)) return;\n\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return; // No auth configured (see assertReadAccess)\n if (callerAuthorId === owner) return;\n\n if (hasScopedPermission({ requestContext, resource, action: 'execute', resourceId })) {\n return;\n }\n if (hasScopedPermission({ requestContext, resource, action: 'read', resourceId })) {\n return;\n }\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n/**\n * Asserts the caller has write access (edit or delete) to the record.\n * Throws 404 if not.\n *\n * Write access is granted when:\n * - The record has no owner (legacy), OR\n * - The caller owns the record, OR\n * - The caller has admin bypass, OR\n * - The caller holds `<resource>:<action>` or `<resource>:<action>:<resourceId>`.\n *\n * `visibility: 'public'` alone does NOT grant write access.\n */\nexport function assertWriteAccess(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n action: 'edit' | 'delete' | 'write';\n record: OwnedRecord;\n}): void {\n const { requestContext, resource, resourceId, action, record } = args;\n const owner = record.authorId ?? null;\n\n if (owner === null) return;\n if (hasAdminBypass(requestContext, resource)) return;\n\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return; // No auth configured (see assertReadAccess)\n if (callerAuthorId === owner) return;\n\n if (hasScopedPermission({ requestContext, resource, action, resourceId })) {\n return;\n }\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n/**\n * Asserts the caller has share access to the record. Throws 404 if not.\n *\n * Share access controls who can change a record's audience/visibility\n * (e.g. flipping `private` ↔ `public`). It is intentionally separate from\n * `write`: a caller with only `<resource>:write` MUST NOT be able to flip\n * visibility — that would let any editor expose private records.\n *\n * Share access is granted when:\n * - The record has no owner (legacy), OR\n * - The caller owns the record (creators can share their own records), OR\n * - The caller has admin bypass (`*`, `<resource>:*`, `<resource>:admin`), OR\n * - The caller holds `<resource>:share` / `<resource>:share:<resourceId>`\n * (or any pattern that matches it, e.g. `*:share`).\n *\n * `visibility: 'public'` does NOT grant share access — being readable doesn't\n * imply the right to change who else can read.\n */\nexport function assertShareAccess(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n record: OwnedRecord;\n}): void {\n const { requestContext, resource, resourceId, record } = args;\n const owner = record.authorId ?? null;\n\n if (owner === null) return;\n if (hasAdminBypass(requestContext, resource)) return;\n\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return; // No auth configured (see assertReadAccess)\n if (callerAuthorId === owner) return;\n\n if (hasScopedPermission({ requestContext, resource, action: 'share', resourceId })) {\n return;\n }\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n/**\n * Alias for `assertWriteAccess` with `action: 'edit'`. Prefer `assertWriteAccess`\n * in new code so the action is explicit.\n */\nexport function assertOwnership(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n record: OwnedRecord;\n}): void {\n assertWriteAccess({ ...args, action: 'edit' });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"authorship.cjs","names":["MASTRA_RESOURCE_ID_KEY","MASTRA_USER_KEY","MASTRA_USER_PERMISSIONS_KEY","HTTPException"],"sources":["../../../src/server/handlers/authorship.ts"],"sourcesContent":["import { matchesPermission } from '@mastra/core/auth/ee';\nimport type { RequestContext } from '@mastra/core/di';\n\nimport { MASTRA_RESOURCE_ID_KEY, MASTRA_USER_KEY, MASTRA_USER_PERMISSIONS_KEY } from '../constants';\nimport { HTTPException } from '../http-exception';\n\n/**\n * Shape of a stored record that carries ownership + visibility metadata.\n * Used by `matchesAuthorFilter` and the access-assertion helpers.\n */\nexport type OwnedRecord = {\n authorId?: string | null;\n visibility?: 'private' | 'public';\n};\n\n/**\n * Returns the author id associated with the authenticated caller, or `null`\n * if auth is not configured / the caller cannot be resolved.\n *\n * Prefers `MASTRA_RESOURCE_ID_KEY` (set by `authConfig.mapUserToResourceId`)\n * and falls back to `user.id` on the authenticated user object.\n */\nexport function getCallerAuthorId(requestContext: RequestContext): string | null {\n const resourceId = requestContext.get(MASTRA_RESOURCE_ID_KEY);\n if (typeof resourceId === 'string' && resourceId.length > 0) {\n return resourceId;\n }\n\n const user = requestContext.get(MASTRA_USER_KEY);\n if (user && typeof user === 'object' && 'id' in user) {\n const id = user.id;\n if (typeof id === 'string' && id.length > 0) {\n return id;\n }\n }\n\n return null;\n}\n\n/**\n * Returns the list of permission strings currently attached to the caller by\n * the RBAC provider. Returns an empty array when RBAC isn't configured.\n */\nexport function getCallerPermissions(requestContext: RequestContext): string[] {\n const raw = requestContext.get(MASTRA_USER_PERMISSIONS_KEY);\n if (Array.isArray(raw)) {\n return raw.filter((p): p is string => typeof p === 'string');\n }\n return [];\n}\n\n/**\n * True if the caller holds a wildcard permission that lets them manage a\n * resource they don't own (e.g. admins listing agents across tenants).\n *\n * Recognizes `*`, `<resource>:*`, and `<resource>:admin`.\n */\nexport function hasAdminBypass(requestContext: RequestContext, resource: string): boolean {\n const permissions = getCallerPermissions(requestContext);\n if (permissions.length === 0) return false;\n const wildcardAll = '*';\n const resourceWildcard = `${resource}:*`;\n const resourceAdmin = `${resource}:admin`;\n return permissions.some(p => p === wildcardAll || p === resourceWildcard || p === resourceAdmin);\n}\n\n/**\n * True if the caller holds a permission explicitly scoped to a specific\n * resource id — e.g. `agents:read:agent-123` or `agents:*:agent-123`.\n *\n * Broad grants without a resource-id segment (e.g. the role-default\n * `agents:execute`) are intentionally NOT treated as satisfying ownership\n * overrides. Those broad grants already gate route access at the\n * `requiresPermission` layer; giving them a second life as per-record\n * overrides would defeat the owner/visibility model.\n *\n * When called without `resourceId` (the legacy shape), falls back to the\n * original \"any matching permission\" behavior.\n */\nexport function hasScopedPermission(args: {\n requestContext: RequestContext;\n resource: string;\n action: string;\n resourceId?: string;\n}): boolean {\n const { requestContext, resource, action, resourceId } = args;\n const permissions = getCallerPermissions(requestContext);\n if (permissions.length === 0) return false;\n\n if (!resourceId) {\n const required = `${resource}:${action}`;\n return permissions.some(p => matchesPermission(p, required));\n }\n\n const required = `${resource}:${action}:${resourceId}`;\n return permissions.some(p => {\n // Only honor grants that explicitly name a resource id. A granted\n // permission with just `<resource>:<action>` (no id segment) is\n // considered a broad role grant, not a per-record override.\n const parts = p.split(':');\n if (parts.length < 3) return false;\n return matchesPermission(p, required);\n });\n}\n\nexport type AuthorFilter =\n | { kind: 'unrestricted' }\n | { kind: 'exact'; authorId: string }\n | { kind: 'ownedOrPublic'; callerAuthorId: string }\n | { kind: 'publicOnly' }\n | { kind: 'ownedOrPublicOthers'; callerAuthorId: string; queryAuthorId: string };\n\n/**\n * Resolves the filter to apply when listing owner-scoped records.\n *\n * Behavior matrix:\n * - Admin bypass + no query overrides → `unrestricted`.\n * - Admin bypass + `authorId=X` → `exact` (all of X's rows).\n * - `visibility=public` (any caller) → `publicOnly` (aggregate public rows across owners).\n * - `authorId=X`, caller === X → `exact` (all of caller's rows).\n * - `authorId=X`, caller !== X (non-admin) → `ownedOrPublicOthers` (only X's public rows).\n * - No caller (auth off) → `unrestricted` (or `exact` if query supplied).\n * - Default → `ownedOrPublic` (caller's rows + legacy unowned + any public rows).\n */\nexport function resolveAuthorFilter(args: {\n requestContext: RequestContext;\n resource: string;\n queryAuthorId?: string;\n queryVisibility?: 'public';\n}): AuthorFilter {\n const { requestContext, resource, queryAuthorId, queryVisibility } = args;\n const callerAuthorId = getCallerAuthorId(requestContext);\n const bypass = hasAdminBypass(requestContext, resource);\n\n if (queryVisibility === 'public' && !queryAuthorId) {\n return { kind: 'publicOnly' };\n }\n\n if (bypass) {\n return queryAuthorId ? { kind: 'exact', authorId: queryAuthorId } : { kind: 'unrestricted' };\n }\n\n // Auth isn't configured (no caller) → treat as unrestricted. The route's\n // `requiresAuth`/`requiresPermission` is what gates access in that mode.\n if (!callerAuthorId) {\n return queryAuthorId ? { kind: 'exact', authorId: queryAuthorId } : { kind: 'unrestricted' };\n }\n\n if (queryAuthorId) {\n if (queryAuthorId === callerAuthorId) {\n return { kind: 'exact', authorId: callerAuthorId };\n }\n // Non-owner asking about another user: only that user's public rows are visible.\n return { kind: 'ownedOrPublicOthers', callerAuthorId, queryAuthorId };\n }\n\n return { kind: 'ownedOrPublic', callerAuthorId };\n}\n\n/**\n * Returns `true` if the record is visible to the caller given the resolved\n * filter. See `resolveAuthorFilter` for the filter semantics.\n *\n * Legacy rows with `authorId == null` are treated as public (visible to all).\n */\nexport function matchesAuthorFilter(record: OwnedRecord, filter: AuthorFilter): boolean {\n const owner = record.authorId ?? null;\n const isPublic = record.visibility === 'public';\n\n switch (filter.kind) {\n case 'unrestricted':\n return true;\n case 'exact':\n return owner === filter.authorId;\n case 'ownedOrPublic':\n return owner === null || owner === filter.callerAuthorId || isPublic;\n case 'publicOnly':\n return owner === null || isPublic;\n case 'ownedOrPublicOthers':\n // Filtering by another author's rows: only expose their public ones.\n // Legacy unowned rows match if the query is for `null`; here the query\n // is always for a concrete id, so unowned rows don't match.\n return owner === filter.queryAuthorId && isPublic;\n }\n}\n\n/**\n * Asserts the caller has read access to the record. Throws 404 if not.\n *\n * Read access is granted when:\n * - The record has no owner (legacy/public), OR\n * - The record is marked `visibility: 'public'`, OR\n * - The caller owns the record, OR\n * - The caller has admin bypass (`*`, `<resource>:*`, `<resource>:admin`), OR\n * - The caller holds `<resource>:read` or `<resource>:read:<resourceId>`.\n */\nexport function assertReadAccess(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n record: OwnedRecord;\n}): void {\n const { requestContext, resource, resourceId, record } = args;\n const owner = record.authorId ?? null;\n\n if (owner === null) return;\n if (record.visibility === 'public') return;\n if (hasAdminBypass(requestContext, resource)) return;\n\n const callerAuthorId = getCallerAuthorId(requestContext);\n // No authenticated user on the request context means auth is not configured\n // (single-user/dev mode). When auth IS configured, coreAuthMiddleware\n // rejects unauthenticated requests with 401 before they reach handlers,\n // so an absent user here genuinely means no auth provider.\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return;\n if (callerAuthorId === owner) return;\n\n if (hasScopedPermission({ requestContext, resource, action: 'read', resourceId })) {\n return;\n }\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n/**\n * Asserts the caller has execute access to the record. Throws 404 if not.\n *\n * Execute access is granted when:\n * - The record has no owner (legacy/public), OR\n * - The record is marked `visibility: 'public'`, OR\n * - The caller owns the record, OR\n * - The caller has admin bypass (`*`, `<resource>:*`, `<resource>:admin`), OR\n * - The caller holds `<resource>:execute` / `<resource>:execute:<resourceId>`, OR\n * - The caller holds `<resource>:read` / `<resource>:read:<resourceId>`\n * (read implies the ability to consume/chat with the resource).\n */\nexport function assertExecuteAccess(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n record: OwnedRecord;\n}): void {\n const { requestContext, resource, resourceId, record } = args;\n const owner = record.authorId ?? null;\n\n if (owner === null) return;\n if (record.visibility === 'public') return;\n if (hasAdminBypass(requestContext, resource)) return;\n\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return; // No auth configured (see assertReadAccess)\n if (callerAuthorId === owner) return;\n\n if (hasScopedPermission({ requestContext, resource, action: 'execute', resourceId })) {\n return;\n }\n if (hasScopedPermission({ requestContext, resource, action: 'read', resourceId })) {\n return;\n }\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n/**\n * Asserts the caller has write access (edit or delete) to the record.\n * Throws 404 if not.\n *\n * Write access is granted when:\n * - The record has no owner (legacy), OR\n * - The caller owns the record, OR\n * - The caller has admin bypass, OR\n * - The caller holds `<resource>:<action>` or `<resource>:<action>:<resourceId>`.\n *\n * `visibility: 'public'` alone does NOT grant write access.\n */\nexport function assertWriteAccess(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n action: 'edit' | 'delete' | 'write';\n record: OwnedRecord;\n}): void {\n const { requestContext, resource, resourceId, action, record } = args;\n const owner = record.authorId ?? null;\n\n if (owner === null) return;\n if (hasAdminBypass(requestContext, resource)) return;\n\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return; // No auth configured (see assertReadAccess)\n if (callerAuthorId === owner) return;\n\n if (hasScopedPermission({ requestContext, resource, action, resourceId })) {\n return;\n }\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n/**\n * Asserts the caller has share access to the record. Throws 404 if not.\n *\n * Share access controls who can change a record's audience/visibility\n * (e.g. flipping `private` ↔ `public`). It is intentionally separate from\n * `write`: a caller with only `<resource>:write` MUST NOT be able to flip\n * visibility — that would let any editor expose private records.\n *\n * Share access is granted when:\n * - The record has no owner (legacy), OR\n * - The caller owns the record (creators can share their own records), OR\n * - The caller has admin bypass (`*`, `<resource>:*`, `<resource>:admin`), OR\n * - The caller holds `<resource>:share` / `<resource>:share:<resourceId>`\n * (or any pattern that matches it, e.g. `*:share`).\n *\n * `visibility: 'public'` does NOT grant share access — being readable doesn't\n * imply the right to change who else can read.\n */\nexport function assertShareAccess(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n record: OwnedRecord;\n}): void {\n const { requestContext, resource, resourceId, record } = args;\n const owner = record.authorId ?? null;\n\n if (owner === null) return;\n if (hasAdminBypass(requestContext, resource)) return;\n\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return; // No auth configured (see assertReadAccess)\n if (callerAuthorId === owner) return;\n\n if (hasScopedPermission({ requestContext, resource, action: 'share', resourceId })) {\n return;\n }\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n/**\n * Alias for `assertWriteAccess` with `action: 'edit'`. Prefer `assertWriteAccess`\n * in new code so the action is explicit.\n */\nexport function assertOwnership(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n record: OwnedRecord;\n}): void {\n assertWriteAccess({ ...args, action: 'edit' });\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"authorship.js","names":[],"sources":["../../../src/server/handlers/authorship.ts"],"sourcesContent":["import { matchesPermission } from '@mastra/core/auth/ee';\nimport type { RequestContext } from '@mastra/core/di';\n\nimport { MASTRA_RESOURCE_ID_KEY, MASTRA_USER_KEY, MASTRA_USER_PERMISSIONS_KEY } from '../constants';\nimport { HTTPException } from '../http-exception';\n\n/**\n * Shape of a stored record that carries ownership + visibility metadata.\n * Used by `matchesAuthorFilter` and the access-assertion helpers.\n */\nexport type OwnedRecord = {\n authorId?: string | null;\n visibility?: 'private' | 'public';\n};\n\n/**\n * Returns the author id associated with the authenticated caller, or `null`\n * if auth is not configured / the caller cannot be resolved.\n *\n * Prefers `MASTRA_RESOURCE_ID_KEY` (set by `authConfig.mapUserToResourceId`)\n * and falls back to `user.id` on the authenticated user object.\n */\nexport function getCallerAuthorId(requestContext: RequestContext): string | null {\n const resourceId = requestContext.get(MASTRA_RESOURCE_ID_KEY);\n if (typeof resourceId === 'string' && resourceId.length > 0) {\n return resourceId;\n }\n\n const user = requestContext.get(MASTRA_USER_KEY);\n if (user && typeof user === 'object' && 'id' in user) {\n const id = (user as { id: unknown }).id;\n if (typeof id === 'string' && id.length > 0) {\n return id;\n }\n }\n\n return null;\n}\n\n/**\n * Returns the list of permission strings currently attached to the caller by\n * the RBAC provider. Returns an empty array when RBAC isn't configured.\n */\nexport function getCallerPermissions(requestContext: RequestContext): string[] {\n const raw = requestContext.get(MASTRA_USER_PERMISSIONS_KEY);\n if (Array.isArray(raw)) {\n return raw.filter((p): p is string => typeof p === 'string');\n }\n return [];\n}\n\n/**\n * True if the caller holds a wildcard permission that lets them manage a\n * resource they don't own (e.g. admins listing agents across tenants).\n *\n * Recognizes `*`, `<resource>:*`, and `<resource>:admin`.\n */\nexport function hasAdminBypass(requestContext: RequestContext, resource: string): boolean {\n const permissions = getCallerPermissions(requestContext);\n if (permissions.length === 0) return false;\n const wildcardAll = '*';\n const resourceWildcard = `${resource}:*`;\n const resourceAdmin = `${resource}:admin`;\n return permissions.some(p => p === wildcardAll || p === resourceWildcard || p === resourceAdmin);\n}\n\n/**\n * True if the caller holds a permission explicitly scoped to a specific\n * resource id — e.g. `agents:read:agent-123` or `agents:*:agent-123`.\n *\n * Broad grants without a resource-id segment (e.g. the role-default\n * `agents:execute`) are intentionally NOT treated as satisfying ownership\n * overrides. Those broad grants already gate route access at the\n * `requiresPermission` layer; giving them a second life as per-record\n * overrides would defeat the owner/visibility model.\n *\n * When called without `resourceId` (the legacy shape), falls back to the\n * original \"any matching permission\" behavior.\n */\nexport function hasScopedPermission(args: {\n requestContext: RequestContext;\n resource: string;\n action: string;\n resourceId?: string;\n}): boolean {\n const { requestContext, resource, action, resourceId } = args;\n const permissions = getCallerPermissions(requestContext);\n if (permissions.length === 0) return false;\n\n if (!resourceId) {\n const required = `${resource}:${action}`;\n return permissions.some(p => matchesPermission(p, required));\n }\n\n const required = `${resource}:${action}:${resourceId}`;\n return permissions.some(p => {\n // Only honor grants that explicitly name a resource id. A granted\n // permission with just `<resource>:<action>` (no id segment) is\n // considered a broad role grant, not a per-record override.\n const parts = p.split(':');\n if (parts.length < 3) return false;\n return matchesPermission(p, required);\n });\n}\n\nexport type AuthorFilter =\n | { kind: 'unrestricted' }\n | { kind: 'exact'; authorId: string }\n | { kind: 'ownedOrPublic'; callerAuthorId: string }\n | { kind: 'publicOnly' }\n | { kind: 'ownedOrPublicOthers'; callerAuthorId: string; queryAuthorId: string };\n\n/**\n * Resolves the filter to apply when listing owner-scoped records.\n *\n * Behavior matrix:\n * - Admin bypass + no query overrides → `unrestricted`.\n * - Admin bypass + `authorId=X` → `exact` (all of X's rows).\n * - `visibility=public` (any caller) → `publicOnly` (aggregate public rows across owners).\n * - `authorId=X`, caller === X → `exact` (all of caller's rows).\n * - `authorId=X`, caller !== X (non-admin) → `ownedOrPublicOthers` (only X's public rows).\n * - No caller (auth off) → `unrestricted` (or `exact` if query supplied).\n * - Default → `ownedOrPublic` (caller's rows + legacy unowned + any public rows).\n */\nexport function resolveAuthorFilter(args: {\n requestContext: RequestContext;\n resource: string;\n queryAuthorId?: string;\n queryVisibility?: 'public';\n}): AuthorFilter {\n const { requestContext, resource, queryAuthorId, queryVisibility } = args;\n const callerAuthorId = getCallerAuthorId(requestContext);\n const bypass = hasAdminBypass(requestContext, resource);\n\n if (queryVisibility === 'public' && !queryAuthorId) {\n return { kind: 'publicOnly' };\n }\n\n if (bypass) {\n return queryAuthorId ? { kind: 'exact', authorId: queryAuthorId } : { kind: 'unrestricted' };\n }\n\n // Auth isn't configured (no caller) → treat as unrestricted. The route's\n // `requiresAuth`/`requiresPermission` is what gates access in that mode.\n if (!callerAuthorId) {\n return queryAuthorId ? { kind: 'exact', authorId: queryAuthorId } : { kind: 'unrestricted' };\n }\n\n if (queryAuthorId) {\n if (queryAuthorId === callerAuthorId) {\n return { kind: 'exact', authorId: callerAuthorId };\n }\n // Non-owner asking about another user: only that user's public rows are visible.\n return { kind: 'ownedOrPublicOthers', callerAuthorId, queryAuthorId };\n }\n\n return { kind: 'ownedOrPublic', callerAuthorId };\n}\n\n/**\n * Returns `true` if the record is visible to the caller given the resolved\n * filter. See `resolveAuthorFilter` for the filter semantics.\n *\n * Legacy rows with `authorId == null` are treated as public (visible to all).\n */\nexport function matchesAuthorFilter(record: OwnedRecord, filter: AuthorFilter): boolean {\n const owner = record.authorId ?? null;\n const isPublic = record.visibility === 'public';\n\n switch (filter.kind) {\n case 'unrestricted':\n return true;\n case 'exact':\n return owner === filter.authorId;\n case 'ownedOrPublic':\n return owner === null || owner === filter.callerAuthorId || isPublic;\n case 'publicOnly':\n return owner === null || isPublic;\n case 'ownedOrPublicOthers':\n // Filtering by another author's rows: only expose their public ones.\n // Legacy unowned rows match if the query is for `null`; here the query\n // is always for a concrete id, so unowned rows don't match.\n return owner === filter.queryAuthorId && isPublic;\n }\n}\n\n/**\n * Asserts the caller has read access to the record. Throws 404 if not.\n *\n * Read access is granted when:\n * - The record has no owner (legacy/public), OR\n * - The record is marked `visibility: 'public'`, OR\n * - The caller owns the record, OR\n * - The caller has admin bypass (`*`, `<resource>:*`, `<resource>:admin`), OR\n * - The caller holds `<resource>:read` or `<resource>:read:<resourceId>`.\n */\nexport function assertReadAccess(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n record: OwnedRecord;\n}): void {\n const { requestContext, resource, resourceId, record } = args;\n const owner = record.authorId ?? null;\n\n if (owner === null) return;\n if (record.visibility === 'public') return;\n if (hasAdminBypass(requestContext, resource)) return;\n\n const callerAuthorId = getCallerAuthorId(requestContext);\n // No authenticated user on the request context means auth is not configured\n // (single-user/dev mode). When auth IS configured, coreAuthMiddleware\n // rejects unauthenticated requests with 401 before they reach handlers,\n // so an absent user here genuinely means no auth provider.\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return;\n if (callerAuthorId === owner) return;\n\n if (hasScopedPermission({ requestContext, resource, action: 'read', resourceId })) {\n return;\n }\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n/**\n * Asserts the caller has execute access to the record. Throws 404 if not.\n *\n * Execute access is granted when:\n * - The record has no owner (legacy/public), OR\n * - The record is marked `visibility: 'public'`, OR\n * - The caller owns the record, OR\n * - The caller has admin bypass (`*`, `<resource>:*`, `<resource>:admin`), OR\n * - The caller holds `<resource>:execute` / `<resource>:execute:<resourceId>`, OR\n * - The caller holds `<resource>:read` / `<resource>:read:<resourceId>`\n * (read implies the ability to consume/chat with the resource).\n */\nexport function assertExecuteAccess(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n record: OwnedRecord;\n}): void {\n const { requestContext, resource, resourceId, record } = args;\n const owner = record.authorId ?? null;\n\n if (owner === null) return;\n if (record.visibility === 'public') return;\n if (hasAdminBypass(requestContext, resource)) return;\n\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return; // No auth configured (see assertReadAccess)\n if (callerAuthorId === owner) return;\n\n if (hasScopedPermission({ requestContext, resource, action: 'execute', resourceId })) {\n return;\n }\n if (hasScopedPermission({ requestContext, resource, action: 'read', resourceId })) {\n return;\n }\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n/**\n * Asserts the caller has write access (edit or delete) to the record.\n * Throws 404 if not.\n *\n * Write access is granted when:\n * - The record has no owner (legacy), OR\n * - The caller owns the record, OR\n * - The caller has admin bypass, OR\n * - The caller holds `<resource>:<action>` or `<resource>:<action>:<resourceId>`.\n *\n * `visibility: 'public'` alone does NOT grant write access.\n */\nexport function assertWriteAccess(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n action: 'edit' | 'delete' | 'write';\n record: OwnedRecord;\n}): void {\n const { requestContext, resource, resourceId, action, record } = args;\n const owner = record.authorId ?? null;\n\n if (owner === null) return;\n if (hasAdminBypass(requestContext, resource)) return;\n\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return; // No auth configured (see assertReadAccess)\n if (callerAuthorId === owner) return;\n\n if (hasScopedPermission({ requestContext, resource, action, resourceId })) {\n return;\n }\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n/**\n * Asserts the caller has share access to the record. Throws 404 if not.\n *\n * Share access controls who can change a record's audience/visibility\n * (e.g. flipping `private` ↔ `public`). It is intentionally separate from\n * `write`: a caller with only `<resource>:write` MUST NOT be able to flip\n * visibility — that would let any editor expose private records.\n *\n * Share access is granted when:\n * - The record has no owner (legacy), OR\n * - The caller owns the record (creators can share their own records), OR\n * - The caller has admin bypass (`*`, `<resource>:*`, `<resource>:admin`), OR\n * - The caller holds `<resource>:share` / `<resource>:share:<resourceId>`\n * (or any pattern that matches it, e.g. `*:share`).\n *\n * `visibility: 'public'` does NOT grant share access — being readable doesn't\n * imply the right to change who else can read.\n */\nexport function assertShareAccess(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n record: OwnedRecord;\n}): void {\n const { requestContext, resource, resourceId, record } = args;\n const owner = record.authorId ?? null;\n\n if (owner === null) return;\n if (hasAdminBypass(requestContext, resource)) return;\n\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return; // No auth configured (see assertReadAccess)\n if (callerAuthorId === owner) return;\n\n if (hasScopedPermission({ requestContext, resource, action: 'share', resourceId })) {\n return;\n }\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n/**\n * Alias for `assertWriteAccess` with `action: 'edit'`. Prefer `assertWriteAccess`\n * in new code so the action is explicit.\n */\nexport function assertOwnership(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n record: OwnedRecord;\n}): void {\n assertWriteAccess({ ...args, action: 'edit' });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"authorship.js","names":[],"sources":["../../../src/server/handlers/authorship.ts"],"sourcesContent":["import { matchesPermission } from '@mastra/core/auth/ee';\nimport type { RequestContext } from '@mastra/core/di';\n\nimport { MASTRA_RESOURCE_ID_KEY, MASTRA_USER_KEY, MASTRA_USER_PERMISSIONS_KEY } from '../constants';\nimport { HTTPException } from '../http-exception';\n\n/**\n * Shape of a stored record that carries ownership + visibility metadata.\n * Used by `matchesAuthorFilter` and the access-assertion helpers.\n */\nexport type OwnedRecord = {\n authorId?: string | null;\n visibility?: 'private' | 'public';\n};\n\n/**\n * Returns the author id associated with the authenticated caller, or `null`\n * if auth is not configured / the caller cannot be resolved.\n *\n * Prefers `MASTRA_RESOURCE_ID_KEY` (set by `authConfig.mapUserToResourceId`)\n * and falls back to `user.id` on the authenticated user object.\n */\nexport function getCallerAuthorId(requestContext: RequestContext): string | null {\n const resourceId = requestContext.get(MASTRA_RESOURCE_ID_KEY);\n if (typeof resourceId === 'string' && resourceId.length > 0) {\n return resourceId;\n }\n\n const user = requestContext.get(MASTRA_USER_KEY);\n if (user && typeof user === 'object' && 'id' in user) {\n const id = user.id;\n if (typeof id === 'string' && id.length > 0) {\n return id;\n }\n }\n\n return null;\n}\n\n/**\n * Returns the list of permission strings currently attached to the caller by\n * the RBAC provider. Returns an empty array when RBAC isn't configured.\n */\nexport function getCallerPermissions(requestContext: RequestContext): string[] {\n const raw = requestContext.get(MASTRA_USER_PERMISSIONS_KEY);\n if (Array.isArray(raw)) {\n return raw.filter((p): p is string => typeof p === 'string');\n }\n return [];\n}\n\n/**\n * True if the caller holds a wildcard permission that lets them manage a\n * resource they don't own (e.g. admins listing agents across tenants).\n *\n * Recognizes `*`, `<resource>:*`, and `<resource>:admin`.\n */\nexport function hasAdminBypass(requestContext: RequestContext, resource: string): boolean {\n const permissions = getCallerPermissions(requestContext);\n if (permissions.length === 0) return false;\n const wildcardAll = '*';\n const resourceWildcard = `${resource}:*`;\n const resourceAdmin = `${resource}:admin`;\n return permissions.some(p => p === wildcardAll || p === resourceWildcard || p === resourceAdmin);\n}\n\n/**\n * True if the caller holds a permission explicitly scoped to a specific\n * resource id — e.g. `agents:read:agent-123` or `agents:*:agent-123`.\n *\n * Broad grants without a resource-id segment (e.g. the role-default\n * `agents:execute`) are intentionally NOT treated as satisfying ownership\n * overrides. Those broad grants already gate route access at the\n * `requiresPermission` layer; giving them a second life as per-record\n * overrides would defeat the owner/visibility model.\n *\n * When called without `resourceId` (the legacy shape), falls back to the\n * original \"any matching permission\" behavior.\n */\nexport function hasScopedPermission(args: {\n requestContext: RequestContext;\n resource: string;\n action: string;\n resourceId?: string;\n}): boolean {\n const { requestContext, resource, action, resourceId } = args;\n const permissions = getCallerPermissions(requestContext);\n if (permissions.length === 0) return false;\n\n if (!resourceId) {\n const required = `${resource}:${action}`;\n return permissions.some(p => matchesPermission(p, required));\n }\n\n const required = `${resource}:${action}:${resourceId}`;\n return permissions.some(p => {\n // Only honor grants that explicitly name a resource id. A granted\n // permission with just `<resource>:<action>` (no id segment) is\n // considered a broad role grant, not a per-record override.\n const parts = p.split(':');\n if (parts.length < 3) return false;\n return matchesPermission(p, required);\n });\n}\n\nexport type AuthorFilter =\n | { kind: 'unrestricted' }\n | { kind: 'exact'; authorId: string }\n | { kind: 'ownedOrPublic'; callerAuthorId: string }\n | { kind: 'publicOnly' }\n | { kind: 'ownedOrPublicOthers'; callerAuthorId: string; queryAuthorId: string };\n\n/**\n * Resolves the filter to apply when listing owner-scoped records.\n *\n * Behavior matrix:\n * - Admin bypass + no query overrides → `unrestricted`.\n * - Admin bypass + `authorId=X` → `exact` (all of X's rows).\n * - `visibility=public` (any caller) → `publicOnly` (aggregate public rows across owners).\n * - `authorId=X`, caller === X → `exact` (all of caller's rows).\n * - `authorId=X`, caller !== X (non-admin) → `ownedOrPublicOthers` (only X's public rows).\n * - No caller (auth off) → `unrestricted` (or `exact` if query supplied).\n * - Default → `ownedOrPublic` (caller's rows + legacy unowned + any public rows).\n */\nexport function resolveAuthorFilter(args: {\n requestContext: RequestContext;\n resource: string;\n queryAuthorId?: string;\n queryVisibility?: 'public';\n}): AuthorFilter {\n const { requestContext, resource, queryAuthorId, queryVisibility } = args;\n const callerAuthorId = getCallerAuthorId(requestContext);\n const bypass = hasAdminBypass(requestContext, resource);\n\n if (queryVisibility === 'public' && !queryAuthorId) {\n return { kind: 'publicOnly' };\n }\n\n if (bypass) {\n return queryAuthorId ? { kind: 'exact', authorId: queryAuthorId } : { kind: 'unrestricted' };\n }\n\n // Auth isn't configured (no caller) → treat as unrestricted. The route's\n // `requiresAuth`/`requiresPermission` is what gates access in that mode.\n if (!callerAuthorId) {\n return queryAuthorId ? { kind: 'exact', authorId: queryAuthorId } : { kind: 'unrestricted' };\n }\n\n if (queryAuthorId) {\n if (queryAuthorId === callerAuthorId) {\n return { kind: 'exact', authorId: callerAuthorId };\n }\n // Non-owner asking about another user: only that user's public rows are visible.\n return { kind: 'ownedOrPublicOthers', callerAuthorId, queryAuthorId };\n }\n\n return { kind: 'ownedOrPublic', callerAuthorId };\n}\n\n/**\n * Returns `true` if the record is visible to the caller given the resolved\n * filter. See `resolveAuthorFilter` for the filter semantics.\n *\n * Legacy rows with `authorId == null` are treated as public (visible to all).\n */\nexport function matchesAuthorFilter(record: OwnedRecord, filter: AuthorFilter): boolean {\n const owner = record.authorId ?? null;\n const isPublic = record.visibility === 'public';\n\n switch (filter.kind) {\n case 'unrestricted':\n return true;\n case 'exact':\n return owner === filter.authorId;\n case 'ownedOrPublic':\n return owner === null || owner === filter.callerAuthorId || isPublic;\n case 'publicOnly':\n return owner === null || isPublic;\n case 'ownedOrPublicOthers':\n // Filtering by another author's rows: only expose their public ones.\n // Legacy unowned rows match if the query is for `null`; here the query\n // is always for a concrete id, so unowned rows don't match.\n return owner === filter.queryAuthorId && isPublic;\n }\n}\n\n/**\n * Asserts the caller has read access to the record. Throws 404 if not.\n *\n * Read access is granted when:\n * - The record has no owner (legacy/public), OR\n * - The record is marked `visibility: 'public'`, OR\n * - The caller owns the record, OR\n * - The caller has admin bypass (`*`, `<resource>:*`, `<resource>:admin`), OR\n * - The caller holds `<resource>:read` or `<resource>:read:<resourceId>`.\n */\nexport function assertReadAccess(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n record: OwnedRecord;\n}): void {\n const { requestContext, resource, resourceId, record } = args;\n const owner = record.authorId ?? null;\n\n if (owner === null) return;\n if (record.visibility === 'public') return;\n if (hasAdminBypass(requestContext, resource)) return;\n\n const callerAuthorId = getCallerAuthorId(requestContext);\n // No authenticated user on the request context means auth is not configured\n // (single-user/dev mode). When auth IS configured, coreAuthMiddleware\n // rejects unauthenticated requests with 401 before they reach handlers,\n // so an absent user here genuinely means no auth provider.\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return;\n if (callerAuthorId === owner) return;\n\n if (hasScopedPermission({ requestContext, resource, action: 'read', resourceId })) {\n return;\n }\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n/**\n * Asserts the caller has execute access to the record. Throws 404 if not.\n *\n * Execute access is granted when:\n * - The record has no owner (legacy/public), OR\n * - The record is marked `visibility: 'public'`, OR\n * - The caller owns the record, OR\n * - The caller has admin bypass (`*`, `<resource>:*`, `<resource>:admin`), OR\n * - The caller holds `<resource>:execute` / `<resource>:execute:<resourceId>`, OR\n * - The caller holds `<resource>:read` / `<resource>:read:<resourceId>`\n * (read implies the ability to consume/chat with the resource).\n */\nexport function assertExecuteAccess(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n record: OwnedRecord;\n}): void {\n const { requestContext, resource, resourceId, record } = args;\n const owner = record.authorId ?? null;\n\n if (owner === null) return;\n if (record.visibility === 'public') return;\n if (hasAdminBypass(requestContext, resource)) return;\n\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return; // No auth configured (see assertReadAccess)\n if (callerAuthorId === owner) return;\n\n if (hasScopedPermission({ requestContext, resource, action: 'execute', resourceId })) {\n return;\n }\n if (hasScopedPermission({ requestContext, resource, action: 'read', resourceId })) {\n return;\n }\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n/**\n * Asserts the caller has write access (edit or delete) to the record.\n * Throws 404 if not.\n *\n * Write access is granted when:\n * - The record has no owner (legacy), OR\n * - The caller owns the record, OR\n * - The caller has admin bypass, OR\n * - The caller holds `<resource>:<action>` or `<resource>:<action>:<resourceId>`.\n *\n * `visibility: 'public'` alone does NOT grant write access.\n */\nexport function assertWriteAccess(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n action: 'edit' | 'delete' | 'write';\n record: OwnedRecord;\n}): void {\n const { requestContext, resource, resourceId, action, record } = args;\n const owner = record.authorId ?? null;\n\n if (owner === null) return;\n if (hasAdminBypass(requestContext, resource)) return;\n\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return; // No auth configured (see assertReadAccess)\n if (callerAuthorId === owner) return;\n\n if (hasScopedPermission({ requestContext, resource, action, resourceId })) {\n return;\n }\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n/**\n * Asserts the caller has share access to the record. Throws 404 if not.\n *\n * Share access controls who can change a record's audience/visibility\n * (e.g. flipping `private` ↔ `public`). It is intentionally separate from\n * `write`: a caller with only `<resource>:write` MUST NOT be able to flip\n * visibility — that would let any editor expose private records.\n *\n * Share access is granted when:\n * - The record has no owner (legacy), OR\n * - The caller owns the record (creators can share their own records), OR\n * - The caller has admin bypass (`*`, `<resource>:*`, `<resource>:admin`), OR\n * - The caller holds `<resource>:share` / `<resource>:share:<resourceId>`\n * (or any pattern that matches it, e.g. `*:share`).\n *\n * `visibility: 'public'` does NOT grant share access — being readable doesn't\n * imply the right to change who else can read.\n */\nexport function assertShareAccess(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n record: OwnedRecord;\n}): void {\n const { requestContext, resource, resourceId, record } = args;\n const owner = record.authorId ?? null;\n\n if (owner === null) return;\n if (hasAdminBypass(requestContext, resource)) return;\n\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return; // No auth configured (see assertReadAccess)\n if (callerAuthorId === owner) return;\n\n if (hasScopedPermission({ requestContext, resource, action: 'share', resourceId })) {\n return;\n }\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n/**\n * Alias for `assertWriteAccess` with `action: 'edit'`. Prefer `assertWriteAccess`\n * in new code so the action is explicit.\n */\nexport function assertOwnership(args: {\n requestContext: RequestContext;\n resource: string;\n resourceId?: string;\n record: OwnedRecord;\n}): void {\n assertWriteAccess({ ...args, action: 'edit' });\n}\n"],"mappings":";;;;;;;;;;;AAsBA,SAAgB,kBAAkB,gBAA+C;CAC/E,MAAM,aAAa,eAAe,IAAI,sBAAsB;CAC5D,IAAI,OAAO,eAAe,YAAY,WAAW,SAAS,GACxD,OAAO;CAGT,MAAM,OAAO,eAAe,IAAI,eAAe;CAC/C,IAAI,QAAQ,OAAO,SAAS,YAAY,QAAQ,MAAM;EACpD,MAAM,KAAK,KAAK;EAChB,IAAI,OAAO,OAAO,YAAY,GAAG,SAAS,GACxC,OAAO;CAEX;CAEA,OAAO;AACT;;;;;AAMA,SAAgB,qBAAqB,gBAA0C;CAC7E,MAAM,MAAM,eAAe,IAAI,2BAA2B;CAC1D,IAAI,MAAM,QAAQ,GAAG,GACnB,OAAO,IAAI,QAAQ,MAAmB,OAAO,MAAM,QAAQ;CAE7D,OAAO,CAAC;AACV;;;;;;;AAQA,SAAgB,eAAe,gBAAgC,UAA2B;CACxF,MAAM,cAAc,qBAAqB,cAAc;CACvD,IAAI,YAAY,WAAW,GAAG,OAAO;CACrC,MAAM,cAAc;CACpB,MAAM,mBAAmB,GAAG,SAAS;CACrC,MAAM,gBAAgB,GAAG,SAAS;CAClC,OAAO,YAAY,MAAK,MAAK,MAAM,eAAe,MAAM,oBAAoB,MAAM,aAAa;AACjG;;;;;;;;;;;;;;AAeA,SAAgB,oBAAoB,MAKxB;CACV,MAAM,EAAE,gBAAgB,UAAU,QAAQ,eAAe;CACzD,MAAM,cAAc,qBAAqB,cAAc;CACvD,IAAI,YAAY,WAAW,GAAG,OAAO;CAErC,IAAI,CAAC,YAAY;EACf,MAAM,WAAW,GAAG,SAAS,GAAG;EAChC,OAAO,YAAY,MAAK,MAAK,kBAAkB,GAAG,QAAQ,CAAC;CAC7D;CAEA,MAAM,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG;CAC1C,OAAO,YAAY,MAAK,MAAK;EAK3B,IADc,EAAE,MAAM,GACd,CAAC,CAAC,SAAS,GAAG,OAAO;EAC7B,OAAO,kBAAkB,GAAG,QAAQ;CACtC,CAAC;AACH;;;;;;;;;;;;;AAqBA,SAAgB,oBAAoB,MAKnB;CACf,MAAM,EAAE,gBAAgB,UAAU,eAAe,oBAAoB;CACrE,MAAM,iBAAiB,kBAAkB,cAAc;CACvD,MAAM,SAAS,eAAe,gBAAgB,QAAQ;CAEtD,IAAI,oBAAoB,YAAY,CAAC,eACnC,OAAO,EAAE,MAAM,aAAa;CAG9B,IAAI,QACF,OAAO,gBAAgB;EAAE,MAAM;EAAS,UAAU;CAAc,IAAI,EAAE,MAAM,eAAe;CAK7F,IAAI,CAAC,gBACH,OAAO,gBAAgB;EAAE,MAAM;EAAS,UAAU;CAAc,IAAI,EAAE,MAAM,eAAe;CAG7F,IAAI,eAAe;EACjB,IAAI,kBAAkB,gBACpB,OAAO;GAAE,MAAM;GAAS,UAAU;EAAe;EAGnD,OAAO;GAAE,MAAM;GAAuB;GAAgB;EAAc;CACtE;CAEA,OAAO;EAAE,MAAM;EAAiB;CAAe;AACjD;;;;;;;AAQA,SAAgB,oBAAoB,QAAqB,QAA+B;CACtF,MAAM,QAAQ,OAAO,YAAY;CACjC,MAAM,WAAW,OAAO,eAAe;CAEvC,QAAQ,OAAO,MAAf;EACE,KAAK,gBACH,OAAO;EACT,KAAK,SACH,OAAO,UAAU,OAAO;EAC1B,KAAK,iBACH,OAAO,UAAU,QAAQ,UAAU,OAAO,kBAAkB;EAC9D,KAAK,cACH,OAAO,UAAU,QAAQ;EAC3B,KAAK,uBAIH,OAAO,UAAU,OAAO,iBAAiB;CAC7C;AACF;;;;;;;;;;;AAYA,SAAgB,iBAAiB,MAKxB;CACP,MAAM,EAAE,gBAAgB,UAAU,YAAY,WAAW;CACzD,MAAM,QAAQ,OAAO,YAAY;CAEjC,IAAI,UAAU,MAAM;CACpB,IAAI,OAAO,eAAe,UAAU;CACpC,IAAI,eAAe,gBAAgB,QAAQ,GAAG;CAE9C,MAAM,iBAAiB,kBAAkB,cAAc;CAKvD,IAAI,CAAC,kBAAkB,CAAC,eAAe,IAAA,cAAmB,GAAG;CAC7D,IAAI,mBAAmB,OAAO;CAE9B,IAAI,oBAAoB;EAAE;EAAgB;EAAU,QAAQ;EAAQ;CAAW,CAAC,GAC9E;CAGF,MAAM,IAAI,cAAc,KAAK,EAAE,SAAS,YAAY,CAAC;AACvD;;;;;;;;;;;;;AAcA,SAAgB,oBAAoB,MAK3B;CACP,MAAM,EAAE,gBAAgB,UAAU,YAAY,WAAW;CACzD,MAAM,QAAQ,OAAO,YAAY;CAEjC,IAAI,UAAU,MAAM;CACpB,IAAI,OAAO,eAAe,UAAU;CACpC,IAAI,eAAe,gBAAgB,QAAQ,GAAG;CAE9C,MAAM,iBAAiB,kBAAkB,cAAc;CACvD,IAAI,CAAC,kBAAkB,CAAC,eAAe,IAAA,cAAmB,GAAG;CAC7D,IAAI,mBAAmB,OAAO;CAE9B,IAAI,oBAAoB;EAAE;EAAgB;EAAU,QAAQ;EAAW;CAAW,CAAC,GACjF;CAEF,IAAI,oBAAoB;EAAE;EAAgB;EAAU,QAAQ;EAAQ;CAAW,CAAC,GAC9E;CAGF,MAAM,IAAI,cAAc,KAAK,EAAE,SAAS,YAAY,CAAC;AACvD;;;;;;;;;;;;;AAcA,SAAgB,kBAAkB,MAMzB;CACP,MAAM,EAAE,gBAAgB,UAAU,YAAY,QAAQ,WAAW;CACjE,MAAM,QAAQ,OAAO,YAAY;CAEjC,IAAI,UAAU,MAAM;CACpB,IAAI,eAAe,gBAAgB,QAAQ,GAAG;CAE9C,MAAM,iBAAiB,kBAAkB,cAAc;CACvD,IAAI,CAAC,kBAAkB,CAAC,eAAe,IAAA,cAAmB,GAAG;CAC7D,IAAI,mBAAmB,OAAO;CAE9B,IAAI,oBAAoB;EAAE;EAAgB;EAAU;EAAQ;CAAW,CAAC,GACtE;CAGF,MAAM,IAAI,cAAc,KAAK,EAAE,SAAS,YAAY,CAAC;AACvD;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,kBAAkB,MAKzB;CACP,MAAM,EAAE,gBAAgB,UAAU,YAAY,WAAW;CACzD,MAAM,QAAQ,OAAO,YAAY;CAEjC,IAAI,UAAU,MAAM;CACpB,IAAI,eAAe,gBAAgB,QAAQ,GAAG;CAE9C,MAAM,iBAAiB,kBAAkB,cAAc;CACvD,IAAI,CAAC,kBAAkB,CAAC,eAAe,IAAA,cAAmB,GAAG;CAC7D,IAAI,mBAAmB,OAAO;CAE9B,IAAI,oBAAoB;EAAE;EAAgB;EAAU,QAAQ;EAAS;CAAW,CAAC,GAC/E;CAGF,MAAM,IAAI,cAAc,KAAK,EAAE,SAAS,YAAY,CAAC;AACvD;;;;;AAMA,SAAgB,gBAAgB,MAKvB;CACP,kBAAkB;EAAE,GAAG;EAAM,QAAQ;CAAO,CAAC;AAC/C"}
@@ -4,8 +4,8 @@ const require_http_exception = require("../../http-exception-CKDHupKw.cjs");
4
4
  const require_route_builder = require("../../route-builder-C8n4ugUf.cjs");
5
5
  const require_utils = require("../../utils-CmYnjLcY.cjs");
6
6
  const require_server_handlers_error = require("./error.cjs");
7
- const require_server_handlers_version_helpers = require("./version-helpers.cjs");
8
7
  const require_mcp_client_versions = require("../../mcp-client-versions-CG7po4hq.cjs");
8
+ const require_server_handlers_version_helpers = require("./version-helpers.cjs");
9
9
  //#region src/server/handlers/mcp-client-versions.ts
10
10
  /**
11
11
  * GET /stored/mcp-clients/:mcpClientId/versions - List all versions for an MCP client
@@ -2,8 +2,8 @@ import { t as HTTPException } from "../../http-exception-CyfxZB6W.js";
2
2
  import { n as createRoute } from "../../route-builder-BveLN9LU.js";
3
3
  import { i as getStoredResourceScope, n as assertStoredResourceScope } from "../../utils-B2vd77Fi.js";
4
4
  import { handleError } from "./error.js";
5
- import { MCP_CLIENT_SNAPSHOT_CONFIG_FIELDS, calculateChangedFields, computeVersionDiffs, createVersionWithRetry, enforceRetentionLimit, extractConfigFromVersion } from "./version-helpers.js";
6
5
  import { a as createMCPClientVersionResponseSchema, c as listMCPClientVersionsQuerySchema, d as mcpClientVersionPathParams, i as createMCPClientVersionBodySchema, l as listMCPClientVersionsResponseSchema, n as compareMCPClientVersionsQuerySchema, o as deleteMCPClientVersionResponseSchema, p as restoreMCPClientVersionResponseSchema, r as compareMCPClientVersionsResponseSchema, s as getMCPClientVersionResponseSchema, t as activateMCPClientVersionResponseSchema, u as mcpClientVersionIdPathParams } from "../../mcp-client-versions-Co8d39A6.js";
6
+ import { MCP_CLIENT_SNAPSHOT_CONFIG_FIELDS, calculateChangedFields, computeVersionDiffs, createVersionWithRetry, enforceRetentionLimit, extractConfigFromVersion } from "./version-helpers.js";
7
7
  //#region src/server/handlers/mcp-client-versions.ts
8
8
  /**
9
9
  * GET /stored/mcp-clients/:mcpClientId/versions - List all versions for an MCP client
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.cjs","names":["createRoute","listMcpServersQuerySchema","listMcpServersResponseSchema","HTTPException","mcpServerDetailPathParams","getMcpServerDetailQuerySchema","serverDetailSchema","mcpServerIdPathParams","listMcpServerToolsResponseSchema","mcpServerToolPathParams","mcpToolInfoSchema","executeToolBodySchema","executeToolResponseSchema","mcpServerResourcePathParams","listResourcesResponseSchema","readResourceBodySchema","readResourceResponseSchema"],"sources":["../../../src/server/handlers/mcp.ts"],"sourcesContent":["import type { MCPServerBase as MastraMCPServerImplementation, ServerInfo } from '@mastra/core/mcp';\nimport { HTTPException } from '../http-exception';\nimport {\n mcpServerDetailPathParams,\n mcpServerToolPathParams,\n executeToolBodySchema,\n listMcpServersQuerySchema,\n getMcpServerDetailQuerySchema,\n listMcpServersResponseSchema,\n serverDetailSchema,\n mcpServerIdPathParams,\n listMcpServerToolsResponseSchema,\n mcpToolInfoSchema,\n executeToolResponseSchema,\n mcpServerResourcePathParams,\n readResourceBodySchema,\n readResourceResponseSchema,\n listResourcesResponseSchema,\n} from '../schemas/mcp';\nimport type { ServerContext } from '../server-adapter';\nimport type { SetMcpRequestAuth } from '../server-adapter/mcp-auth';\nimport { createRoute } from '../server-adapter/routes/route-builder';\n\n// ============================================================================\n// Route Definitions (createRoute pattern for server adapters)\n// ============================================================================\n\nexport const LIST_MCP_SERVERS_ROUTE = createRoute({\n method: 'GET',\n path: '/mcp/v0/servers',\n responseType: 'json',\n queryParamSchema: listMcpServersQuerySchema,\n responseSchema: listMcpServersResponseSchema,\n summary: 'List MCP servers',\n description: 'Returns a list of registered MCP servers with pagination support',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({\n mastra,\n routePrefix,\n page,\n perPage,\n limit,\n offset,\n }: ServerContext & { page?: number; perPage?: number; limit?: number; offset?: number }) => {\n if (!mastra || typeof mastra.listMCPServers !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or listMCPServers method not available' });\n }\n\n const servers = mastra.listMCPServers();\n\n if (!servers) {\n return { servers: [], total_count: 0, next: null };\n }\n\n const serverList = Object.values(servers) as MastraMCPServerImplementation[];\n const totalCount = serverList.length;\n\n // Support both page/perPage and limit/offset for backwards compatibility\n // Detect which format user is using - prefer page/perPage if both provided\n const useLegacyFormat =\n (limit !== undefined || offset !== undefined) && page === undefined && perPage === undefined;\n\n // If perPage provided, use it; otherwise fall back to limit\n const finalPerPage = perPage ?? limit;\n // If page provided, use it; otherwise convert from offset\n let finalPage = page;\n if (finalPage === undefined && offset !== undefined && finalPerPage !== undefined && finalPerPage > 0) {\n finalPage = Math.floor(offset / finalPerPage);\n }\n\n // Calculate offset from page/perPage\n const actualOffset = finalPage !== undefined && finalPerPage !== undefined ? finalPage * finalPerPage : 0;\n\n // Apply pagination\n let paginatedServers = serverList;\n let nextUrl: string | null = null;\n\n if (finalPerPage !== undefined) {\n paginatedServers = serverList.slice(actualOffset, actualOffset + finalPerPage);\n\n // Calculate next URL if there are more results\n if (actualOffset + finalPerPage < totalCount) {\n const nextPage = (finalPage ?? 0) + 1;\n // Return next URL in same format as request (legacy limit/offset or page/perPage)\n const prefix = routePrefix ?? '';\n if (useLegacyFormat) {\n const nextOffset = actualOffset + finalPerPage;\n nextUrl = `${prefix}/mcp/v0/servers?limit=${finalPerPage}&offset=${nextOffset}`;\n } else {\n nextUrl = `${prefix}/mcp/v0/servers?perPage=${finalPerPage}&page=${nextPage}`;\n }\n }\n }\n\n // Get server info for each server\n const serverInfoList: ServerInfo[] = paginatedServers.map(server => server.getServerInfo());\n\n return {\n servers: serverInfoList,\n total_count: totalCount,\n next: nextUrl,\n };\n },\n});\n\nexport const GET_MCP_SERVER_DETAIL_ROUTE = createRoute({\n method: 'GET',\n path: '/mcp/v0/servers/:id',\n responseType: 'json',\n pathParamSchema: mcpServerDetailPathParams,\n queryParamSchema: getMcpServerDetailQuerySchema,\n responseSchema: serverDetailSchema,\n summary: 'Get MCP server details',\n description: 'Returns detailed information about a specific MCP server',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({ mastra, id, version }: ServerContext & { id: string; version?: string }) => {\n if (!mastra || typeof mastra.getMCPServerById !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or getMCPServerById method not available' });\n }\n\n const server = mastra.getMCPServerById(id);\n\n if (!server) {\n throw new HTTPException(404, { message: `MCP server with ID '${id}' not found` });\n }\n\n const serverDetail = server.getServerDetail();\n\n // If a specific version was requested, check if it matches\n if (version && serverDetail.version_detail.version !== version) {\n throw new HTTPException(404, {\n message: `MCP server with ID '${id}' found, but not version '${version}'. Available version: ${serverDetail.version_detail.version}`,\n });\n }\n\n return serverDetail;\n },\n});\n\nexport const LIST_MCP_SERVER_TOOLS_ROUTE = createRoute({\n method: 'GET',\n path: '/mcp/:serverId/tools',\n responseType: 'json',\n pathParamSchema: mcpServerIdPathParams,\n responseSchema: listMcpServerToolsResponseSchema,\n summary: 'List MCP server tools',\n description: 'Returns a list of tools available on the specified MCP server',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({ mastra, serverId, requestContext }: ServerContext & { serverId: string }) => {\n if (!mastra || typeof mastra.getMCPServerById !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or getMCPServerById method not available' });\n }\n\n const server = mastra.getMCPServerById(serverId);\n\n if (!server) {\n throw new HTTPException(404, { message: `MCP server with ID '${serverId}' not found` });\n }\n\n if (typeof server.getToolListInfo !== 'function') {\n throw new HTTPException(501, { message: `Server '${serverId}' cannot list tools in this way.` });\n }\n\n return await server.getToolListInfo(requestContext);\n },\n});\n\nexport const GET_MCP_SERVER_TOOL_DETAIL_ROUTE = createRoute({\n method: 'GET',\n path: '/mcp/:serverId/tools/:toolId',\n responseType: 'json',\n pathParamSchema: mcpServerToolPathParams,\n responseSchema: mcpToolInfoSchema,\n summary: 'Get MCP server tool details',\n description: 'Returns detailed information about a specific tool on the MCP server',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({ mastra, serverId, toolId }: ServerContext & { serverId: string; toolId: string }) => {\n if (!mastra || typeof mastra.getMCPServerById !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or getMCPServerById method not available' });\n }\n\n const server = mastra.getMCPServerById(serverId);\n\n if (!server) {\n throw new HTTPException(404, { message: `MCP server with ID '${serverId}' not found` });\n }\n\n if (typeof server.getToolInfo !== 'function') {\n throw new HTTPException(501, { message: `Server '${serverId}' cannot provide tool details in this way.` });\n }\n\n const toolInfo = await server.getToolInfo(toolId);\n if (!toolInfo) {\n throw new HTTPException(404, { message: `Tool with ID '${toolId}' not found on MCP server '${serverId}'` });\n }\n\n return toolInfo;\n },\n});\n\nexport const EXECUTE_MCP_SERVER_TOOL_ROUTE = createRoute({\n method: 'POST',\n path: '/mcp/:serverId/tools/:toolId/execute',\n responseType: 'json',\n pathParamSchema: mcpServerToolPathParams,\n bodySchema: executeToolBodySchema,\n responseSchema: executeToolResponseSchema,\n summary: 'Execute MCP server tool',\n description: 'Executes a tool on the specified MCP server with the provided arguments',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({\n mastra,\n serverId,\n toolId,\n data,\n requestContext,\n }: ServerContext & { serverId: string; toolId: string; data?: unknown }) => {\n if (!mastra || typeof mastra.getMCPServerById !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or getMCPServerById method not available' });\n }\n\n const server = mastra.getMCPServerById(serverId);\n\n if (!server) {\n throw new HTTPException(404, { message: `MCP server with ID '${serverId}' not found` });\n }\n\n if (typeof server.executeTool !== 'function') {\n throw new HTTPException(501, { message: `Server '${serverId}' cannot execute tools in this way.` });\n }\n\n const result = await server.executeTool(toolId, data, { requestContext });\n return { result };\n },\n});\n\n// ============================================================================\n// MCP Resource Routes\n// ============================================================================\n\nexport const LIST_MCP_SERVER_RESOURCES_ROUTE = createRoute({\n method: 'GET',\n path: '/mcp/:serverId/resources',\n responseType: 'json',\n pathParamSchema: mcpServerResourcePathParams,\n responseSchema: listResourcesResponseSchema,\n summary: 'List MCP server resources',\n description: 'Returns a list of resources available on the MCP server, including ui:// app resources',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({ mastra, serverId }: ServerContext & { serverId: string }) => {\n if (!mastra || typeof mastra.getMCPServerById !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or getMCPServerById method not available' });\n }\n\n const server = mastra.getMCPServerById(serverId);\n\n if (!server) {\n throw new HTTPException(404, { message: `MCP server with ID '${serverId}' not found` });\n }\n\n if (typeof server.listResources !== 'function') {\n return { resources: [] };\n }\n\n return server.listResources();\n },\n});\n\nexport const READ_MCP_SERVER_RESOURCE_ROUTE = createRoute({\n method: 'POST',\n path: '/mcp/:serverId/resources/read',\n responseType: 'json',\n pathParamSchema: mcpServerResourcePathParams,\n bodySchema: readResourceBodySchema,\n responseSchema: readResourceResponseSchema,\n summary: 'Read MCP server resource content',\n description: 'Reads the content of a resource by URI, used for rendering MCP App ui:// resources',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({ mastra, serverId, uri }: ServerContext & { serverId: string; uri: string }) => {\n if (!mastra || typeof mastra.getMCPServerById !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or getMCPServerById method not available' });\n }\n\n const server = mastra.getMCPServerById(serverId);\n\n if (!server) {\n throw new HTTPException(404, { message: `MCP server with ID '${serverId}' not found` });\n }\n\n if (typeof server.readResource !== 'function') {\n throw new HTTPException(501, { message: `Server '${serverId}' does not support reading resources` });\n }\n\n try {\n return await server.readResource(uri);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (message.includes('not found') || message.includes('not configured')) {\n throw new HTTPException(404, { message: `Resource '${uri}' not found on server '${serverId}'` });\n }\n throw error;\n }\n },\n});\n\n// ============================================================================\n// MCP Transport Routes (Streamable HTTP and SSE)\n// ============================================================================\n\n/**\n * MCP transport options that can be passed to startHTTP() or startSSE().\n * Includes serverless mode for running in stateless environments like Cloudflare Workers or Vercel Edge.\n */\nexport interface MCPTransportOptions {\n /**\n * When true, runs in stateless mode without session management.\n * Ideal for serverless environments where you can't maintain persistent connections.\n */\n serverless?: boolean;\n /**\n * Custom session ID generator function.\n */\n sessionIdGenerator?: () => string;\n /**\n * Sets `req.auth` before the MCP transport reads it. Overrides the default\n * bridge that forwards the principal resolved by `server.auth`.\n */\n setRequestAuth?: SetMcpRequestAuth;\n}\n\n/**\n * MCP HTTP Transport response type.\n * Adapters use this to set up the HTTP transport via MCPServer.startHTTP()\n */\nexport interface MCPHttpTransportResult {\n server: MastraMCPServerImplementation;\n httpPath: string;\n /**\n * Optional MCP transport options for this specific route.\n * These override any class-level mcpOptions configured on the adapter.\n */\n mcpOptions?: MCPTransportOptions;\n}\n\n/**\n * MCP SSE Transport response type.\n * Adapters use this to set up the SSE transport via MCPServer.startSSE() or startHonoSSE()\n *\n * Note: SSE transport is inherently stateful and doesn't support serverless mode.\n */\nexport interface MCPSseTransportResult {\n server: MastraMCPServerImplementation;\n ssePath: string;\n messagePath: string;\n}\n\nexport const MCP_HTTP_TRANSPORT_ROUTE = createRoute({\n method: 'ALL',\n path: '/mcp/:serverId/mcp',\n responseType: 'mcp-http',\n pathParamSchema: mcpServerIdPathParams,\n summary: 'MCP HTTP Transport',\n description: 'Streamable HTTP transport endpoint for MCP protocol communication',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({ mastra, serverId }: ServerContext & { serverId: string }): Promise<MCPHttpTransportResult> => {\n if (!mastra || typeof mastra.getMCPServerById !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or getMCPServerById method not available' });\n }\n\n const server = mastra.getMCPServerById(serverId);\n\n if (!server) {\n throw new HTTPException(404, { message: `MCP server '${serverId}' not found` });\n }\n\n return {\n server,\n httpPath: `/mcp/${serverId}/mcp`,\n };\n },\n});\n\nexport const MCP_SSE_TRANSPORT_ROUTE = createRoute({\n method: 'ALL',\n path: '/mcp/:serverId/sse',\n responseType: 'mcp-sse',\n pathParamSchema: mcpServerIdPathParams,\n summary: 'MCP SSE Transport',\n description: 'SSE transport endpoint for MCP protocol communication',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({ mastra, serverId }: ServerContext & { serverId: string }): Promise<MCPSseTransportResult> => {\n if (!mastra || typeof mastra.getMCPServerById !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or getMCPServerById method not available' });\n }\n\n const server = mastra.getMCPServerById(serverId);\n\n if (!server) {\n throw new HTTPException(404, { message: `MCP server '${serverId}' not found` });\n }\n\n return {\n server,\n ssePath: `/mcp/${serverId}/sse`,\n messagePath: `/mcp/${serverId}/messages`,\n };\n },\n});\n\nexport const MCP_SSE_MESSAGES_ROUTE = createRoute({\n method: 'POST',\n path: '/mcp/:serverId/messages',\n responseType: 'mcp-sse',\n pathParamSchema: mcpServerIdPathParams,\n summary: 'MCP SSE Messages',\n description: 'Message endpoint for SSE transport (posts messages to active SSE streams)',\n tags: ['MCP'],\n requiresAuth: true,\n handler: MCP_SSE_TRANSPORT_ROUTE.handler,\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"mcp.cjs","names":["createRoute","listMcpServersQuerySchema","listMcpServersResponseSchema","HTTPException","mcpServerDetailPathParams","getMcpServerDetailQuerySchema","serverDetailSchema","mcpServerIdPathParams","listMcpServerToolsResponseSchema","mcpServerToolPathParams","mcpToolInfoSchema","executeToolBodySchema","executeToolResponseSchema","mcpServerResourcePathParams","listResourcesResponseSchema","readResourceBodySchema","readResourceResponseSchema"],"sources":["../../../src/server/handlers/mcp.ts"],"sourcesContent":["import type { MCPServerBase as MastraMCPServerImplementation, ServerInfo } from '@mastra/core/mcp';\nimport { HTTPException } from '../http-exception';\nimport {\n mcpServerDetailPathParams,\n mcpServerToolPathParams,\n executeToolBodySchema,\n listMcpServersQuerySchema,\n getMcpServerDetailQuerySchema,\n listMcpServersResponseSchema,\n serverDetailSchema,\n mcpServerIdPathParams,\n listMcpServerToolsResponseSchema,\n mcpToolInfoSchema,\n executeToolResponseSchema,\n mcpServerResourcePathParams,\n readResourceBodySchema,\n readResourceResponseSchema,\n listResourcesResponseSchema,\n} from '../schemas/mcp';\nimport type { ServerContext } from '../server-adapter';\nimport type { SetMcpRequestAuth } from '../server-adapter/mcp-auth';\nimport { createRoute } from '../server-adapter/routes/route-builder';\n\n// ============================================================================\n// Route Definitions (createRoute pattern for server adapters)\n// ============================================================================\n\nexport const LIST_MCP_SERVERS_ROUTE = createRoute({\n method: 'GET',\n path: '/mcp/v0/servers',\n responseType: 'json',\n queryParamSchema: listMcpServersQuerySchema,\n responseSchema: listMcpServersResponseSchema,\n summary: 'List MCP servers',\n description: 'Returns a list of registered MCP servers with pagination support',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({\n mastra,\n routePrefix,\n page,\n perPage,\n limit,\n offset,\n }: ServerContext & { page?: number; perPage?: number; limit?: number; offset?: number }) => {\n if (!mastra || typeof mastra.listMCPServers !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or listMCPServers method not available' });\n }\n\n const servers = mastra.listMCPServers();\n\n if (!servers) {\n return { servers: [], total_count: 0, next: null };\n }\n\n const serverList = Object.values(servers);\n const totalCount = serverList.length;\n\n // Support both page/perPage and limit/offset for backwards compatibility\n // Detect which format user is using - prefer page/perPage if both provided\n const useLegacyFormat =\n (limit !== undefined || offset !== undefined) && page === undefined && perPage === undefined;\n\n // If perPage provided, use it; otherwise fall back to limit\n const finalPerPage = perPage ?? limit;\n // If page provided, use it; otherwise convert from offset\n let finalPage = page;\n if (finalPage === undefined && offset !== undefined && finalPerPage !== undefined && finalPerPage > 0) {\n finalPage = Math.floor(offset / finalPerPage);\n }\n\n // Calculate offset from page/perPage\n const actualOffset = finalPage !== undefined && finalPerPage !== undefined ? finalPage * finalPerPage : 0;\n\n // Apply pagination\n let paginatedServers = serverList;\n let nextUrl: string | null = null;\n\n if (finalPerPage !== undefined) {\n paginatedServers = serverList.slice(actualOffset, actualOffset + finalPerPage);\n\n // Calculate next URL if there are more results\n if (actualOffset + finalPerPage < totalCount) {\n const nextPage = (finalPage ?? 0) + 1;\n // Return next URL in same format as request (legacy limit/offset or page/perPage)\n const prefix = routePrefix ?? '';\n if (useLegacyFormat) {\n const nextOffset = actualOffset + finalPerPage;\n nextUrl = `${prefix}/mcp/v0/servers?limit=${finalPerPage}&offset=${nextOffset}`;\n } else {\n nextUrl = `${prefix}/mcp/v0/servers?perPage=${finalPerPage}&page=${nextPage}`;\n }\n }\n }\n\n // Get server info for each server\n const serverInfoList: ServerInfo[] = paginatedServers.map(server => server.getServerInfo());\n\n return {\n servers: serverInfoList,\n total_count: totalCount,\n next: nextUrl,\n };\n },\n});\n\nexport const GET_MCP_SERVER_DETAIL_ROUTE = createRoute({\n method: 'GET',\n path: '/mcp/v0/servers/:id',\n responseType: 'json',\n pathParamSchema: mcpServerDetailPathParams,\n queryParamSchema: getMcpServerDetailQuerySchema,\n responseSchema: serverDetailSchema,\n summary: 'Get MCP server details',\n description: 'Returns detailed information about a specific MCP server',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({ mastra, id, version }: ServerContext & { id: string; version?: string }) => {\n if (!mastra || typeof mastra.getMCPServerById !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or getMCPServerById method not available' });\n }\n\n const server = mastra.getMCPServerById(id);\n\n if (!server) {\n throw new HTTPException(404, { message: `MCP server with ID '${id}' not found` });\n }\n\n const serverDetail = server.getServerDetail();\n\n // If a specific version was requested, check if it matches\n if (version && serverDetail.version_detail.version !== version) {\n throw new HTTPException(404, {\n message: `MCP server with ID '${id}' found, but not version '${version}'. Available version: ${serverDetail.version_detail.version}`,\n });\n }\n\n return serverDetail;\n },\n});\n\nexport const LIST_MCP_SERVER_TOOLS_ROUTE = createRoute({\n method: 'GET',\n path: '/mcp/:serverId/tools',\n responseType: 'json',\n pathParamSchema: mcpServerIdPathParams,\n responseSchema: listMcpServerToolsResponseSchema,\n summary: 'List MCP server tools',\n description: 'Returns a list of tools available on the specified MCP server',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({ mastra, serverId, requestContext }: ServerContext & { serverId: string }) => {\n if (!mastra || typeof mastra.getMCPServerById !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or getMCPServerById method not available' });\n }\n\n const server = mastra.getMCPServerById(serverId);\n\n if (!server) {\n throw new HTTPException(404, { message: `MCP server with ID '${serverId}' not found` });\n }\n\n if (typeof server.getToolListInfo !== 'function') {\n throw new HTTPException(501, { message: `Server '${serverId}' cannot list tools in this way.` });\n }\n\n return await server.getToolListInfo(requestContext);\n },\n});\n\nexport const GET_MCP_SERVER_TOOL_DETAIL_ROUTE = createRoute({\n method: 'GET',\n path: '/mcp/:serverId/tools/:toolId',\n responseType: 'json',\n pathParamSchema: mcpServerToolPathParams,\n responseSchema: mcpToolInfoSchema,\n summary: 'Get MCP server tool details',\n description: 'Returns detailed information about a specific tool on the MCP server',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({ mastra, serverId, toolId }: ServerContext & { serverId: string; toolId: string }) => {\n if (!mastra || typeof mastra.getMCPServerById !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or getMCPServerById method not available' });\n }\n\n const server = mastra.getMCPServerById(serverId);\n\n if (!server) {\n throw new HTTPException(404, { message: `MCP server with ID '${serverId}' not found` });\n }\n\n if (typeof server.getToolInfo !== 'function') {\n throw new HTTPException(501, { message: `Server '${serverId}' cannot provide tool details in this way.` });\n }\n\n const toolInfo = await server.getToolInfo(toolId);\n if (!toolInfo) {\n throw new HTTPException(404, { message: `Tool with ID '${toolId}' not found on MCP server '${serverId}'` });\n }\n\n return toolInfo;\n },\n});\n\nexport const EXECUTE_MCP_SERVER_TOOL_ROUTE = createRoute({\n method: 'POST',\n path: '/mcp/:serverId/tools/:toolId/execute',\n responseType: 'json',\n pathParamSchema: mcpServerToolPathParams,\n bodySchema: executeToolBodySchema,\n responseSchema: executeToolResponseSchema,\n summary: 'Execute MCP server tool',\n description: 'Executes a tool on the specified MCP server with the provided arguments',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({\n mastra,\n serverId,\n toolId,\n data,\n requestContext,\n }: ServerContext & { serverId: string; toolId: string; data?: unknown }) => {\n if (!mastra || typeof mastra.getMCPServerById !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or getMCPServerById method not available' });\n }\n\n const server = mastra.getMCPServerById(serverId);\n\n if (!server) {\n throw new HTTPException(404, { message: `MCP server with ID '${serverId}' not found` });\n }\n\n if (typeof server.executeTool !== 'function') {\n throw new HTTPException(501, { message: `Server '${serverId}' cannot execute tools in this way.` });\n }\n\n const result = await server.executeTool(toolId, data, { requestContext });\n return { result };\n },\n});\n\n// ============================================================================\n// MCP Resource Routes\n// ============================================================================\n\nexport const LIST_MCP_SERVER_RESOURCES_ROUTE = createRoute({\n method: 'GET',\n path: '/mcp/:serverId/resources',\n responseType: 'json',\n pathParamSchema: mcpServerResourcePathParams,\n responseSchema: listResourcesResponseSchema,\n summary: 'List MCP server resources',\n description: 'Returns a list of resources available on the MCP server, including ui:// app resources',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({ mastra, serverId }: ServerContext & { serverId: string }) => {\n if (!mastra || typeof mastra.getMCPServerById !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or getMCPServerById method not available' });\n }\n\n const server = mastra.getMCPServerById(serverId);\n\n if (!server) {\n throw new HTTPException(404, { message: `MCP server with ID '${serverId}' not found` });\n }\n\n if (typeof server.listResources !== 'function') {\n return { resources: [] };\n }\n\n return server.listResources();\n },\n});\n\nexport const READ_MCP_SERVER_RESOURCE_ROUTE = createRoute({\n method: 'POST',\n path: '/mcp/:serverId/resources/read',\n responseType: 'json',\n pathParamSchema: mcpServerResourcePathParams,\n bodySchema: readResourceBodySchema,\n responseSchema: readResourceResponseSchema,\n summary: 'Read MCP server resource content',\n description: 'Reads the content of a resource by URI, used for rendering MCP App ui:// resources',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({ mastra, serverId, uri }: ServerContext & { serverId: string; uri: string }) => {\n if (!mastra || typeof mastra.getMCPServerById !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or getMCPServerById method not available' });\n }\n\n const server = mastra.getMCPServerById(serverId);\n\n if (!server) {\n throw new HTTPException(404, { message: `MCP server with ID '${serverId}' not found` });\n }\n\n if (typeof server.readResource !== 'function') {\n throw new HTTPException(501, { message: `Server '${serverId}' does not support reading resources` });\n }\n\n try {\n return await server.readResource(uri);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (message.includes('not found') || message.includes('not configured')) {\n throw new HTTPException(404, { message: `Resource '${uri}' not found on server '${serverId}'` });\n }\n throw error;\n }\n },\n});\n\n// ============================================================================\n// MCP Transport Routes (Streamable HTTP and SSE)\n// ============================================================================\n\n/**\n * MCP transport options that can be passed to startHTTP() or startSSE().\n * Includes serverless mode for running in stateless environments like Cloudflare Workers or Vercel Edge.\n */\nexport interface MCPTransportOptions {\n /**\n * When true, runs in stateless mode without session management.\n * Ideal for serverless environments where you can't maintain persistent connections.\n */\n serverless?: boolean;\n /**\n * Custom session ID generator function.\n */\n sessionIdGenerator?: () => string;\n /**\n * Sets `req.auth` before the MCP transport reads it. Overrides the default\n * bridge that forwards the principal resolved by `server.auth`.\n */\n setRequestAuth?: SetMcpRequestAuth;\n}\n\n/**\n * MCP HTTP Transport response type.\n * Adapters use this to set up the HTTP transport via MCPServer.startHTTP()\n */\nexport interface MCPHttpTransportResult {\n server: MastraMCPServerImplementation;\n httpPath: string;\n /**\n * Optional MCP transport options for this specific route.\n * These override any class-level mcpOptions configured on the adapter.\n */\n mcpOptions?: MCPTransportOptions;\n}\n\n/**\n * MCP SSE Transport response type.\n * Adapters use this to set up the SSE transport via MCPServer.startSSE() or startHonoSSE()\n *\n * Note: SSE transport is inherently stateful and doesn't support serverless mode.\n */\nexport interface MCPSseTransportResult {\n server: MastraMCPServerImplementation;\n ssePath: string;\n messagePath: string;\n}\n\nexport const MCP_HTTP_TRANSPORT_ROUTE = createRoute({\n method: 'ALL',\n path: '/mcp/:serverId/mcp',\n responseType: 'mcp-http',\n pathParamSchema: mcpServerIdPathParams,\n summary: 'MCP HTTP Transport',\n description: 'Streamable HTTP transport endpoint for MCP protocol communication',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({ mastra, serverId }: ServerContext & { serverId: string }): Promise<MCPHttpTransportResult> => {\n if (!mastra || typeof mastra.getMCPServerById !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or getMCPServerById method not available' });\n }\n\n const server = mastra.getMCPServerById(serverId);\n\n if (!server) {\n throw new HTTPException(404, { message: `MCP server '${serverId}' not found` });\n }\n\n return {\n server,\n httpPath: `/mcp/${serverId}/mcp`,\n };\n },\n});\n\nexport const MCP_SSE_TRANSPORT_ROUTE = createRoute({\n method: 'ALL',\n path: '/mcp/:serverId/sse',\n responseType: 'mcp-sse',\n pathParamSchema: mcpServerIdPathParams,\n summary: 'MCP SSE Transport',\n description: 'SSE transport endpoint for MCP protocol communication',\n tags: ['MCP'],\n requiresAuth: true,\n handler: async ({ mastra, serverId }: ServerContext & { serverId: string }): Promise<MCPSseTransportResult> => {\n if (!mastra || typeof mastra.getMCPServerById !== 'function') {\n throw new HTTPException(500, { message: 'Mastra instance or getMCPServerById method not available' });\n }\n\n const server = mastra.getMCPServerById(serverId);\n\n if (!server) {\n throw new HTTPException(404, { message: `MCP server '${serverId}' not found` });\n }\n\n return {\n server,\n ssePath: `/mcp/${serverId}/sse`,\n messagePath: `/mcp/${serverId}/messages`,\n };\n },\n});\n\nexport const MCP_SSE_MESSAGES_ROUTE = createRoute({\n method: 'POST',\n path: '/mcp/:serverId/messages',\n responseType: 'mcp-sse',\n pathParamSchema: mcpServerIdPathParams,\n summary: 'MCP SSE Messages',\n description: 'Message endpoint for SSE transport (posts messages to active SSE streams)',\n tags: ['MCP'],\n requiresAuth: true,\n handler: MCP_SSE_TRANSPORT_ROUTE.handler,\n});\n"],"mappings":"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"}