@mastra/factory 0.21.1-alpha.3 → 0.22.0-alpha.4

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 (174) hide show
  1. package/dist/capabilities/version-control.d.ts +13 -8
  2. package/dist/capabilities/version-control.d.ts.map +1 -1
  3. package/dist/environment/build-runner.d.ts +72 -0
  4. package/dist/environment/build-runner.d.ts.map +1 -0
  5. package/dist/environment/build-runner.js +131 -0
  6. package/dist/environment/build-runner.js.map +1 -0
  7. package/dist/environment/build-schedule.d.ts +40 -0
  8. package/dist/environment/build-schedule.d.ts.map +1 -0
  9. package/dist/environment/build-schedule.js +94 -0
  10. package/dist/environment/build-schedule.js.map +1 -0
  11. package/dist/environment/build-workflow.d.ts +62 -0
  12. package/dist/environment/build-workflow.d.ts.map +1 -0
  13. package/dist/environment/build-workflow.js +149 -0
  14. package/dist/environment/build-workflow.js.map +1 -0
  15. package/dist/environment/build.d.ts +111 -0
  16. package/dist/environment/build.d.ts.map +1 -0
  17. package/dist/environment/build.js +344 -0
  18. package/dist/environment/build.js.map +1 -0
  19. package/dist/environment/heads.d.ts +36 -0
  20. package/dist/environment/heads.d.ts.map +1 -0
  21. package/dist/environment/heads.js +60 -0
  22. package/dist/environment/heads.js.map +1 -0
  23. package/dist/factory.d.ts +18 -4
  24. package/dist/factory.d.ts.map +1 -1
  25. package/dist/factory.js +89 -15
  26. package/dist/factory.js.map +1 -1
  27. package/dist/index.d.ts +2 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +3 -2
  30. package/dist/integrations/base.d.ts +17 -2
  31. package/dist/integrations/base.d.ts.map +1 -1
  32. package/dist/integrations/github/commits.d.ts +11 -0
  33. package/dist/integrations/github/commits.d.ts.map +1 -1
  34. package/dist/integrations/github/commits.js +20 -1
  35. package/dist/integrations/github/commits.js.map +1 -1
  36. package/dist/integrations/github/config.d.ts +3 -3
  37. package/dist/integrations/github/config.d.ts.map +1 -1
  38. package/dist/integrations/github/config.js +1 -1
  39. package/dist/integrations/github/config.js.map +1 -1
  40. package/dist/integrations/github/routes.d.ts +2 -2
  41. package/dist/integrations/github/routes.d.ts.map +1 -1
  42. package/dist/integrations/github/routes.js +6 -5
  43. package/dist/integrations/github/routes.js.map +1 -1
  44. package/dist/integrations/github/rules.d.ts +3 -1
  45. package/dist/integrations/github/rules.d.ts.map +1 -1
  46. package/dist/integrations/github/rules.js +31 -1
  47. package/dist/integrations/github/rules.js.map +1 -1
  48. package/dist/integrations/github/sandbox.d.ts +35 -0
  49. package/dist/integrations/github/sandbox.d.ts.map +1 -1
  50. package/dist/integrations/github/sandbox.js +203 -2
  51. package/dist/integrations/github/sandbox.js.map +1 -1
  52. package/dist/integrations/github/session-subscriptions.d.ts.map +1 -1
  53. package/dist/integrations/github/session-subscriptions.js +117 -62
  54. package/dist/integrations/github/session-subscriptions.js.map +1 -1
  55. package/dist/integrations/github/token-refresh.d.ts +7 -0
  56. package/dist/integrations/github/token-refresh.d.ts.map +1 -1
  57. package/dist/integrations/github/token-refresh.js.map +1 -1
  58. package/dist/integrations/github/webhook.js.map +1 -1
  59. package/dist/integrations/gitlab/agent-tools.js +1 -1
  60. package/dist/integrations/gitlab/routes.d.ts +2 -2
  61. package/dist/integrations/gitlab/routes.d.ts.map +1 -1
  62. package/dist/integrations/gitlab/routes.js.map +1 -1
  63. package/dist/integrations/gitlab/session-subscriptions.d.ts.map +1 -1
  64. package/dist/integrations/gitlab/session-subscriptions.js +8 -7
  65. package/dist/integrations/gitlab/session-subscriptions.js.map +1 -1
  66. package/dist/integrations/incidentio/agent-tools.js +1 -1
  67. package/dist/integrations/jira/agent-tools.js +1 -1
  68. package/dist/integrations/linear/agent-tools.js +1 -1
  69. package/dist/integrations/platform/github/integration.d.ts.map +1 -1
  70. package/dist/integrations/platform/github/integration.js +46 -2
  71. package/dist/integrations/platform/github/integration.js.map +1 -1
  72. package/dist/integrations/platform/jira/agent-tools.js +1 -1
  73. package/dist/integrations/slack/slack.d.ts.map +1 -1
  74. package/dist/integrations/slack/slack.js +15 -16
  75. package/dist/integrations/slack/slack.js.map +1 -1
  76. package/dist/integrations/subscription-session.js +1 -1
  77. package/dist/packages/_internals/workspace/dist/index.js +21 -1
  78. package/dist/packages/_internals/workspace/dist/index.js.map +1 -1
  79. package/dist/routes/contracts.d.ts +386 -2
  80. package/dist/routes/contracts.d.ts.map +1 -1
  81. package/dist/routes/contracts.js +166 -1
  82. package/dist/routes/contracts.js.map +1 -1
  83. package/dist/routes/fs.d.ts +25 -0
  84. package/dist/routes/fs.d.ts.map +1 -1
  85. package/dist/routes/fs.js +142 -46
  86. package/dist/routes/fs.js.map +1 -1
  87. package/dist/routes/projects.d.ts +6 -0
  88. package/dist/routes/projects.d.ts.map +1 -1
  89. package/dist/routes/projects.js +344 -1
  90. package/dist/routes/projects.js.map +1 -1
  91. package/dist/routes/source-control-sessions.d.ts +2 -0
  92. package/dist/routes/source-control-sessions.d.ts.map +1 -1
  93. package/dist/routes/source-control-sessions.js +36 -1
  94. package/dist/routes/source-control-sessions.js.map +1 -1
  95. package/dist/routes/supervisor.js +1 -1
  96. package/dist/routes/surface.d.ts +6 -3
  97. package/dist/routes/surface.d.ts.map +1 -1
  98. package/dist/routes/surface.js +21 -34
  99. package/dist/routes/surface.js.map +1 -1
  100. package/dist/rules/binding-context.d.ts +1 -1
  101. package/dist/rules/binding-context.d.ts.map +1 -1
  102. package/dist/rules/binding-context.js +1 -1
  103. package/dist/rules/binding-context.js.map +1 -1
  104. package/dist/rules/review-source-tool.js +1 -1
  105. package/dist/rules/start-coordinator.d.ts.map +1 -1
  106. package/dist/rules/start-coordinator.js +7 -2
  107. package/dist/rules/start-coordinator.js.map +1 -1
  108. package/dist/rules/tools.js +1 -1
  109. package/dist/sandbox/callback-factory-sandbox.d.ts +15 -0
  110. package/dist/sandbox/callback-factory-sandbox.d.ts.map +1 -0
  111. package/dist/sandbox/callback-factory-sandbox.js +22 -0
  112. package/dist/sandbox/callback-factory-sandbox.js.map +1 -0
  113. package/dist/sandbox/local-factory-sandbox.d.ts +20 -0
  114. package/dist/sandbox/local-factory-sandbox.d.ts.map +1 -0
  115. package/dist/sandbox/local-factory-sandbox.js +27 -0
  116. package/dist/sandbox/local-factory-sandbox.js.map +1 -0
  117. package/dist/sandbox/session-retirement.d.ts.map +1 -1
  118. package/dist/sandbox/session-retirement.js +23 -3
  119. package/dist/sandbox/session-retirement.js.map +1 -1
  120. package/dist/sandbox/session-sandbox.d.ts +82 -40
  121. package/dist/sandbox/session-sandbox.d.ts.map +1 -1
  122. package/dist/sandbox/session-sandbox.js +130 -13
  123. package/dist/sandbox/session-sandbox.js.map +1 -1
  124. package/dist/sandbox/workdir.d.ts +10 -0
  125. package/dist/sandbox/workdir.d.ts.map +1 -1
  126. package/dist/sandbox/workdir.js +10 -1
  127. package/dist/sandbox/workdir.js.map +1 -1
  128. package/dist/session/environment-repositories.d.ts +31 -0
  129. package/dist/session/environment-repositories.d.ts.map +1 -0
  130. package/dist/session/environment-repositories.js +89 -0
  131. package/dist/session/environment-repositories.js.map +1 -0
  132. package/dist/session/environment-state-processor.d.ts +59 -0
  133. package/dist/session/environment-state-processor.d.ts.map +1 -0
  134. package/dist/session/environment-state-processor.js +105 -0
  135. package/dist/session/environment-state-processor.js.map +1 -0
  136. package/dist/session/factory-session.d.ts +26 -35
  137. package/dist/session/factory-session.d.ts.map +1 -1
  138. package/dist/session/factory-session.js +34 -71
  139. package/dist/session/factory-session.js.map +1 -1
  140. package/dist/session/filesystem-capture.d.ts +13 -0
  141. package/dist/session/filesystem-capture.d.ts.map +1 -1
  142. package/dist/session/filesystem-capture.js +73 -14
  143. package/dist/session/filesystem-capture.js.map +1 -1
  144. package/dist/session/source-control-tools.d.ts +1 -1
  145. package/dist/session/source-control-tools.d.ts.map +1 -1
  146. package/dist/session/source-control-tools.js +144 -71
  147. package/dist/session/source-control-tools.js.map +1 -1
  148. package/dist/spa-static.js +2 -2
  149. package/dist/storage/domains/audit/agent-audit.d.ts +6 -1
  150. package/dist/storage/domains/audit/agent-audit.d.ts.map +1 -1
  151. package/dist/storage/domains/audit/agent-audit.js +31 -13
  152. package/dist/storage/domains/audit/agent-audit.js.map +1 -1
  153. package/dist/storage/domains/projects/base.d.ts +115 -2
  154. package/dist/storage/domains/projects/base.d.ts.map +1 -1
  155. package/dist/storage/domains/projects/base.js +219 -12
  156. package/dist/storage/domains/projects/base.js.map +1 -1
  157. package/dist/storage/domains/source-control/base.d.ts +123 -7
  158. package/dist/storage/domains/source-control/base.d.ts.map +1 -1
  159. package/dist/storage/domains/source-control/base.js +406 -33
  160. package/dist/storage/domains/source-control/base.js.map +1 -1
  161. package/dist/storage/domains/source-control/inmemory.d.ts +19 -6
  162. package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
  163. package/dist/storage/domains/source-control/inmemory.js +90 -2
  164. package/dist/storage/domains/source-control/inmemory.js.map +1 -1
  165. package/dist/storage/domains/work-items/base.d.ts.map +1 -1
  166. package/dist/storage/domains/work-items/base.js +12 -5
  167. package/dist/storage/domains/work-items/base.js.map +1 -1
  168. package/dist/supervisor/read-tools.js +1 -1
  169. package/dist/supervisor/write-tools.js +1 -1
  170. package/dist/workspace.d.ts +50 -7
  171. package/dist/workspace.d.ts.map +1 -1
  172. package/dist/workspace.js +344 -24
  173. package/dist/workspace.js.map +1 -1
  174. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"contracts.js","names":[],"sources":["../../src/routes/contracts.ts"],"sourcesContent":["import { z } from 'zod';\n\nimport { FACTORY_ROLE_STAGES } from '../rules/types.js';\nimport { BOARD_IDENTIFIER_RE, MAX_BOARD_IDENTIFIER_LENGTH } from '../rules/validation.js';\nimport { FACTORY_MODEL_SCOPES } from '../storage/domains/projects/base.js';\n\nconst FACTORY_ROLE_VALUES = Object.keys(FACTORY_ROLE_STAGES) as [string, ...string[]];\n\nexport type FactoryRouteContract = {\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE';\n path: string;\n description: string;\n pathSchema?: z.ZodType;\n querySchema?: z.ZodType;\n bodySchema?: z.ZodType;\n responseSchema: z.ZodType;\n};\n\nexport const UUID_PATTERN = '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$';\nconst uuidSchema = z.string().regex(new RegExp(UUID_PATTERN));\nconst entitySchema = z.record(z.string(), z.unknown());\nconst nonEmptyTrimmed = (max: number) => z.string().trim().min(1).max(max);\nconst rawBoundedTrimmed = (max: number) =>\n z\n .string()\n .max(max)\n .transform(value => value.trim())\n .pipe(z.string().min(1));\nconst trimmedUuidSchema = z.string().trim().regex(new RegExp(UUID_PATTERN));\nconst nullableTrimmed = (max: number) =>\n z.union([\n z\n .string()\n .trim()\n .max(max)\n .transform(value => value || null),\n z.null(),\n ]);\nconst projectPathSchema = z.object({ id: uuidSchema });\nconst projectDecisionPathSchema = z.object({ id: uuidSchema, decisionId: uuidSchema });\nconst workItemPathSchema = z.object({ id: uuidSchema });\nconst transitionPathSchema = z.object({ id: uuidSchema, workItemId: uuidSchema });\n\nconst projectSchema = entitySchema;\nconst projectResponseSchema = z.object({ project: projectSchema });\nconst workItemResponseSchema = z.object({ workItem: entitySchema });\nconst decisionResponseSchema = z.object({ decision: entitySchema });\n\nexport const createProjectBodySchema = z.object({\n name: nonEmptyTrimmed(200),\n description: nullableTrimmed(2_000).optional().default(null),\n});\n\nexport const updateProjectBodySchema = z\n .object({\n name: nonEmptyTrimmed(200).optional(),\n description: nullableTrimmed(2_000).optional(),\n defaultModelId: nullableTrimmed(200).optional(),\n modelScope: z.enum(FACTORY_MODEL_SCOPES).optional(),\n slackWorkItemsEnabled: z.boolean().optional(),\n autoRunEnabled: z.boolean().optional(),\n autoApprovePlans: z.boolean().optional(),\n })\n .refine(input => Object.keys(input).length > 0, { message: 'At least one project field is required' });\n\nconst stagesSchema = z\n .array(\n z\n .string()\n .max(64)\n .regex(/^[a-z0-9][a-z0-9_-]*$/i),\n )\n .min(1)\n .max(16)\n .refine(stages => new Set(stages).size === stages.length, { message: 'Stages must be unique' });\n\nconst externalSourceSchema = z\n .object({\n integrationId: z.string().min(1).max(128),\n type: z.string().min(1).max(128),\n externalId: z.string().min(1).max(512),\n url: z.string().max(2_048).optional(),\n })\n .nullable();\n\nconst sessionSchema = z.object({\n sessionId: z.string().min(1).max(512),\n branch: z.string().min(1).max(512),\n threadId: z.string().min(1).max(512),\n});\n\nconst sessionsSchema = z.record(z.string().min(1).max(64), sessionSchema);\nconst metadataSchema = z\n .union([z.record(z.string(), z.unknown()), z.null()])\n .refine(value => {\n try {\n return JSON.stringify(value).length <= 16 * 1024;\n } catch {\n return false;\n }\n }, 'Metadata exceeds 16 KiB')\n .transform(value => {\n if (value === null) return null;\n const {\n factoryRuleMaterializationKey: _materialization,\n factoryPullRequestReconciliation: _reconciliation,\n externalSourceMissingAt: _externalSourceMissingAt,\n ...metadata\n } = value;\n return metadata;\n });\n\nexport const createWorkItemBodySchema = z.object({\n title: rawBoundedTrimmed(500),\n board: z.string().min(1).max(128).optional(),\n externalSource: externalSourceSchema.optional(),\n parentWorkItemId: uuidSchema.nullable().optional(),\n stages: stagesSchema.optional(),\n sessions: sessionsSchema.optional(),\n metadata: metadataSchema.optional(),\n});\n\nexport const updateWorkItemBodySchema = z\n .object({\n title: rawBoundedTrimmed(500).optional(),\n board: z.string().min(1).max(128).optional(),\n parentWorkItemId: uuidSchema.nullable().optional(),\n stages: stagesSchema.optional(),\n sessions: sessionsSchema.optional(),\n metadata: metadataSchema.optional(),\n plansPreapproved: z.literal(true).optional(),\n })\n .refine(input => Object.keys(input).length > 0, { message: 'At least one work-item field is required' });\n\nexport const transitionBodySchema = z\n .object({\n board: z.string().max(MAX_BOARD_IDENTIFIER_LENGTH).regex(BOARD_IDENTIFIER_RE),\n stage: z.string().max(MAX_BOARD_IDENTIFIER_LENGTH).regex(BOARD_IDENTIFIER_RE),\n expectedRevision: z.number().int().min(1),\n requestId: trimmedUuidSchema,\n cause: nonEmptyTrimmed(256),\n reenter: z.unknown().optional(),\n })\n .transform(input => ({\n board: input.board,\n stage: input.stage,\n expectedRevision: input.expectedRevision,\n ingress: { type: 'human' as const, identity: input.requestId },\n cause: input.cause,\n ...(input.reenter === true ? { reenter: true } : {}),\n }));\n\nexport const startWorkItemBodySchema = z.object({\n sessionId: trimmedUuidSchema,\n threadTitle: nonEmptyTrimmed(512),\n kickoffKey: trimmedUuidSchema,\n workItem: z.object({\n id: trimmedUuidSchema,\n role: nonEmptyTrimmed(32),\n input: createWorkItemBodySchema,\n }),\n});\n\nexport const automationRunStartBodySchema = z\n .object({\n requestId: trimmedUuidSchema,\n expectedRevision: z.number().int().min(1),\n role: z.enum(FACTORY_ROLE_VALUES),\n skillName: nonEmptyTrimmed(128),\n arguments: nonEmptyTrimmed(4_096).optional(),\n })\n .strict();\n\nexport const metricsQuerySchema = z.object({\n from: z.string().optional(),\n to: z.string().optional(),\n});\n\nconst decisionStatusSchema = z.enum([\n 'pending',\n 'proposed',\n 'dismissed',\n 'superseded',\n 'leased',\n 'retry',\n 'succeeded',\n 'failed',\n]);\nconst boundedLimitSchema = (defaultValue: number, max: number) =>\n z\n .string()\n .optional()\n .transform(value => {\n const parsed = value ? Number.parseInt(value, 10) : defaultValue;\n return Number.isFinite(parsed) ? Math.max(1, Math.min(max, parsed)) : defaultValue;\n });\nconst decisionCursorSchema = z\n .string()\n .optional()\n .transform((value, context) => {\n if (!value) return undefined;\n try {\n const decoded = JSON.parse(Buffer.from(value, 'base64url').toString('utf8')) as unknown;\n if (\n !Array.isArray(decoded) ||\n decoded.length !== 2 ||\n typeof decoded[0] !== 'string' ||\n typeof decoded[1] !== 'string'\n ) {\n throw new Error('invalid cursor');\n }\n const createdAt = new Date(decoded[0]);\n if (Number.isNaN(createdAt.getTime()) || !new RegExp(UUID_PATTERN).test(decoded[1])) {\n throw new Error('invalid cursor');\n }\n return { createdAt, id: decoded[1] };\n } catch {\n context.addIssue({ code: 'custom', message: 'Invalid cursor' });\n return z.NEVER;\n }\n });\n\nexport const decisionQuerySchema = z.object({\n statuses: z\n .string()\n .optional()\n .transform(value => {\n if (!value) return undefined;\n const statuses = [...new Set(value.split(',').map(status => status.trim()))].filter(\n status => decisionStatusSchema.safeParse(status).success,\n ) as Array<z.infer<typeof decisionStatusSchema>>;\n return statuses.length > 0 ? statuses : undefined;\n }),\n before: decisionCursorSchema,\n limit: boundedLimitSchema(25, 50),\n});\n\nconst attentionKindSchema = z.enum([\n 'automation-failed',\n 'automation-proposed',\n 'mention',\n 'activity',\n 'supervisor-finding',\n 'agent-waiting',\n]);\ntype AttentionKind = z.infer<typeof attentionKindSchema>;\ntype AttentionStreamPosition = { occurredAt: Date; id: string };\ntype AttentionCursorMap = Map<AttentionKind, AttentionStreamPosition | undefined>;\n\nfunction parseAttentionStreamPosition(value: unknown): AttentionStreamPosition | undefined {\n if (!Array.isArray(value) || value.length !== 2 || typeof value[0] !== 'string' || typeof value[1] !== 'string') {\n return undefined;\n }\n const occurredAt = new Date(value[0]);\n if (Number.isNaN(occurredAt.getTime()) || !new RegExp(UUID_PATTERN).test(value[1])) return undefined;\n return { occurredAt, id: value[1] };\n}\n\nconst attentionCursorSchema = z\n .string()\n .optional()\n .transform((value, context) => {\n if (!value) return undefined;\n try {\n const decoded: unknown = JSON.parse(Buffer.from(value, 'base64url').toString('utf8'));\n if (Array.isArray(decoded)) {\n const legacy = parseAttentionStreamPosition(decoded);\n if (!legacy) throw new Error('invalid cursor');\n return new Map<AttentionKind, AttentionStreamPosition | undefined>([['automation-failed', legacy]]);\n }\n if (!decoded || typeof decoded !== 'object') throw new Error('invalid cursor');\n const cursors: AttentionCursorMap = new Map();\n for (const [kind, positionValue] of Object.entries(decoded)) {\n const parsedKind = attentionKindSchema.safeParse(kind);\n if (!parsedKind.success) throw new Error('invalid cursor');\n if (positionValue === null) {\n cursors.set(parsedKind.data, undefined);\n continue;\n }\n const position = parseAttentionStreamPosition(positionValue);\n if (!position) throw new Error('invalid cursor');\n cursors.set(parsedKind.data, position);\n }\n if (cursors.size === 0) throw new Error('invalid cursor');\n return cursors;\n } catch {\n context.addIssue({ code: 'custom', message: 'Invalid cursor' });\n return z.NEVER;\n }\n });\n\nexport const attentionQuerySchema = z.object({\n view: z.enum(['open', 'unread', 'archived']).optional().default('open'),\n kind: z.array(attentionKindSchema).optional(),\n before: attentionCursorSchema,\n limit: boundedLimitSchema(25, 50),\n search: z\n .string()\n .optional()\n .transform(value => value?.trim().toLowerCase().slice(0, 200) || undefined),\n});\n\nconst attentionActionPathSchema = z\n .object({\n id: uuidSchema,\n kind: attentionKindSchema,\n sourceId: z.string().min(1).max(256),\n occurrence: z\n .string()\n .regex(/^(0|[1-9]\\d*)$/)\n .transform((value, context) => {\n const occurrence = Number(value);\n if (Number.isSafeInteger(occurrence)) return occurrence;\n context.addIssue({ code: 'custom', message: 'Invalid occurrence' });\n return z.NEVER;\n }),\n })\n .refine(\n input =>\n input.kind === 'supervisor-finding'\n ? /^[a-z0-9:_-]{1,256}$/i.test(input.sourceId)\n : new RegExp(UUID_PATTERN).test(input.sourceId),\n { message: 'Invalid attention source id', path: ['sourceId'] },\n );\n\nexport const FACTORY_ROUTE_CONTRACTS = {\n projectList: {\n method: 'GET',\n path: '/web/factory/projects',\n description: 'List Factory projects for the current organization',\n responseSchema: z.object({ projects: z.array(projectSchema) }),\n },\n projectCreate: {\n method: 'POST',\n path: '/web/factory/projects',\n description: 'Create a Factory project',\n bodySchema: createProjectBodySchema,\n responseSchema: projectResponseSchema,\n },\n projectGet: {\n method: 'GET',\n path: '/web/factory/projects/:id',\n description: 'Get a Factory project',\n pathSchema: projectPathSchema,\n responseSchema: projectResponseSchema,\n },\n projectUpdate: {\n method: 'PATCH',\n path: '/web/factory/projects/:id',\n description: 'Update a Factory project',\n pathSchema: projectPathSchema,\n bodySchema: updateProjectBodySchema,\n responseSchema: projectResponseSchema,\n },\n projectApplyDefaultModel: {\n method: 'POST',\n path: '/web/factory/projects/:id/apply-default-model',\n description: 'Apply the Factory default model to running work and review threads',\n pathSchema: projectPathSchema,\n responseSchema: z.object({\n modelId: z.string(),\n applied: z.array(z.string()),\n skipped: z.array(\n z.object({\n threadId: z.string(),\n reason: z.enum([\n 'not-running',\n 'work-item-missing',\n 'stage-inactive',\n 'thread-missing',\n 'mode-unknown',\n 'apply-failed',\n ]),\n }),\n ),\n }),\n },\n projectDelete: {\n method: 'DELETE',\n path: '/web/factory/projects/:id',\n description: 'Delete a Factory project',\n pathSchema: projectPathSchema,\n responseSchema: z.null(),\n },\n metricsGet: {\n method: 'GET',\n path: '/web/factory/projects/:id/metrics',\n description: 'Get Factory project metrics',\n pathSchema: projectPathSchema,\n querySchema: metricsQuerySchema,\n responseSchema: z.object({ metrics: entitySchema }),\n },\n healthThresholdsGet: {\n method: 'GET',\n path: '/web/factory/projects/:id/health/thresholds',\n description: 'Get queue-health thresholds',\n pathSchema: projectPathSchema,\n responseSchema: z.object({ thresholds: z.array(z.number().finite()) }),\n },\n boardCatalog: {\n method: 'GET',\n path: '/web/factory/projects/:id/boards',\n description: 'List installed Factory boards',\n pathSchema: projectPathSchema,\n responseSchema: z.object({\n boards: z.array(\n z.object({\n id: z.string(),\n title: z.string(),\n initialPhase: z.string(),\n phases: z.array(\n z.object({\n id: z.string(),\n title: z.string(),\n kind: z.enum(['resting', 'working', 'terminal']),\n role: z.string().optional(),\n transitions: z.array(z.object({ outcome: z.string().nullable(), to: z.string() })),\n }),\n ),\n }),\n ),\n }),\n },\n workItemList: {\n method: 'GET',\n path: '/web/factory/projects/:id/work-items',\n description: 'List Factory work items and running sessions',\n pathSchema: projectPathSchema,\n responseSchema: z.object({\n workItems: z.array(entitySchema),\n runningSessionIds: z.array(z.string()),\n parkedSessionIds: z.array(z.string()),\n }),\n },\n workItemCreate: {\n method: 'POST',\n path: '/web/factory/projects/:id/work-items',\n description: 'Create a work item in Intake',\n pathSchema: projectPathSchema,\n bodySchema: createWorkItemBodySchema,\n responseSchema: workItemResponseSchema,\n },\n workItemUpdate: {\n method: 'PATCH',\n path: '/web/factory/work-items/:id',\n description: 'Update non-stage work-item fields',\n pathSchema: workItemPathSchema,\n bodySchema: updateWorkItemBodySchema,\n responseSchema: workItemResponseSchema,\n },\n workItemDelete: {\n method: 'DELETE',\n path: '/web/factory/work-items/:id',\n description: 'Delete a Factory work item',\n pathSchema: workItemPathSchema,\n responseSchema: z.object({ ok: z.literal(true) }),\n },\n workItemTransition: {\n method: 'POST',\n path: '/web/factory/projects/:id/work-items/:workItemId/transition',\n description: 'Transition a work item with its expected revision',\n pathSchema: transitionPathSchema,\n bodySchema: transitionBodySchema,\n responseSchema: entitySchema,\n },\n workItemStart: {\n method: 'POST',\n path: '/web/factory/projects/:id/runs/start',\n description: 'Explicitly start a Factory work-item run',\n pathSchema: projectPathSchema,\n bodySchema: startWorkItemBodySchema,\n responseSchema: entitySchema,\n },\n workItemAutomationRun: {\n method: 'POST',\n path: '/web/factory/projects/:id/work-items/:workItemId/automation-runs',\n description: 'Enqueue an idempotent deferred skill dispatch for a trusted external orchestrator',\n pathSchema: transitionPathSchema,\n bodySchema: automationRunStartBodySchema,\n responseSchema: entitySchema,\n },\n decisionList: {\n method: 'GET',\n path: '/web/factory/projects/:id/decisions',\n description: 'List Factory decisions',\n pathSchema: projectPathSchema,\n querySchema: decisionQuerySchema,\n responseSchema: z.object({ decisions: z.array(entitySchema), nextCursor: z.string().optional() }),\n },\n decisionApprove: {\n method: 'POST',\n path: '/web/factory/projects/:id/decisions/:decisionId/approve',\n description: 'Approve a proposed Factory decision',\n pathSchema: projectDecisionPathSchema,\n responseSchema: decisionResponseSchema,\n },\n decisionDismiss: {\n method: 'POST',\n path: '/web/factory/projects/:id/decisions/:decisionId/dismiss',\n description: 'Dismiss a proposed Factory decision',\n pathSchema: projectDecisionPathSchema,\n responseSchema: decisionResponseSchema,\n },\n decisionRetry: {\n method: 'POST',\n path: '/web/factory/projects/:id/decisions/:decisionId/retry',\n description: 'Retry a failed retryable Factory decision',\n pathSchema: projectDecisionPathSchema,\n responseSchema: decisionResponseSchema,\n },\n attentionList: {\n method: 'GET',\n path: '/web/factory/projects/:id/attention',\n description: 'List the Factory attention inbox',\n pathSchema: projectPathSchema,\n querySchema: attentionQuerySchema,\n responseSchema: z.object({\n items: z.array(entitySchema),\n kinds: z.record(\n attentionKindSchema,\n z.object({\n open: z.number(),\n unread: z.number(),\n latest: z.object({ key: z.string(), at: z.string(), unread: z.boolean() }).nullable(),\n }),\n ),\n hasMore: z.boolean(),\n nextCursor: z.string().optional(),\n }),\n },\n attentionReadAll: {\n method: 'POST',\n path: '/web/factory/projects/:id/attention/read-all',\n description: 'Mark all Factory attention as read',\n pathSchema: projectPathSchema,\n querySchema: z.object({ before: attentionCursorSchema }),\n responseSchema: z.object({ ok: z.literal(true), hasMore: z.boolean(), nextCursor: z.string().optional() }),\n },\n attentionRead: {\n method: 'POST',\n path: '/web/factory/projects/:id/attention/:kind/:sourceId/:occurrence/read',\n description: 'Mark a Factory attention receipt as read',\n pathSchema: attentionActionPathSchema,\n responseSchema: z.object({ receipt: entitySchema }),\n },\n attentionArchive: {\n method: 'POST',\n path: '/web/factory/projects/:id/attention/:kind/:sourceId/:occurrence/archive',\n description: 'Archive a Factory attention receipt',\n pathSchema: attentionActionPathSchema,\n responseSchema: z.object({ receipt: entitySchema }),\n },\n attentionRestore: {\n method: 'POST',\n path: '/web/factory/projects/:id/attention/:kind/:sourceId/:occurrence/restore',\n description: 'Restore an archived Factory attention receipt',\n pathSchema: attentionActionPathSchema,\n responseSchema: z.object({ receipt: entitySchema }),\n },\n supervisorSession: {\n method: 'POST',\n path: '/web/factory/projects/:id/supervisor/session',\n description: 'Get the deterministic Factory supervisor session address',\n pathSchema: projectPathSchema,\n responseSchema: z.object({ sessionId: z.string(), threadId: z.string(), factoryProjectId: uuidSchema }),\n },\n supervisorHealth: {\n method: 'GET',\n path: '/web/factory/projects/:id/supervisor/health',\n description: 'Run the deterministic Factory supervisor health check',\n pathSchema: projectPathSchema,\n responseSchema: z.object({\n checkedAt: z.string(),\n findings: z.array(entitySchema),\n counts: z.record(z.string(), z.number().int().nonnegative()),\n }),\n },\n} as const satisfies Record<string, FactoryRouteContract>;\n\nexport type FactoryRouteContractKey = keyof typeof FACTORY_ROUTE_CONTRACTS;\n"],"mappings":"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"}
1
+ {"version":3,"file":"contracts.js","names":[],"sources":["../../src/routes/contracts.ts"],"sourcesContent":["import { z } from 'zod';\n\nimport { FACTORY_ROLE_STAGES } from '../rules/types.js';\nimport { BOARD_IDENTIFIER_RE, MAX_BOARD_IDENTIFIER_LENGTH } from '../rules/validation.js';\nimport { FACTORY_MODEL_SCOPES } from '../storage/domains/projects/base.js';\n\nconst FACTORY_ROLE_VALUES = Object.keys(FACTORY_ROLE_STAGES) as [string, ...string[]];\n\nexport type FactoryRouteContract = {\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE';\n path: string;\n description: string;\n pathSchema?: z.ZodType;\n querySchema?: z.ZodType;\n bodySchema?: z.ZodType;\n responseSchema: z.ZodType;\n};\n\nexport const UUID_PATTERN = '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$';\nconst uuidSchema = z.string().regex(new RegExp(UUID_PATTERN));\nconst entitySchema = z.record(z.string(), z.unknown());\nconst nonEmptyTrimmed = (max: number) => z.string().trim().min(1).max(max);\nconst rawBoundedTrimmed = (max: number) =>\n z\n .string()\n .max(max)\n .transform(value => value.trim())\n .pipe(z.string().min(1));\nconst trimmedUuidSchema = z.string().trim().regex(new RegExp(UUID_PATTERN));\nconst nullableTrimmed = (max: number) =>\n z.union([\n z\n .string()\n .trim()\n .max(max)\n .transform(value => value || null),\n z.null(),\n ]);\nconst projectPathSchema = z.object({ id: uuidSchema });\nconst projectDecisionPathSchema = z.object({ id: uuidSchema, decisionId: uuidSchema });\nconst workItemPathSchema = z.object({ id: uuidSchema });\nconst transitionPathSchema = z.object({ id: uuidSchema, workItemId: uuidSchema });\n\nconst projectSchema = entitySchema;\nconst projectResponseSchema = z.object({ project: projectSchema });\nconst workItemResponseSchema = z.object({ workItem: entitySchema });\nconst decisionResponseSchema = z.object({ decision: entitySchema });\n\nexport const createProjectBodySchema = z.object({\n name: nonEmptyTrimmed(200),\n description: nullableTrimmed(2_000).optional().default(null),\n});\n\nexport const updateProjectBodySchema = z\n .object({\n name: nonEmptyTrimmed(200).optional(),\n description: nullableTrimmed(2_000).optional(),\n defaultModelId: nullableTrimmed(200).optional(),\n modelScope: z.enum(FACTORY_MODEL_SCOPES).optional(),\n slackWorkItemsEnabled: z.boolean().optional(),\n autoRunEnabled: z.boolean().optional(),\n autoApprovePlans: z.boolean().optional(),\n })\n .refine(input => Object.keys(input).length > 0, { message: 'At least one project field is required' });\n\nconst environmentRepositorySchema = z.object({\n projectRepositoryId: z.string(),\n connectionId: z.string(),\n repositoryId: z.string(),\n // Null when the repository row behind the link is missing.\n slug: z.string().nullable(),\n defaultBranch: z.string().nullable(),\n position: z.number().int(),\n inEnvironment: z.boolean(),\n setupCommand: z.string().nullable(),\n teardownCommand: z.string().nullable(),\n lastBuildStatus: z.enum(['unbuilt', 'configured', 'failed']),\n lastBuildError: z.string().nullable(),\n lastBuiltAt: z.string().nullable(),\n});\n\n/** The configured FactorySandbox as factory describes it: provider id, JSON Schema of its settings, capabilities. */\nexport const environmentSandboxSchema = z.object({\n provider: z.string(),\n settingsSchema: z.record(z.string(), z.unknown()),\n capabilities: z.object({\n template: z.boolean(),\n builds: z.object({ available: z.boolean(), history: z.boolean() }),\n }),\n});\n\n/** When the environment builds on its own; present only when the sandbox can build. */\nexport const environmentBuildTriggersSchema = z.object({\n schedule: z.object({\n enabled: z.boolean(),\n cron: z.string().nullable(),\n timezone: z.string().nullable(),\n /** False when the host's storage has no schedules domain; the cron trigger cannot be enabled then. */\n scheduleAvailable: z.boolean(),\n }),\n push: z.object({ enabled: z.boolean(), debounceMinutes: z.number().int() }),\n});\n\n/** The last build factory asked the provider for, from the project row only; status is read live. */\nexport const environmentLastBuildSchema = z.object({ buildId: z.string(), attemptedAt: z.string().nullable() });\n\nexport const projectEnvironmentResponseSchema = z.object({\n environment: z.object({\n sandbox: environmentSandboxSchema,\n /** The stored settings document; only keys the user set. */\n settings: z.record(z.string(), z.unknown()),\n sandboxWorkingDirectory: z.string().nullable(),\n workspaceSetupCommand: z.string().nullable(),\n activeTemplateId: z.string().nullable(),\n activeTemplateHeads: z.record(z.string(), z.string()).nullable(),\n repositories: z.array(environmentRepositorySchema),\n buildTriggers: environmentBuildTriggersSchema.optional(),\n build: environmentLastBuildSchema.nullable().optional(),\n }),\n});\n\nconst environmentBuildStatusSchema = z.enum(['pending', 'building', 'ready', 'failed', 'unknown']);\n\nexport const environmentBuildStartResponseSchema = z.object({\n outcome: z.enum(['started', 'skipped', 'unavailable', 'failed']),\n buildId: z.string().optional(),\n templateId: z.string().optional(),\n reason: z.string().optional(),\n});\n\nexport const environmentBuildSchema = z.object({\n buildId: z.string(),\n status: environmentBuildStatusSchema,\n templateId: z.string().optional(),\n startedAt: z.string().optional(),\n finishedAt: z.string().optional(),\n error: z.string().optional(),\n logs: z.array(z.string()).optional(),\n});\n\nexport const environmentBuildsResponseSchema = z.object({ builds: z.array(environmentBuildSchema) });\nexport const environmentBuildResponseSchema = z.object({ build: environmentBuildSchema });\n\nconst buildPathSchema = projectPathSchema.extend({ buildId: z.string().min(1) });\n\nconst environmentRepositoryPatchSchema = z.object({\n projectRepositoryId: uuidSchema,\n position: z.number().int().min(1).optional(),\n inEnvironment: z.boolean().optional(),\n setupCommand: nullableTrimmed(2_000).optional(),\n teardownCommand: nullableTrimmed(2_000).optional(),\n});\n\nexport const updateProjectEnvironmentBodySchema = z\n .object({\n sandboxWorkingDirectory: nullableTrimmed(1_000)\n .refine(value => value === null || value.startsWith('/'), {\n message: 'sandboxWorkingDirectory must be absolute',\n })\n .optional(),\n /** Partial settings merged onto the stored document; null removes a key. Validated by the FactorySandbox. */\n settings: z.record(z.string(), z.unknown().nullable()).optional(),\n workspaceSetupCommand: nullableTrimmed(2_000).optional(),\n /** Build triggers; only accepted when the sandbox can build. */\n buildTriggers: z\n .object({\n schedule: z\n .object({\n enabled: z.boolean(),\n cron: z.string().trim().min(1).max(100).optional(),\n timezone: z.string().trim().min(1).max(100).optional(),\n })\n .optional(),\n push: z\n .object({\n enabled: z.boolean().optional(),\n debounceMinutes: z.number().int().min(0).max(1_440).optional(),\n })\n .optional(),\n })\n .optional(),\n repositories: z\n .array(environmentRepositoryPatchSchema)\n .max(100)\n .superRefine((entries, ctx) => {\n const ids = new Set(entries.map(entry => entry.projectRepositoryId));\n if (ids.size !== entries.length) {\n ctx.addIssue({ code: 'custom', message: 'Each repository may be listed once' });\n }\n const positions = entries.flatMap(entry => (entry.position === undefined ? [] : [entry.position]));\n if (positions.length === 0) return;\n const expected = Array.from({ length: entries.length }, (_, index) => index + 1);\n if (\n positions.length !== entries.length ||\n [...positions].sort((a, b) => a - b).some((p, i) => p !== expected[i])\n ) {\n ctx.addIssue({\n code: 'custom',\n message: 'Positions must be a permutation of 1..n over the listed repositories',\n });\n }\n })\n .optional(),\n })\n .refine(input => Object.keys(input).length > 0, { message: 'At least one environment field is required' });\n\nconst stagesSchema = z\n .array(\n z\n .string()\n .max(64)\n .regex(/^[a-z0-9][a-z0-9_-]*$/i),\n )\n .min(1)\n .max(16)\n .refine(stages => new Set(stages).size === stages.length, { message: 'Stages must be unique' });\n\nconst externalSourceSchema = z\n .object({\n integrationId: z.string().min(1).max(128),\n type: z.string().min(1).max(128),\n externalId: z.string().min(1).max(512),\n url: z.string().max(2_048).optional(),\n })\n .nullable();\n\nconst sessionSchema = z.object({\n sessionId: z.string().min(1).max(512),\n branch: z.string().min(1).max(512),\n threadId: z.string().min(1).max(512),\n});\n\nconst sessionsSchema = z.record(z.string().min(1).max(64), sessionSchema);\nconst metadataSchema = z\n .union([z.record(z.string(), z.unknown()), z.null()])\n .refine(value => {\n try {\n return JSON.stringify(value).length <= 16 * 1024;\n } catch {\n return false;\n }\n }, 'Metadata exceeds 16 KiB')\n .transform(value => {\n if (value === null) return null;\n const {\n factoryRuleMaterializationKey: _materialization,\n factoryPullRequestReconciliation: _reconciliation,\n externalSourceMissingAt: _externalSourceMissingAt,\n ...metadata\n } = value;\n return metadata;\n });\n\nexport const createWorkItemBodySchema = z.object({\n title: rawBoundedTrimmed(500),\n board: z.string().min(1).max(128).optional(),\n externalSource: externalSourceSchema.optional(),\n parentWorkItemId: uuidSchema.nullable().optional(),\n stages: stagesSchema.optional(),\n sessions: sessionsSchema.optional(),\n metadata: metadataSchema.optional(),\n});\n\nexport const updateWorkItemBodySchema = z\n .object({\n title: rawBoundedTrimmed(500).optional(),\n board: z.string().min(1).max(128).optional(),\n parentWorkItemId: uuidSchema.nullable().optional(),\n stages: stagesSchema.optional(),\n sessions: sessionsSchema.optional(),\n metadata: metadataSchema.optional(),\n plansPreapproved: z.literal(true).optional(),\n })\n .refine(input => Object.keys(input).length > 0, { message: 'At least one work-item field is required' });\n\nexport const transitionBodySchema = z\n .object({\n board: z.string().max(MAX_BOARD_IDENTIFIER_LENGTH).regex(BOARD_IDENTIFIER_RE),\n stage: z.string().max(MAX_BOARD_IDENTIFIER_LENGTH).regex(BOARD_IDENTIFIER_RE),\n expectedRevision: z.number().int().min(1),\n requestId: trimmedUuidSchema,\n cause: nonEmptyTrimmed(256),\n reenter: z.unknown().optional(),\n })\n .transform(input => ({\n board: input.board,\n stage: input.stage,\n expectedRevision: input.expectedRevision,\n ingress: { type: 'human' as const, identity: input.requestId },\n cause: input.cause,\n ...(input.reenter === true ? { reenter: true } : {}),\n }));\n\nexport const startWorkItemBodySchema = z.object({\n sessionId: trimmedUuidSchema,\n threadTitle: nonEmptyTrimmed(512),\n kickoffKey: trimmedUuidSchema,\n workItem: z.object({\n id: trimmedUuidSchema,\n role: nonEmptyTrimmed(32),\n input: createWorkItemBodySchema,\n }),\n});\n\nexport const automationRunStartBodySchema = z\n .object({\n requestId: trimmedUuidSchema,\n expectedRevision: z.number().int().min(1),\n role: z.enum(FACTORY_ROLE_VALUES),\n skillName: nonEmptyTrimmed(128),\n arguments: nonEmptyTrimmed(4_096).optional(),\n })\n .strict();\n\nexport const metricsQuerySchema = z.object({\n from: z.string().optional(),\n to: z.string().optional(),\n});\n\nconst decisionStatusSchema = z.enum([\n 'pending',\n 'proposed',\n 'dismissed',\n 'superseded',\n 'leased',\n 'retry',\n 'succeeded',\n 'failed',\n]);\nconst boundedLimitSchema = (defaultValue: number, max: number) =>\n z\n .string()\n .optional()\n .transform(value => {\n const parsed = value ? Number.parseInt(value, 10) : defaultValue;\n return Number.isFinite(parsed) ? Math.max(1, Math.min(max, parsed)) : defaultValue;\n });\nconst decisionCursorSchema = z\n .string()\n .optional()\n .transform((value, context) => {\n if (!value) return undefined;\n try {\n const decoded = JSON.parse(Buffer.from(value, 'base64url').toString('utf8')) as unknown;\n if (\n !Array.isArray(decoded) ||\n decoded.length !== 2 ||\n typeof decoded[0] !== 'string' ||\n typeof decoded[1] !== 'string'\n ) {\n throw new Error('invalid cursor');\n }\n const createdAt = new Date(decoded[0]);\n if (Number.isNaN(createdAt.getTime()) || !new RegExp(UUID_PATTERN).test(decoded[1])) {\n throw new Error('invalid cursor');\n }\n return { createdAt, id: decoded[1] };\n } catch {\n context.addIssue({ code: 'custom', message: 'Invalid cursor' });\n return z.NEVER;\n }\n });\n\nexport const decisionQuerySchema = z.object({\n statuses: z\n .string()\n .optional()\n .transform(value => {\n if (!value) return undefined;\n const statuses = [...new Set(value.split(',').map(status => status.trim()))].filter(\n status => decisionStatusSchema.safeParse(status).success,\n ) as Array<z.infer<typeof decisionStatusSchema>>;\n return statuses.length > 0 ? statuses : undefined;\n }),\n before: decisionCursorSchema,\n limit: boundedLimitSchema(25, 50),\n});\n\nconst attentionKindSchema = z.enum([\n 'automation-failed',\n 'automation-proposed',\n 'mention',\n 'activity',\n 'supervisor-finding',\n 'agent-waiting',\n]);\ntype AttentionKind = z.infer<typeof attentionKindSchema>;\ntype AttentionStreamPosition = { occurredAt: Date; id: string };\ntype AttentionCursorMap = Map<AttentionKind, AttentionStreamPosition | undefined>;\n\nfunction parseAttentionStreamPosition(value: unknown): AttentionStreamPosition | undefined {\n if (!Array.isArray(value) || value.length !== 2 || typeof value[0] !== 'string' || typeof value[1] !== 'string') {\n return undefined;\n }\n const occurredAt = new Date(value[0]);\n if (Number.isNaN(occurredAt.getTime()) || !new RegExp(UUID_PATTERN).test(value[1])) return undefined;\n return { occurredAt, id: value[1] };\n}\n\nconst attentionCursorSchema = z\n .string()\n .optional()\n .transform((value, context) => {\n if (!value) return undefined;\n try {\n const decoded: unknown = JSON.parse(Buffer.from(value, 'base64url').toString('utf8'));\n if (Array.isArray(decoded)) {\n const legacy = parseAttentionStreamPosition(decoded);\n if (!legacy) throw new Error('invalid cursor');\n return new Map<AttentionKind, AttentionStreamPosition | undefined>([['automation-failed', legacy]]);\n }\n if (!decoded || typeof decoded !== 'object') throw new Error('invalid cursor');\n const cursors: AttentionCursorMap = new Map();\n for (const [kind, positionValue] of Object.entries(decoded)) {\n const parsedKind = attentionKindSchema.safeParse(kind);\n if (!parsedKind.success) throw new Error('invalid cursor');\n if (positionValue === null) {\n cursors.set(parsedKind.data, undefined);\n continue;\n }\n const position = parseAttentionStreamPosition(positionValue);\n if (!position) throw new Error('invalid cursor');\n cursors.set(parsedKind.data, position);\n }\n if (cursors.size === 0) throw new Error('invalid cursor');\n return cursors;\n } catch {\n context.addIssue({ code: 'custom', message: 'Invalid cursor' });\n return z.NEVER;\n }\n });\n\nexport const attentionQuerySchema = z.object({\n view: z.enum(['open', 'unread', 'archived']).optional().default('open'),\n kind: z.array(attentionKindSchema).optional(),\n before: attentionCursorSchema,\n limit: boundedLimitSchema(25, 50),\n search: z\n .string()\n .optional()\n .transform(value => value?.trim().toLowerCase().slice(0, 200) || undefined),\n});\n\nconst attentionActionPathSchema = z\n .object({\n id: uuidSchema,\n kind: attentionKindSchema,\n sourceId: z.string().min(1).max(256),\n occurrence: z\n .string()\n .regex(/^(0|[1-9]\\d*)$/)\n .transform((value, context) => {\n const occurrence = Number(value);\n if (Number.isSafeInteger(occurrence)) return occurrence;\n context.addIssue({ code: 'custom', message: 'Invalid occurrence' });\n return z.NEVER;\n }),\n })\n .refine(\n input =>\n input.kind === 'supervisor-finding'\n ? /^[a-z0-9:_-]{1,256}$/i.test(input.sourceId)\n : new RegExp(UUID_PATTERN).test(input.sourceId),\n { message: 'Invalid attention source id', path: ['sourceId'] },\n );\n\nexport const FACTORY_ROUTE_CONTRACTS = {\n projectList: {\n method: 'GET',\n path: '/web/factory/projects',\n description: 'List Factory projects for the current organization',\n responseSchema: z.object({ projects: z.array(projectSchema) }),\n },\n projectCreate: {\n method: 'POST',\n path: '/web/factory/projects',\n description: 'Create a Factory project',\n bodySchema: createProjectBodySchema,\n responseSchema: projectResponseSchema,\n },\n projectGet: {\n method: 'GET',\n path: '/web/factory/projects/:id',\n description: 'Get a Factory project',\n pathSchema: projectPathSchema,\n responseSchema: projectResponseSchema,\n },\n projectUpdate: {\n method: 'PATCH',\n path: '/web/factory/projects/:id',\n description: 'Update a Factory project',\n pathSchema: projectPathSchema,\n bodySchema: updateProjectBodySchema,\n responseSchema: projectResponseSchema,\n },\n projectEnvironmentGet: {\n method: 'GET',\n path: '/web/factory/projects/:id/environment',\n description: 'Get the sandbox environment of a Factory project: provider settings and its repositories in order',\n pathSchema: projectPathSchema,\n responseSchema: projectEnvironmentResponseSchema,\n },\n projectEnvironmentUpdate: {\n method: 'PATCH',\n path: '/web/factory/projects/:id/environment',\n description: 'Update the sandbox environment of a Factory project: provider settings, repository order and setup',\n pathSchema: projectPathSchema,\n bodySchema: updateProjectEnvironmentBodySchema,\n responseSchema: projectEnvironmentResponseSchema,\n },\n projectEnvironmentBuild: {\n method: 'POST',\n path: '/web/factory/projects/:id/environment/build',\n description: 'Build the sandbox environment template of a Factory project now',\n pathSchema: projectPathSchema,\n responseSchema: environmentBuildStartResponseSchema,\n },\n projectEnvironmentBuilds: {\n method: 'GET',\n path: '/web/factory/projects/:id/environment/builds',\n description:\n 'List the environment template builds of a Factory project, newest first, when the provider keeps history',\n pathSchema: projectPathSchema,\n responseSchema: environmentBuildsResponseSchema,\n },\n projectEnvironmentBuildGet: {\n method: 'GET',\n path: '/web/factory/projects/:id/environment/builds/:buildId',\n description: 'Get the live status of one environment template build of a Factory project',\n pathSchema: buildPathSchema,\n responseSchema: environmentBuildResponseSchema,\n },\n projectApplyDefaultModel: {\n method: 'POST',\n path: '/web/factory/projects/:id/apply-default-model',\n description: 'Apply the Factory default model to running work and review threads',\n pathSchema: projectPathSchema,\n responseSchema: z.object({\n modelId: z.string(),\n applied: z.array(z.string()),\n skipped: z.array(\n z.object({\n threadId: z.string(),\n reason: z.enum([\n 'not-running',\n 'work-item-missing',\n 'stage-inactive',\n 'thread-missing',\n 'mode-unknown',\n 'apply-failed',\n ]),\n }),\n ),\n }),\n },\n projectDelete: {\n method: 'DELETE',\n path: '/web/factory/projects/:id',\n description: 'Delete a Factory project',\n pathSchema: projectPathSchema,\n responseSchema: z.null(),\n },\n metricsGet: {\n method: 'GET',\n path: '/web/factory/projects/:id/metrics',\n description: 'Get Factory project metrics',\n pathSchema: projectPathSchema,\n querySchema: metricsQuerySchema,\n responseSchema: z.object({ metrics: entitySchema }),\n },\n healthThresholdsGet: {\n method: 'GET',\n path: '/web/factory/projects/:id/health/thresholds',\n description: 'Get queue-health thresholds',\n pathSchema: projectPathSchema,\n responseSchema: z.object({ thresholds: z.array(z.number().finite()) }),\n },\n boardCatalog: {\n method: 'GET',\n path: '/web/factory/projects/:id/boards',\n description: 'List installed Factory boards',\n pathSchema: projectPathSchema,\n responseSchema: z.object({\n boards: z.array(\n z.object({\n id: z.string(),\n title: z.string(),\n initialPhase: z.string(),\n phases: z.array(\n z.object({\n id: z.string(),\n title: z.string(),\n kind: z.enum(['resting', 'working', 'terminal']),\n role: z.string().optional(),\n transitions: z.array(z.object({ outcome: z.string().nullable(), to: z.string() })),\n }),\n ),\n }),\n ),\n }),\n },\n workItemList: {\n method: 'GET',\n path: '/web/factory/projects/:id/work-items',\n description: 'List Factory work items and running sessions',\n pathSchema: projectPathSchema,\n responseSchema: z.object({\n workItems: z.array(entitySchema),\n runningSessionIds: z.array(z.string()),\n parkedSessionIds: z.array(z.string()),\n }),\n },\n workItemCreate: {\n method: 'POST',\n path: '/web/factory/projects/:id/work-items',\n description: 'Create a work item in Intake',\n pathSchema: projectPathSchema,\n bodySchema: createWorkItemBodySchema,\n responseSchema: workItemResponseSchema,\n },\n workItemUpdate: {\n method: 'PATCH',\n path: '/web/factory/work-items/:id',\n description: 'Update non-stage work-item fields',\n pathSchema: workItemPathSchema,\n bodySchema: updateWorkItemBodySchema,\n responseSchema: workItemResponseSchema,\n },\n workItemDelete: {\n method: 'DELETE',\n path: '/web/factory/work-items/:id',\n description: 'Delete a Factory work item',\n pathSchema: workItemPathSchema,\n responseSchema: z.object({ ok: z.literal(true) }),\n },\n workItemTransition: {\n method: 'POST',\n path: '/web/factory/projects/:id/work-items/:workItemId/transition',\n description: 'Transition a work item with its expected revision',\n pathSchema: transitionPathSchema,\n bodySchema: transitionBodySchema,\n responseSchema: entitySchema,\n },\n workItemStart: {\n method: 'POST',\n path: '/web/factory/projects/:id/runs/start',\n description: 'Explicitly start a Factory work-item run',\n pathSchema: projectPathSchema,\n bodySchema: startWorkItemBodySchema,\n responseSchema: entitySchema,\n },\n workItemAutomationRun: {\n method: 'POST',\n path: '/web/factory/projects/:id/work-items/:workItemId/automation-runs',\n description: 'Enqueue an idempotent deferred skill dispatch for a trusted external orchestrator',\n pathSchema: transitionPathSchema,\n bodySchema: automationRunStartBodySchema,\n responseSchema: entitySchema,\n },\n decisionList: {\n method: 'GET',\n path: '/web/factory/projects/:id/decisions',\n description: 'List Factory decisions',\n pathSchema: projectPathSchema,\n querySchema: decisionQuerySchema,\n responseSchema: z.object({ decisions: z.array(entitySchema), nextCursor: z.string().optional() }),\n },\n decisionApprove: {\n method: 'POST',\n path: '/web/factory/projects/:id/decisions/:decisionId/approve',\n description: 'Approve a proposed Factory decision',\n pathSchema: projectDecisionPathSchema,\n responseSchema: decisionResponseSchema,\n },\n decisionDismiss: {\n method: 'POST',\n path: '/web/factory/projects/:id/decisions/:decisionId/dismiss',\n description: 'Dismiss a proposed Factory decision',\n pathSchema: projectDecisionPathSchema,\n responseSchema: decisionResponseSchema,\n },\n decisionRetry: {\n method: 'POST',\n path: '/web/factory/projects/:id/decisions/:decisionId/retry',\n description: 'Retry a failed retryable Factory decision',\n pathSchema: projectDecisionPathSchema,\n responseSchema: decisionResponseSchema,\n },\n attentionList: {\n method: 'GET',\n path: '/web/factory/projects/:id/attention',\n description: 'List the Factory attention inbox',\n pathSchema: projectPathSchema,\n querySchema: attentionQuerySchema,\n responseSchema: z.object({\n items: z.array(entitySchema),\n kinds: z.record(\n attentionKindSchema,\n z.object({\n open: z.number(),\n unread: z.number(),\n latest: z.object({ key: z.string(), at: z.string(), unread: z.boolean() }).nullable(),\n }),\n ),\n hasMore: z.boolean(),\n nextCursor: z.string().optional(),\n }),\n },\n attentionReadAll: {\n method: 'POST',\n path: '/web/factory/projects/:id/attention/read-all',\n description: 'Mark all Factory attention as read',\n pathSchema: projectPathSchema,\n querySchema: z.object({ before: attentionCursorSchema }),\n responseSchema: z.object({ ok: z.literal(true), hasMore: z.boolean(), nextCursor: z.string().optional() }),\n },\n attentionRead: {\n method: 'POST',\n path: '/web/factory/projects/:id/attention/:kind/:sourceId/:occurrence/read',\n description: 'Mark a Factory attention receipt as read',\n pathSchema: attentionActionPathSchema,\n responseSchema: z.object({ receipt: entitySchema }),\n },\n attentionArchive: {\n method: 'POST',\n path: '/web/factory/projects/:id/attention/:kind/:sourceId/:occurrence/archive',\n description: 'Archive a Factory attention receipt',\n pathSchema: attentionActionPathSchema,\n responseSchema: z.object({ receipt: entitySchema }),\n },\n attentionRestore: {\n method: 'POST',\n path: '/web/factory/projects/:id/attention/:kind/:sourceId/:occurrence/restore',\n description: 'Restore an archived Factory attention receipt',\n pathSchema: attentionActionPathSchema,\n responseSchema: z.object({ receipt: entitySchema }),\n },\n supervisorSession: {\n method: 'POST',\n path: '/web/factory/projects/:id/supervisor/session',\n description: 'Get the deterministic Factory supervisor session address',\n pathSchema: projectPathSchema,\n responseSchema: z.object({ sessionId: z.string(), threadId: z.string(), factoryProjectId: uuidSchema }),\n },\n supervisorHealth: {\n method: 'GET',\n path: '/web/factory/projects/:id/supervisor/health',\n description: 'Run the deterministic Factory supervisor health check',\n pathSchema: projectPathSchema,\n responseSchema: z.object({\n checkedAt: z.string(),\n findings: z.array(entitySchema),\n counts: z.record(z.string(), z.number().int().nonnegative()),\n }),\n },\n} as const satisfies Record<string, FactoryRouteContract>;\n\nexport type FactoryRouteContractKey = keyof typeof FACTORY_ROUTE_CONTRACTS;\n"],"mappings":"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"}
@@ -66,6 +66,15 @@ export interface WorkspaceFilesListing {
66
66
  files: Array<{
67
67
  path: string;
68
68
  }>;
69
+ /**
70
+ * The environment repositories the paths are prefixed by, in position
71
+ * order. Present only when the session's environment holds two or more
72
+ * repositories; a one-repository session lists unprefixed paths.
73
+ */
74
+ repositories?: Array<{
75
+ slug: string;
76
+ prefix: string;
77
+ }>;
69
78
  }
70
79
  export type WorkspaceChangeStatus = 'modified' | 'added' | 'deleted' | 'renamed' | 'copied' | 'untracked' | 'conflicted';
71
80
  export interface WorkspaceChange {
@@ -76,12 +85,28 @@ export interface WorkspaceChange {
76
85
  deletions?: number;
77
86
  binary?: boolean;
78
87
  }
88
+ export interface WorkspaceChangesRepository {
89
+ slug: string;
90
+ /** The path prefix of this repository's changes in the flat list, e.g. `platform/`. */
91
+ prefix: string;
92
+ /** False when the checkout could not be inspected (missing, or git failed). */
93
+ available: boolean;
94
+ changes: WorkspaceChange[];
95
+ additions?: number;
96
+ deletions?: number;
97
+ }
79
98
  export interface WorkspaceChanges {
80
99
  workspacePath: string;
81
100
  available: boolean;
101
+ /** Every repository's changes, paths prefixed by the repository directory in a multi-repository session. */
82
102
  changes: WorkspaceChange[];
83
103
  additions?: number;
84
104
  deletions?: number;
105
+ /**
106
+ * One group per environment repository, in position order. Present only
107
+ * when the session's environment holds two or more repositories.
108
+ */
109
+ repositories?: WorkspaceChangesRepository[];
85
110
  }
86
111
  export interface WorkspaceDiff {
87
112
  workspacePath: string;
@@ -1 +1 @@
1
- {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/routes/fs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/routes/fs.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AASpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACtF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,4EAA4E;IAC5E,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,wBAAwB;IACvC,2CAA2C;IAC3C,aAAa,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,sBAAsB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,aAAa,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,aAAa,CAAC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,uCAAuC;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/B;;;;OAIG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxD;AAED,MAAM,MAAM,qBAAqB,GAC7B,UAAU,GACV,OAAO,GACP,SAAS,GACT,SAAS,GACT,QAAQ,GACR,WAAW,GACX,YAAY,CAAC;AAEjB,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,uFAAuF;IACvF,MAAM,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,4GAA4G;IAC5G,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,YAAY,CAAC,EAAE,0BAA0B,EAAE,CAAC;CAC7C;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,aAAa,GAAG,sBAAsB,CAAC;AAEnD,MAAM,WAAW,eAAe;IAC9B,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAkDD,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAEnD;AA0ED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAuCnG;AAqCD,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,wBAAwB,CAAC,CAkBnC;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA4CjH;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAOjG;AAUD,iFAAiF;AACjF,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE;QAAE,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAA;KAAE,CAAC;IACtF,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC;CAClD;AA0BD,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC,EAChD,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,qBAAqB,CAAC,CAkBhC;AAiFD,iFAAiF;AACjF,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,oBAAoB,EAC7B,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,wBAAwB,CAAC,CAsCnC;AAED,kIAAkI;AAClI,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,oBAAoB,EAC7B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC9C,OAAO,CAAC,aAAa,CAAC,CAyBxB;AAYD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,EAAE,CAoBvE;AACD,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,EAAE,CAiB9E;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM;gBAEV,MAAM;gBAAc,MAAM;aAAW,OAAO;GA+BzF;AAyED,wBAAsB,2BAA2B,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA4C1G;AAiBD,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,oBAAoB,EAC7B,IAAI,EAAE,MAAM,EACZ,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,aAAa,CAAC,CAyExB;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB,CAUrE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,aAAa,CAAA;CAAO,GAAG,QAAQ,EAAE,CA2LpG"}
package/dist/routes/fs.js CHANGED
@@ -1,11 +1,12 @@
1
1
  import { requireExec } from "../sandbox/materialization.js";
2
- import { peekSessionSandbox } from "../sandbox/session-sandbox.js";
2
+ import { peekSessionSandbox, sessionLayout } from "../sandbox/session-sandbox.js";
3
+ import { peekSessionEnvironment } from "../session/environment-state-processor.js";
3
4
  import { waitForPendingFilesystemCapture } from "../session/filesystem-capture.js";
4
5
  import { registerApiRoute } from "@mastra/core/server";
5
6
  import { isAbsolute, join, posix, resolve, sep } from "path";
7
+ import { SandboxFilesystem } from "@mastra/code-sdk/agents/sandbox-filesystem";
6
8
  import { lstat, open, readdir, realpath, stat } from "fs/promises";
7
9
  import { homedir } from "os";
8
- import { SandboxFilesystem } from "@mastra/code-sdk/agents/sandbox-filesystem";
9
10
  import { detectProject, getResourceIdOverride } from "@mastra/code-sdk/utils/project";
10
11
  //#region src/routes/fs.ts
11
12
  const MAX_TEXT_FILE_BYTES = 512 * 1024;
@@ -278,41 +279,88 @@ async function listSessionFilesystemFiles(filesystem, session, threadId) {
278
279
  const safeThreadId = threadId.trim();
279
280
  if (!safeThreadId) throw new Error("Missing required query param: threadId");
280
281
  await waitForPendingFilesystemCapture(session.sessionId);
282
+ const layout = sessionLayout(peekSessionSandbox(session.id));
281
283
  return {
282
284
  workspacePath: session.sessionId,
283
285
  threadId: safeThreadId,
284
286
  files: await filesystem.listFiles({
285
287
  resourceId: session.sessionId,
286
288
  threadId: safeThreadId
287
- })
289
+ }),
290
+ ...layout && layout.repos.length > 1 ? { repositories: layout.repos.map((repo) => ({
291
+ slug: repo.slug,
292
+ prefix: repo.prefix
293
+ })) } : {}
288
294
  };
289
295
  }
290
296
  /**
291
- * Resolve the session's sandbox from the per-process memo and wrap its
292
- * workdir in a `SandboxFilesystem`. Returns `null` when the session has no
293
- * sandbox in this process (never opened here, or evicted by retirement).
294
- * This is a passive read path, so it never constructs or provisions: the
295
- * session's files come back the next time the workspace is actually opened
296
- * (e.g. by sending a message).
297
+ * Resolve the session's sandbox from the per-process memo and wrap the
298
+ * session layout's root in a `SandboxFilesystem`: the checkout for a
299
+ * one-repository session, the workspace root (one directory per repository)
300
+ * otherwise. Returns `null` when the session has no sandbox in this process
301
+ * (never opened here, or evicted by retirement). This is a passive read path,
302
+ * so it never constructs or provisions: the session's files come back the
303
+ * next time the workspace is actually opened (e.g. by sending a message).
297
304
  */
298
305
  async function sessionSandbox(session) {
299
306
  const entry = peekSessionSandbox(session.id);
300
- if (!entry?.workdir) return null;
307
+ const layout = sessionLayout(entry);
308
+ if (!entry || !layout) return null;
301
309
  const sandbox = requireExec(entry.sandbox);
302
310
  return {
303
311
  sandbox,
304
312
  filesystem: new SandboxFilesystem({
305
313
  sandbox,
306
- workdir: entry.workdir
314
+ workdir: layout.root
307
315
  }),
308
- workdir: entry.workdir
316
+ layout,
317
+ baseBranches: repositoryBaseBranches(session, layout, entry.ownRepo)
318
+ };
319
+ }
320
+ /**
321
+ * The branch each layout repository is compared against: the session base
322
+ * branch for the session's own repository (session branch vs base), the
323
+ * default branch the boot recorded for every other one, `HEAD` (the checkout's
324
+ * own `origin/HEAD`) until the boot has recorded it.
325
+ */
326
+ function repositoryBaseBranches(session, layout, ownRepo) {
327
+ const environment = layout.repos.length > 1 ? peekSessionEnvironment(session.sessionId) : void 0;
328
+ const bases = /* @__PURE__ */ new Map();
329
+ for (const repo of layout.repos) {
330
+ if (layout.repos.length === 1 || repo.slug.toLowerCase() === ownRepo.toLowerCase()) {
331
+ bases.set(repo.slug, session.baseBranch);
332
+ continue;
333
+ }
334
+ const state = environment?.repositories.find((candidate) => candidate.slug.toLowerCase() === repo.slug.toLowerCase());
335
+ bases.set(repo.slug, state?.defaultBranch ?? "HEAD");
336
+ }
337
+ return bases;
338
+ }
339
+ /**
340
+ * Split a client path into the layout repository it belongs to and the path
341
+ * inside that checkout. Longest prefix wins; the inside path is validated
342
+ * again so a prefix cannot smuggle a traversal. A path matching no repository
343
+ * (including a bare prefix) is not available: the file routes only serve the
344
+ * checkouts, never the workspace root itself.
345
+ */
346
+ function resolveLayoutPath(layout, path, label) {
347
+ const safePath = assertRelativePath(path, label);
348
+ if (layout.repos.length === 1) return {
349
+ repo: layout.repos[0],
350
+ relative: safePath
351
+ };
352
+ const repo = layout.repos.filter((candidate) => safePath.startsWith(candidate.prefix) && safePath.length > candidate.prefix.length).toSorted((a, b) => b.prefix.length - a.prefix.length)[0];
353
+ if (!repo) throw new Error(`${label} is not available in this session's repositories`);
354
+ return {
355
+ repo,
356
+ relative: assertRelativePath(safePath.slice(repo.prefix.length), label)
309
357
  };
310
358
  }
311
359
  /** List an approved rendered root inside a Factory session's sandbox workdir. */
312
360
  async function listSessionRenderedPath(session, renderedRoot) {
313
361
  const safeRoot = assertApprovedRenderedRoot(renderedRoot);
314
362
  const handle = await sessionSandbox(session);
315
- const rootPath = posix.join(handle?.workdir ?? "", safeRoot);
363
+ const rootPath = posix.join(handle?.layout.root ?? "", safeRoot);
316
364
  const empty = {
317
365
  workspacePath: session.sessionId,
318
366
  root: safeRoot,
@@ -478,78 +526,122 @@ function unavailableWorkspaceChanges(workspacePath) {
478
526
  changes: []
479
527
  };
480
528
  }
481
- async function resolveSessionComparisonBase(session, sandbox, workdir) {
529
+ async function resolveSessionComparisonBase(sandbox, workdir, baseBranch) {
482
530
  const result = await sandbox.executeCommand("git", [
483
531
  "-C",
484
532
  workdir,
485
533
  "merge-base",
486
534
  "HEAD",
487
- `origin/${session.baseBranch}`
535
+ `origin/${baseBranch}`
488
536
  ], { timeout: 3e4 });
489
537
  const sha = result.stdout.trim();
490
538
  return result.exitCode === 0 && /^[0-9a-f]{40,64}$/i.test(sha) ? sha : "HEAD";
491
539
  }
492
- async function listSessionWorkspaceChanges(session) {
493
- const handle = await sessionSandbox(session);
494
- if (!handle) return unavailableWorkspaceChanges(session.sessionId);
495
- const comparisonBase = await resolveSessionComparisonBase(session, handle.sandbox, handle.workdir);
540
+ /** The changes of one checkout against its comparison base; `available: false` when git cannot inspect it. */
541
+ async function listRepositoryChanges(sandbox, workdir, baseBranch) {
542
+ const comparisonBase = await resolveSessionComparisonBase(sandbox, workdir, baseBranch);
496
543
  const [statusResult, trackedResult, statsResult] = await Promise.all([
497
- handle.sandbox.executeCommand("git", [
544
+ sandbox.executeCommand("git", [
498
545
  "-C",
499
- handle.workdir,
546
+ workdir,
500
547
  "status",
501
548
  "--porcelain=v1",
502
549
  "-z",
503
550
  "--untracked-files=all"
504
551
  ], { timeout: 3e4 }),
505
- handle.sandbox.executeCommand("git", [
552
+ sandbox.executeCommand("git", [
506
553
  "-C",
507
- handle.workdir,
554
+ workdir,
508
555
  "diff",
509
556
  "--name-status",
510
557
  "-z",
511
558
  "--find-renames",
512
559
  comparisonBase
513
560
  ], { timeout: 3e4 }),
514
- handle.sandbox.executeCommand("sh", [
561
+ sandbox.executeCommand("sh", [
515
562
  "-c",
516
563
  WORKSPACE_NUMSTAT_SCRIPT,
517
564
  "mastracode-numstat",
518
- handle.workdir,
565
+ workdir,
519
566
  comparisonBase
520
567
  ], { timeout: 3e4 })
521
568
  ]);
522
- if (statusResult.exitCode !== 0) return unavailableWorkspaceChanges(session.sessionId);
569
+ if (statusResult.exitCode !== 0) return {
570
+ available: false,
571
+ changes: []
572
+ };
523
573
  const statusChanges = parseWorkspaceChanges(statusResult.stdout);
524
574
  const trackedChanges = trackedResult.exitCode === 0 ? parseWorkspaceTrackedChanges(trackedResult.stdout) : [];
525
575
  const changesByPath = new Map(trackedChanges.map((change) => [change.path, change]));
526
576
  for (const change of statusChanges) if (trackedResult.exitCode !== 0 || change.status === "untracked" || change.status === "conflicted") changesByPath.set(change.path, change);
527
577
  const changes = [...changesByPath.values()].toSorted((a, b) => a.path.localeCompare(b.path));
528
578
  if (statsResult.exitCode !== 0) return {
529
- workspacePath: session.sessionId,
530
579
  available: true,
531
580
  changes
532
581
  };
533
582
  const stats = parseWorkspaceChangeStats(statsResult.stdout);
534
583
  let additions = 0;
535
584
  let deletions = 0;
536
- const changesWithStats = changes.map((change) => {
537
- const changeStats = stats.get(change.path);
538
- additions += changeStats?.additions ?? 0;
539
- deletions += changeStats?.deletions ?? 0;
540
- return {
541
- ...change,
542
- ...changeStats
543
- };
544
- });
545
585
  return {
546
- workspacePath: session.sessionId,
547
586
  available: true,
548
- changes: changesWithStats,
587
+ changes: changes.map((change) => {
588
+ const changeStats = stats.get(change.path);
589
+ additions += changeStats?.additions ?? 0;
590
+ deletions += changeStats?.deletions ?? 0;
591
+ return {
592
+ ...change,
593
+ ...changeStats
594
+ };
595
+ }),
549
596
  additions,
550
597
  deletions
551
598
  };
552
599
  }
600
+ function prefixChange(change, prefix) {
601
+ if (!prefix) return change;
602
+ return {
603
+ ...change,
604
+ path: `${prefix}${change.path}`,
605
+ ...change.previousPath ? { previousPath: `${prefix}${change.previousPath}` } : {}
606
+ };
607
+ }
608
+ async function listSessionWorkspaceChanges(session) {
609
+ const handle = await sessionSandbox(session);
610
+ if (!handle) return unavailableWorkspaceChanges(session.sessionId);
611
+ const { layout, baseBranches: bases } = handle;
612
+ if (layout.repos.length === 1) {
613
+ const repo = layout.repos[0];
614
+ const result = await listRepositoryChanges(handle.sandbox, repo.dir, bases.get(repo.slug) ?? session.baseBranch);
615
+ if (!result.available) return unavailableWorkspaceChanges(session.sessionId);
616
+ return {
617
+ workspacePath: session.sessionId,
618
+ ...result
619
+ };
620
+ }
621
+ const groups = await Promise.all(layout.repos.map(async (repo) => {
622
+ const result = await listRepositoryChanges(handle.sandbox, repo.dir, bases.get(repo.slug));
623
+ return {
624
+ slug: repo.slug,
625
+ prefix: repo.prefix,
626
+ ...result,
627
+ changes: result.changes.map((change) => prefixChange(change, repo.prefix))
628
+ };
629
+ }));
630
+ const available = groups.filter((group) => group.available);
631
+ const changes = available.flatMap((group) => group.changes).toSorted((a, b) => a.path.localeCompare(b.path));
632
+ const counted = available.filter((group) => group.additions !== void 0);
633
+ const totals = counted.length > 0 ? {
634
+ additions: counted.reduce((sum, group) => sum + (group.additions ?? 0), 0),
635
+ deletions: counted.reduce((sum, group) => sum + (group.deletions ?? 0), 0)
636
+ } : {};
637
+ return {
638
+ workspacePath: session.sessionId,
639
+ available: available.length > 0,
640
+ changes,
641
+ ...totals,
642
+ repositories: groups
643
+ };
644
+ }
553
645
  async function executeBoundedGitDiff(sandbox, args, allowExitOne = false) {
554
646
  return sandbox.executeCommand("sh", [
555
647
  "-c",
@@ -567,15 +659,19 @@ function truncatePatch(patchBuffer) {
567
659
  }
568
660
  async function readSessionWorkspaceDiff(session, path, previousPath) {
569
661
  const safePath = assertRelativePath(path, "path");
570
- const safePreviousPath = previousPath ? assertRelativePath(previousPath, "previousPath") : void 0;
662
+ if (previousPath) assertRelativePath(previousPath, "previousPath");
571
663
  const handle = await sessionSandbox(session);
572
664
  if (!handle) throw new Error("Session workspace is not available");
573
- const comparisonBase = await resolveSessionComparisonBase(session, handle.sandbox, handle.workdir);
574
- const pathspecs = safePreviousPath ? [safePreviousPath, safePath] : [safePath];
665
+ const target = resolveLayoutPath(handle.layout, safePath, "path");
666
+ const previous = previousPath ? resolveLayoutPath(handle.layout, previousPath, "previousPath") : void 0;
667
+ if (previous && previous.repo !== target.repo) throw new Error("previousPath is not available in the repository of path");
668
+ const workdir = target.repo.dir;
669
+ const comparisonBase = await resolveSessionComparisonBase(handle.sandbox, workdir, handle.baseBranches.get(target.repo.slug));
670
+ const pathspecs = previous ? [previous.relative, target.relative] : [target.relative];
575
671
  let result = await executeBoundedGitDiff(handle.sandbox, [
576
672
  "--literal-pathspecs",
577
673
  "-C",
578
- handle.workdir,
674
+ workdir,
579
675
  "diff",
580
676
  "--find-renames",
581
677
  "--no-ext-diff",
@@ -590,17 +686,17 @@ async function readSessionWorkspaceDiff(session, path, previousPath) {
590
686
  const untracked = await handle.sandbox.executeCommand("git", [
591
687
  "--literal-pathspecs",
592
688
  "-C",
593
- handle.workdir,
689
+ workdir,
594
690
  "ls-files",
595
691
  "--others",
596
692
  "--exclude-standard",
597
693
  "--",
598
- safePath
694
+ target.relative
599
695
  ], { timeout: 3e4 });
600
696
  if (untracked.exitCode === 0 && untracked.stdout.trim()) {
601
697
  result = await executeBoundedGitDiff(handle.sandbox, [
602
698
  "-C",
603
- handle.workdir,
699
+ workdir,
604
700
  "diff",
605
701
  "--no-index",
606
702
  "--no-ext-diff",
@@ -608,7 +704,7 @@ async function readSessionWorkspaceDiff(session, path, previousPath) {
608
704
  "--unified=3",
609
705
  "--",
610
706
  "/dev/null",
611
- safePath
707
+ target.relative
612
708
  ], true);
613
709
  if (result.exitCode !== 0 && result.exitCode !== 1) throw new Error(result.stderr || "Unable to read workspace diff");
614
710
  }