@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.
- package/dist/capabilities/version-control.d.ts +13 -8
- package/dist/capabilities/version-control.d.ts.map +1 -1
- package/dist/environment/build-runner.d.ts +72 -0
- package/dist/environment/build-runner.d.ts.map +1 -0
- package/dist/environment/build-runner.js +131 -0
- package/dist/environment/build-runner.js.map +1 -0
- package/dist/environment/build-schedule.d.ts +40 -0
- package/dist/environment/build-schedule.d.ts.map +1 -0
- package/dist/environment/build-schedule.js +94 -0
- package/dist/environment/build-schedule.js.map +1 -0
- package/dist/environment/build-workflow.d.ts +62 -0
- package/dist/environment/build-workflow.d.ts.map +1 -0
- package/dist/environment/build-workflow.js +149 -0
- package/dist/environment/build-workflow.js.map +1 -0
- package/dist/environment/build.d.ts +111 -0
- package/dist/environment/build.d.ts.map +1 -0
- package/dist/environment/build.js +344 -0
- package/dist/environment/build.js.map +1 -0
- package/dist/environment/heads.d.ts +36 -0
- package/dist/environment/heads.d.ts.map +1 -0
- package/dist/environment/heads.js +60 -0
- package/dist/environment/heads.js.map +1 -0
- package/dist/factory.d.ts +18 -4
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +89 -15
- package/dist/factory.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/integrations/base.d.ts +17 -2
- package/dist/integrations/base.d.ts.map +1 -1
- package/dist/integrations/github/commits.d.ts +11 -0
- package/dist/integrations/github/commits.d.ts.map +1 -1
- package/dist/integrations/github/commits.js +20 -1
- package/dist/integrations/github/commits.js.map +1 -1
- package/dist/integrations/github/config.d.ts +3 -3
- package/dist/integrations/github/config.d.ts.map +1 -1
- package/dist/integrations/github/config.js +1 -1
- package/dist/integrations/github/config.js.map +1 -1
- package/dist/integrations/github/routes.d.ts +2 -2
- package/dist/integrations/github/routes.d.ts.map +1 -1
- package/dist/integrations/github/routes.js +6 -5
- package/dist/integrations/github/routes.js.map +1 -1
- package/dist/integrations/github/rules.d.ts +3 -1
- package/dist/integrations/github/rules.d.ts.map +1 -1
- package/dist/integrations/github/rules.js +31 -1
- package/dist/integrations/github/rules.js.map +1 -1
- package/dist/integrations/github/sandbox.d.ts +35 -0
- package/dist/integrations/github/sandbox.d.ts.map +1 -1
- package/dist/integrations/github/sandbox.js +203 -2
- package/dist/integrations/github/sandbox.js.map +1 -1
- package/dist/integrations/github/session-subscriptions.d.ts.map +1 -1
- package/dist/integrations/github/session-subscriptions.js +117 -62
- package/dist/integrations/github/session-subscriptions.js.map +1 -1
- package/dist/integrations/github/token-refresh.d.ts +7 -0
- package/dist/integrations/github/token-refresh.d.ts.map +1 -1
- package/dist/integrations/github/token-refresh.js.map +1 -1
- package/dist/integrations/github/webhook.js.map +1 -1
- package/dist/integrations/gitlab/agent-tools.js +1 -1
- package/dist/integrations/gitlab/routes.d.ts +2 -2
- package/dist/integrations/gitlab/routes.d.ts.map +1 -1
- package/dist/integrations/gitlab/routes.js.map +1 -1
- package/dist/integrations/gitlab/session-subscriptions.d.ts.map +1 -1
- package/dist/integrations/gitlab/session-subscriptions.js +8 -7
- package/dist/integrations/gitlab/session-subscriptions.js.map +1 -1
- package/dist/integrations/incidentio/agent-tools.js +1 -1
- package/dist/integrations/jira/agent-tools.js +1 -1
- package/dist/integrations/linear/agent-tools.js +1 -1
- package/dist/integrations/platform/github/integration.d.ts.map +1 -1
- package/dist/integrations/platform/github/integration.js +46 -2
- package/dist/integrations/platform/github/integration.js.map +1 -1
- package/dist/integrations/platform/jira/agent-tools.js +1 -1
- package/dist/integrations/slack/slack.d.ts.map +1 -1
- package/dist/integrations/slack/slack.js +15 -16
- package/dist/integrations/slack/slack.js.map +1 -1
- package/dist/integrations/subscription-session.js +1 -1
- package/dist/packages/_internals/workspace/dist/index.js +21 -1
- package/dist/packages/_internals/workspace/dist/index.js.map +1 -1
- package/dist/routes/contracts.d.ts +386 -2
- package/dist/routes/contracts.d.ts.map +1 -1
- package/dist/routes/contracts.js +166 -1
- package/dist/routes/contracts.js.map +1 -1
- package/dist/routes/fs.d.ts +25 -0
- package/dist/routes/fs.d.ts.map +1 -1
- package/dist/routes/fs.js +142 -46
- package/dist/routes/fs.js.map +1 -1
- package/dist/routes/projects.d.ts +6 -0
- package/dist/routes/projects.d.ts.map +1 -1
- package/dist/routes/projects.js +344 -1
- package/dist/routes/projects.js.map +1 -1
- package/dist/routes/source-control-sessions.d.ts +2 -0
- package/dist/routes/source-control-sessions.d.ts.map +1 -1
- package/dist/routes/source-control-sessions.js +36 -1
- package/dist/routes/source-control-sessions.js.map +1 -1
- package/dist/routes/supervisor.js +1 -1
- package/dist/routes/surface.d.ts +6 -3
- package/dist/routes/surface.d.ts.map +1 -1
- package/dist/routes/surface.js +21 -34
- package/dist/routes/surface.js.map +1 -1
- package/dist/rules/binding-context.d.ts +1 -1
- package/dist/rules/binding-context.d.ts.map +1 -1
- package/dist/rules/binding-context.js +1 -1
- package/dist/rules/binding-context.js.map +1 -1
- package/dist/rules/review-source-tool.js +1 -1
- package/dist/rules/start-coordinator.d.ts.map +1 -1
- package/dist/rules/start-coordinator.js +7 -2
- package/dist/rules/start-coordinator.js.map +1 -1
- package/dist/rules/tools.js +1 -1
- package/dist/sandbox/callback-factory-sandbox.d.ts +15 -0
- package/dist/sandbox/callback-factory-sandbox.d.ts.map +1 -0
- package/dist/sandbox/callback-factory-sandbox.js +22 -0
- package/dist/sandbox/callback-factory-sandbox.js.map +1 -0
- package/dist/sandbox/local-factory-sandbox.d.ts +20 -0
- package/dist/sandbox/local-factory-sandbox.d.ts.map +1 -0
- package/dist/sandbox/local-factory-sandbox.js +27 -0
- package/dist/sandbox/local-factory-sandbox.js.map +1 -0
- package/dist/sandbox/session-retirement.d.ts.map +1 -1
- package/dist/sandbox/session-retirement.js +23 -3
- package/dist/sandbox/session-retirement.js.map +1 -1
- package/dist/sandbox/session-sandbox.d.ts +82 -40
- package/dist/sandbox/session-sandbox.d.ts.map +1 -1
- package/dist/sandbox/session-sandbox.js +130 -13
- package/dist/sandbox/session-sandbox.js.map +1 -1
- package/dist/sandbox/workdir.d.ts +10 -0
- package/dist/sandbox/workdir.d.ts.map +1 -1
- package/dist/sandbox/workdir.js +10 -1
- package/dist/sandbox/workdir.js.map +1 -1
- package/dist/session/environment-repositories.d.ts +31 -0
- package/dist/session/environment-repositories.d.ts.map +1 -0
- package/dist/session/environment-repositories.js +89 -0
- package/dist/session/environment-repositories.js.map +1 -0
- package/dist/session/environment-state-processor.d.ts +59 -0
- package/dist/session/environment-state-processor.d.ts.map +1 -0
- package/dist/session/environment-state-processor.js +105 -0
- package/dist/session/environment-state-processor.js.map +1 -0
- package/dist/session/factory-session.d.ts +26 -35
- package/dist/session/factory-session.d.ts.map +1 -1
- package/dist/session/factory-session.js +34 -71
- package/dist/session/factory-session.js.map +1 -1
- package/dist/session/filesystem-capture.d.ts +13 -0
- package/dist/session/filesystem-capture.d.ts.map +1 -1
- package/dist/session/filesystem-capture.js +73 -14
- package/dist/session/filesystem-capture.js.map +1 -1
- package/dist/session/source-control-tools.d.ts +1 -1
- package/dist/session/source-control-tools.d.ts.map +1 -1
- package/dist/session/source-control-tools.js +144 -71
- package/dist/session/source-control-tools.js.map +1 -1
- package/dist/spa-static.js +2 -2
- package/dist/storage/domains/audit/agent-audit.d.ts +6 -1
- package/dist/storage/domains/audit/agent-audit.d.ts.map +1 -1
- package/dist/storage/domains/audit/agent-audit.js +31 -13
- package/dist/storage/domains/audit/agent-audit.js.map +1 -1
- package/dist/storage/domains/projects/base.d.ts +115 -2
- package/dist/storage/domains/projects/base.d.ts.map +1 -1
- package/dist/storage/domains/projects/base.js +219 -12
- package/dist/storage/domains/projects/base.js.map +1 -1
- package/dist/storage/domains/source-control/base.d.ts +123 -7
- package/dist/storage/domains/source-control/base.d.ts.map +1 -1
- package/dist/storage/domains/source-control/base.js +406 -33
- package/dist/storage/domains/source-control/base.js.map +1 -1
- package/dist/storage/domains/source-control/inmemory.d.ts +19 -6
- package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
- package/dist/storage/domains/source-control/inmemory.js +90 -2
- package/dist/storage/domains/source-control/inmemory.js.map +1 -1
- package/dist/storage/domains/work-items/base.d.ts.map +1 -1
- package/dist/storage/domains/work-items/base.js +12 -5
- package/dist/storage/domains/work-items/base.js.map +1 -1
- package/dist/supervisor/read-tools.js +1 -1
- package/dist/supervisor/write-tools.js +1 -1
- package/dist/workspace.d.ts +50 -7
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +344 -24
- package/dist/workspace.js.map +1 -1
- 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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"}
|
package/dist/routes/fs.d.ts
CHANGED
|
@@ -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;
|
package/dist/routes/fs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/routes/fs.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/routes/fs.ts"],"names":[],"mappings":"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"}
|
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
|
|
292
|
-
*
|
|
293
|
-
*
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
*
|
|
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
|
-
|
|
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:
|
|
314
|
+
workdir: layout.root
|
|
307
315
|
}),
|
|
308
|
-
|
|
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?.
|
|
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(
|
|
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/${
|
|
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
|
-
|
|
493
|
-
|
|
494
|
-
|
|
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
|
-
|
|
544
|
+
sandbox.executeCommand("git", [
|
|
498
545
|
"-C",
|
|
499
|
-
|
|
546
|
+
workdir,
|
|
500
547
|
"status",
|
|
501
548
|
"--porcelain=v1",
|
|
502
549
|
"-z",
|
|
503
550
|
"--untracked-files=all"
|
|
504
551
|
], { timeout: 3e4 }),
|
|
505
|
-
|
|
552
|
+
sandbox.executeCommand("git", [
|
|
506
553
|
"-C",
|
|
507
|
-
|
|
554
|
+
workdir,
|
|
508
555
|
"diff",
|
|
509
556
|
"--name-status",
|
|
510
557
|
"-z",
|
|
511
558
|
"--find-renames",
|
|
512
559
|
comparisonBase
|
|
513
560
|
], { timeout: 3e4 }),
|
|
514
|
-
|
|
561
|
+
sandbox.executeCommand("sh", [
|
|
515
562
|
"-c",
|
|
516
563
|
WORKSPACE_NUMSTAT_SCRIPT,
|
|
517
564
|
"mastracode-numstat",
|
|
518
|
-
|
|
565
|
+
workdir,
|
|
519
566
|
comparisonBase
|
|
520
567
|
], { timeout: 3e4 })
|
|
521
568
|
]);
|
|
522
|
-
if (statusResult.exitCode !== 0) return
|
|
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:
|
|
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
|
-
|
|
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
|
|
574
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
689
|
+
workdir,
|
|
594
690
|
"ls-files",
|
|
595
691
|
"--others",
|
|
596
692
|
"--exclude-standard",
|
|
597
693
|
"--",
|
|
598
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|