@mastra/factory 0.13.0-alpha.8 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +232 -10
- package/dist/auth.d.ts +2 -0
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +29 -4
- package/dist/auth.js.map +1 -1
- package/dist/boards/define-board.d.ts +36 -2
- package/dist/boards/define-board.d.ts.map +1 -1
- package/dist/boards/define-board.js +58 -1
- package/dist/boards/define-board.js.map +1 -1
- package/dist/boards/index.d.ts +4 -2
- package/dist/boards/index.d.ts.map +1 -1
- package/dist/boards/index.js +2 -1
- package/dist/boards/index.js.map +1 -1
- package/dist/boards/relocate.d.ts +17 -0
- package/dist/boards/relocate.d.ts.map +1 -0
- package/dist/boards/relocate.js +53 -0
- package/dist/boards/relocate.js.map +1 -0
- package/dist/boards/review.d.ts +1 -1
- package/dist/boards/review.d.ts.map +1 -1
- package/dist/boards/review.js +17 -4
- package/dist/boards/review.js.map +1 -1
- package/dist/boards/semantics.d.ts +28 -0
- package/dist/boards/semantics.d.ts.map +1 -0
- package/dist/boards/semantics.js +41 -0
- package/dist/boards/semantics.js.map +1 -0
- package/dist/boards/work-tool-rules.d.ts +8 -0
- package/dist/boards/work-tool-rules.d.ts.map +1 -0
- package/dist/boards/work-tool-rules.js +20 -0
- package/dist/boards/work-tool-rules.js.map +1 -0
- package/dist/boards/work.d.ts +1 -1
- package/dist/boards/work.d.ts.map +1 -1
- package/dist/boards/work.js +13 -0
- package/dist/boards/work.js.map +1 -1
- package/dist/capabilities/intake.d.ts +2 -0
- package/dist/capabilities/intake.d.ts.map +1 -1
- package/dist/factory.d.ts +5 -6
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +41 -12
- package/dist/factory.js.map +1 -1
- package/dist/integrations/base.d.ts +7 -4
- package/dist/integrations/base.d.ts.map +1 -1
- package/dist/integrations/github/default-rules.d.ts +2 -2
- package/dist/integrations/github/default-rules.d.ts.map +1 -1
- package/dist/integrations/github/default-rules.js +2 -2
- package/dist/integrations/github/default-rules.js.map +1 -1
- package/dist/integrations/github/issue-reconciler.d.ts.map +1 -1
- package/dist/integrations/github/issue-reconciler.js +4 -3
- package/dist/integrations/github/issue-reconciler.js.map +1 -1
- package/dist/integrations/github/rules.d.ts +6 -2
- package/dist/integrations/github/rules.d.ts.map +1 -1
- package/dist/integrations/github/rules.js +96 -15
- package/dist/integrations/github/rules.js.map +1 -1
- package/dist/integrations/github/sandbox.d.ts +6 -3
- package/dist/integrations/github/sandbox.d.ts.map +1 -1
- package/dist/integrations/github/sandbox.js +21 -2
- package/dist/integrations/github/sandbox.js.map +1 -1
- package/dist/integrations/issue-reconciler.d.ts +2 -0
- package/dist/integrations/issue-reconciler.d.ts.map +1 -1
- package/dist/integrations/issue-reconciler.js +1 -3
- package/dist/integrations/issue-reconciler.js.map +1 -1
- package/dist/integrations/linear/agent-tools.d.ts.map +1 -1
- package/dist/integrations/linear/agent-tools.js.map +1 -1
- package/dist/integrations/linear/default-rules.d.ts +2 -2
- package/dist/integrations/linear/default-rules.d.ts.map +1 -1
- package/dist/integrations/linear/default-rules.js +2 -2
- package/dist/integrations/linear/default-rules.js.map +1 -1
- package/dist/integrations/linear/integration.js +1 -0
- package/dist/integrations/linear/integration.js.map +1 -1
- package/dist/integrations/linear/issue-reconciler.d.ts.map +1 -1
- package/dist/integrations/linear/issue-reconciler.js +9 -4
- package/dist/integrations/linear/issue-reconciler.js.map +1 -1
- package/dist/integrations/linear/reconciliation-config.d.ts.map +1 -1
- package/dist/integrations/linear/reconciliation-config.js.map +1 -1
- package/dist/integrations/linear/routes.d.ts.map +1 -1
- package/dist/integrations/linear/routes.js +19 -26
- package/dist/integrations/linear/routes.js.map +1 -1
- package/dist/integrations/linear/rules.d.ts +7 -2
- package/dist/integrations/linear/rules.d.ts.map +1 -1
- package/dist/integrations/linear/rules.js +20 -8
- package/dist/integrations/linear/rules.js.map +1 -1
- package/dist/integrations/platform/api-client.d.ts.map +1 -1
- package/dist/integrations/platform/api-client.js +25 -4
- package/dist/integrations/platform/api-client.js.map +1 -1
- package/dist/integrations/platform/github/integration.d.ts +1 -0
- package/dist/integrations/platform/github/integration.d.ts.map +1 -1
- package/dist/integrations/platform/github/integration.js +5 -0
- package/dist/integrations/platform/github/integration.js.map +1 -1
- package/dist/integrations/platform/linear/integration.d.ts.map +1 -1
- package/dist/integrations/platform/linear/integration.js +5 -2
- package/dist/integrations/platform/linear/integration.js.map +1 -1
- package/dist/integrations/slack/emoji-shortcodes.generated.d.ts +8 -0
- package/dist/integrations/slack/emoji-shortcodes.generated.d.ts.map +1 -0
- package/dist/integrations/slack/emoji-shortcodes.generated.js +1985 -0
- package/dist/integrations/slack/emoji-shortcodes.generated.js.map +1 -0
- package/dist/integrations/slack/emoji.d.ts +3 -0
- package/dist/integrations/slack/emoji.d.ts.map +1 -0
- package/dist/integrations/slack/emoji.js +12 -0
- package/dist/integrations/slack/emoji.js.map +1 -0
- package/dist/integrations/slack/integration.js +1 -1
- package/dist/integrations/slack/integration.js.map +1 -1
- package/dist/integrations/slack/slack.d.ts.map +1 -1
- package/dist/integrations/slack/slack.js +16 -2
- package/dist/integrations/slack/slack.js.map +1 -1
- package/dist/routes/attention-activity.d.ts +2 -3
- package/dist/routes/attention-activity.d.ts.map +1 -1
- package/dist/routes/attention-activity.js +12 -3
- package/dist/routes/attention-activity.js.map +1 -1
- package/dist/routes/attention-parked.d.ts +22 -0
- package/dist/routes/attention-parked.d.ts.map +1 -0
- package/dist/routes/attention-parked.js +136 -0
- package/dist/routes/attention-parked.js.map +1 -0
- package/dist/routes/attention-providers.js +8 -8
- package/dist/routes/attention-providers.js.map +1 -1
- package/dist/routes/attention.d.ts +2 -0
- package/dist/routes/attention.d.ts.map +1 -1
- package/dist/routes/attention.js +47 -118
- package/dist/routes/attention.js.map +1 -1
- package/dist/routes/contracts.d.ts +627 -0
- package/dist/routes/contracts.d.ts.map +1 -0
- package/dist/routes/contracts.js +468 -0
- package/dist/routes/contracts.js.map +1 -0
- package/dist/routes/intake.d.ts +18 -0
- package/dist/routes/intake.d.ts.map +1 -1
- package/dist/routes/intake.js +265 -15
- package/dist/routes/intake.js.map +1 -1
- package/dist/routes/projects.d.ts.map +1 -1
- package/dist/routes/projects.js +26 -76
- package/dist/routes/projects.js.map +1 -1
- package/dist/routes/supervisor.d.ts +2 -0
- package/dist/routes/supervisor.d.ts.map +1 -1
- package/dist/routes/supervisor.js +7 -6
- package/dist/routes/supervisor.js.map +1 -1
- package/dist/routes/surface.d.ts +7 -4
- package/dist/routes/surface.d.ts.map +1 -1
- package/dist/routes/surface.js +17 -11
- package/dist/routes/surface.js.map +1 -1
- package/dist/routes/telemetry.d.ts +13 -0
- package/dist/routes/telemetry.d.ts.map +1 -0
- package/dist/routes/telemetry.js +60 -0
- package/dist/routes/telemetry.js.map +1 -0
- package/dist/routes/work-items.d.ts +3 -3
- package/dist/routes/work-items.d.ts.map +1 -1
- package/dist/routes/work-items.js +134 -250
- package/dist/routes/work-items.js.map +1 -1
- package/dist/rules/dispatch-errors.d.ts +2 -2
- package/dist/rules/dispatch-errors.d.ts.map +1 -1
- package/dist/rules/dispatch-errors.js +10 -6
- package/dist/rules/dispatch-errors.js.map +1 -1
- package/dist/rules/dispatcher.d.ts +9 -2
- package/dist/rules/dispatcher.d.ts.map +1 -1
- package/dist/rules/dispatcher.js +76 -23
- package/dist/rules/dispatcher.js.map +1 -1
- package/dist/rules/index.d.ts +4 -5
- package/dist/rules/index.d.ts.map +1 -1
- package/dist/rules/index.js +3 -4
- package/dist/rules/processor.d.ts +3 -3
- package/dist/rules/processor.d.ts.map +1 -1
- package/dist/rules/processor.js +24 -31
- package/dist/rules/processor.js.map +1 -1
- package/dist/rules/resolve.d.ts +1 -3
- package/dist/rules/resolve.d.ts.map +1 -1
- package/dist/rules/resolve.js +1 -4
- package/dist/rules/resolve.js.map +1 -1
- package/dist/rules/start-coordinator.d.ts.map +1 -1
- package/dist/rules/start-coordinator.js +3 -1
- package/dist/rules/start-coordinator.js.map +1 -1
- package/dist/rules/tools.d.ts.map +1 -1
- package/dist/rules/tools.js +20 -10
- package/dist/rules/tools.js.map +1 -1
- package/dist/rules/transition-service.d.ts +7 -7
- package/dist/rules/transition-service.d.ts.map +1 -1
- package/dist/rules/transition-service.js +21 -25
- package/dist/rules/transition-service.js.map +1 -1
- package/dist/rules/types.d.ts +16 -11
- package/dist/rules/types.d.ts.map +1 -1
- package/dist/rules/types.js.map +1 -1
- package/dist/rules/validation.d.ts +12 -2
- package/dist/rules/validation.d.ts.map +1 -1
- package/dist/rules/validation.js +29 -20
- package/dist/rules/validation.js.map +1 -1
- package/dist/session/live-sessions.d.ts +33 -3
- package/dist/session/live-sessions.d.ts.map +1 -1
- package/dist/session/live-sessions.js +67 -5
- package/dist/session/live-sessions.js.map +1 -1
- package/dist/storage/domains/intake/base.d.ts +54 -1
- package/dist/storage/domains/intake/base.d.ts.map +1 -1
- package/dist/storage/domains/intake/base.js +136 -4
- package/dist/storage/domains/intake/base.js.map +1 -1
- package/dist/storage/domains/work-items/base.d.ts +22 -7
- package/dist/storage/domains/work-items/base.d.ts.map +1 -1
- package/dist/storage/domains/work-items/base.js +41 -26
- package/dist/storage/domains/work-items/base.js.map +1 -1
- package/dist/supervisor/health-worker.d.ts +2 -0
- package/dist/supervisor/health-worker.d.ts.map +1 -1
- package/dist/supervisor/health-worker.js +3 -1
- package/dist/supervisor/health-worker.js.map +1 -1
- package/dist/supervisor/health.d.ts +12 -14
- package/dist/supervisor/health.d.ts.map +1 -1
- package/dist/supervisor/health.js +24 -52
- package/dist/supervisor/health.js.map +1 -1
- package/dist/supervisor/instructions.d.ts +1 -1
- package/dist/supervisor/instructions.d.ts.map +1 -1
- package/dist/supervisor/instructions.js +10 -8
- package/dist/supervisor/instructions.js.map +1 -1
- package/dist/supervisor/read-tools.d.ts +2 -0
- package/dist/supervisor/read-tools.d.ts.map +1 -1
- package/dist/supervisor/read-tools.js +2 -2
- package/dist/supervisor/read-tools.js.map +1 -1
- package/dist/supervisor/write-tools.d.ts.map +1 -1
- package/dist/supervisor/write-tools.js +6 -4
- package/dist/supervisor/write-tools.js.map +1 -1
- package/dist/telemetry-types.d.ts +7 -0
- package/dist/telemetry-types.d.ts.map +1 -0
- package/dist/telemetry-types.js +24 -0
- package/dist/telemetry-types.js.map +1 -0
- package/dist/telemetry.d.ts +9 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +47 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/work-item-branch.d.ts +2 -0
- package/dist/work-item-branch.d.ts.map +1 -1
- package/dist/work-item-branch.js +6 -1
- package/dist/work-item-branch.js.map +1 -1
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +3 -1
- package/dist/workspace.js.map +1 -1
- package/factory-skills/configure-factory-rules/SKILL.md +30 -10
- package/package.json +11 -9
- package/dist/rules/defaults.d.ts +0 -9
- package/dist/rules/defaults.d.ts.map +0 -1
- package/dist/rules/defaults.js +0 -50
- package/dist/rules/defaults.js.map +0 -1
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
import { BOARD_IDENTIFIER_RE } from "../rules/validation.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/routes/contracts.ts
|
|
4
|
+
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}$";
|
|
5
|
+
const uuidSchema = z.string().regex(new RegExp(UUID_PATTERN));
|
|
6
|
+
const entitySchema = z.record(z.string(), z.unknown());
|
|
7
|
+
const nonEmptyTrimmed = (max) => z.string().trim().min(1).max(max);
|
|
8
|
+
const rawBoundedTrimmed = (max) => z.string().max(max).transform((value) => value.trim()).pipe(z.string().min(1));
|
|
9
|
+
const trimmedUuidSchema = z.string().trim().regex(new RegExp(UUID_PATTERN));
|
|
10
|
+
const nullableTrimmed = (max) => z.union([z.string().trim().max(max).transform((value) => value || null), z.null()]);
|
|
11
|
+
const projectPathSchema = z.object({ id: uuidSchema });
|
|
12
|
+
const projectDecisionPathSchema = z.object({
|
|
13
|
+
id: uuidSchema,
|
|
14
|
+
decisionId: uuidSchema
|
|
15
|
+
});
|
|
16
|
+
const workItemPathSchema = z.object({ id: uuidSchema });
|
|
17
|
+
const transitionPathSchema = z.object({
|
|
18
|
+
id: uuidSchema,
|
|
19
|
+
workItemId: uuidSchema
|
|
20
|
+
});
|
|
21
|
+
const projectSchema = entitySchema;
|
|
22
|
+
const projectResponseSchema = z.object({ project: projectSchema });
|
|
23
|
+
const workItemResponseSchema = z.object({ workItem: entitySchema });
|
|
24
|
+
const decisionResponseSchema = z.object({ decision: entitySchema });
|
|
25
|
+
const createProjectBodySchema = z.object({
|
|
26
|
+
name: nonEmptyTrimmed(200),
|
|
27
|
+
description: nullableTrimmed(2e3).optional().default(null)
|
|
28
|
+
});
|
|
29
|
+
const updateProjectBodySchema = z.object({
|
|
30
|
+
name: nonEmptyTrimmed(200).optional(),
|
|
31
|
+
description: nullableTrimmed(2e3).optional(),
|
|
32
|
+
defaultModelId: nullableTrimmed(200).optional(),
|
|
33
|
+
slackWorkItemsEnabled: z.boolean().optional(),
|
|
34
|
+
autoRunEnabled: z.boolean().optional(),
|
|
35
|
+
autoApprovePlans: z.boolean().optional()
|
|
36
|
+
}).refine((input) => Object.keys(input).length > 0, { message: "At least one project field is required" });
|
|
37
|
+
const stagesSchema = z.array(z.string().max(64).regex(/^[a-z0-9][a-z0-9_-]*$/i)).min(1).max(16).refine((stages) => new Set(stages).size === stages.length, { message: "Stages must be unique" });
|
|
38
|
+
const externalSourceSchema = z.object({
|
|
39
|
+
integrationId: z.string().min(1).max(128),
|
|
40
|
+
type: z.string().min(1).max(128),
|
|
41
|
+
externalId: z.string().min(1).max(512),
|
|
42
|
+
url: z.string().max(2048).optional()
|
|
43
|
+
}).nullable();
|
|
44
|
+
const sessionSchema = z.object({
|
|
45
|
+
sessionId: z.string().min(1).max(512),
|
|
46
|
+
branch: z.string().min(1).max(512),
|
|
47
|
+
threadId: z.string().min(1).max(512)
|
|
48
|
+
});
|
|
49
|
+
const sessionsSchema = z.record(z.string().min(1).max(64), sessionSchema);
|
|
50
|
+
const metadataSchema = z.union([z.record(z.string(), z.unknown()), z.null()]).refine((value) => {
|
|
51
|
+
try {
|
|
52
|
+
return JSON.stringify(value).length <= 16 * 1024;
|
|
53
|
+
} catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}, "Metadata exceeds 16 KiB").transform((value) => {
|
|
57
|
+
if (value === null) return null;
|
|
58
|
+
const { factoryRuleMaterializationKey: _materialization, factoryPullRequestReconciliation: _reconciliation, ...metadata } = value;
|
|
59
|
+
return metadata;
|
|
60
|
+
});
|
|
61
|
+
const createWorkItemBodySchema = z.object({
|
|
62
|
+
title: rawBoundedTrimmed(500),
|
|
63
|
+
board: z.string().min(1).max(128).optional(),
|
|
64
|
+
externalSource: externalSourceSchema.optional(),
|
|
65
|
+
parentWorkItemId: uuidSchema.nullable().optional(),
|
|
66
|
+
stages: stagesSchema.optional(),
|
|
67
|
+
sessions: sessionsSchema.optional(),
|
|
68
|
+
metadata: metadataSchema.optional()
|
|
69
|
+
});
|
|
70
|
+
const updateWorkItemBodySchema = z.object({
|
|
71
|
+
title: rawBoundedTrimmed(500).optional(),
|
|
72
|
+
board: z.string().min(1).max(128).optional(),
|
|
73
|
+
parentWorkItemId: uuidSchema.nullable().optional(),
|
|
74
|
+
stages: stagesSchema.optional(),
|
|
75
|
+
sessions: sessionsSchema.optional(),
|
|
76
|
+
metadata: metadataSchema.optional(),
|
|
77
|
+
plansPreapproved: z.literal(true).optional()
|
|
78
|
+
}).refine((input) => Object.keys(input).length > 0, { message: "At least one work-item field is required" });
|
|
79
|
+
const transitionBodySchema = z.object({
|
|
80
|
+
board: z.string().max(128).regex(BOARD_IDENTIFIER_RE),
|
|
81
|
+
stage: z.string().max(128).regex(BOARD_IDENTIFIER_RE),
|
|
82
|
+
expectedRevision: z.number().int().min(1),
|
|
83
|
+
requestId: trimmedUuidSchema,
|
|
84
|
+
cause: nonEmptyTrimmed(256),
|
|
85
|
+
reenter: z.unknown().optional()
|
|
86
|
+
}).transform((input) => ({
|
|
87
|
+
board: input.board,
|
|
88
|
+
stage: input.stage,
|
|
89
|
+
expectedRevision: input.expectedRevision,
|
|
90
|
+
ingress: {
|
|
91
|
+
type: "human",
|
|
92
|
+
identity: input.requestId
|
|
93
|
+
},
|
|
94
|
+
cause: input.cause,
|
|
95
|
+
...input.reenter === true ? { reenter: true } : {}
|
|
96
|
+
}));
|
|
97
|
+
const startWorkItemBodySchema = z.object({
|
|
98
|
+
sessionId: trimmedUuidSchema,
|
|
99
|
+
threadTitle: nonEmptyTrimmed(512),
|
|
100
|
+
kickoffKey: trimmedUuidSchema,
|
|
101
|
+
workItem: z.object({
|
|
102
|
+
id: trimmedUuidSchema,
|
|
103
|
+
role: nonEmptyTrimmed(32),
|
|
104
|
+
input: createWorkItemBodySchema
|
|
105
|
+
})
|
|
106
|
+
});
|
|
107
|
+
const metricsQuerySchema = z.object({
|
|
108
|
+
from: z.string().optional(),
|
|
109
|
+
to: z.string().optional()
|
|
110
|
+
});
|
|
111
|
+
const decisionStatusSchema = z.enum([
|
|
112
|
+
"pending",
|
|
113
|
+
"proposed",
|
|
114
|
+
"dismissed",
|
|
115
|
+
"superseded",
|
|
116
|
+
"leased",
|
|
117
|
+
"retry",
|
|
118
|
+
"succeeded",
|
|
119
|
+
"failed"
|
|
120
|
+
]);
|
|
121
|
+
const boundedLimitSchema = (defaultValue, max) => z.string().optional().transform((value) => {
|
|
122
|
+
const parsed = value ? Number.parseInt(value, 10) : defaultValue;
|
|
123
|
+
return Number.isFinite(parsed) ? Math.max(1, Math.min(max, parsed)) : defaultValue;
|
|
124
|
+
});
|
|
125
|
+
const decisionCursorSchema = z.string().optional().transform((value, context) => {
|
|
126
|
+
if (!value) return void 0;
|
|
127
|
+
try {
|
|
128
|
+
const decoded = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
|
|
129
|
+
if (!Array.isArray(decoded) || decoded.length !== 2 || typeof decoded[0] !== "string" || typeof decoded[1] !== "string") throw new Error("invalid cursor");
|
|
130
|
+
const createdAt = new Date(decoded[0]);
|
|
131
|
+
if (Number.isNaN(createdAt.getTime()) || !(/* @__PURE__ */ new RegExp("^[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}$")).test(decoded[1])) throw new Error("invalid cursor");
|
|
132
|
+
return {
|
|
133
|
+
createdAt,
|
|
134
|
+
id: decoded[1]
|
|
135
|
+
};
|
|
136
|
+
} catch {
|
|
137
|
+
context.addIssue({
|
|
138
|
+
code: "custom",
|
|
139
|
+
message: "Invalid cursor"
|
|
140
|
+
});
|
|
141
|
+
return z.NEVER;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
const decisionQuerySchema = z.object({
|
|
145
|
+
statuses: z.string().optional().transform((value) => {
|
|
146
|
+
if (!value) return void 0;
|
|
147
|
+
const statuses = [...new Set(value.split(",").map((status) => status.trim()))].filter((status) => decisionStatusSchema.safeParse(status).success);
|
|
148
|
+
return statuses.length > 0 ? statuses : void 0;
|
|
149
|
+
}),
|
|
150
|
+
before: decisionCursorSchema,
|
|
151
|
+
limit: boundedLimitSchema(25, 50)
|
|
152
|
+
});
|
|
153
|
+
const attentionKindSchema = z.enum([
|
|
154
|
+
"automation-failed",
|
|
155
|
+
"automation-proposed",
|
|
156
|
+
"mention",
|
|
157
|
+
"activity",
|
|
158
|
+
"supervisor-finding",
|
|
159
|
+
"agent-waiting"
|
|
160
|
+
]);
|
|
161
|
+
function parseAttentionStreamPosition(value) {
|
|
162
|
+
if (!Array.isArray(value) || value.length !== 2 || typeof value[0] !== "string" || typeof value[1] !== "string") return;
|
|
163
|
+
const occurredAt = new Date(value[0]);
|
|
164
|
+
if (Number.isNaN(occurredAt.getTime()) || !(/* @__PURE__ */ new RegExp("^[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}$")).test(value[1])) return void 0;
|
|
165
|
+
return {
|
|
166
|
+
occurredAt,
|
|
167
|
+
id: value[1]
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
const attentionCursorSchema = z.string().optional().transform((value, context) => {
|
|
171
|
+
if (!value) return void 0;
|
|
172
|
+
try {
|
|
173
|
+
const decoded = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
|
|
174
|
+
if (Array.isArray(decoded)) {
|
|
175
|
+
const legacy = parseAttentionStreamPosition(decoded);
|
|
176
|
+
if (!legacy) throw new Error("invalid cursor");
|
|
177
|
+
return /* @__PURE__ */ new Map([["automation-failed", legacy]]);
|
|
178
|
+
}
|
|
179
|
+
if (!decoded || typeof decoded !== "object") throw new Error("invalid cursor");
|
|
180
|
+
const cursors = /* @__PURE__ */ new Map();
|
|
181
|
+
for (const [kind, positionValue] of Object.entries(decoded)) {
|
|
182
|
+
const parsedKind = attentionKindSchema.safeParse(kind);
|
|
183
|
+
if (!parsedKind.success) throw new Error("invalid cursor");
|
|
184
|
+
if (positionValue === null) {
|
|
185
|
+
cursors.set(parsedKind.data, void 0);
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const position = parseAttentionStreamPosition(positionValue);
|
|
189
|
+
if (!position) throw new Error("invalid cursor");
|
|
190
|
+
cursors.set(parsedKind.data, position);
|
|
191
|
+
}
|
|
192
|
+
if (cursors.size === 0) throw new Error("invalid cursor");
|
|
193
|
+
return cursors;
|
|
194
|
+
} catch {
|
|
195
|
+
context.addIssue({
|
|
196
|
+
code: "custom",
|
|
197
|
+
message: "Invalid cursor"
|
|
198
|
+
});
|
|
199
|
+
return z.NEVER;
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
const attentionQuerySchema = z.object({
|
|
203
|
+
view: z.enum([
|
|
204
|
+
"open",
|
|
205
|
+
"unread",
|
|
206
|
+
"archived"
|
|
207
|
+
]).optional().default("open"),
|
|
208
|
+
kind: z.array(attentionKindSchema).optional(),
|
|
209
|
+
before: attentionCursorSchema,
|
|
210
|
+
limit: boundedLimitSchema(25, 50),
|
|
211
|
+
search: z.string().optional().transform((value) => value?.trim().toLowerCase().slice(0, 200) || void 0)
|
|
212
|
+
});
|
|
213
|
+
const attentionActionPathSchema = z.object({
|
|
214
|
+
id: uuidSchema,
|
|
215
|
+
kind: attentionKindSchema,
|
|
216
|
+
sourceId: z.string().min(1).max(256),
|
|
217
|
+
occurrence: z.string().regex(/^(0|[1-9]\d*)$/).transform((value, context) => {
|
|
218
|
+
const occurrence = Number(value);
|
|
219
|
+
if (Number.isSafeInteger(occurrence)) return occurrence;
|
|
220
|
+
context.addIssue({
|
|
221
|
+
code: "custom",
|
|
222
|
+
message: "Invalid occurrence"
|
|
223
|
+
});
|
|
224
|
+
return z.NEVER;
|
|
225
|
+
})
|
|
226
|
+
}).refine((input) => input.kind === "supervisor-finding" ? /^[a-z0-9:_-]{1,256}$/i.test(input.sourceId) : new RegExp(UUID_PATTERN).test(input.sourceId), {
|
|
227
|
+
message: "Invalid attention source id",
|
|
228
|
+
path: ["sourceId"]
|
|
229
|
+
});
|
|
230
|
+
const FACTORY_ROUTE_CONTRACTS = {
|
|
231
|
+
projectList: {
|
|
232
|
+
method: "GET",
|
|
233
|
+
path: "/web/factory/projects",
|
|
234
|
+
description: "List Factory projects for the current organization",
|
|
235
|
+
responseSchema: z.object({ projects: z.array(projectSchema) })
|
|
236
|
+
},
|
|
237
|
+
projectCreate: {
|
|
238
|
+
method: "POST",
|
|
239
|
+
path: "/web/factory/projects",
|
|
240
|
+
description: "Create a Factory project",
|
|
241
|
+
bodySchema: createProjectBodySchema,
|
|
242
|
+
responseSchema: projectResponseSchema
|
|
243
|
+
},
|
|
244
|
+
projectGet: {
|
|
245
|
+
method: "GET",
|
|
246
|
+
path: "/web/factory/projects/:id",
|
|
247
|
+
description: "Get a Factory project",
|
|
248
|
+
pathSchema: projectPathSchema,
|
|
249
|
+
responseSchema: projectResponseSchema
|
|
250
|
+
},
|
|
251
|
+
projectUpdate: {
|
|
252
|
+
method: "PATCH",
|
|
253
|
+
path: "/web/factory/projects/:id",
|
|
254
|
+
description: "Update a Factory project",
|
|
255
|
+
pathSchema: projectPathSchema,
|
|
256
|
+
bodySchema: updateProjectBodySchema,
|
|
257
|
+
responseSchema: projectResponseSchema
|
|
258
|
+
},
|
|
259
|
+
projectDelete: {
|
|
260
|
+
method: "DELETE",
|
|
261
|
+
path: "/web/factory/projects/:id",
|
|
262
|
+
description: "Delete a Factory project",
|
|
263
|
+
pathSchema: projectPathSchema,
|
|
264
|
+
responseSchema: z.null()
|
|
265
|
+
},
|
|
266
|
+
metricsGet: {
|
|
267
|
+
method: "GET",
|
|
268
|
+
path: "/web/factory/projects/:id/metrics",
|
|
269
|
+
description: "Get Factory project metrics",
|
|
270
|
+
pathSchema: projectPathSchema,
|
|
271
|
+
querySchema: metricsQuerySchema,
|
|
272
|
+
responseSchema: z.object({ metrics: entitySchema })
|
|
273
|
+
},
|
|
274
|
+
healthThresholdsGet: {
|
|
275
|
+
method: "GET",
|
|
276
|
+
path: "/web/factory/projects/:id/health/thresholds",
|
|
277
|
+
description: "Get queue-health thresholds",
|
|
278
|
+
pathSchema: projectPathSchema,
|
|
279
|
+
responseSchema: z.object({ thresholds: z.array(z.number().finite()) })
|
|
280
|
+
},
|
|
281
|
+
boardCatalog: {
|
|
282
|
+
method: "GET",
|
|
283
|
+
path: "/web/factory/projects/:id/boards",
|
|
284
|
+
description: "List installed Factory boards",
|
|
285
|
+
pathSchema: projectPathSchema,
|
|
286
|
+
responseSchema: z.object({ boards: z.array(z.object({
|
|
287
|
+
id: z.string(),
|
|
288
|
+
title: z.string(),
|
|
289
|
+
initialPhase: z.string(),
|
|
290
|
+
phases: z.array(z.object({
|
|
291
|
+
id: z.string(),
|
|
292
|
+
title: z.string(),
|
|
293
|
+
kind: z.enum([
|
|
294
|
+
"resting",
|
|
295
|
+
"working",
|
|
296
|
+
"terminal"
|
|
297
|
+
]),
|
|
298
|
+
role: z.string().optional(),
|
|
299
|
+
transitions: z.array(z.object({
|
|
300
|
+
outcome: z.string().nullable(),
|
|
301
|
+
to: z.string()
|
|
302
|
+
}))
|
|
303
|
+
}))
|
|
304
|
+
})) })
|
|
305
|
+
},
|
|
306
|
+
workItemList: {
|
|
307
|
+
method: "GET",
|
|
308
|
+
path: "/web/factory/projects/:id/work-items",
|
|
309
|
+
description: "List Factory work items and running sessions",
|
|
310
|
+
pathSchema: projectPathSchema,
|
|
311
|
+
responseSchema: z.object({
|
|
312
|
+
workItems: z.array(entitySchema),
|
|
313
|
+
runningSessionIds: z.array(z.string()),
|
|
314
|
+
parkedSessionIds: z.array(z.string())
|
|
315
|
+
})
|
|
316
|
+
},
|
|
317
|
+
workItemCreate: {
|
|
318
|
+
method: "POST",
|
|
319
|
+
path: "/web/factory/projects/:id/work-items",
|
|
320
|
+
description: "Create a work item in Intake",
|
|
321
|
+
pathSchema: projectPathSchema,
|
|
322
|
+
bodySchema: createWorkItemBodySchema,
|
|
323
|
+
responseSchema: workItemResponseSchema
|
|
324
|
+
},
|
|
325
|
+
workItemUpdate: {
|
|
326
|
+
method: "PATCH",
|
|
327
|
+
path: "/web/factory/work-items/:id",
|
|
328
|
+
description: "Update non-stage work-item fields",
|
|
329
|
+
pathSchema: workItemPathSchema,
|
|
330
|
+
bodySchema: updateWorkItemBodySchema,
|
|
331
|
+
responseSchema: workItemResponseSchema
|
|
332
|
+
},
|
|
333
|
+
workItemDelete: {
|
|
334
|
+
method: "DELETE",
|
|
335
|
+
path: "/web/factory/work-items/:id",
|
|
336
|
+
description: "Delete a Factory work item",
|
|
337
|
+
pathSchema: workItemPathSchema,
|
|
338
|
+
responseSchema: z.object({ ok: z.literal(true) })
|
|
339
|
+
},
|
|
340
|
+
workItemTransition: {
|
|
341
|
+
method: "POST",
|
|
342
|
+
path: "/web/factory/projects/:id/work-items/:workItemId/transition",
|
|
343
|
+
description: "Transition a work item with its expected revision",
|
|
344
|
+
pathSchema: transitionPathSchema,
|
|
345
|
+
bodySchema: transitionBodySchema,
|
|
346
|
+
responseSchema: entitySchema
|
|
347
|
+
},
|
|
348
|
+
workItemStart: {
|
|
349
|
+
method: "POST",
|
|
350
|
+
path: "/web/factory/projects/:id/runs/start",
|
|
351
|
+
description: "Explicitly start a Factory work-item run",
|
|
352
|
+
pathSchema: projectPathSchema,
|
|
353
|
+
bodySchema: startWorkItemBodySchema,
|
|
354
|
+
responseSchema: entitySchema
|
|
355
|
+
},
|
|
356
|
+
decisionList: {
|
|
357
|
+
method: "GET",
|
|
358
|
+
path: "/web/factory/projects/:id/decisions",
|
|
359
|
+
description: "List Factory decisions",
|
|
360
|
+
pathSchema: projectPathSchema,
|
|
361
|
+
querySchema: decisionQuerySchema,
|
|
362
|
+
responseSchema: z.object({
|
|
363
|
+
decisions: z.array(entitySchema),
|
|
364
|
+
nextCursor: z.string().optional()
|
|
365
|
+
})
|
|
366
|
+
},
|
|
367
|
+
decisionApprove: {
|
|
368
|
+
method: "POST",
|
|
369
|
+
path: "/web/factory/projects/:id/decisions/:decisionId/approve",
|
|
370
|
+
description: "Approve a proposed Factory decision",
|
|
371
|
+
pathSchema: projectDecisionPathSchema,
|
|
372
|
+
responseSchema: decisionResponseSchema
|
|
373
|
+
},
|
|
374
|
+
decisionDismiss: {
|
|
375
|
+
method: "POST",
|
|
376
|
+
path: "/web/factory/projects/:id/decisions/:decisionId/dismiss",
|
|
377
|
+
description: "Dismiss a proposed Factory decision",
|
|
378
|
+
pathSchema: projectDecisionPathSchema,
|
|
379
|
+
responseSchema: decisionResponseSchema
|
|
380
|
+
},
|
|
381
|
+
decisionRetry: {
|
|
382
|
+
method: "POST",
|
|
383
|
+
path: "/web/factory/projects/:id/decisions/:decisionId/retry",
|
|
384
|
+
description: "Retry a failed retryable Factory decision",
|
|
385
|
+
pathSchema: projectDecisionPathSchema,
|
|
386
|
+
responseSchema: decisionResponseSchema
|
|
387
|
+
},
|
|
388
|
+
attentionList: {
|
|
389
|
+
method: "GET",
|
|
390
|
+
path: "/web/factory/projects/:id/attention",
|
|
391
|
+
description: "List the Factory attention inbox",
|
|
392
|
+
pathSchema: projectPathSchema,
|
|
393
|
+
querySchema: attentionQuerySchema,
|
|
394
|
+
responseSchema: z.object({
|
|
395
|
+
items: z.array(entitySchema),
|
|
396
|
+
kinds: z.record(attentionKindSchema, z.object({
|
|
397
|
+
open: z.number(),
|
|
398
|
+
unread: z.number(),
|
|
399
|
+
latest: z.object({
|
|
400
|
+
key: z.string(),
|
|
401
|
+
at: z.string(),
|
|
402
|
+
unread: z.boolean()
|
|
403
|
+
}).nullable()
|
|
404
|
+
})),
|
|
405
|
+
hasMore: z.boolean(),
|
|
406
|
+
nextCursor: z.string().optional()
|
|
407
|
+
})
|
|
408
|
+
},
|
|
409
|
+
attentionReadAll: {
|
|
410
|
+
method: "POST",
|
|
411
|
+
path: "/web/factory/projects/:id/attention/read-all",
|
|
412
|
+
description: "Mark all Factory attention as read",
|
|
413
|
+
pathSchema: projectPathSchema,
|
|
414
|
+
querySchema: z.object({ before: attentionCursorSchema }),
|
|
415
|
+
responseSchema: z.object({
|
|
416
|
+
ok: z.literal(true),
|
|
417
|
+
hasMore: z.boolean(),
|
|
418
|
+
nextCursor: z.string().optional()
|
|
419
|
+
})
|
|
420
|
+
},
|
|
421
|
+
attentionRead: {
|
|
422
|
+
method: "POST",
|
|
423
|
+
path: "/web/factory/projects/:id/attention/:kind/:sourceId/:occurrence/read",
|
|
424
|
+
description: "Mark a Factory attention receipt as read",
|
|
425
|
+
pathSchema: attentionActionPathSchema,
|
|
426
|
+
responseSchema: z.object({ receipt: entitySchema })
|
|
427
|
+
},
|
|
428
|
+
attentionArchive: {
|
|
429
|
+
method: "POST",
|
|
430
|
+
path: "/web/factory/projects/:id/attention/:kind/:sourceId/:occurrence/archive",
|
|
431
|
+
description: "Archive a Factory attention receipt",
|
|
432
|
+
pathSchema: attentionActionPathSchema,
|
|
433
|
+
responseSchema: z.object({ receipt: entitySchema })
|
|
434
|
+
},
|
|
435
|
+
attentionRestore: {
|
|
436
|
+
method: "POST",
|
|
437
|
+
path: "/web/factory/projects/:id/attention/:kind/:sourceId/:occurrence/restore",
|
|
438
|
+
description: "Restore an archived Factory attention receipt",
|
|
439
|
+
pathSchema: attentionActionPathSchema,
|
|
440
|
+
responseSchema: z.object({ receipt: entitySchema })
|
|
441
|
+
},
|
|
442
|
+
supervisorSession: {
|
|
443
|
+
method: "POST",
|
|
444
|
+
path: "/web/factory/projects/:id/supervisor/session",
|
|
445
|
+
description: "Get the deterministic Factory supervisor session address",
|
|
446
|
+
pathSchema: projectPathSchema,
|
|
447
|
+
responseSchema: z.object({
|
|
448
|
+
sessionId: z.string(),
|
|
449
|
+
threadId: z.string(),
|
|
450
|
+
factoryProjectId: uuidSchema
|
|
451
|
+
})
|
|
452
|
+
},
|
|
453
|
+
supervisorHealth: {
|
|
454
|
+
method: "GET",
|
|
455
|
+
path: "/web/factory/projects/:id/supervisor/health",
|
|
456
|
+
description: "Run the deterministic Factory supervisor health check",
|
|
457
|
+
pathSchema: projectPathSchema,
|
|
458
|
+
responseSchema: z.object({
|
|
459
|
+
checkedAt: z.string(),
|
|
460
|
+
findings: z.array(entitySchema),
|
|
461
|
+
counts: z.record(z.string(), z.number().int().nonnegative())
|
|
462
|
+
})
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
//#endregion
|
|
466
|
+
export { FACTORY_ROUTE_CONTRACTS, UUID_PATTERN, attentionQuerySchema, createProjectBodySchema, createWorkItemBodySchema, decisionQuerySchema, metricsQuerySchema, startWorkItemBodySchema, transitionBodySchema, updateProjectBodySchema, updateWorkItemBodySchema };
|
|
467
|
+
|
|
468
|
+
//# sourceMappingURL=contracts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.js","names":[],"sources":["../../src/routes/contracts.ts"],"sourcesContent":["import { z } from 'zod';\n\nimport { BOARD_IDENTIFIER_RE, MAX_BOARD_IDENTIFIER_LENGTH } from '../rules/validation.js';\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 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 ...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 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 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 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/intake.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { ApiRoute } from '@mastra/core/server';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import type { BoardRegistry } from '../boards/index.js';
|
|
2
4
|
import type { Intake } from '../capabilities/intake.js';
|
|
3
5
|
import type { AuditEmitter } from '../storage/domains/audit/domain.js';
|
|
4
6
|
import type { IntakeConfig, IntakeStorage } from '../storage/domains/intake/base.js';
|
|
7
|
+
import type { WorkItemsStorage } from '../storage/domains/work-items/base.js';
|
|
5
8
|
import type { RouteDependencies } from './route.js';
|
|
6
9
|
import { Route } from './route.js';
|
|
7
10
|
export interface IntakeIntegration {
|
|
@@ -20,6 +23,10 @@ export interface IntakeRoutesDeps extends RouteDependencies {
|
|
|
20
23
|
}): Promise<unknown | null>;
|
|
21
24
|
};
|
|
22
25
|
integrations?: IntakeIntegration[];
|
|
26
|
+
/** Installed boards, used to validate binding targets. Absent means only legacy routing is accepted. */
|
|
27
|
+
boardRegistry?: BoardRegistry;
|
|
28
|
+
/** Work items domain handle; when present, rebinding a source to another board moves its resting cards. */
|
|
29
|
+
workItems?: Pick<WorkItemsStorage, 'list' | 'update' | 'supersedeDecisionsForWorkItem'>;
|
|
23
30
|
}
|
|
24
31
|
/** One integration that failed while the rest of the aggregation succeeded. */
|
|
25
32
|
export interface IntakeIntegrationFailure {
|
|
@@ -30,9 +37,20 @@ interface ParsedBinding {
|
|
|
30
37
|
integrationId: string;
|
|
31
38
|
sourceId: string;
|
|
32
39
|
factoryProjectId: string | null;
|
|
40
|
+
/** Installed board target; `null`/omitted keeps legacy source-type routing. */
|
|
41
|
+
board: string | null;
|
|
33
42
|
}
|
|
34
43
|
/** Validate a binding request body, rejecting unknown shapes. */
|
|
35
44
|
export declare function parseIntakeBinding(body: unknown): ParsedBinding | null;
|
|
45
|
+
declare const labelRouteBodySchema: z.ZodObject<{
|
|
46
|
+
factoryProjectId: z.ZodString;
|
|
47
|
+
integrationId: z.ZodString;
|
|
48
|
+
label: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
49
|
+
board: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null, string | null | undefined>>;
|
|
50
|
+
}, z.core.$strip>;
|
|
51
|
+
type ParsedLabelRoute = z.output<typeof labelRouteBodySchema>;
|
|
52
|
+
/** Validate a label-route request body, rejecting unknown shapes. */
|
|
53
|
+
export declare function parseIntakeLabelRoute(body: unknown): ParsedLabelRoute | null;
|
|
36
54
|
/** Validate a request body into an intake config, rejecting unknown shapes. */
|
|
37
55
|
export declare function parseIntakeConfig(body: unknown): IntakeConfig | null;
|
|
38
56
|
export declare class IntakeRoutes extends Route<IntakeRoutesDeps> {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intake.d.ts","sourceRoot":"","sources":["../../src/routes/intake.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"intake.d.ts","sourceRoot":"","sources":["../../src/routes/intake.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAEvE,OAAO,KAAK,EAAE,YAAY,EAAoB,aAAa,EAAE,MAAM,mCAAmC,CAAC;AACvG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,CAAC,CAAC;CACnD;AAYD,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB;IACzD,KAAK,EAAE,YAAY,CAAC;IACpB,sCAAsC;IACtC,MAAM,EAAE,aAAa,CAAC;IACtB,uEAAuE;IACvE,QAAQ,CAAC,EAAE;QAAE,GAAG,CAAC,KAAK,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;KAAE,CAAC;IAClF,YAAY,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACnC,wGAAwG;IACxG,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,2GAA2G;IAC3G,SAAS,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,MAAM,GAAG,QAAQ,GAAG,+BAA+B,CAAC,CAAC;CACzF;AAuHD,+EAA+E;AAC/E,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AAkDD,UAAU,aAAa;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,+EAA+E;IAC/E,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,IAAI,CAatE;AAGD,QAAA,MAAM,oBAAoB;;;;;iBAUxB,CAAC;AACH,KAAK,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAE9D,qEAAqE;AACrE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,CAG5E;AAaD,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,GAAG,IAAI,CAyBpE;AAmBD,qBAAa,YAAa,SAAQ,KAAK,CAAC,gBAAgB,CAAC;;IAgBvD,MAAM,IAAI,QAAQ,EAAE;CAsUrB"}
|